diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e38dee92db2931..03920982ee0862 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -511,6 +511,7 @@ void CodeGenModule::Release() { EmitGlobalAnnotations(); EmitStaticExternCAliases(); EmitDeferredUnusedCoverageMappings(); + CodeGenPGO(*this).setValueProfilingFlag(getModule()); if (CoverageMapping) CoverageMapping->emit(); if (CodeGenOpts.SanitizeCfiCrossDso) { diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 49b38a404f5dcc..d828ac0eb5e989 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -962,6 +962,12 @@ void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S, makeArrayRef(Args)); } +void CodeGenPGO::setValueProfilingFlag(llvm::Module &M) { + if (CGM.getCodeGenOpts().hasProfileClangInstr()) + M.addModuleFlag(llvm::Module::Warning, "EnableValueProfiling", + uint32_t(EnableValueProfiling)); +} + // This method either inserts a call to the profile run-time during // instrumentation or puts profile data into metadata for PGO use. void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind, diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index 906c5e406d77c4..f740692ac205b9 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -87,6 +87,10 @@ class CodeGenPGO { // Insert instrumentation or attach profile metadata at value sites void valueProfile(CGBuilderTy &Builder, uint32_t ValueKind, llvm::Instruction *ValueSite, llvm::Value *ValuePtr); + + // Set a module flag indicating if value profiling is enabled. + void setValueProfilingFlag(llvm::Module &M); + private: void setFuncName(llvm::Function *Fn); void setFuncName(StringRef Name, llvm::GlobalValue::LinkageTypes Linkage); diff --git a/compiler-rt/test/profile/instrprof-value-prof-2.c b/compiler-rt/test/profile/instrprof-value-prof-2.c index 88a2de039979e1..abc990ac8b0523 100644 --- a/compiler-rt/test/profile/instrprof-value-prof-2.c +++ b/compiler-rt/test/profile/instrprof-value-prof-2.c @@ -1,4 +1,4 @@ -// RUN: %clang_profgen -O2 -o %t %s +// RUN: %clang_profgen -mllvm -enable-value-profiling -O2 -o %t %s // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t // RUN: llvm-profdata merge -o %t.profdata %t.profraw // RUN: llvm-profdata show --all-functions -ic-targets %t.profdata > %t.out diff --git a/compiler-rt/test/profile/instrprof-value-prof.c b/compiler-rt/test/profile/instrprof-value-prof.c index 53e5fdafc5207e..3e8203f8182d10 100644 --- a/compiler-rt/test/profile/instrprof-value-prof.c +++ b/compiler-rt/test/profile/instrprof-value-prof.c @@ -1,4 +1,4 @@ -// RUN: %clang_profgen -mllvm -vp-static-alloc=false -O2 -o %t %s +// RUN: %clang_profgen -mllvm -enable-value-profiling -mllvm -vp-static-alloc=false -O2 -o %t %s // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t // RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t DO_NOT_INSTRUMENT // RUN: llvm-profdata merge -o %t.profdata %t.profraw diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index bdb182403041e5..1b092f25180413 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -748,7 +748,26 @@ static std::string getVarName(InstrProfIncrementInst *Inc, StringRef Prefix) { return (Prefix + Name + "." + Twine(FuncHash)).str(); } +static uint64_t getIntModuleFlagOrZero(Module *M, StringRef Flag) { + auto *MD = dyn_cast_or_null(M->getModuleFlag(Flag)); + if (!MD) + return 0; + + // If the flag is a ConstantAsMetadata, it should be an integer representable + // in 64-bits. + return cast(MD->getValue())->getZExtValue(); +} + static inline bool shouldRecordFunctionAddr(Function *F) { + // Only record function addresses if IR PGO is enabled or if clang value + // profiling is enabled. Recording function addresses greatly increases object + // file size, because it prevents the inliner from deleting functions that + // have been inlined everywhere. + if (!isIRPGOFlagSet(F->getParent()) && + getIntModuleFlagOrZero(F->getParent(), "EnableValueProfiling") == 0) { + return false; + } + // Check the linkage bool HasAvailableExternallyLinkage = F->hasAvailableExternallyLinkage(); if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage() &&