Skip to content

Commit 06e0b34

Browse files
committed
[nfc] Improve testability of PGOInstrumentationGen
1 parent 85da39d commit 06e0b34

File tree

6 files changed

+69
-47
lines changed

6 files changed

+69
-47
lines changed

llvm/include/llvm/Transforms/Instrumentation/PGOInstrumentation.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,14 @@ class PGOInstrumentationGenCreateVar
5656
/// The instrumentation (profile-instr-gen) pass for IR based PGO.
5757
class PGOInstrumentationGen : public PassInfoMixin<PGOInstrumentationGen> {
5858
public:
59-
PGOInstrumentationGen(bool IsCS = false) : IsCS(IsCS) {}
59+
PGOInstrumentationGen(bool IsCS = false, bool IsCtxProf = false)
60+
: IsCS(IsCS), IsCtxProf(IsCtxProf) {}
6061
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
6162

6263
private:
6364
// If this is a context sensitive instrumentation.
64-
bool IsCS;
65+
const bool IsCS;
66+
const bool IsCtxProf;
6567
};
6668

6769
/// The profile annotation (profile-instr-use) pass for IR based PGO.

llvm/lib/Passes/PassBuilderPipelines.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
11931193
PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile,
11941194
PGOOpt->FS);
11951195
} else if (IsCtxProfGen || IsCtxProfUse) {
1196-
MPM.addPass(PGOInstrumentationGen(false));
1196+
MPM.addPass(PGOInstrumentationGen(/*IsCS=*/false, /*IsCtxProf=*/true));
11971197
// In pre-link, we just want the instrumented IR. We use the contextual
11981198
// profile in the post-thinlink phase.
11991199
// The instrumentation will be removed in post-thinlink after IPO.

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ MODULE_PASS("constmerge", ConstantMergePass())
5656
MODULE_PASS("coro-cleanup", CoroCleanupPass())
5757
MODULE_PASS("coro-early", CoroEarlyPass())
5858
MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass())
59+
MODULE_PASS("ctx-instr-gen", PGOInstrumentationGen(false, true))
5960
MODULE_PASS("deadargelim", DeadArgumentEliminationPass())
6061
MODULE_PASS("debugify", NewPMDebugifyPass())
6162
MODULE_PASS("dfsan", DataFlowSanitizerPass())

llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@
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

323322
extern cl::opt<unsigned> MaxNumVTableAnnotations;
324-
extern cl::opt<std::string> UseCtxProfile;
325323

326324
namespace llvm {
327325
// Command line option to turn on CFG dot dump after profile annotation.
@@ -339,21 +337,41 @@ extern cl::opt<bool> EnableVTableProfileUse;
339337
extern 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()),
891-
FuncInfo.FunctionHash);
905+
auto CFGHash =
906+
ConstantInt::get(Type::getInt64Ty(M.getContext()), 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,9 +977,9 @@ 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
966-
? Intrinsic::instrprof_cover
967-
: Intrinsic::instrprof_increment),
980+
Intrinsic::getDeclaration(&M, PGOBlockCoverage
981+
? Intrinsic::instrprof_cover
982+
: Intrinsic::instrprof_increment),
968983
{Name, CFGHash, Builder.getInt32(NumCounters), Builder.getInt32(I++)});
969984
}
970985

@@ -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.
17481763
void 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) {
18611876
static 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) {

llvm/test/Transforms/PGOProfile/ctx-instrumentation-invalid-roots.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: not opt -passes=pgo-instr-gen,ctx-instr-lower -profile-context-root=good \
1+
; RUN: not opt -passes=ctx-instr-gen,ctx-instr-lower -profile-context-root=good \
22
; RUN: -profile-context-root=bad \
33
; RUN: -S < %s 2>&1 | FileCheck %s
44

llvm/test/Transforms/PGOProfile/ctx-instrumentation.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 4
2-
; RUN: opt -passes=pgo-instr-gen -profile-context-root=an_entrypoint \
2+
; RUN: opt -passes=ctx-instr-gen -profile-context-root=an_entrypoint \
33
; RUN: -S < %s | FileCheck --check-prefix=INSTRUMENT %s
4-
; RUN: opt -passes=pgo-instr-gen,assign-guid,ctx-instr-lower -profile-context-root=an_entrypoint \
4+
; RUN: opt -passes=ctx-instr-gen,assign-guid,ctx-instr-lower -profile-context-root=an_entrypoint \
55
; RUN: -profile-context-root=another_entrypoint_no_callees \
66
; RUN: -S < %s | FileCheck --check-prefix=LOWERING %s
77

0 commit comments

Comments
 (0)