[llvm] [ctxprof] don't inline weak symbols after instrumentation (PR #128811)
Mircea Trofin via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 25 19:52:05 PST 2025
https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/128811
>From 20b7123d09587321cb4cdd2233558cda3e4f6d57 Mon Sep 17 00:00:00 2001
From: Mircea Trofin <mtrofin at google.com>
Date: Tue, 25 Feb 2025 19:46:25 -0800
Subject: [PATCH] [ctxprof] don't inline weak symbols after instrumentation
---
llvm/include/llvm/IR/GlobalValue.h | 7 +++++++
.../Instrumentation/PGOCtxProfLowering.h | 15 ++++++++++++++
llvm/lib/Passes/PassBuilderPipelines.cpp | 7 +++++++
llvm/lib/Passes/PassRegistry.def | 1 +
.../Instrumentation/PGOCtxProfLowering.cpp | 20 +++++++++++++++++++
.../ctx-instrumentation-block-inline.ll | 13 ++++++++++++
6 files changed, 63 insertions(+)
create mode 100644 llvm/test/Transforms/PGOProfile/ctx-instrumentation-block-inline.ll
diff --git a/llvm/include/llvm/IR/GlobalValue.h b/llvm/include/llvm/IR/GlobalValue.h
index 2176e2c2cfbfc..12ba84ef93102 100644
--- a/llvm/include/llvm/IR/GlobalValue.h
+++ b/llvm/include/llvm/IR/GlobalValue.h
@@ -550,6 +550,13 @@ class GlobalValue : public Constant {
return isDiscardableIfUnused(getLinkage());
}
+ // the symbol in this module may be replaced by a prevailing copy.
+ bool mayBeReplacedByPrevailingCopy() const {
+ return getLinkage() != GlobalValue::ExternalLinkage ||
+ getLinkage() != GlobalValue::InternalLinkage ||
+ getLinkage() != GlobalValue::PrivateLinkage;
+ }
+
bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); }
protected:
diff --git a/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h b/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h
index f127d16b8de12..8010c1c091e40 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/PGOCtxProfLowering.h
@@ -24,5 +24,20 @@ class PGOCtxProfLoweringPass : public PassInfoMixin<PGOCtxProfLoweringPass> {
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
};
+
+// Utility pass blocking inlining for any function that may be overridden during
+// linking by a prevailing copy.
+// This avoids confusingly collecting profiles for the same GUID corresponding
+// to different variants of the function. We could do like PGO and identify
+// functions by a (GUID, Hash) tuple, but since the ctxprof "use" waits for
+// thinlto to happen before performing any further optimizations, it's
+// unnecessary to collect profiles for non-prevailing copies.
+class NoinlineNonPrevailing : public PassInfoMixin<NoinlineNonPrevailing> {
+public:
+ explicit NoinlineNonPrevailing() = default;
+
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+};
+
} // namespace llvm
#endif
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 6ca2f90aa0668..f0541dbfe3597 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -1249,6 +1249,13 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
MPM.addPass(AssignGUIDPass());
if (IsCtxProfUse)
return MPM;
+ // Block further inlining in the instrumented ctxprof case. This avoids
+ // confusingly collecting profiles for the same GUID corresponding to
+ // different variants of the function. We could do like PGO and identify
+ // functions by a (GUID, Hash) tuple, but since the ctxprof "use" waits for
+ // thinlto to happen before performing any further optimizations, it's
+ // unnecessary to collect profiles for non-prevailing copies.
+ MPM.addPass(NoinlineNonPrevailing());
addPostPGOLoopRotation(MPM, Level);
MPM.addPass(PGOCtxProfLoweringPass());
} else if (IsColdFuncOnlyInstrGen) {
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index a664d6fd7085f..bfd952df25e98 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -62,6 +62,7 @@ MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass())
MODULE_PASS("ctx-instr-gen",
PGOInstrumentationGen(PGOInstrumentationType::CTXPROF))
MODULE_PASS("ctx-prof-flatten", PGOCtxProfFlatteningPass())
+MODULE_PASS("noinline-nonprevailing", NoinlineNonPrevailing())
MODULE_PASS("deadargelim", DeadArgumentEliminationPass())
MODULE_PASS("debugify", NewPMDebugifyPass())
MODULE_PASS("dfsan", DataFlowSanitizerPass())
diff --git a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
index e7b7c26c493e5..19d899b08150e 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOCtxProfLowering.cpp
@@ -351,3 +351,23 @@ bool CtxInstrumentationLowerer::lowerFunction(Function &F) {
F.getName());
return true;
}
+
+PreservedAnalyses NoinlineNonPrevailing::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+ bool Changed = false;
+ for (auto &F : M) {
+ if (F.isDeclaration())
+ continue;
+ if (F.hasFnAttribute(Attribute::NoInline))
+ continue;
+ if (F.mayBeReplacedByPrevailingCopy()) {
+ F.addFnAttr(Attribute::NoInline);
+ if (F.hasFnAttribute(Attribute::AlwaysInline))
+ F.removeFnAttr(Attribute::AlwaysInline);
+ Changed = true;
+ }
+ }
+ if (Changed)
+ return PreservedAnalyses::none();
+ return PreservedAnalyses::all();
+}
diff --git a/llvm/test/Transforms/PGOProfile/ctx-instrumentation-block-inline.ll b/llvm/test/Transforms/PGOProfile/ctx-instrumentation-block-inline.ll
new file mode 100644
index 0000000000000..4a72a0035dc70
--- /dev/null
+++ b/llvm/test/Transforms/PGOProfile/ctx-instrumentation-block-inline.ll
@@ -0,0 +1,13 @@
+; RUN: opt -passes=noinline-nonprevailing -S < %s 2>&1 | FileCheck %s
+
+define void @a() {
+ call void @b()
+ ret void
+}
+
+define weak_odr void @b() {
+ ret void
+}
+
+; CHECK: void @b() #0
+; CHECK: attributes #0 = { noinline }
More information about the llvm-commits
mailing list