diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenPGO.cpp | 33 | ||||
| -rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Driver/Tools.cpp | 7 |
3 files changed, 32 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 7b45650572a..ef490ff6799 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -814,6 +814,35 @@ namespace { }; } +static void emitRuntimeHook(CodeGenModule &CGM) { + constexpr const char *RuntimeVarName = "__llvm_profile_runtime"; + constexpr const char *RuntimeUserName = "__llvm_profile_runtime_user"; + if (CGM.getModule().getGlobalVariable(RuntimeVarName)) + return; + + // Declare the runtime hook. + llvm::LLVMContext &Ctx = CGM.getLLVMContext(); + auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); + auto *Var = new llvm::GlobalVariable(CGM.getModule(), Int32Ty, false, + llvm::GlobalValue::ExternalLinkage, + nullptr, RuntimeVarName); + + // Make a function that uses it. + auto *User = llvm::Function::Create(llvm::FunctionType::get(Int32Ty, false), + llvm::GlobalValue::LinkOnceODRLinkage, + RuntimeUserName, &CGM.getModule()); + User->addFnAttr(llvm::Attribute::NoInline); + if (CGM.getCodeGenOpts().DisableRedZone) + User->addFnAttr(llvm::Attribute::NoRedZone); + CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", User)); + auto *Load = Builder.CreateLoad(Var); + Builder.CreateRet(Load); + + // Create a use of the function. Now the definition of the runtime variable + // should get pulled in, along with any static initializears. + CGM.addUsedGlobal(User); +} + void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) { bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate; PGOProfileData *PGOData = CGM.getPGOData(); @@ -839,8 +868,10 @@ void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) { } mapRegionCounters(D); - if (InstrumentRegions) + if (InstrumentRegions) { + emitRuntimeHook(CGM); emitCounterVariables(); + } if (PGOData) { loadRegionCounts(PGOData); computeRegionCounts(D); diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index b348d6c24d6..4bb8332ea7d 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -325,13 +325,6 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, Args.hasArg(options::OPT_fprofile_instr_generate) || Args.hasArg(options::OPT_fcreate_profile) || Args.hasArg(options::OPT_coverage)) { - // Pull in runtime for -fprofile-inst-generate. This is required since - // there are no calls to the runtime in the code. - if (Args.hasArg(options::OPT_fprofile_instr_generate)) { - CmdArgs.push_back("-u"); - CmdArgs.push_back("___llvm_profile_runtime"); - } - // Select the appropriate runtime library for the target. if (isTargetIOSBased()) AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a"); diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 2141cc9656b..9a31eb9f9d6 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1817,13 +1817,6 @@ static void addProfileRT( Args.hasArg(options::OPT_coverage))) return; - // Pull in runtime for -fprofile-inst-generate. This is required since there - // are no calls to the runtime in the code. - if (Args.hasArg(options::OPT_fprofile_instr_generate)) { - CmdArgs.push_back("-u"); - CmdArgs.push_back("___llvm_profile_runtime"); - } - SmallString<128> LibProfile = getCompilerRTLibDir(TC); llvm::sys::path::append(LibProfile, Twine("libclang_rt.profile-") + getArchNameForCompilerRTLib(TC) + ".a"); |

