110
110
#include " llvm/Transforms/Instrumentation.h"
111
111
#include " llvm/Transforms/Instrumentation/BlockCoverageInference.h"
112
112
#include " llvm/Transforms/Instrumentation/CFGMST.h"
113
- #include " llvm/Transforms/Instrumentation/PGOCtxProfLowering.h"
114
113
#include " llvm/Transforms/Utils/BasicBlockUtils.h"
115
114
#include " llvm/Transforms/Utils/MisExpect.h"
116
115
#include " llvm/Transforms/Utils/ModuleUtils.h"
@@ -321,7 +320,6 @@ static cl::opt<unsigned> PGOFunctionCriticalEdgeThreshold(
321
320
" greater than this threshold." ));
322
321
323
322
extern cl::opt<unsigned > MaxNumVTableAnnotations;
324
- extern cl::opt<std::string> UseCtxProfile;
325
323
326
324
namespace llvm {
327
325
// Command line option to turn on CFG dot dump after profile annotation.
@@ -339,21 +337,41 @@ extern cl::opt<bool> EnableVTableProfileUse;
339
337
extern cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate;
340
338
} // namespace llvm
341
339
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;
349
348
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
357
375
358
376
// Return a string describing the branch condition that can be
359
377
// used in static branch probability heuristics:
@@ -395,13 +413,14 @@ static const char *ValueProfKindDescr[] = {
395
413
396
414
// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
397
415
// 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) {
399
418
const StringRef VarName (INSTR_PROF_QUOTE (INSTR_PROF_RAW_VERSION_VAR));
400
419
Type *IntTy64 = Type::getInt64Ty (M.getContext ());
401
420
uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
402
421
if (IsCS)
403
422
ProfileVersion |= VARIANT_MASK_CSIR_PROF;
404
- if (shouldInstrumentEntryBB () )
423
+ if (PGOInstrumentEntry || IsCtxProf )
405
424
ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
406
425
if (DebugInfoCorrelate || ProfileCorrelate == InstrProfCorrelator::DEBUG_INFO)
407
426
ProfileVersion |= VARIANT_MASK_DBG_CORRELATE;
@@ -871,11 +890,7 @@ populateEHOperandBundle(VPCandidateInfo &Cand,
871
890
872
891
// Visit all edge and instrument the edges not in MST, and do value profiling.
873
892
// 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 () {
879
894
if (!PGOBlockCoverage) {
880
895
// Split indirectbr critical edges here before computing the MST rather than
881
896
// later in getInstrBB() to avoid invalidating it.
@@ -887,15 +902,15 @@ static void instrumentOneFunc(
887
902
PGOBlockCoverage);
888
903
889
904
auto Name = FuncInfo.FuncNameVar ;
890
- auto CFGHash = ConstantInt::get ( Type::getInt64Ty (M-> getContext ()),
891
- FuncInfo.FunctionHash );
905
+ auto CFGHash =
906
+ ConstantInt::get ( Type::getInt64Ty (M. getContext ()), FuncInfo.FunctionHash );
892
907
if (PGOFunctionEntryCoverage) {
893
908
auto &EntryBB = F.getEntryBlock ();
894
909
IRBuilder<> Builder (&EntryBB, EntryBB.getFirstInsertionPt ());
895
910
// llvm.instrprof.cover(i8* <name>, i64 <hash>, i32 <num-counters>,
896
911
// i32 <index>)
897
912
Builder.CreateCall (
898
- Intrinsic::getDeclaration (M, Intrinsic::instrprof_cover),
913
+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_cover),
899
914
{Name, CFGHash, Builder.getInt32 (1 ), Builder.getInt32 (0 )});
900
915
return ;
901
916
}
@@ -905,9 +920,9 @@ static void instrumentOneFunc(
905
920
unsigned NumCounters =
906
921
InstrumentBBs.size () + FuncInfo.SIVisitor .getNumOfSelectInsts ();
907
922
908
- if (shouldInstrumentForCtxProf () ) {
923
+ if (IsCtxProf ) {
909
924
auto *CSIntrinsic =
910
- Intrinsic::getDeclaration (M, Intrinsic::instrprof_callsite);
925
+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_callsite);
911
926
// We want to count the instrumentable callsites, then instrument them. This
912
927
// is because the llvm.instrprof.callsite intrinsic has an argument (like
913
928
// the other instrprof intrinsics) capturing the total number of
@@ -950,7 +965,7 @@ static void instrumentOneFunc(
950
965
// llvm.instrprof.timestamp(i8* <name>, i64 <hash>, i32 <num-counters>,
951
966
// i32 <index>)
952
967
Builder.CreateCall (
953
- Intrinsic::getDeclaration (M, Intrinsic::instrprof_timestamp),
968
+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_timestamp),
954
969
{Name, CFGHash, Builder.getInt32 (NumCounters), Builder.getInt32 (I)});
955
970
I += PGOBlockCoverage ? 8 : 1 ;
956
971
}
@@ -962,9 +977,9 @@ static void instrumentOneFunc(
962
977
// llvm.instrprof.increment(i8* <name>, i64 <hash>, i32 <num-counters>,
963
978
// i32 <index>)
964
979
Builder.CreateCall (
965
- Intrinsic::getDeclaration (M, PGOBlockCoverage
966
- ? Intrinsic::instrprof_cover
967
- : Intrinsic::instrprof_increment),
980
+ Intrinsic::getDeclaration (& M, PGOBlockCoverage
981
+ ? Intrinsic::instrprof_cover
982
+ : Intrinsic::instrprof_increment),
968
983
{Name, CFGHash, Builder.getInt32 (NumCounters), Builder.getInt32 (I++)});
969
984
}
970
985
@@ -1011,7 +1026,7 @@ static void instrumentOneFunc(
1011
1026
SmallVector<OperandBundleDef, 1 > OpBundles;
1012
1027
populateEHOperandBundle (Cand, BlockColors, OpBundles);
1013
1028
Builder.CreateCall (
1014
- Intrinsic::getDeclaration (M, Intrinsic::instrprof_value_profile),
1029
+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_value_profile),
1015
1030
{FuncInfo.FuncNameVar , Builder.getInt64 (FuncInfo.FunctionHash ),
1016
1031
ToProfile, Builder.getInt32 (Kind), Builder.getInt32 (SiteIndex++)},
1017
1032
OpBundles);
@@ -1746,7 +1761,7 @@ static uint32_t getMaxNumAnnotations(InstrProfValueKind ValueProfKind) {
1746
1761
1747
1762
// Traverse all valuesites and annotate the instructions for all value kind.
1748
1763
void PGOUseFunc::annotateValueSites () {
1749
- if (isValueProfilingDisabled () )
1764
+ if (DisableValueProfiling )
1750
1765
return ;
1751
1766
1752
1767
// Create the PGOFuncName meta data.
@@ -1861,11 +1876,12 @@ static bool skipPGOGen(const Function &F) {
1861
1876
static bool InstrumentAllFunctions (
1862
1877
Module &M, function_ref<TargetLibraryInfo &(Function &)> LookupTLI,
1863
1878
function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
1864
- function_ref<BlockFrequencyInfo *(Function &)> LookupBFI, bool IsCS) {
1879
+ function_ref<BlockFrequencyInfo *(Function &)> LookupBFI, bool IsCS,
1880
+ bool IsCtxProf) {
1865
1881
// For the context-sensitve instrumentation, we should have a separated pass
1866
1882
// (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 );
1869
1885
1870
1886
Triple TT (M.getTargetTriple ());
1871
1887
LLVMContext &Ctx = M.getContext ();
@@ -1884,7 +1900,9 @@ static bool InstrumentAllFunctions(
1884
1900
auto &TLI = LookupTLI (F);
1885
1901
auto *BPI = LookupBPI (F);
1886
1902
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 ();
1888
1906
}
1889
1907
return true ;
1890
1908
}
@@ -1894,7 +1912,8 @@ PGOInstrumentationGenCreateVar::run(Module &M, ModuleAnalysisManager &MAM) {
1894
1912
createProfileFileNameVar (M, CSInstrName);
1895
1913
// The variable in a comdat may be discarded by LTO. Ensure the declaration
1896
1914
// will be retained.
1897
- appendToCompilerUsed (M, createIRLevelProfileFlagVar (M, /* IsCS=*/ true ));
1915
+ appendToCompilerUsed (
1916
+ M, createIRLevelProfileFlagVar (M, /* IsCS=*/ true , /* IsCtxProf=*/ false ));
1898
1917
if (ProfileSampling)
1899
1918
createProfileSamplingVar (M);
1900
1919
PreservedAnalyses PA;
@@ -1916,7 +1935,8 @@ PreservedAnalyses PGOInstrumentationGen::run(Module &M,
1916
1935
return &FAM.getResult <BlockFrequencyAnalysis>(F);
1917
1936
};
1918
1937
1919
- if (!InstrumentAllFunctions (M, LookupTLI, LookupBPI, LookupBFI, IsCS))
1938
+ if (!InstrumentAllFunctions (M, LookupTLI, LookupBPI, LookupBFI, IsCS,
1939
+ IsCtxProf))
1920
1940
return PreservedAnalyses::all ();
1921
1941
1922
1942
return PreservedAnalyses::none ();
@@ -2115,7 +2135,6 @@ static bool annotateAllFunctions(
2115
2135
bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled ();
2116
2136
if (PGOInstrumentEntry.getNumOccurrences () > 0 )
2117
2137
InstrumentFuncEntry = PGOInstrumentEntry;
2118
- InstrumentFuncEntry |= shouldInstrumentForCtxProf ();
2119
2138
2120
2139
bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage ();
2121
2140
for (auto &F : M) {
0 commit comments