[llvm] [PromoteMem2Reg] Optimize memory usage in PromoteMem2Reg (PR #142474)
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 3 14:48:53 PDT 2025
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/142474
>From 129774fed83f63c954ba908d368379b26e66ec6e Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Mon, 2 Jun 2025 13:05:41 -0700
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
=?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6
[skip ci]
---
.../Utils/PromoteMemoryToRegister.cpp | 77 +++++++++++--------
.../2009-02-20-InstCombine-SROA.ll | 4 +-
.../Hexagon/switch-to-lookup-table.ll | 2 +-
3 files changed, 47 insertions(+), 36 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index 6ba64968193cf..9ddcbd516e00a 100644
--- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -392,6 +392,15 @@ struct PromoteMem2Reg {
/// number.
SmallVector<unsigned> BBNumPreds;
+ /// The state of incoming values for the current DFS step.
+ RenamePassData::ValVector IncomingVals;
+
+ /// The state of incoming locations for the current DFS step.
+ RenamePassData::LocationVector IncomingLocs;
+
+ // DFS work stack.
+ SmallVector<RenamePassData, 8> WorkList;
+
/// Whether the function has the no-signed-zeros-fp-math attribute set.
bool NoSignedZeros = false;
@@ -423,10 +432,7 @@ struct PromoteMem2Reg {
void ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
const SmallPtrSetImpl<BasicBlock *> &DefBlocks,
SmallPtrSetImpl<BasicBlock *> &LiveInBlocks);
- void RenamePass(BasicBlock *BB, BasicBlock *Pred,
- RenamePassData::ValVector &IncVals,
- RenamePassData::LocationVector &IncLocs,
- std::vector<RenamePassData> &Worklist);
+ void RenamePass(BasicBlock *BB, BasicBlock *Pred);
bool QueuePhiNode(BasicBlock *BB, unsigned AllocaIdx, unsigned &Version);
/// Delete dbg.assigns that have been demoted to dbg.values.
@@ -438,6 +444,20 @@ struct PromoteMem2Reg {
DVR->eraseFromParent();
DVRAssignsToDelete.clear();
}
+
+ void pushToWorklist(BasicBlock *BB, BasicBlock *Pred,
+ RenamePassData::ValVector IncVals,
+ RenamePassData::LocationVector IncLocs) {
+ WorkList.emplace_back(BB, Pred, std::move(IncVals), std::move(IncLocs));
+ }
+
+ RenamePassData popFromWorklist() {
+ RenamePassData R = std::move(WorkList.back());
+ WorkList.pop_back();
+ IncomingVals = std::move(R.Values);
+ IncomingLocs = std::move(R.Locations);
+ return R;
+ }
};
} // end anonymous namespace
@@ -849,28 +869,26 @@ void PromoteMem2Reg::run() {
// Set the incoming values for the basic block to be null values for all of
// the alloca's. We do this in case there is a load of a value that has not
// been stored yet. In this case, it will get this null value.
- RenamePassData::ValVector Values(Allocas.size());
+ IncomingVals.assign(Allocas.size(), nullptr);
for (unsigned i = 0, e = Allocas.size(); i != e; ++i)
- Values[i] = UndefValue::get(Allocas[i]->getAllocatedType());
+ IncomingVals[i] = UndefValue::get(Allocas[i]->getAllocatedType());
// When handling debug info, treat all incoming values as if they have unknown
// locations until proven otherwise.
- RenamePassData::LocationVector Locations(Allocas.size());
+ IncomingLocs.assign(Allocas.size(), {});
// The renamer uses the Visited set to avoid infinite loops.
Visited.resize(F.getMaxBlockNumber());
// Walks all basic blocks in the function performing the SSA rename algorithm
// and inserting the phi nodes we marked as necessary
- std::vector<RenamePassData> RenamePassWorkList;
- RenamePassWorkList.emplace_back(&F.front(), nullptr, std::move(Values),
- std::move(Locations));
+ pushToWorklist(&F.front(), nullptr, std::move(IncomingVals),
+ std::move(IncomingLocs));
do {
- RenamePassData RPD = std::move(RenamePassWorkList.back());
- RenamePassWorkList.pop_back();
+ RenamePassData RPD = popFromWorklist();
// RenamePass may add new worklist entries.
- RenamePass(RPD.BB, RPD.Pred, RPD.Values, RPD.Locations, RenamePassWorkList);
- } while (!RenamePassWorkList.empty());
+ RenamePass(RPD.BB, RPD.Pred);
+ } while (!WorkList.empty());
// Remove the allocas themselves from the function.
for (Instruction *A : Allocas) {
@@ -1095,11 +1113,7 @@ static void updateForIncomingValueLocation(PHINode *PN, DebugLoc DL,
///
/// IncomingVals indicates what value each Alloca contains on exit from the
/// predecessor block Pred.
-void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
- RenamePassData::ValVector &IncomingVals,
- RenamePassData::LocationVector &IncomingLocs,
- std::vector<RenamePassData> &Worklist) {
-NextIteration:
+void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
// If we are inserting any phi nodes into this BB, they will already be in the
// block.
if (PHINode *APN = dyn_cast<PHINode>(BB->begin())) {
@@ -1215,24 +1229,21 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
}
// 'Recurse' to our successors.
- succ_iterator I = succ_begin(BB), E = succ_end(BB);
- if (I == E)
- return;
// Keep track of the successors so we don't visit the same successor twice
SmallPtrSet<BasicBlock *, 8> VisitedSuccs;
- // Handle the first successor without using the worklist.
- VisitedSuccs.insert(*I);
- Pred = BB;
- BB = *I;
- ++I;
-
- for (; I != E; ++I)
- if (VisitedSuccs.insert(*I).second)
- Worklist.emplace_back(*I, Pred, IncomingVals, IncomingLocs);
-
- goto NextIteration;
+ for (BasicBlock *S : reverse(successors(BB)))
+ if (VisitedSuccs.insert(S).second) {
+ if (VisitedSuccs.size() == 1) {
+ // Let the first successor to own allocated arrays.
+ pushToWorklist(S, BB, std::move(IncomingVals), std::move(IncomingLocs));
+ } else {
+ // Other successors have to make a copy.
+ pushToWorklist(S, BB, WorkList.back().Values,
+ WorkList.back().Locations);
+ }
+ }
}
void llvm::PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
diff --git a/llvm/test/Transforms/InstCombine/2009-02-20-InstCombine-SROA.ll b/llvm/test/Transforms/InstCombine/2009-02-20-InstCombine-SROA.ll
index b532c81556738..ef414885bf809 100644
--- a/llvm/test/Transforms/InstCombine/2009-02-20-InstCombine-SROA.ll
+++ b/llvm/test/Transforms/InstCombine/2009-02-20-InstCombine-SROA.ll
@@ -215,7 +215,7 @@ define ptr @_Z3fooRSt6vectorIiSaIiEE(ptr %X) {
; IC_SROA-NEXT: [[TMP27:%.*]] = getelementptr i8, ptr [[__FIRST_ADDR_I_I_SROA_0_0]], i32 4
; IC_SROA-NEXT: br label [[BB18_I_I]]
; IC_SROA: bb18.i.i:
-; IC_SROA-NEXT: [[__FIRST_ADDR_I_I_SROA_0_1:%.*]] = phi ptr [ [[TMP27]], [[BB17_I_I]] ], [ [[__FIRST_ADDR_I_I_SROA_0_0]], [[BB13_I_I]] ]
+; IC_SROA-NEXT: [[__FIRST_ADDR_I_I_SROA_0_1:%.*]] = phi ptr [ [[__FIRST_ADDR_I_I_SROA_0_0]], [[BB13_I_I]] ], [ [[TMP27]], [[BB17_I_I]] ]
; IC_SROA-NEXT: [[TMP28:%.*]] = load i32, ptr [[__FIRST_ADDR_I_I_SROA_0_1]], align 4
; IC_SROA-NEXT: [[TMP29:%.*]] = icmp eq i32 [[TMP28]], 42
; IC_SROA-NEXT: br i1 [[TMP29]], label [[BB20_I_I:%.*]], label [[BB21_I_I:%.*]]
@@ -225,7 +225,7 @@ define ptr @_Z3fooRSt6vectorIiSaIiEE(ptr %X) {
; IC_SROA-NEXT: [[TMP30:%.*]] = getelementptr i8, ptr [[__FIRST_ADDR_I_I_SROA_0_1]], i32 4
; IC_SROA-NEXT: br label [[BB22_I_I]]
; IC_SROA: bb22.i.i:
-; IC_SROA-NEXT: [[__FIRST_ADDR_I_I_SROA_0_2:%.*]] = phi ptr [ [[TMP30]], [[BB21_I_I]] ], [ [[__FIRST_ADDR_I_I_SROA_0_0]], [[BB13_I_I]] ]
+; IC_SROA-NEXT: [[__FIRST_ADDR_I_I_SROA_0_2:%.*]] = phi ptr [ [[__FIRST_ADDR_I_I_SROA_0_0]], [[BB13_I_I]] ], [ [[TMP30]], [[BB21_I_I]] ]
; IC_SROA-NEXT: [[TMP31:%.*]] = load i32, ptr [[__FIRST_ADDR_I_I_SROA_0_2]], align 4
; IC_SROA-NEXT: [[TMP32:%.*]] = icmp eq i32 [[TMP31]], 42
; IC_SROA-NEXT: br i1 [[TMP32]], label [[BB24_I_I:%.*]], label [[BB25_I_I:%.*]]
diff --git a/llvm/test/Transforms/SimplifyCFG/Hexagon/switch-to-lookup-table.ll b/llvm/test/Transforms/SimplifyCFG/Hexagon/switch-to-lookup-table.ll
index 349a18148460f..a29c6a2fdd642 100644
--- a/llvm/test/Transforms/SimplifyCFG/Hexagon/switch-to-lookup-table.ll
+++ b/llvm/test/Transforms/SimplifyCFG/Hexagon/switch-to-lookup-table.ll
@@ -43,7 +43,7 @@ define i32 @foo(i32 %x) #0 section ".tcm_text" {
; DISABLE: sw.default:
; DISABLE-NEXT: br label [[RETURN]]
; DISABLE: return:
-; DISABLE-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 19, [[SW_DEFAULT]] ], [ 33, [[SW_BB5]] ], [ 12, [[SW_BB4]] ], [ 22, [[SW_BB3]] ], [ 14, [[SW_BB2]] ], [ 20, [[SW_BB1]] ], [ 9, [[ENTRY:%.*]] ]
+; DISABLE-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 19, [[SW_DEFAULT]] ], [ 20, [[SW_BB1]] ], [ 14, [[SW_BB2]] ], [ 22, [[SW_BB3]] ], [ 12, [[SW_BB4]] ], [ 33, [[SW_BB5]] ], [ 9, [[ENTRY:%.*]] ]
; DISABLE-NEXT: ret i32 [[RETVAL_0]]
;
entry:
>From 67df9b07f00aa5a9c93dca58ec2d0278ce112fb2 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Mon, 2 Jun 2025 15:26:36 -0700
Subject: [PATCH 2/2] rebase
Created using spr 1.3.6
---
llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index 2ac304cf7f231..6902156630a77 100644
--- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -306,7 +306,10 @@ template <typename T> class VectorWithUndo {
Vals[Idx] = Val;
}
- void init(size_t Idx, const T &Val) { Vals[Idx] = Val; }
+ void init(size_t Idx, const T &Val) {
+ assert(Undo.empty());
+ Vals[Idx] = Val;
+ }
};
/// Data package used by RenamePass().
More information about the llvm-commits
mailing list