[llvm] [NFC] Various Cleanup in StackColoring, StackSlotColoring, LiveStacks (PR #143931)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 12 10:15:45 PDT 2025
https://github.com/Ralender updated https://github.com/llvm/llvm-project/pull/143931
>From 5a895411a79f090375fdf015cd9d4be29da9c48a Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Tue, 20 May 2025 22:28:40 +0200
Subject: [PATCH 1/9] [NFC][StackColoring] Remove unused member for
StackColoring
---
llvm/lib/CodeGen/StackColoring.cpp | 5 -----
1 file changed, 5 deletions(-)
diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index 0f93822d9792b..8946c7cd44058 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -402,9 +402,6 @@ class StackColoring {
using LivenessMap = DenseMap<const MachineBasicBlock *, BlockLifetimeInfo>;
LivenessMap BlockLiveness;
- /// Maps serial numbers to basic blocks.
- DenseMap<const MachineBasicBlock *, int> BasicBlocks;
-
/// Maps basic blocks to a serial number.
SmallVector<const MachineBasicBlock *, 8> BasicBlockNumbering;
@@ -727,7 +724,6 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
// deterministic numbering.
for (MachineBasicBlock *MBB : depth_first(MF)) {
// Assign a serial number to this basic block.
- BasicBlocks[MBB] = BasicBlockNumbering.size();
BasicBlockNumbering.push_back(MBB);
// Keep a reference to avoid repeated lookups.
@@ -1211,7 +1207,6 @@ bool StackColoring::run(MachineFunction &Func) {
MF = &Func;
MFI = &MF->getFrameInfo();
BlockLiveness.clear();
- BasicBlocks.clear();
BasicBlockNumbering.clear();
Markers.clear();
Intervals.clear();
>From 25e4f3f31a2f119bff7b44348b5646c88f65d6cb Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Tue, 20 May 2025 23:23:46 +0200
Subject: [PATCH 2/9] [NFC][StackColoring] Use LiveRange instead of
LiveInterval in StackColoring
---
llvm/lib/CodeGen/StackColoring.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index 8946c7cd44058..609ee3bbc369c 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -407,7 +407,7 @@ class StackColoring {
/// Maps slots to their use interval. Outside of this interval, slots
/// values are either dead or `undef` and they will not be written to.
- SmallVector<std::unique_ptr<LiveInterval>, 16> Intervals;
+ SmallVector<std::unique_ptr<LiveRange>, 16> Intervals;
/// Maps slots to the points where they can become in-use.
SmallVector<SmallVector<SlotIndex, 4>, 16> LiveStarts;
@@ -1035,7 +1035,7 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
// validating the instructions.
if (!I.isDebugInstr() && TouchesMemory && ProtectFromEscapedAllocas) {
SlotIndex Index = Indexes->getInstructionIndex(I);
- const LiveInterval *Interval = &*Intervals[FromSlot];
+ const LiveRange *Interval = &*Intervals[FromSlot];
assert(Interval->find(Index) != Interval->end() &&
"Found instruction usage outside of live range.");
}
@@ -1155,7 +1155,7 @@ void StackColoring::removeInvalidSlotRanges() {
// Check that the used slot is inside the calculated lifetime range.
// If it is not, warn about it and invalidate the range.
- LiveInterval *Interval = &*Intervals[Slot];
+ LiveRange *Interval = &*Intervals[Slot];
SlotIndex Index = Indexes->getInstructionIndex(I);
if (Interval->find(Index) == Interval->end()) {
Interval->clear();
@@ -1247,7 +1247,7 @@ bool StackColoring::run(MachineFunction &Func) {
}
for (unsigned i=0; i < NumSlots; ++i) {
- std::unique_ptr<LiveInterval> LI(new LiveInterval(i, 0));
+ std::unique_ptr<LiveRange> LI(new LiveRange());
LI->getNextValue(Indexes->getZeroIndex(), VNInfoAllocator);
Intervals.push_back(std::move(LI));
SortedSlots.push_back(i);
@@ -1317,8 +1317,8 @@ bool StackColoring::run(MachineFunction &Func) {
if (MFI->getStackID(FirstSlot) != MFI->getStackID(SecondSlot))
continue;
- LiveInterval *First = &*Intervals[FirstSlot];
- LiveInterval *Second = &*Intervals[SecondSlot];
+ LiveRange *First = &*Intervals[FirstSlot];
+ LiveRange *Second = &*Intervals[SecondSlot];
auto &FirstS = LiveStarts[FirstSlot];
auto &SecondS = LiveStarts[SecondSlot];
assert(!First->empty() && !Second->empty() && "Found an empty range");
>From cf275f987ce5179c4be6317ba9d642b5d351b5d2 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 22 May 2025 20:11:39 +0200
Subject: [PATCH 3/9] [NFC][CodeGen] Cleanup lifetime in StackColoring instead
of DeadMachineInstructionElim
---
llvm/lib/CodeGen/MachineInstr.cpp | 4 ---
llvm/lib/CodeGen/StackColoring.cpp | 22 +++++++++++++---
llvm/test/CodeGen/X86/StackColoring.ll | 35 ++++++++++++++++++++++++++
3 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index da3665b3b6a0b..3e5fd59534105 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -1417,10 +1417,6 @@ bool MachineInstr::isDead(const MachineRegisterInfo &MRI,
if (isInlineAsm())
return false;
- // FIXME: See issue #105950 for why LIFETIME markers are considered dead here.
- if (isLifetimeMarker())
- return true;
-
// If there are no defs with uses, then we call the instruction dead so long
// as we do not suspect it may have sideeffects.
return wouldBeTriviallyDead();
diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index 609ee3bbc369c..d9efe838220fa 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -656,8 +656,10 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
if (MI.getOpcode() == TargetOpcode::LIFETIME_START ||
MI.getOpcode() == TargetOpcode::LIFETIME_END) {
int Slot = getStartOrEndSlot(MI);
- if (Slot < 0)
+ if (Slot < 0) {
+ Markers.push_back(&MI);
continue;
+ }
InterestingSlots.set(Slot);
if (MI.getOpcode() == TargetOpcode::LIFETIME_START) {
BetweenStartEnd.set(Slot);
@@ -896,6 +898,18 @@ bool StackColoring::removeAllMarkers() {
}
Markers.clear();
+ for (MachineBasicBlock &MBB : *MF) {
+ if (BlockLiveness.contains(&MBB))
+ continue;
+ for (MachineInstr &MI : make_early_inc_range(MBB)) {
+ if (MI.getOpcode() == TargetOpcode::LIFETIME_START ||
+ MI.getOpcode() == TargetOpcode::LIFETIME_END) {
+ Count++;
+ MI.eraseFromParent();
+ }
+ }
+ }
+
LLVM_DEBUG(dbgs() << "Removed " << Count << " markers.\n");
return Count;
}
@@ -1216,8 +1230,8 @@ bool StackColoring::run(MachineFunction &Func) {
unsigned NumSlots = MFI->getObjectIndexEnd();
// If there are no stack slots then there are no markers to remove.
- if (!NumSlots)
- return false;
+ if (!NumSlots || DisableColoring)
+ return removeAllMarkers();
SmallVector<int, 8> SortedSlots;
SortedSlots.reserve(NumSlots);
@@ -1241,7 +1255,7 @@ bool StackColoring::run(MachineFunction &Func) {
// Don't continue because there are not enough lifetime markers, or the
// stack is too small, or we are told not to optimize the slots.
- if (NumMarkers < 2 || TotalSize < 16 || DisableColoring) {
+ if (NumMarkers < 2 || TotalSize < 16) {
LLVM_DEBUG(dbgs() << "Will not try to merge slots.\n");
return removeAllMarkers();
}
diff --git a/llvm/test/CodeGen/X86/StackColoring.ll b/llvm/test/CodeGen/X86/StackColoring.ll
index db3e7dcdfe2d5..4cc54c5bd1361 100644
--- a/llvm/test/CodeGen/X86/StackColoring.ll
+++ b/llvm/test/CodeGen/X86/StackColoring.ll
@@ -581,6 +581,41 @@ onerr:
%Data = type { [32 x i64] }
+declare void @throw()
+
+declare i32 @__CxxFrameHandler3(...)
+
+declare void @llvm.trap()
+
+;CHECK-LABEL: removed_all_lifetime:
+;YESCOLOR-NOT: LIFETIME_END
+;NOFIRSTUSE-NOT: LIFETIME_END
+;NOCOLOR-NOT: LIFETIME_END
+define void @removed_all_lifetime() personality ptr @__CxxFrameHandler3 {
+entry:
+ %alloca2 = alloca ptr, align 4
+ %alloca1 = alloca ptr, align 4
+ store volatile ptr null, ptr %alloca1
+ invoke void @throw()
+ to label %unreachable unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %cs = catchswitch within none [label %catch.pad] unwind to caller
+
+catch.pad: ; preds = %catch.dispatch
+ %cp = catchpad within %cs [ptr null, i32 0, ptr %alloca1]
+ %v = load volatile ptr, ptr %alloca1
+ store volatile ptr null, ptr %alloca1
+ call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %alloca1)
+ call void @llvm.lifetime.start.p0(i64 4, ptr %alloca2)
+ store volatile ptr null, ptr %alloca1
+ call void @llvm.trap()
+ unreachable
+
+unreachable: ; preds = %entry
+ unreachable
+}
+
declare void @destructor()
declare void @inita(ptr)
>From 25de44364c8a94f35c6613271b9e299c1caf4a86 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Tue, 10 Jun 2025 22:08:43 +0200
Subject: [PATCH 4/9] [NFC] make constructor explicit LiveRange
Without it it can lead to crazy situtation, when passing a LiveRange* to a function expecting a const LiveRange&
the LiveRange* is converted to bool and a new empty LiveRange is created.
---
llvm/include/llvm/CodeGen/LiveInterval.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/LiveInterval.h b/llvm/include/llvm/CodeGen/LiveInterval.h
index e1c5717f5face..e9ca9e36c95b9 100644
--- a/llvm/include/llvm/CodeGen/LiveInterval.h
+++ b/llvm/include/llvm/CodeGen/LiveInterval.h
@@ -237,9 +237,9 @@ namespace llvm {
}
/// Constructs a new LiveRange object.
- LiveRange(bool UseSegmentSet = false)
- : segmentSet(UseSegmentSet ? std::make_unique<SegmentSet>()
- : nullptr) {}
+ explicit LiveRange(bool UseSegmentSet = false)
+ : segmentSet(UseSegmentSet ? std::make_unique<SegmentSet>() : nullptr) {
+ }
/// Constructs a new LiveRange object by copying segments and valnos from
/// another LiveRange.
>From f85177e3bbfe021e9a38d661389332d5d2782530 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 29 May 2025 15:06:25 +0200
Subject: [PATCH 5/9] [NFC] MachineFrameInfo::print add a bit more informations
---
llvm/lib/CodeGen/MachineFrameInfo.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/llvm/lib/CodeGen/MachineFrameInfo.cpp b/llvm/lib/CodeGen/MachineFrameInfo.cpp
index e4b993850f73d..698bed56e506b 100644
--- a/llvm/lib/CodeGen/MachineFrameInfo.cpp
+++ b/llvm/lib/CodeGen/MachineFrameInfo.cpp
@@ -20,6 +20,7 @@
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
@@ -221,6 +222,12 @@ void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{
if (SO.StackID != 0)
OS << "id=" << static_cast<unsigned>(SO.StackID) << ' ';
+ if (SO.Alloca)
+ OS << "alloca=" << SO.Alloca->getName() << ' ';
+
+ if (SO.isSpillSlot)
+ OS << "spill ";
+
if (SO.Size == ~0ULL) {
OS << "dead\n";
continue;
>From 1bdaaaed5f1ea71b3d4beba2dd9557772f3e4c4b Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 29 May 2025 16:18:52 +0200
Subject: [PATCH 6/9] [NFC][LiveStacks] Use vectors instead of map and
unordred_map
---
llvm/include/llvm/CodeGen/LiveStacks.h | 43 +++++++++++---------------
llvm/lib/CodeGen/LiveStacks.cpp | 41 ++++++++++++------------
llvm/lib/CodeGen/StackSlotColoring.cpp | 14 ++-------
3 files changed, 42 insertions(+), 56 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/LiveStacks.h b/llvm/include/llvm/CodeGen/LiveStacks.h
index 02c640bfc4a93..38650bf21bcf5 100644
--- a/llvm/include/llvm/CodeGen/LiveStacks.h
+++ b/llvm/include/llvm/CodeGen/LiveStacks.h
@@ -40,49 +40,42 @@ class LiveStacks {
///
VNInfo::Allocator VNInfoAllocator;
- /// S2IMap - Stack slot indices to live interval mapping.
- using SS2IntervalMap = std::unordered_map<int, LiveInterval>;
- SS2IntervalMap S2IMap;
-
- /// S2RCMap - Stack slot indices to register class mapping.
- std::map<int, const TargetRegisterClass *> S2RCMap;
+ int StartIdx = -1;
+ SmallVector<LiveInterval *> S2LI;
+ SmallVector<const TargetRegisterClass *> S2RC;
public:
- using iterator = SS2IntervalMap::iterator;
- using const_iterator = SS2IntervalMap::const_iterator;
+ using iterator = SmallVector<LiveInterval *>::iterator;
+ using const_iterator = SmallVector<LiveInterval *>::const_iterator;
- const_iterator begin() const { return S2IMap.begin(); }
- const_iterator end() const { return S2IMap.end(); }
- iterator begin() { return S2IMap.begin(); }
- iterator end() { return S2IMap.end(); }
+ const_iterator begin() const { return S2LI.begin(); }
+ const_iterator end() const { return S2LI.end(); }
+ iterator begin() { return S2LI.begin(); }
+ iterator end() { return S2LI.end(); }
- unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
+ unsigned getNumIntervals() const { return (unsigned)S2LI.size(); }
LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC);
LiveInterval &getInterval(int Slot) {
assert(Slot >= 0 && "Spill slot indice must be >= 0");
- SS2IntervalMap::iterator I = S2IMap.find(Slot);
- assert(I != S2IMap.end() && "Interval does not exist for stack slot");
- return I->second;
+ return *S2LI[Slot - StartIdx];
}
const LiveInterval &getInterval(int Slot) const {
assert(Slot >= 0 && "Spill slot indice must be >= 0");
- SS2IntervalMap::const_iterator I = S2IMap.find(Slot);
- assert(I != S2IMap.end() && "Interval does not exist for stack slot");
- return I->second;
+ return *S2LI[Slot - StartIdx];
}
- bool hasInterval(int Slot) const { return S2IMap.count(Slot); }
+ bool hasInterval(int Slot) const {
+ if (Slot < StartIdx || StartIdx == -1)
+ return false;
+ return !getInterval(Slot).empty();
+ }
const TargetRegisterClass *getIntervalRegClass(int Slot) const {
assert(Slot >= 0 && "Spill slot indice must be >= 0");
- std::map<int, const TargetRegisterClass *>::const_iterator I =
- S2RCMap.find(Slot);
- assert(I != S2RCMap.end() &&
- "Register class info does not exist for stack slot");
- return I->second;
+ return S2RC[Slot - StartIdx];
}
VNInfo::Allocator &getVNInfoAllocator() { return VNInfoAllocator; }
diff --git a/llvm/lib/CodeGen/LiveStacks.cpp b/llvm/lib/CodeGen/LiveStacks.cpp
index c07d985a09d1f..ea158b2d96a4e 100644
--- a/llvm/lib/CodeGen/LiveStacks.cpp
+++ b/llvm/lib/CodeGen/LiveStacks.cpp
@@ -37,10 +37,12 @@ void LiveStacksWrapperLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
}
void LiveStacks::releaseMemory() {
+ for (int Idx = 0; Idx < (int)S2LI.size(); ++Idx)
+ S2LI[Idx]->~LiveInterval();
// Release VNInfo memory regions, VNInfo objects don't need to be dtor'd.
VNInfoAllocator.Reset();
- S2IMap.clear();
- S2RCMap.clear();
+ S2LI.clear();
+ S2RC.clear();
}
void LiveStacks::init(MachineFunction &MF) {
@@ -52,20 +54,22 @@ void LiveStacks::init(MachineFunction &MF) {
LiveInterval &
LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
assert(Slot >= 0 && "Spill slot indice must be >= 0");
- SS2IntervalMap::iterator I = S2IMap.find(Slot);
- if (I == S2IMap.end()) {
- I = S2IMap
- .emplace(
- std::piecewise_construct, std::forward_as_tuple(Slot),
- std::forward_as_tuple(Register::index2StackSlot(Slot), 0.0F))
- .first;
- S2RCMap.insert(std::make_pair(Slot, RC));
+ if (StartIdx == -1)
+ StartIdx = Slot;
+
+ int Idx = Slot - StartIdx;
+ assert(Idx >= 0 && "Slot not in order ?");
+ if (Idx < (int)S2LI.size()) {
+ S2RC[Idx] = TRI->getCommonSubClass(S2RC[Idx], RC);
} else {
- // Use the largest common subclass register class.
- const TargetRegisterClass *&OldRC = S2RCMap[Slot];
- OldRC = TRI->getCommonSubClass(OldRC, RC);
+ S2RC.resize(Idx + 1);
+ S2LI.resize(Idx + 1);
+ S2LI[Idx] = this->VNInfoAllocator.Allocate<LiveInterval>();
+ new (S2LI[Idx]) LiveInterval(Register::index2StackSlot(Slot), 0.0F);
+ S2RC[Idx] = RC;
}
- return I->second;
+ assert(S2RC.size() == S2LI.size());
+ return *S2LI[Idx];
}
AnalysisKey LiveStacksAnalysis::Key;
@@ -96,13 +100,12 @@ void LiveStacksWrapperLegacy::print(raw_ostream &OS, const Module *) const {
}
/// print - Implement the dump method.
-void LiveStacks::print(raw_ostream &OS, const Module*) const {
+void LiveStacks::print(raw_ostream &OS, const Module *) const {
OS << "********** INTERVALS **********\n";
- for (const_iterator I = begin(), E = end(); I != E; ++I) {
- I->second.print(OS);
- int Slot = I->first;
- const TargetRegisterClass *RC = getIntervalRegClass(Slot);
+ for (int Idx = 0; Idx < (int)S2LI.size(); ++Idx) {
+ S2LI[Idx]->print(OS);
+ const TargetRegisterClass *RC = S2RC[Idx];
if (RC)
OS << " [" << TRI->getRegClassName(RC) << "]\n";
else
diff --git a/llvm/lib/CodeGen/StackSlotColoring.cpp b/llvm/lib/CodeGen/StackSlotColoring.cpp
index 2f81bea4e86ba..9a7df897e3b21 100644
--- a/llvm/lib/CodeGen/StackSlotColoring.cpp
+++ b/llvm/lib/CodeGen/StackSlotColoring.cpp
@@ -262,20 +262,10 @@ void StackSlotColoring::InitializeSlots() {
UsedColors[0].resize(LastFI);
Assignments.resize(LastFI);
- using Pair = std::iterator_traits<LiveStacks::iterator>::value_type;
-
- SmallVector<Pair *, 16> Intervals;
-
- Intervals.reserve(LS->getNumIntervals());
- for (auto &I : *LS)
- Intervals.push_back(&I);
- llvm::sort(Intervals,
- [](Pair *LHS, Pair *RHS) { return LHS->first < RHS->first; });
-
// Gather all spill slots into a list.
LLVM_DEBUG(dbgs() << "Spill slot intervals:\n");
- for (auto *I : Intervals) {
- LiveInterval &li = I->second;
+ for (auto *I : *LS) {
+ LiveInterval &li = *I;
LLVM_DEBUG(li.dump());
int FI = li.reg().stackSlotIndex();
if (MFI->isDeadObjectIndex(FI))
>From c012ebd1987aac596621d32c83d547821a58343d Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 29 May 2025 17:42:37 +0200
Subject: [PATCH 7/9] [NFC][StackSlotColoring] Remove dead code
---
llvm/lib/CodeGen/StackSlotColoring.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/lib/CodeGen/StackSlotColoring.cpp b/llvm/lib/CodeGen/StackSlotColoring.cpp
index 9a7df897e3b21..6fcaa81644387 100644
--- a/llvm/lib/CodeGen/StackSlotColoring.cpp
+++ b/llvm/lib/CodeGen/StackSlotColoring.cpp
@@ -359,7 +359,6 @@ bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
SmallVector<int, 16> SlotMapping(NumObjs, -1);
SmallVector<float, 16> SlotWeights(NumObjs, 0.0);
SmallVector<SmallVector<int, 4>, 16> RevMap(NumObjs);
- BitVector UsedColors(NumObjs);
LLVM_DEBUG(dbgs() << "Color spill slot intervals:\n");
bool Changed = false;
@@ -370,7 +369,6 @@ bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
SlotMapping[SS] = NewSS;
RevMap[NewSS].push_back(SS);
SlotWeights[NewSS] += li->weight();
- UsedColors.set(NewSS);
Changed |= (SS != NewSS);
}
>From 3979f273fa7bf1f323a8c606b6351dbb12413409 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 29 May 2025 23:01:22 +0200
Subject: [PATCH 8/9] [NFC][StackColoring] Use block numbers instead of maps
---
llvm/lib/CodeGen/StackColoring.cpp | 58 +++++++++++++++---------------
1 file changed, 28 insertions(+), 30 deletions(-)
diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index d9efe838220fa..39c9ed408cb9e 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -396,11 +396,11 @@ class StackColoring {
/// Which slots are marked as LIVE_OUT, coming out of each basic block.
BitVector LiveOut;
+
+ bool isEmpty() { return Begin.empty(); }
};
- /// Maps active slots (per bit) for each basic block.
- using LivenessMap = DenseMap<const MachineBasicBlock *, BlockLifetimeInfo>;
- LivenessMap BlockLiveness;
+ SmallVector<BlockLifetimeInfo, 0> BlockLiveness;
/// Maps basic blocks to a serial number.
SmallVector<const MachineBasicBlock *, 8> BasicBlockNumbering;
@@ -438,9 +438,6 @@ class StackColoring {
bool run(MachineFunction &Func);
private:
- /// Used in collectMarkers
- using BlockBitVecMap = DenseMap<const MachineBasicBlock *, BitVector>;
-
/// Debug.
void dump() const;
void dumpIntervals() const;
@@ -538,9 +535,7 @@ LLVM_DUMP_METHOD void StackColoring::dumpBV(const char *tag,
}
LLVM_DUMP_METHOD void StackColoring::dumpBB(MachineBasicBlock *MBB) const {
- LivenessMap::const_iterator BI = BlockLiveness.find(MBB);
- assert(BI != BlockLiveness.end() && "Block not found");
- const BlockLifetimeInfo &BlockInfo = BI->second;
+ const BlockLifetimeInfo &BlockInfo = BlockLiveness[MBB->getNumber()];
dumpBV("BEGIN", BlockInfo.Begin);
dumpBV("END", BlockInfo.End);
@@ -624,7 +619,7 @@ bool StackColoring::isLifetimeStartOrEnd(const MachineInstr &MI,
unsigned StackColoring::collectMarkers(unsigned NumSlot) {
unsigned MarkersFound = 0;
- BlockBitVecMap SeenStartMap;
+ SmallVector<BitVector> SeenStartMap;
InterestingSlots.clear();
InterestingSlots.resize(NumSlot);
ConservativeSlots.clear();
@@ -634,6 +629,8 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
SmallVector<int, 8> NumStartLifetimes(NumSlot, 0);
SmallVector<int, 8> NumEndLifetimes(NumSlot, 0);
+ SeenStartMap.resize(MF->getNumBlockIDs());
+
// Step 1: collect markers and populate the "InterestingSlots"
// and "ConservativeSlots" sets.
for (MachineBasicBlock *MBB : depth_first(MF)) {
@@ -642,10 +639,11 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
// to this bb).
BitVector BetweenStartEnd;
BetweenStartEnd.resize(NumSlot);
+ SeenStartMap[MBB->getNumber()].resize(NumSlot);
for (const MachineBasicBlock *Pred : MBB->predecessors()) {
- BlockBitVecMap::const_iterator I = SeenStartMap.find(Pred);
- if (I != SeenStartMap.end()) {
- BetweenStartEnd |= I->second;
+ BitVector &PredSet = SeenStartMap[Pred->getNumber()];
+ if (!PredSet.empty()) {
+ BetweenStartEnd |= PredSet;
}
}
@@ -693,7 +691,7 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
}
}
}
- BitVector &SeenStart = SeenStartMap[MBB];
+ BitVector &SeenStart = SeenStartMap[MBB->getNumber()];
SeenStart |= BetweenStartEnd;
}
if (!MarkersFound) {
@@ -720,6 +718,7 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
LLVM_DEBUG(dumpBV("Conservative slots", ConservativeSlots));
+ BlockLiveness.resize(MF->getNumBlockIDs());
// Step 2: compute begin/end sets for each block
// NOTE: We use a depth-first iteration to ensure that we obtain a
@@ -729,7 +728,7 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
BasicBlockNumbering.push_back(MBB);
// Keep a reference to avoid repeated lookups.
- BlockLifetimeInfo &BlockInfo = BlockLiveness[MBB];
+ BlockLifetimeInfo &BlockInfo = BlockLiveness[MBB->getNumber()];
BlockInfo.Begin.resize(NumSlot);
BlockInfo.End.resize(NumSlot);
@@ -786,19 +785,19 @@ void StackColoring::calculateLocalLiveness() {
for (const MachineBasicBlock *BB : BasicBlockNumbering) {
// Use an iterator to avoid repeated lookups.
- LivenessMap::iterator BI = BlockLiveness.find(BB);
- assert(BI != BlockLiveness.end() && "Block not found");
- BlockLifetimeInfo &BlockInfo = BI->second;
+ BlockLifetimeInfo &BlockInfo = BlockLiveness[BB->getNumber()];
+ if (BlockInfo.isEmpty())
+ continue;
// Compute LiveIn by unioning together the LiveOut sets of all preds.
LocalLiveIn.clear();
for (MachineBasicBlock *Pred : BB->predecessors()) {
- LivenessMap::const_iterator I = BlockLiveness.find(Pred);
+ BlockLifetimeInfo &PrefInfo = BlockLiveness[Pred->getNumber()];
// PR37130: transformations prior to stack coloring can
// sometimes leave behind statically unreachable blocks; these
// can be safely skipped here.
- if (I != BlockLiveness.end())
- LocalLiveIn |= I->second.LiveOut;
+ if (!PrefInfo.isEmpty())
+ LocalLiveIn |= PrefInfo.LiveOut;
}
// Compute LiveOut by subtracting out lifetimes that end in this
@@ -842,7 +841,7 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
DefinitelyInUse.resize(NumSlots);
// Start the interval of the slots that we previously found to be 'in-use'.
- BlockLifetimeInfo &MBBLiveness = BlockLiveness[&MBB];
+ BlockLifetimeInfo &MBBLiveness = BlockLiveness[MBB.getNumber()];
for (int pos = MBBLiveness.LiveIn.find_first(); pos != -1;
pos = MBBLiveness.LiveIn.find_next(pos)) {
Starts[pos] = Indexes->getMBBStartIdx(&MBB);
@@ -899,15 +898,14 @@ bool StackColoring::removeAllMarkers() {
Markers.clear();
for (MachineBasicBlock &MBB : *MF) {
- if (BlockLiveness.contains(&MBB))
- continue;
- for (MachineInstr &MI : make_early_inc_range(MBB)) {
- if (MI.getOpcode() == TargetOpcode::LIFETIME_START ||
- MI.getOpcode() == TargetOpcode::LIFETIME_END) {
- Count++;
- MI.eraseFromParent();
+ if (BlockLiveness.empty() || BlockLiveness[MBB.getNumber()].isEmpty())
+ for (MachineInstr &MI : make_early_inc_range(MBB)) {
+ if (MI.getOpcode() == TargetOpcode::LIFETIME_START ||
+ MI.getOpcode() == TargetOpcode::LIFETIME_END) {
+ Count++;
+ MI.eraseFromParent();
+ }
}
- }
}
LLVM_DEBUG(dbgs() << "Removed " << Count << " markers.\n");
>From 611fdf75b02dcaad9cb3fc3c801c80742ac29874 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Tue, 10 Jun 2025 22:30:38 +0200
Subject: [PATCH 9/9] [NFC] Improve BitVector dump
---
llvm/lib/CodeGen/StackColoring.cpp | 50 +++++++++++++++++++++++++-----
1 file changed, 42 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index 39c9ed408cb9e..184f1eb4612c7 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -57,6 +57,7 @@
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
+#include <cmath>
#include <limits>
#include <memory>
#include <utility>
@@ -442,7 +443,6 @@ class StackColoring {
void dump() const;
void dumpIntervals() const;
void dumpBB(MachineBasicBlock *MBB) const;
- void dumpBV(const char *tag, const BitVector &BV) const;
/// Removes all of the lifetime marker instructions from the function.
/// \returns true if any markers were removed.
@@ -526,12 +526,39 @@ void StackColoringLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_DUMP_METHOD void StackColoring::dumpBV(const char *tag,
- const BitVector &BV) const {
- dbgs() << tag << " : { ";
- for (unsigned I = 0, E = BV.size(); I != E; ++I)
- dbgs() << BV.test(I) << " ";
- dbgs() << "}\n";
+
+LLVM_DUMP_METHOD void dumpBV(StringRef tag, const BitVector &BV) {
+ constexpr unsigned ColumnWidth = 150;
+ unsigned LineStartOffset = tag.size() + /*" : "*/ 3;
+ unsigned WidthAfterTag = ColumnWidth - LineStartOffset;
+ unsigned NumBitsPerColumn = WidthAfterTag / 2;
+ unsigned BitsCount = BV.size();
+ for (unsigned Bits = 0; Bits < BitsCount; Bits += NumBitsPerColumn) {
+ unsigned Start = Bits;
+ unsigned End = std::min(Start + NumBitsPerColumn, BitsCount);
+
+ dbgs() << tag << " : ";
+
+ for (unsigned I = Start; I < End; ++I)
+ dbgs() << BV.test(I) << " ";
+ dbgs() << '\n';
+ dbgs() << tag << " : ";
+ unsigned next = Start;
+ for (unsigned I = Start; I < End; ++I) {
+ if (I < next)
+ continue;
+ if (BV.test(I)) {
+ int numDidgits = I != 0 ? (log10(I) + 1) : 1;
+ // Make sure number have spacing while staying aligned to the line above
+ next = I + 1 + numDidgits / 2;
+ dbgs() << I << ' ';
+ if (numDidgits % 2 == 0)
+ dbgs() << ' ';
+ } else
+ dbgs() << " ";
+ }
+ dbgs() << '\n';
+ }
}
LLVM_DUMP_METHOD void StackColoring::dumpBB(MachineBasicBlock *MBB) const {
@@ -553,8 +580,15 @@ LLVM_DUMP_METHOD void StackColoring::dump() const {
LLVM_DUMP_METHOD void StackColoring::dumpIntervals() const {
for (unsigned I = 0, E = Intervals.size(); I != E; ++I) {
- dbgs() << "Interval[" << I << "]:\n";
+ dbgs() << "Interval[" << I << "]:";
+ if (MFI->getObjectAllocation(I))
+ dbgs() << *MFI->getObjectAllocation(I);
+ dbgs() << "\n";
Intervals[I]->dump();
+ dbgs() << "LiveStarts:";
+ for (SlotIndex SIdx : LiveStarts[I])
+ dbgs() << " " << SIdx;
+ dbgs() << "\n";
}
}
#endif
More information about the llvm-commits
mailing list