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,43 @@ 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 PGOInstrumentationType InstrumentationType;
350
+
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 ||
357
+ InstrumentationType == PGOInstrumentationType::CTXPROF;
358
+ }
359
+
360
+ bool shouldInstrumentEntryBB () const {
361
+ return PGOInstrumentEntry ||
362
+ InstrumentationType == PGOInstrumentationType::CTXPROF;
363
+ }
364
+
365
+ public:
366
+ FunctionInstrumenter (
367
+ Module &M, Function &F, TargetLibraryInfo &TLI,
368
+ std::unordered_multimap<Comdat *, GlobalValue *> &ComdatMembers,
369
+ BranchProbabilityInfo *BPI = nullptr , BlockFrequencyInfo *BFI = nullptr ,
370
+ PGOInstrumentationType InstrumentationType = PGOInstrumentationType::FDO)
371
+ : M(M), F(F), TLI(TLI), ComdatMembers(ComdatMembers), BPI(BPI), BFI(BFI),
372
+ InstrumentationType (InstrumentationType) {}
373
+
374
+ void instrument ();
375
+ };
376
+ } // namespace
357
377
358
378
// Return a string describing the branch condition that can be
359
379
// used in static branch probability heuristics:
@@ -395,13 +415,16 @@ static const char *ValueProfKindDescr[] = {
395
415
396
416
// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
397
417
// aware this is an ir_level profile so it can set the version flag.
398
- static GlobalVariable *createIRLevelProfileFlagVar (Module &M, bool IsCS) {
418
+ static GlobalVariable *
419
+ createIRLevelProfileFlagVar (Module &M,
420
+ PGOInstrumentationType InstrumentationType) {
399
421
const StringRef VarName (INSTR_PROF_QUOTE (INSTR_PROF_RAW_VERSION_VAR));
400
422
Type *IntTy64 = Type::getInt64Ty (M.getContext ());
401
423
uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
402
- if (IsCS )
424
+ if (InstrumentationType == PGOInstrumentationType::CSFDO )
403
425
ProfileVersion |= VARIANT_MASK_CSIR_PROF;
404
- if (shouldInstrumentEntryBB ())
426
+ if (PGOInstrumentEntry ||
427
+ InstrumentationType == PGOInstrumentationType::CTXPROF)
405
428
ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
406
429
if (DebugInfoCorrelate || ProfileCorrelate == InstrProfCorrelator::DEBUG_INFO)
407
430
ProfileVersion |= VARIANT_MASK_DBG_CORRELATE;
@@ -871,31 +894,28 @@ populateEHOperandBundle(VPCandidateInfo &Cand,
871
894
872
895
// Visit all edge and instrument the edges not in MST, and do value profiling.
873
896
// 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) {
897
+ void FunctionInstrumenter::instrument () {
879
898
if (!PGOBlockCoverage) {
880
899
// Split indirectbr critical edges here before computing the MST rather than
881
900
// later in getInstrBB() to avoid invalidating it.
882
901
SplitIndirectBrCriticalEdges (F, /* IgnoreBlocksWithoutPHI=*/ false , BPI, BFI);
883
902
}
884
903
885
904
FuncPGOInstrumentation<PGOEdge, PGOBBInfo> FuncInfo (
886
- F, TLI, ComdatMembers, true , BPI, BFI, IsCS, shouldInstrumentEntryBB (),
887
- PGOBlockCoverage);
905
+ F, TLI, ComdatMembers, true , BPI, BFI,
906
+ InstrumentationType == PGOInstrumentationType::CSFDO,
907
+ shouldInstrumentEntryBB (), PGOBlockCoverage);
888
908
889
909
auto Name = FuncInfo.FuncNameVar ;
890
- auto CFGHash = ConstantInt::get ( Type::getInt64Ty (M-> getContext ()),
891
- FuncInfo.FunctionHash );
910
+ auto CFGHash =
911
+ ConstantInt::get ( Type::getInt64Ty (M. getContext ()), FuncInfo.FunctionHash );
892
912
if (PGOFunctionEntryCoverage) {
893
913
auto &EntryBB = F.getEntryBlock ();
894
914
IRBuilder<> Builder (&EntryBB, EntryBB.getFirstInsertionPt ());
895
915
// llvm.instrprof.cover(i8* <name>, i64 <hash>, i32 <num-counters>,
896
916
// i32 <index>)
897
917
Builder.CreateCall (
898
- Intrinsic::getDeclaration (M, Intrinsic::instrprof_cover),
918
+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_cover),
899
919
{Name, CFGHash, Builder.getInt32 (1 ), Builder.getInt32 (0 )});
900
920
return ;
901
921
}
@@ -905,9 +925,9 @@ static void instrumentOneFunc(
905
925
unsigned NumCounters =
906
926
InstrumentBBs.size () + FuncInfo.SIVisitor .getNumOfSelectInsts ();
907
927
908
- if (shouldInstrumentForCtxProf () ) {
928
+ if (InstrumentationType == PGOInstrumentationType::CTXPROF ) {
909
929
auto *CSIntrinsic =
910
- Intrinsic::getDeclaration (M, Intrinsic::instrprof_callsite);
930
+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_callsite);
911
931
// We want to count the instrumentable callsites, then instrument them. This
912
932
// is because the llvm.instrprof.callsite intrinsic has an argument (like
913
933
// the other instrprof intrinsics) capturing the total number of
@@ -950,7 +970,7 @@ static void instrumentOneFunc(
950
970
// llvm.instrprof.timestamp(i8* <name>, i64 <hash>, i32 <num-counters>,
951
971
// i32 <index>)
952
972
Builder.CreateCall (
953
- Intrinsic::getDeclaration (M, Intrinsic::instrprof_timestamp),
973
+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_timestamp),
954
974
{Name, CFGHash, Builder.getInt32 (NumCounters), Builder.getInt32 (I)});
955
975
I += PGOBlockCoverage ? 8 : 1 ;
956
976
}
@@ -962,9 +982,9 @@ static void instrumentOneFunc(
962
982
// llvm.instrprof.increment(i8* <name>, i64 <hash>, i32 <num-counters>,
963
983
// i32 <index>)
964
984
Builder.CreateCall (
965
- Intrinsic::getDeclaration (M, PGOBlockCoverage
966
- ? Intrinsic::instrprof_cover
967
- : Intrinsic::instrprof_increment),
985
+ Intrinsic::getDeclaration (& M, PGOBlockCoverage
986
+ ? Intrinsic::instrprof_cover
987
+ : Intrinsic::instrprof_increment),
968
988
{Name, CFGHash, Builder.getInt32 (NumCounters), Builder.getInt32 (I++)});
969
989
}
970
990
@@ -1011,7 +1031,7 @@ static void instrumentOneFunc(
1011
1031
SmallVector<OperandBundleDef, 1 > OpBundles;
1012
1032
populateEHOperandBundle (Cand, BlockColors, OpBundles);
1013
1033
Builder.CreateCall (
1014
- Intrinsic::getDeclaration (M, Intrinsic::instrprof_value_profile),
1034
+ Intrinsic::getDeclaration (& M, Intrinsic::instrprof_value_profile),
1015
1035
{FuncInfo.FuncNameVar , Builder.getInt64 (FuncInfo.FunctionHash ),
1016
1036
ToProfile, Builder.getInt32 (Kind), Builder.getInt32 (SiteIndex++)},
1017
1037
OpBundles);
@@ -1746,7 +1766,7 @@ static uint32_t getMaxNumAnnotations(InstrProfValueKind ValueProfKind) {
1746
1766
1747
1767
// Traverse all valuesites and annotate the instructions for all value kind.
1748
1768
void PGOUseFunc::annotateValueSites () {
1749
- if (isValueProfilingDisabled () )
1769
+ if (DisableValueProfiling )
1750
1770
return ;
1751
1771
1752
1772
// Create the PGOFuncName meta data.
@@ -1861,11 +1881,12 @@ static bool skipPGOGen(const Function &F) {
1861
1881
static bool InstrumentAllFunctions (
1862
1882
Module &M, function_ref<TargetLibraryInfo &(Function &)> LookupTLI,
1863
1883
function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
1864
- function_ref<BlockFrequencyInfo *(Function &)> LookupBFI, bool IsCS) {
1884
+ function_ref<BlockFrequencyInfo *(Function &)> LookupBFI,
1885
+ PGOInstrumentationType InstrumentationType) {
1865
1886
// For the context-sensitve instrumentation, we should have a separated pass
1866
1887
// (before LTO/ThinLTO linking) to create these variables.
1867
- if (!IsCS && ! shouldInstrumentForCtxProf () )
1868
- createIRLevelProfileFlagVar (M, /* IsCS= */ false );
1888
+ if (InstrumentationType == PGOInstrumentationType::FDO )
1889
+ createIRLevelProfileFlagVar (M, InstrumentationType );
1869
1890
1870
1891
Triple TT (M.getTargetTriple ());
1871
1892
LLVMContext &Ctx = M.getContext ();
@@ -1884,7 +1905,9 @@ static bool InstrumentAllFunctions(
1884
1905
auto &TLI = LookupTLI (F);
1885
1906
auto *BPI = LookupBPI (F);
1886
1907
auto *BFI = LookupBFI (F);
1887
- instrumentOneFunc (F, &M, TLI, BPI, BFI, ComdatMembers, IsCS);
1908
+ FunctionInstrumenter FI (M, F, TLI, ComdatMembers, BPI, BFI,
1909
+ InstrumentationType);
1910
+ FI.instrument ();
1888
1911
}
1889
1912
return true ;
1890
1913
}
@@ -1894,7 +1917,8 @@ PGOInstrumentationGenCreateVar::run(Module &M, ModuleAnalysisManager &MAM) {
1894
1917
createProfileFileNameVar (M, CSInstrName);
1895
1918
// The variable in a comdat may be discarded by LTO. Ensure the declaration
1896
1919
// will be retained.
1897
- appendToCompilerUsed (M, createIRLevelProfileFlagVar (M, /* IsCS=*/ true ));
1920
+ appendToCompilerUsed (
1921
+ M, createIRLevelProfileFlagVar (M, PGOInstrumentationType::CSFDO));
1898
1922
if (ProfileSampling)
1899
1923
createProfileSamplingVar (M);
1900
1924
PreservedAnalyses PA;
@@ -1916,7 +1940,8 @@ PreservedAnalyses PGOInstrumentationGen::run(Module &M,
1916
1940
return &FAM.getResult <BlockFrequencyAnalysis>(F);
1917
1941
};
1918
1942
1919
- if (!InstrumentAllFunctions (M, LookupTLI, LookupBPI, LookupBFI, IsCS))
1943
+ if (!InstrumentAllFunctions (M, LookupTLI, LookupBPI, LookupBFI,
1944
+ InstrumentationType))
1920
1945
return PreservedAnalyses::all ();
1921
1946
1922
1947
return PreservedAnalyses::none ();
@@ -2115,7 +2140,6 @@ static bool annotateAllFunctions(
2115
2140
bool InstrumentFuncEntry = PGOReader->instrEntryBBEnabled ();
2116
2141
if (PGOInstrumentEntry.getNumOccurrences () > 0 )
2117
2142
InstrumentFuncEntry = PGOInstrumentEntry;
2118
- InstrumentFuncEntry |= shouldInstrumentForCtxProf ();
2119
2143
2120
2144
bool HasSingleByteCoverage = PGOReader->hasSingleByteCoverage ();
2121
2145
for (auto &F : M) {
0 commit comments