[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