Skip to content

Commit

Permalink
[CGProfile] Use callee's PGO name when caller->callee is an indirect …
Browse files Browse the repository at this point in the history
…call. (#78610)

- With PGO, indirect call edges are constructed using value profiles, and the profile address is mapped to a function's PGO name. The PGO name is computed using a functions linkage before LTO internalization or global promotion.
- With ThinLTO, local functions [could be
promoted](https://github.com/llvm/llvm-project/blob/2663d2cb9c9361f0b234c40a0f50c7ba0748eb26/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp#L288) to have external linkage; and with
[full](https://github.com/llvm/llvm-project/blob/2663d2cb9c9361f0b234c40a0f50c7ba0748eb26/llvm/lib/LTO/LTO.cpp#L1328)
or
[thin](https://github.com/llvm/llvm-project/blob/2663d2cb9c9361f0b234c40a0f50c7ba0748eb26/llvm/lib/LTO/LTO.cpp#L448)
LTO, global functions could be internalized. Edge construction should use a function's PGO name before its linkage is updated.
  • Loading branch information
minglotus-6 committed Jan 22, 2024
1 parent f4c2ee1 commit 5ce2868
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 12 deletions.
4 changes: 4 additions & 0 deletions llvm/include/llvm/Transforms/Instrumentation/CGProfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ namespace llvm {
class Module;
class CGProfilePass : public PassInfoMixin<CGProfilePass> {
public:
CGProfilePass(bool InLTO) : InLTO(InLTO) {}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);

private:
bool InLTO = false;
};
} // end namespace llvm

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,10 @@ Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
return parseSinglePassOption(Params, "vfe-linkage-unit-visibility", "GlobalDCE");
}

Expected<bool> parseCGProfilePassOptions(StringRef Params) {
return parseSinglePassOption(Params, "in-lto-post-link", "CGProfile");
}

Expected<bool> parseInlinerPassOptions(StringRef Params) {
return parseSinglePassOption(Params, "only-mandatory", "InlinerPass");
}
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Passes/PassBuilderPipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1477,7 +1477,8 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
MPM.addPass(ConstantMergePass());

if (PTO.CallGraphProfile && !LTOPreLink)
MPM.addPass(CGProfilePass());
MPM.addPass(CGProfilePass(LTOPhase == ThinOrFullLTOPhase::FullLTOPostLink ||
LTOPhase == ThinOrFullLTOPhase::ThinLTOPostLink));

// TODO: Relative look table converter pass caused an issue when full lto is
// enabled. See https://reviews.llvm.org/D94355 for more details.
Expand Down Expand Up @@ -1972,7 +1973,7 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
MPM.addPass(MergeFunctionsPass());

if (PTO.CallGraphProfile)
MPM.addPass(CGProfilePass());
MPM.addPass(CGProfilePass(/*InLTOPostLink=*/true));

invokeFullLinkTimeOptimizationLastEPCallbacks(MPM, Level);

Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ MODULE_PASS("attributor", AttributorPass())
MODULE_PASS("attributor-light", AttributorLightPass())
MODULE_PASS("called-value-propagation", CalledValuePropagationPass())
MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass())
MODULE_PASS("cg-profile", CGProfilePass())
MODULE_PASS("check-debugify", NewPMCheckDebugifyPass())
MODULE_PASS("constmerge", ConstantMergePass())
MODULE_PASS("coro-cleanup", CoroCleanupPass())
Expand Down Expand Up @@ -151,6 +150,10 @@ MODULE_PASS_WITH_PARAMS(
"asan", "AddressSanitizerPass",
[](AddressSanitizerOptions Opts) { return AddressSanitizerPass(Opts); },
parseASanPassOptions, "kernel")
MODULE_PASS_WITH_PARAMS(
"cg-profile", "CGProfilePass",
[](bool InLTOPostLink) { return CGProfilePass(InLTOPostLink);},
parseCGProfilePassOptions, "in-lto-post-link")
MODULE_PASS_WITH_PARAMS(
"global-merge", "GlobalMergePass",
[TM = TM](GlobalMergeOptions Opts) { return GlobalMergePass(TM, Opts); },
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Transforms/Instrumentation/CGProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ addModuleFlags(Module &M,
return true;
}

static bool runCGProfilePass(
Module &M, FunctionAnalysisManager &FAM) {
static bool runCGProfilePass(Module &M, FunctionAnalysisManager &FAM,
bool InLTO) {
MapVector<std::pair<Function *, Function *>, uint64_t> Counts;
InstrProfSymtab Symtab;
auto UpdateCounts = [&](TargetTransformInfo &TTI, Function *F,
Expand All @@ -59,7 +59,7 @@ static bool runCGProfilePass(
Count = SaturatingAdd(Count, NewCount);
};
// Ignore error here. Indirect calls are ignored if this fails.
(void)(bool) Symtab.create(M);
(void)(bool)Symtab.create(M, InLTO);
for (auto &F : M) {
// Avoid extra cost of running passes for BFI when the function doesn't have
// entry count.
Expand Down Expand Up @@ -101,7 +101,7 @@ static bool runCGProfilePass(
PreservedAnalyses CGProfilePass::run(Module &M, ModuleAnalysisManager &MAM) {
FunctionAnalysisManager &FAM =
MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
runCGProfilePass(M, FAM);
runCGProfilePass(M, FAM, InLTO);

return PreservedAnalyses::all();
}
17 changes: 12 additions & 5 deletions llvm/test/Instrumentation/cgprofile.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: opt < %s -passes cg-profile -S | FileCheck %s
; RUN: opt < %s -passes='cg-profile<in-lto-post-link>' -S | FileCheck %s --check-prefixes=CHECK,LTO
; RUN: opt < %s -passes='cg-profile' -S | FileCheck %s --check-prefixes=CHECK,NOLTO --implicit-check-not="!{ptr @freq, ptr @func3.llvm.12345"

declare void @b()

Expand All @@ -7,10 +8,14 @@ define void @a() !prof !1 {
ret void
}

define void @func3.llvm.12345() !PGOFuncName !4 {
ret void
}

@foo = common global ptr null, align 8
declare i32 @func1()
declare i32 @func2()
declare i32 @func3()

declare i32 @func4()
declare dllimport i32 @func5()
declare i32 @func6()
Expand All @@ -29,15 +34,17 @@ B:

!1 = !{!"function_entry_count", i64 32}
!2 = !{!"branch_weights", i32 5, i32 10}
!3 = !{!"VP", i32 0, i64 1600, i64 7651369219802541373, i64 1030, i64 -4377547752858689819, i64 410, i64 -6929281286627296573, i64 150, i64 -2545542355363006406, i64 10, i64 3667884930908592509, i64 1, i64 15435711456043681792, i64 0}
!3 = !{!"VP", i32 0, i64 1600, i64 7651369219802541373, i64 1030, i64 -4377547752858689819, i64 410, i64 5415368997850289431, i64 150, i64 -2545542355363006406, i64 10, i64 3667884930908592509, i64 1, i64 15435711456043681792, i64 0}
!4 = !{!"cgprofile.ll;func3"}

; CHECK: !llvm.module.flags = !{![[cgprof:[0-9]+]]}
; CHECK: ![[cgprof]] = !{i32 5, !"CG Profile", ![[prof:[0-9]+]]}
; CHECK: ![[prof]] = distinct !{![[e0:[0-9]+]], ![[e1:[0-9]+]], ![[e2:[0-9]+]], ![[e3:[0-9]+]], ![[e4:[0-9]+]], ![[e5:[0-9]+]], ![[e6:[0-9]+]]}
; LTO: ![[prof]] = distinct !{![[e0:[0-9]+]], ![[e1:[0-9]+]], ![[e2:[0-9]+]], ![[e3:[0-9]+]], ![[e4:[0-9]+]], ![[e5:[0-9]+]], ![[e6:[0-9]+]]}
; NOLTO: ![[prof]] = distinct !{![[e0:[0-9]+]], ![[e1:[0-9]+]], ![[e2:[0-9]+]], ![[e4:[0-9]+]], ![[e5:[0-9]+]], ![[e6:[0-9]+]]}
; CHECK: ![[e0]] = !{ptr @a, ptr @b, i64 32}
; CHECK: ![[e1]] = !{ptr @freq, ptr @func4, i64 1030}
; CHECK: ![[e2]] = !{ptr @freq, ptr @func2, i64 410}
; CHECK: ![[e3]] = !{ptr @freq, ptr @func3, i64 150}
; LTO: ![[e3]] = !{ptr @freq, ptr @func3.llvm.12345, i64 150}
; CHECK: ![[e4]] = !{ptr @freq, ptr @func1, i64 10}
; CHECK: ![[e5]] = !{ptr @freq, ptr @a, i64 11}
; CHECK: ![[e6]] = !{ptr @freq, ptr @b, i64 21}
Expand Down

0 comments on commit 5ce2868

Please sign in to comment.