[llvm] [Attributor] Only seed live internal callees during deduction (PR #222226)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 8 22:46:55 PDT 2026
https://github.com/int-zjt updated https://github.com/llvm/llvm-project/pull/222226
>From 95c56d032bb4d36d3573bcc38808c587162665eb Mon Sep 17 00:00:00 2001
From: "zhangjiatong.0" <zhangjiatong.0 at bytedance.com>
Date: Wed, 9 Sep 2026 11:40:27 +0800
Subject: [PATCH 1/2] [Attributor] Only seed live internal callees during
deduction
---
llvm/include/llvm/Transforms/IPO/Attributor.h | 9 +++-
.../Transforms/IPO/AttributorAttributes.cpp | 3 ++
.../Transforms/IPO/AttributorTest.cpp | 48 +++++++++++++++++++
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 00b20eee4d5df..4cce13397a882 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -1705,7 +1705,7 @@ struct Attributor {
AAPtr = &AA;
// Register AA with the synthetic root only before the manifest stage.
- if (Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE)
+ if (isDuringDeduction())
DG.SyntheticRoot.Deps.insert(
AADepGraphNode::DepTy(&AA, unsigned(DepClassTy::REQUIRED)));
@@ -1745,7 +1745,7 @@ struct Attributor {
template <typename AAType> bool shouldUpdateAA(const IRPosition &IRP) {
// If this is queried in the manifest stage, we force the AA to indicate
// pessimistic fixpoint immediately.
- if (Phase == AttributorPhase::MANIFEST || Phase == AttributorPhase::CLEANUP)
+ if (!isDuringDeduction())
return false;
Function *AssociatedFn = IRP.getAssociatedFunction();
@@ -1821,6 +1821,11 @@ struct Attributor {
(Configuration.IPOAmendableCB && Configuration.IPOAmendableCB(F));
}
+ /// Return whether attributes can participate in fixed-point deduction.
+ bool isDuringDeduction() const {
+ return Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE;
+ }
+
/// Mark the internal function \p F as live.
///
/// This will trigger the identification and initialization of attributes for
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 22af6f7741544..ac4268f78143d 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -4673,6 +4673,9 @@ struct AAIsDeadFunction : public AAIsDead {
if (!AssumedLiveBlocks.insert(&BB).second)
return false;
+ if (!A.isDuringDeduction())
+ return true;
+
// We assume that all of BB is (probably) live now and if there are calls to
// internal functions we will assume that those are now live as well. This
// is a performance optimization for blocks with calls to a lot of internal
diff --git a/llvm/unittests/Transforms/IPO/AttributorTest.cpp b/llvm/unittests/Transforms/IPO/AttributorTest.cpp
index 8d90b308f840c..9d3d64f75a458 100644
--- a/llvm/unittests/Transforms/IPO/AttributorTest.cpp
+++ b/llvm/unittests/Transforms/IPO/AttributorTest.cpp
@@ -212,4 +212,52 @@ TEST_F(AttributorTestBase, AAReachabilityTest) {
ASSERT_FALSE(F9AA.instructionCanReach(A, F9FirstInst, F4));
}
+TEST_F(AttributorTestBase, CleanupDoesNotSeedLiveCallees) {
+ for (bool SeedCaller : {false, true}) {
+ SCOPED_TRACE(SeedCaller);
+ Module &M = parseModule(R"(
+ define internal void @leaf() { ret void }
+ define internal void @sibling() { ret void }
+ define void @caller() {
+ call void @leaf()
+ call void @sibling()
+ ret void
+ }
+ )");
+ SetVector<Function *> Functions;
+ for (Function &F : M)
+ Functions.insert(&F);
+ AnalysisGetter AG;
+ CallGraphUpdater CGUpdater;
+ BumpPtrAllocator Allocator;
+ InformationCache InfoCache(M, AG, Allocator, nullptr);
+ AttributorConfig AC(CGUpdater);
+ AC.DefaultInitializeLiveInternals = false;
+ unsigned NumInitializations = 0;
+ // This callback observes markLiveInternalFunction without seeding other
+ // AAs.
+ AC.InitializationCallback = [&](Attributor &, const Function &) {
+ ++NumInitializations;
+ };
+ Attributor A(Functions, InfoCache, AC);
+ auto CallerPos = IRPosition::function(*M.getFunction("caller"));
+ EXPECT_EQ(A.lookupAAFor<AAIsDead>(CallerPos, nullptr, DepClassTy::NONE,
+ /*AllowInvalidState=*/true),
+ nullptr);
+ if (SeedCaller) {
+ // Control: discovering a live block during seeding still seeds callees.
+ A.getOrCreateAAFor<AAIsDead>(CallerPos);
+ EXPECT_EQ(NumInitializations, 2u);
+ }
+
+ // Without an initial AA, cleanup's dead-function check creates caller's
+ // liveness AA. Its initializer must not seed leaf or sibling.
+ EXPECT_EQ(A.run(), ChangeStatus::UNCHANGED);
+ EXPECT_NE(A.lookupAAFor<AAIsDead>(CallerPos, nullptr, DepClassTy::NONE,
+ /*AllowInvalidState=*/true),
+ nullptr);
+ EXPECT_EQ(NumInitializations, SeedCaller ? 2u : 0u);
+ }
+}
+
} // namespace llvm
>From 9e090d13512b376ea01a8397905d5cb3b52ae4c9 Mon Sep 17 00:00:00 2001
From: "zhangjiatong.0" <zhangjiatong.0 at bytedance.com>
Date: Wed, 9 Sep 2026 13:46:22 +0800
Subject: [PATCH 2/2] clang format
---
llvm/include/llvm/Transforms/IPO/Attributor.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 4cce13397a882..066883afafb95 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -1823,7 +1823,8 @@ struct Attributor {
/// Return whether attributes can participate in fixed-point deduction.
bool isDuringDeduction() const {
- return Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE;
+ return Phase == AttributorPhase::SEEDING ||
+ Phase == AttributorPhase::UPDATE;
}
/// Mark the internal function \p F as live.
More information about the llvm-commits
mailing list