110110#include " llvm/Transforms/Instrumentation.h"
111111#include " llvm/Transforms/Instrumentation/BlockCoverageInference.h"
112112#include " llvm/Transforms/Instrumentation/CFGMST.h"
113- #include " llvm/Transforms/Instrumentation/PGOCtxProfLowering.h"
114113#include " llvm/Transforms/Utils/BasicBlockUtils.h"
115114#include " llvm/Transforms/Utils/MisExpect.h"
116115#include " llvm/Transforms/Utils/ModuleUtils.h"
@@ -321,7 +320,6 @@ static cl::opt<unsigned> PGOFunctionCriticalEdgeThreshold(
321320 " greater than this threshold." ));
322321
323322extern cl::opt<unsigned > MaxNumVTableAnnotations;
324- extern cl::opt<std::string> UseCtxProfile;
325323
326324namespace llvm {
327325// Command line option to turn on CFG dot dump after profile annotation.
@@ -339,21 +337,41 @@ extern cl::opt<bool> EnableVTableProfileUse;
339337extern cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate;
340338} // namespace llvm
341339
342- bool shouldInstrumentForCtxProf () {
343- return PGOCtxProfLoweringPass::isCtxIRPGOInstrEnabled () ||
344- !UseCtxProfile.empty ();
345- }
346- bool shouldInstrumentEntryBB () {
347- return PGOInstrumentEntry || shouldInstrumentForCtxProf ();
348- }
340+ namespace {
341+ class FunctionInstrumenter final {
342+ Module &M;
343+ Function &F;
344+ TargetLibraryInfo &TLI;
345+ std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers;
346+ BranchProbabilityInfo *const BPI;
347+ BlockFrequencyInfo *const BFI;
349348
350- // FIXME(mtrofin): re-enable this for ctx profiling, for non-indirect calls. Ctx
351- // profiling implicitly captures indirect call cases, but not other values.
352- // Supporting other values is relatively straight-forward - just another counter
353- // range within the context.
354- bool isValueProfilingDisabled () {
355- return DisableValueProfiling || shouldInstrumentForCtxProf ();
356- }
349+ const bool IsCS;
350+ const bool IsCtxProf;
351+ // FIXME(mtrofin): re-enable this for ctx profiling, for non-indirect calls.
352+ // Ctx profiling implicitly captures indirect call cases, but not other
353+ // values. Supporting other values is relatively straight-forward - just
354+ // another counter range within the context.
355+ bool isValueProfilingDisabled () const {
356+ return DisableValueProfiling || IsCtxProf;
357+ }
358+
359+ bool shouldInstrumentEntryBB () const {
360+ return PGOInstrumentEntry || IsCtxProf;
361+ }
362+
363+ public:
364+ FunctionInstrumenter (
365+ Module &M, Function &F, TargetLibraryInfo &TLI,
366+ std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
367+ BranchProbabilityInfo *BPI = nullptr , BlockFrequencyInfo *BFI = nullptr ,
368+ bool IsCS = false , bool IsCtxProf = false )
369+ : M(M), F(F), TLI(TLI), ComdatMembers(ComdatMembers), BPI(BPI), BFI(BFI),
370+ IsCS (IsCS), IsCtxProf(IsCtxProf) {}
371+
372+ void instrument ();
373+ };
374+ } // namespace
357375
358376// Return a string describing the branch condition that can be
359377// used in static branch probability heuristics:
@@ -395,13 +413,14 @@ static const char *ValueProfKindDescr[] = {
395413
396414// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
397415// aware this is an ir_level profile so it can set the version flag.
398- static GlobalVariable *createIRLevelProfileFlagVar (Module &M, bool IsCS) {
416+ static GlobalVariable *createIRLevelProfileFlagVar (Module &M, bool IsCS,
417+ bool IsCtxProf) {
399418 const StringRef VarName (INSTR_PROF_QUOTE (INSTR_PROF_RAW_VERSION_VAR));
400419 Type *IntTy64 = Type::getInt64Ty (M.getContext ());
401420 uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
402421 if (IsCS)
403422 ProfileVersion |= VARIANT_MASK_CSIR_PROF;
404- if (shouldInstrumentEntryBB () )
423+ if (PGOInstrumentEntry || IsCtxProf )
405424 ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
406425 if (DebugInfoCorrelate || ProfileCorrelate == InstrProfCorrelator::DEBUG_INFO)
407426 ProfileVersion |= VARIANT_MASK_DBG_CORRELATE;
@@ -871,11 +890,7 @@ populateEHOperandBundle(VPCandidateInfo &Cand,
871890
872891// Visit all edge and instrument the edges not in MST, and do value profiling.
873892// Critical edges will be split.
874- static void instrumentOneFunc (
875- Function &F, Module *M, TargetLibraryInfo &TLI, BranchProbabilityInfo *BPI,
876- BlockFrequencyInfo *BFI,
877- std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
878- bool IsCS) {
893+ void FunctionInstrumenter::instrument () {
879894 if (!PGOBlockCoverage) {
880895 // Split indirectbr critical edges here before computing the MST rather than
881896 // later in getInstrBB() to avoid invalidating it.
@@ -887,15 +902,15 @@ static void instrumentOneFunc(
887902 PGOBlockCoverage);
888903
889904 auto Name = FuncInfo.FuncNameVar ;
890- auto CFGHash = ConstantInt::get (Type::getInt64Ty (M-> getContext ()),
905+ auto CFGHash = ConstantInt::get (Type::getInt64Ty (M. getContext ()),
891906 FuncInfo.FunctionHash );
892907 if (PGOFunctionEntryCoverage) {
893908 auto &EntryBB = F.getEntryBlock ();
894909 IRBuilder<> Builder (&EntryBB, EntryBB.getFirstInsertionPt ());
895910 // llvm.instrprof.cover(i8* <name>, i64 <hash>, i32 <num-counters>,
896911 // i32 <index>)
897912 Builder.CreateCall (
898- Intrinsic::getDeclaration (M, Intrinsic::instrprof_cover),
913+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_cover),
899914 {Name, CFGHash, Builder.getInt32 (1 ), Builder.getInt32 (0 )});
900915 return ;
901916 }
@@ -905,9 +920,9 @@ static void instrumentOneFunc(
905920 unsigned NumCounters =
906921 InstrumentBBs.size () + FuncInfo.SIVisitor .getNumOfSelectInsts ();
907922
908- if (shouldInstrumentForCtxProf () ) {
923+ if (IsCtxProf ) {
909924 auto *CSIntrinsic =
910- Intrinsic::getDeclaration (M, Intrinsic::instrprof_callsite);
925+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_callsite);
911926 // We want to count the instrumentable callsites, then instrument them. This
912927 // is because the llvm.instrprof.callsite intrinsic has an argument (like
913928 // the other instrprof intrinsics) capturing the total number of
@@ -950,7 +965,7 @@ static void instrumentOneFunc(
950965 // llvm.instrprof.timestamp(i8* <name>, i64 <hash>, i32 <num-counters>,
951966 // i32 <index>)
952967 Builder.CreateCall (
953- Intrinsic::getDeclaration (M, Intrinsic::instrprof_timestamp),
968+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_timestamp),
954969 {Name, CFGHash, Builder.getInt32 (NumCounters), Builder.getInt32 (I)});
955970 I += PGOBlockCoverage ? 8 : 1 ;
956971 }
@@ -962,7 +977,7 @@ static void instrumentOneFunc(
962977 // llvm.instrprof.increment(i8* <name>, i64 <hash>, i32 <num-counters>,
963978 // i32 <index>)
964979 Builder.CreateCall (
965- Intrinsic::getDeclaration (M, PGOBlockCoverage
980+ Intrinsic::getDeclaration (& M, PGOBlockCoverage
966981 ? Intrinsic::instrprof_cover
967982 : Intrinsic::instrprof_increment),
968983 {Name, CFGHash, Builder.getInt32 (NumCounters), Builder.getInt32 (I++)});
@@ -1011,7 +1026,7 @@ static void instrumentOneFunc(
10111026 SmallVector<OperandBundleDef, 1 > OpBundles;
10121027 populateEHOperandBundle (Cand, BlockColors, OpBundles);
10131028 Builder.CreateCall (
1014- Intrinsic::getDeclaration (M, Intrinsic::instrprof_value_profile),
1029+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_value_profile),
10151030 {FuncInfo.FuncNameVar , Builder.getInt64 (FuncInfo.FunctionHash ),
10161031 ToProfile, Builder.getInt32 (Kind), Builder.getInt32 (SiteIndex++)},
10171032 OpBundles);
@@ -1746,7 +1761,7 @@ static uint32_t getMaxNumAnnotations(InstrProfValueKind ValueProfKind) {
17461761
17471762// Traverse all valuesites and annotate the instructions for all value kind.
17481763void PGOUseFunc::annotateValueSites () {
1749- if (isValueProfilingDisabled () )
1764+ if (DisableValueProfiling )
17501765 return ;
17511766
17521767 // Create the PGOFuncName meta data.
@@ -1861,11 +1876,12 @@ static bool skipPGOGen(const Function &F) {
18611876static bool InstrumentAllFunctions (
18621877 Module &M, function_ref<TargetLibraryInfo &(Function &)> LookupTLI,
18631878 function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
1864- function_ref<BlockFrequencyInfo *(Function &)> LookupBFI, bool IsCS) {
1879+ function_ref<BlockFrequencyInfo *(Function &)> LookupBFI, bool IsCS,
1880+ bool IsCtxProf) {
18651881 // For the context-sensitve instrumentation, we should have a separated pass
18661882 // (before LTO/ThinLTO linking) to create these variables.
1867- if (!IsCS && !shouldInstrumentForCtxProf () )
1868- createIRLevelProfileFlagVar (M, /* IsCS=*/ false );
1883+ if (!IsCS && !IsCtxProf )
1884+ createIRLevelProfileFlagVar (M, /* IsCS=*/ false , /* IsCtxProf= */ IsCtxProf );
18691885
18701886 Triple TT (M.getTargetTriple ());
18711887 LLVMContext &Ctx = M.getContext ();
@@ -1884,7 +1900,9 @@ static bool InstrumentAllFunctions(
18841900 auto &TLI = LookupTLI (F);
18851901 auto *BPI = LookupBPI (F);
18861902 auto *BFI = LookupBFI (F);
1887- instrumentOneFunc (F, &M, TLI, BPI, BFI, ComdatMembers, IsCS);
1903+ FunctionInstrumenter FI (M, F, TLI, ComdatMembers, BPI, BFI, IsCS,
1904+ IsCtxProf);
1905+ FI.instrument ();
18881906 }
18891907 return true ;
18901908}
@@ -1894,7 +1912,8 @@ PGOInstrumentationGenCreateVar::run(Module &M, ModuleAnalysisManager &MAM) {
18941912 createProfileFileNameVar (M, CSInstrName);
18951913 // The variable in a comdat may be discarded by LTO. Ensure the declaration
18961914 // will be retained.
1897- appendToCompilerUsed (M, createIRLevelProfileFlagVar (M, /* IsCS=*/ true ));
1915+ appendToCompilerUsed (
1916+ M, createIRLevelProfileFlagVar (M, /* IsCS=*/ true , /* IsCtxProf=*/ false ));
18981917 if (ProfileSampling)
18991918 createProfileSamplingVar (M);
19001919 PreservedAnalyses PA;
@@ -1916,7 +1935,8 @@ PreservedAnalyses PGOInstrumentationGen::run(Module &M,
19161935 return &FAM.getResult <BlockFrequencyAnalysis>(F);
19171936 };
19181937
1919- if (!InstrumentAllFunctions (M, LookupTLI, LookupBPI, LookupBFI, IsCS))
1938+ if (!InstrumentAllFunctions (M, LookupTLI, LookupBPI, LookupBFI, IsCS,
1939+ IsCtxProf))
19201940 return PreservedAnalyses::all ();
19211941
19221942 return PreservedAnalyses::none ();
@@ -2115,7 +2135,6 @@ static bool annotateAllFunctions(
21152135 bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled ();
21162136 if (PGOInstrumentEntry.getNumOccurrences () > 0 )
21172137 InstrumentFuncEntry = PGOInstrumentEntry;
2118- InstrumentFuncEntry |= shouldInstrumentForCtxProf ();
21192138
21202139 bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage ();
21212140 for (auto &F : M) {
0 commit comments