[llvm] [JumpThreading] Refractor redirectValuesFromPredecessorsToPhi: avoid unnecessary map resizing in gatherIncomingValuesToPhi (PR #173596)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 30 04:00:15 PST 2025
https://github.com/int-zjt updated https://github.com/llvm/llvm-project/pull/173596
>From 9958963e59d13b90179c87151d3ef23c3ab3a465 Mon Sep 17 00:00:00 2001
From: "zhangjiatong.0" <zhangjiatong.0 at bytedance.com>
Date: Thu, 11 Dec 2025 19:48:27 +0800
Subject: [PATCH 1/4] [JumpThreading] Add fast path for single-pred blocks in
redirectValuesFromPredecessorsToPhi
---
llvm/lib/Transforms/Utils/Local.cpp | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index f7842a235b20d..9e5115d0b0795 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1077,6 +1077,19 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
Value *OldVal = PN->removeIncomingValue(BB, false);
assert(OldVal && "No entry in PHI for Pred BB!");
+ // Fast path: If BB has a single predecessor and the incoming value is not
+ // defined in BB itself, we can directly redirect the edge.
+ //
+ // Note: We rely on TryToSimplifyUncondBranchFromEmptyBlock (the caller) to
+ // have already verified via CanPropagatePredecessorsForPHIs that merging
+ // blocks won't introduce value conflicts for any common predecessors.
+ auto *BBSinglePred = BB->getSinglePredecessor();
+ Instruction *OldInst = dyn_cast<Instruction>(OldVal);
+ if (BBSinglePred && OldInst && OldInst->getParent() != BB) {
+ PN->addIncoming(OldVal, BBSinglePred);
+ return;
+ }
+
IncomingValueMap IncomingValues;
// We are merging two blocks - BB, and the block containing PN - and
>From efc76213c515606b1264094132eccb22694c9635 Mon Sep 17 00:00:00 2001
From: "zhangjiatong.0" <zhangjiatong.0bytedance.com>
Date: Mon, 29 Dec 2025 14:19:30 +0800
Subject: [PATCH 2/4] Replace IncomingValues by a known value
---
llvm/lib/Transforms/Utils/Local.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 9e5115d0b0795..60e89932ae1a7 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1087,6 +1087,14 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
Instruction *OldInst = dyn_cast<Instruction>(OldVal);
if (BBSinglePred && OldInst && OldInst->getParent() != BB) {
PN->addIncoming(OldVal, BBSinglePred);
+
+ auto *knownDefine = OldVal;
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (PN->getIncomingBlock(i) == BBSinglePred && !isa<UndefValue>(PN->getIncomingValue(i)))
+ knownDefine = PN->getIncomingValue(i);
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (PN->getIncomingBlock(i) == BBSinglePred)
+ PN->setIncomingValue(i, knownDefine);
return;
}
>From 68feda8189e5ff16db983efccb01090bc5ade172 Mon Sep 17 00:00:00 2001
From: "zhangjiatong.0" <zhangjiatong.0bytedance.com>
Date: Mon, 29 Dec 2025 14:20:28 +0800
Subject: [PATCH 3/4] Format
---
llvm/lib/Transforms/Utils/Local.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 60e89932ae1a7..1a00f9fd91ae7 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1087,10 +1087,11 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
Instruction *OldInst = dyn_cast<Instruction>(OldVal);
if (BBSinglePred && OldInst && OldInst->getParent() != BB) {
PN->addIncoming(OldVal, BBSinglePred);
-
+
auto *knownDefine = OldVal;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
- if (PN->getIncomingBlock(i) == BBSinglePred && !isa<UndefValue>(PN->getIncomingValue(i)))
+ if (PN->getIncomingBlock(i) == BBSinglePred &&
+ !isa<UndefValue>(PN->getIncomingValue(i)))
knownDefine = PN->getIncomingValue(i);
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
if (PN->getIncomingBlock(i) == BBSinglePred)
>From 6f5040509262dbef3867e7aafb3f2faf238d1e4a Mon Sep 17 00:00:00 2001
From: "zhangjiatong.0" <zhangjiatong.0bytedance.com>
Date: Mon, 29 Dec 2025 17:13:18 +0800
Subject: [PATCH 4/4] Refractor redirectValuesFromPredecessorsToPhi
---
llvm/lib/Transforms/Utils/Local.cpp | 67 +++++++++++++----------------
1 file changed, 31 insertions(+), 36 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 1a00f9fd91ae7..d01944b5d2efa 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -926,16 +926,18 @@ using IncomingValueMap = SmallDenseMap<BasicBlock *, Value *, 16>;
static Value *selectIncomingValueForBlock(Value *OldVal, BasicBlock *BB,
IncomingValueMap &IncomingValues) {
if (!isa<UndefValue>(OldVal)) {
- assert((!IncomingValues.count(BB) ||
- IncomingValues.find(BB)->second == OldVal) &&
+ assert((IncomingValues.count(BB) &&
+ (isa<UndefValue>(IncomingValues.find(BB)->second) ||
+ IncomingValues.find(BB)->second == OldVal)) &&
"Expected OldVal to match incoming value from BB!");
- IncomingValues.insert(std::make_pair(BB, OldVal));
+ IncomingValues.insert_or_assign(BB, OldVal);
return OldVal;
}
IncomingValueMap::const_iterator It = IncomingValues.find(BB);
- if (It != IncomingValues.end()) return It->second;
+ if (It != IncomingValues.end() && !isa<UndefValue>(It->second))
+ return It->second;
return OldVal;
}
@@ -943,19 +945,30 @@ static Value *selectIncomingValueForBlock(Value *OldVal, BasicBlock *BB,
/// Create a map from block to value for the operands of a
/// given phi.
///
-/// Create a map from block to value for each non-undef value flowing
-/// into \p PN.
+/// This function initializes the map with UndefValue for all predecessors
+/// in BBPreds, and then updates the map with concrete non-undef values
+/// found in the PHI node.
///
/// \param PN The phi we are collecting the map for.
+/// \param BBPreds The list of all predecessor blocks to initialize with Undef.
/// \param IncomingValues [out] The map from block to value for this phi.
-static void gatherIncomingValuesToPhi(PHINode *PN,
- IncomingValueMap &IncomingValues) {
+static void gatherIncomingValuesToPhi(llvm::PHINode *PN,
+ IncomingValueMap &IncomingValues,
+ const PredBlockVector &BBPreds) {
+ llvm::Value *Undef = llvm::UndefValue::get(PN->getType());
+ for (llvm::BasicBlock *Pred : BBPreds) {
+ IncomingValues[Pred] = Undef;
+ }
+
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- BasicBlock *BB = PN->getIncomingBlock(i);
- Value *V = PN->getIncomingValue(i);
+ llvm::Value *V = PN->getIncomingValue(i);
+ if (llvm::isa<llvm::UndefValue>(V))
+ continue;
- if (!isa<UndefValue>(V))
- IncomingValues.insert(std::make_pair(BB, V));
+ llvm::BasicBlock *BB = PN->getIncomingBlock(i);
+ if (IncomingValues.count(BB)) {
+ IncomingValues[BB] = V;
+ }
}
}
@@ -974,12 +987,15 @@ static void replaceUndefValuesInPhi(PHINode *PN,
BasicBlock *BB = PN->getIncomingBlock(i);
IncomingValueMap::const_iterator It = IncomingValues.find(BB);
+ if (It == IncomingValues.end()) {
+ continue;
+ }
// Keep track of undef/poison incoming values. Those must match, so we fix
// them up below if needed.
// Note: this is conservatively correct, but we could try harder and group
// the undef values per incoming basic block.
- if (It == IncomingValues.end()) {
+ if (isa<UndefValue>(It->second)) {
TrueUndefOps.push_back(i);
continue;
}
@@ -1077,28 +1093,7 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
Value *OldVal = PN->removeIncomingValue(BB, false);
assert(OldVal && "No entry in PHI for Pred BB!");
- // Fast path: If BB has a single predecessor and the incoming value is not
- // defined in BB itself, we can directly redirect the edge.
- //
- // Note: We rely on TryToSimplifyUncondBranchFromEmptyBlock (the caller) to
- // have already verified via CanPropagatePredecessorsForPHIs that merging
- // blocks won't introduce value conflicts for any common predecessors.
- auto *BBSinglePred = BB->getSinglePredecessor();
- Instruction *OldInst = dyn_cast<Instruction>(OldVal);
- if (BBSinglePred && OldInst && OldInst->getParent() != BB) {
- PN->addIncoming(OldVal, BBSinglePred);
-
- auto *knownDefine = OldVal;
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
- if (PN->getIncomingBlock(i) == BBSinglePred &&
- !isa<UndefValue>(PN->getIncomingValue(i)))
- knownDefine = PN->getIncomingValue(i);
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
- if (PN->getIncomingBlock(i) == BBSinglePred)
- PN->setIncomingValue(i, knownDefine);
- return;
- }
-
+ // Map BBPreds to defined or undefined values in PN
IncomingValueMap IncomingValues;
// We are merging two blocks - BB, and the block containing PN - and
@@ -1110,7 +1105,7 @@ static void redirectValuesFromPredecessorsToPhi(BasicBlock *BB,
// values flowing into PN, we want to rewrite those values to be
// consistent with the non-undef values.
- gatherIncomingValuesToPhi(PN, IncomingValues);
+ gatherIncomingValuesToPhi(PN, IncomingValues, BBPreds);
// If this incoming value is one of the PHI nodes in BB, the new entries
// in the PHI node are the entries from the old PHI.
More information about the llvm-commits
mailing list