[llvm] [NFC] Various Cleanup in StackColoring, StackSlotColoring, LiveStacks (PR #143931)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 23 10:44:27 PDT 2025


https://github.com/Ralender updated https://github.com/llvm/llvm-project/pull/143931

>From 79bdc6d5c24555a5738b98fb6a6c4d9b50a36e6f 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 6053499c60b4613640f7ad1de924d1c722738a45 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 6994da502239f5c696b75ac4367cf6a6bd467ffe Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Tue, 10 Jun 2025 22:08:43 +0200
Subject: [PATCH 3/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 234d0e7fd4b97e9c0edc6836e89bec74c4d1c0ac Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 29 May 2025 15:06:25 +0200
Subject: [PATCH 4/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..14dc871d89c13 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 && !SO.Alloca->getName().empty())
+      OS << "alloca=" << SO.Alloca->getName() << ' ';
+
+    if (SO.isSpillSlot)
+      OS << "spill ";
+
     if (SO.Size == ~0ULL) {
       OS << "dead\n";
       continue;

>From 61fb22b4214e0fa767a035e12870fdd66a807462 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 29 May 2025 17:42:37 +0200
Subject: [PATCH 5/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 2f81bea4e86ba..aaff2d6238c1e 100644
--- a/llvm/lib/CodeGen/StackSlotColoring.cpp
+++ b/llvm/lib/CodeGen/StackSlotColoring.cpp
@@ -369,7 +369,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;
@@ -380,7 +379,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 c426f399311ccdba3ee36fbdb8ba3bb46c93a747 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 29 May 2025 23:01:22 +0200
Subject: [PATCH 6/9] [NFC][StackColoring] Use block numbers instead of maps

---
 llvm/lib/CodeGen/StackColoring.cpp | 43 +++++++++++++++---------------
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index 609ee3bbc369c..1bb1861a06f44 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;
       }
     }
 
@@ -691,7 +689,7 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
         }
       }
     }
-    BitVector &SeenStart = SeenStartMap[MBB];
+    BitVector &SeenStart = SeenStartMap[MBB->getNumber()];
     SeenStart |= BetweenStartEnd;
   }
   if (!MarkersFound) {
@@ -718,6 +716,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
@@ -727,7 +726,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);
@@ -784,19 +783,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
@@ -840,7 +839,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);

>From 0f99d72243be9ef5f6468c0dacbe3d024a2f257f Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 19 Jun 2025 23:01:33 +0200
Subject: [PATCH 7/9] [NFC] implement NumDigitsBase10 in MathExtras.h and
 update some users of log10

---
 .../llvm/DebugInfo/PDB/Native/FormatUtil.h    | 43 -------------------
 .../llvm/DebugInfo/PDB/Native/InputFile.h     |  4 +-
 llvm/include/llvm/Support/MathExtras.h        | 35 +++++++++++++++
 llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp    |  2 +-
 llvm/lib/Support/Signals.cpp                  |  2 +-
 llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp  |  2 +-
 llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp   | 18 ++++----
 llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp |  6 +--
 .../llvm-remarkutil/RemarkInstructionMix.cpp  |  2 +-
 llvm/unittests/Support/MathExtrasTest.cpp     | 15 +++++++
 llvm/utils/FileCheck/FileCheck.cpp            |  2 +-
 11 files changed, 69 insertions(+), 62 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h b/llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h
index 76a019ddf8f34..a76b5c0d44791 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h
@@ -62,49 +62,6 @@ LLVM_ABI std::string formatChunkKind(codeview::DebugSubsectionKind Kind,
 LLVM_ABI std::string formatSymbolKind(codeview::SymbolKind K);
 LLVM_ABI std::string formatTypeLeafKind(codeview::TypeLeafKind K);
 
-/// Returns the number of digits in the given integer.
-inline int NumDigits(uint64_t N) {
-  if (N < 10ULL)
-    return 1;
-  if (N < 100ULL)
-    return 2;
-  if (N < 1000ULL)
-    return 3;
-  if (N < 10000ULL)
-    return 4;
-  if (N < 100000ULL)
-    return 5;
-  if (N < 1000000ULL)
-    return 6;
-  if (N < 10000000ULL)
-    return 7;
-  if (N < 100000000ULL)
-    return 8;
-  if (N < 1000000000ULL)
-    return 9;
-  if (N < 10000000000ULL)
-    return 10;
-  if (N < 100000000000ULL)
-    return 11;
-  if (N < 1000000000000ULL)
-    return 12;
-  if (N < 10000000000000ULL)
-    return 13;
-  if (N < 100000000000000ULL)
-    return 14;
-  if (N < 1000000000000000ULL)
-    return 15;
-  if (N < 10000000000000000ULL)
-    return 16;
-  if (N < 100000000000000000ULL)
-    return 17;
-  if (N < 1000000000000000000ULL)
-    return 18;
-  if (N < 10000000000000000000ULL)
-    return 19;
-  return 20;
-}
-
 namespace detail {
 template <typename T>
 struct EndianAdapter final
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h b/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h
index 0e7b9663f27d2..d4b0c6cc75292 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h
@@ -183,7 +183,7 @@ Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
   if (Filters.DumpModi) {
     uint32_t Modi = *Filters.DumpModi;
     SymbolGroup SG(&Input, Modi);
-    return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
+    return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigitsBase10(Modi)),
                             SG, Modi, Callback);
   }
 
@@ -192,7 +192,7 @@ Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
   for (const auto &SG : Input.symbol_groups()) {
     if (shouldDumpSymbolGroup(I, SG, Filters))
       if (auto Err =
-              iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)),
+              iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigitsBase10(I)),
                                SG, I, Callback))
         return Err;
 
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index ae3150e5602ee..21a1829b97d97 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -795,6 +795,41 @@ using stack_float_t = volatile float;
 using stack_float_t = float;
 #endif
 
+/// Returns the number of digits in the given integer.
+inline int NumDigitsBase10(uint64_t X) {
+  static constexpr struct ConstexprData {
+    uint8_t AtLeast[65] = {};
+    uint64_t Boundaries[20] = {};
+    static constexpr int NumDigitsConstexpr(uint64_t N) {
+      int res = 1;
+      while (N >= 10) {
+        res++;
+        N /= 10;
+      }
+      return res;
+    }
+    constexpr ConstexprData() {
+      uint64_t Val = ~0ull;
+      for (uint64_t i = 0; i <= 64; i++) {
+        uint64_t Digits = NumDigitsConstexpr(Val) - 1;
+        AtLeast[i] = Digits;
+        Val >>= 1;
+      }
+      // Special case because X=0 should return 1 and not 0
+      Boundaries[0] = 0;
+      Val = 10;
+      for (uint64_t i = 1; i < 20; i++) {
+        Boundaries[i] = Val;
+        Val *= 10;
+      }
+    }
+  } Data;
+
+  uint64_t Base2 = X ? countl_zero(X) : 64;
+  uint64_t Digits = Data.AtLeast[Base2];
+  return Digits + (X >= Data.Boundaries[Digits]);
+}
+
 } // namespace llvm
 
 #endif
diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
index 989fde9749b18..957c0c4c8f9a9 100644
--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -84,7 +84,7 @@ class SourceCode {
   void format(raw_ostream &OS) {
     if (!PrunedSource)
       return;
-    size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
+    size_t MaxLineNumberWidth = NumDigitsBase10(LastLine);
     int64_t L = FirstLine;
     for (size_t Pos = 0; Pos < PrunedSource->size(); ++L) {
       size_t PosEnd = PrunedSource->find('\n', Pos);
diff --git a/llvm/lib/Support/Signals.cpp b/llvm/lib/Support/Signals.cpp
index 9f9030e79d104..634a66aba6d88 100644
--- a/llvm/lib/Support/Signals.cpp
+++ b/llvm/lib/Support/Signals.cpp
@@ -221,7 +221,7 @@ static bool printSymbolizedStackTrace(StringRef Argv0, void **StackTrace,
   for (int i = 0; i < Depth; i++) {
     auto PrintLineHeader = [&]() {
       OS << right_justify(formatv("#{0}", frame_no++).str(),
-                          std::log10(Depth) + 2)
+                          NumDigitsBase10(Depth) + 1)
          << ' ' << format_ptr(StackTrace[i]) << ' ';
     };
     if (!Modules[i]) {
diff --git a/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp b/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp
index 4c851e14a12dd..3adc6593ac884 100644
--- a/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp
@@ -370,7 +370,7 @@ static void iterateModules(PDBFile &File, LinePrinter &P, uint32_t IndentLevel,
                      Callback);
   } else {
     uint32_t Count = Modules.getModuleCount();
-    uint32_t Digits = NumDigits(Count);
+    uint32_t Digits = NumDigitsBase10(Count);
     for (uint32_t I = 0; I < Count; ++I) {
       iterateOneModule(File, P, Modules, I, Digits, IndentLevel, Callback);
     }
diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
index b2362ecb75703..89d444c35590b 100644
--- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
@@ -363,16 +363,16 @@ Error DumpOutputStyle::dumpStreamSummary() {
   for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
     P.formatLine(
         "Stream {0} ({1} bytes): [{2}]",
-        fmt_align(StreamIdx, AlignStyle::Right, NumDigits(StreamCount)),
+        fmt_align(StreamIdx, AlignStyle::Right, NumDigitsBase10(StreamCount)),
         fmt_align(getPdb().getStreamByteSize(StreamIdx), AlignStyle::Right,
-                  NumDigits(MaxStreamSize)),
+                  NumDigitsBase10(MaxStreamSize)),
         StreamPurposes[StreamIdx].getLongName());
 
     if (opts::dump::DumpStreamBlocks) {
       auto Blocks = getPdb().getStreamBlockList(StreamIdx);
       std::vector<uint32_t> BV(Blocks.begin(), Blocks.end());
       P.formatLine("       {0}  Blocks: [{1}]",
-                   fmt_repeat(' ', NumDigits(StreamCount)),
+                   fmt_repeat(' ', NumDigitsBase10(StreamCount)),
                    make_range(BV.begin(), BV.end()));
     }
   }
@@ -572,7 +572,7 @@ Error DumpOutputStyle::dumpSymbolStats() {
             if (StreamIdx == kInvalidStreamIndex) {
               P.formatLine(
                   "Mod {0} (debug info not present): [{1}]",
-                  fmt_align(Modi, AlignStyle::Right, NumDigits(ModCount)),
+                  fmt_align(Modi, AlignStyle::Right, NumDigitsBase10(ModCount)),
                   Desc.getModuleName());
               return Error::success();
             }
@@ -749,11 +749,11 @@ Error DumpOutputStyle::dumpUdtStats() {
   // separators.
   StringRef CountHeader("Count");
   StringRef SizeHeader("Size");
-  size_t CD = NumDigits(UdtStats.Totals.Count);
+  size_t CD = NumDigitsBase10(UdtStats.Totals.Count);
   CD += (CD - 1) / 3;
   CD = std::max(CD, CountHeader.size());
 
-  size_t SD = NumDigits(UdtStats.Totals.Size);
+  size_t SD = NumDigitsBase10(UdtStats.Totals.Size);
   SD += (SD - 1) / 3;
   SD = std::max(SD, SizeHeader.size());
 
@@ -1071,7 +1071,7 @@ Error DumpOutputStyle::dumpStringTableFromPdb() {
       P.formatLine("Empty");
     else {
       auto MaxID = llvm::max_element(IS->name_ids());
-      uint32_t Digits = NumDigits(*MaxID);
+      uint32_t Digits = NumDigitsBase10(*MaxID);
 
       P.formatLine("{0} | {1}", fmt_align("ID", AlignStyle::Right, Digits),
                    "String");
@@ -1205,7 +1205,7 @@ dumpFullTypeStream(LinePrinter &Printer, LazyRandomTypeCollection &Types,
                    TpiStream *Stream, bool Bytes, bool Extras) {
 
   Printer.formatLine("Showing {0:N} records", NumTypeRecords);
-  uint32_t Width = NumDigits(TypeIndex::FirstNonSimpleIndex + NumTypeRecords);
+  uint32_t Width = NumDigitsBase10(TypeIndex::FirstNonSimpleIndex + NumTypeRecords);
 
   MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types, RefTracker,
                            NumHashBuckets, HashValues, Stream);
@@ -1222,7 +1222,7 @@ static void dumpPartialTypeStream(LinePrinter &Printer,
                                   TpiStream &Stream, ArrayRef<TypeIndex> TiList,
                                   bool Bytes, bool Extras, bool Deps) {
   uint32_t Width =
-      NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
+      NumDigitsBase10(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
 
   MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types, RefTracker,
                            Stream.getNumHashBuckets(), Stream.getHashValues(),
diff --git a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
index db3a752d58165..5f0f95b3775e6 100644
--- a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
@@ -309,7 +309,7 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
     return Error::success();
 
   auto Max = llvm::max_element(Indices);
-  uint32_t W = NumDigits(Max->getIndex()) + 2;
+  uint32_t W = NumDigitsBase10(Max->getIndex()) + 2;
 
   for (auto I : Indices)
     P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
@@ -324,7 +324,7 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
     return Error::success();
 
   auto Max = llvm::max_element(Indices);
-  uint32_t W = NumDigits(Max->getIndex()) + 2;
+  uint32_t W = NumDigitsBase10(Max->getIndex()) + 2;
 
   for (auto I : Indices)
     P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
@@ -494,7 +494,7 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
     return Error::success();
 
   auto Max = llvm::max_element(Indices);
-  uint32_t W = NumDigits(Max->getIndex()) + 2;
+  uint32_t W = NumDigitsBase10(Max->getIndex()) + 2;
 
   for (auto I : Indices)
     P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
diff --git a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
index 7c8ac474c0fdb..62310440ef4fb 100644
--- a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
+++ b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
@@ -111,7 +111,7 @@ static Error tryInstructionMix() {
         Mix.begin(), Mix.end(), 1, [](unsigned MaxValue, const MixEntry &Elt) {
           return std::max(MaxValue, Elt.second);
         });
-    unsigned ValueWidth = std::log10(MaxValue) + 1;
+    unsigned ValueWidth = NumDigitsBase10(MaxValue);
     FOS << "Instruction";
     FOS.PadToColumn(MaxMnemonic + 1) << "Count\n";
     FOS << "-----------";
diff --git a/llvm/unittests/Support/MathExtrasTest.cpp b/llvm/unittests/Support/MathExtrasTest.cpp
index 984185fece4aa..afdeb664a21cb 100644
--- a/llvm/unittests/Support/MathExtrasTest.cpp
+++ b/llvm/unittests/Support/MathExtrasTest.cpp
@@ -692,4 +692,19 @@ TYPED_TEST(OverflowTest, MulResultZero) {
   EXPECT_FALSE(MulOverflow<TypeParam>(0, -5, Result));
   EXPECT_EQ(Result, TypeParam(0));
 }
+
+TEST(MathExtras, NumDigitsBase10) {
+  EXPECT_EQ(NumDigitsBase10(0), 1);
+  EXPECT_EQ(NumDigitsBase10(1), 1);
+
+  uint64_t Val = 10;
+  for (int i = 2; i <= 20; i++) {
+    EXPECT_EQ(NumDigitsBase10(Val - 1), i - 1);
+    EXPECT_EQ(NumDigitsBase10(Val), i);
+    Val *= 10;
+  }
+
+  EXPECT_EQ(NumDigitsBase10(std::numeric_limits<uint64_t>::max()), 20);
+}
+
 } // namespace
diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp
index 9cf3a3164dfec..39fb9d7f34023 100644
--- a/llvm/utils/FileCheck/FileCheck.cpp
+++ b/llvm/utils/FileCheck/FileCheck.cpp
@@ -595,7 +595,7 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
   unsigned LineCount = InputFileText.count('\n');
   if (InputFileEnd[-1] != '\n')
     ++LineCount;
-  unsigned LineNoWidth = std::log10(LineCount) + 1;
+  unsigned LineNoWidth = NumDigitsBase10(LineCount);
   // +3 below adds spaces (1) to the left of the (right-aligned) line numbers
   // on input lines and (2) to the right of the (left-aligned) labels on
   // annotation lines so that input lines and annotation lines are more

>From 12a91534b8c75a65ba0948a189a4e60c31dea514 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 19 Jun 2025 23:05:40 +0200
Subject: [PATCH 8/9] [NFC] Improve debug output of StackColoring

---
 llvm/lib/CodeGen/StackColoring.cpp | 50 ++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index 1bb1861a06f44..b2a2e3d8713dd 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -442,7 +442,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 +525,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 numDigits = NumDigitsBase10(I);
+        // Make sure number have spacing while staying aligned to the line above
+        next = I + 1 + numDigits / 2;
+        dbgs() << I << ' ';
+        if (numDigits % 2 == 0)
+          dbgs() << ' ';
+      } else
+        dbgs() << "  ";
+    }
+    dbgs() << '\n';
+  }
 }
 
 LLVM_DUMP_METHOD void StackColoring::dumpBB(MachineBasicBlock *MBB) const {
@@ -553,8 +579,14 @@ 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";
-    Intervals[I]->dump();
+    dbgs() << "Interval[" << I << "]:";
+    if (MFI->getObjectAllocation(I))
+      dbgs() << *MFI->getObjectAllocation(I);
+    dbgs() << '\n' << *Intervals[I] << '\n';
+    dbgs() << "LiveStarts:";
+    for (SlotIndex SIdx : LiveStarts[I])
+      dbgs() << ' ' << SIdx;
+    dbgs() << '\n';
   }
 }
 #endif

>From 7e75c0dc8077858f9d4e72385e242f2448393b89 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 29 May 2025 16:18:52 +0200
Subject: [PATCH 9/9] [NFC][LiveStacks] Use vectors instead of map and
 unordred_map

---
 llvm/include/llvm/CodeGen/LiveStacks.h        | 44 ++++++++-----------
 llvm/lib/CodeGen/LiveStacks.cpp               | 41 +++++++++--------
 llvm/lib/CodeGen/StackSlotColoring.cpp        | 20 +++------
 .../AMDGPU/AMDGPUMarkLastScratchLoad.cpp      |  6 +--
 4 files changed, 49 insertions(+), 62 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/LiveStacks.h b/llvm/include/llvm/CodeGen/LiveStacks.h
index 02c640bfc4a93..3b4550901dc7e 100644
--- a/llvm/include/llvm/CodeGen/LiveStacks.h
+++ b/llvm/include/llvm/CodeGen/LiveStacks.h
@@ -40,49 +40,43 @@ 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 getStartIdx() const { return StartIdx; }
+  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 aaff2d6238c1e..95597be5f1ebe 100644
--- a/llvm/lib/CodeGen/StackSlotColoring.cpp
+++ b/llvm/lib/CodeGen/StackSlotColoring.cpp
@@ -262,24 +262,14 @@ 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;
-    LLVM_DEBUG(li.dump());
-    int FI = li.reg().stackSlotIndex();
-    if (MFI->isDeadObjectIndex(FI))
+  for (auto [Idx, I] : llvm::enumerate(*LS)) {
+    int FI = Idx + LS->getStartIdx();
+    if (!I || MFI->isDeadObjectIndex(FI))
       continue;
+    LiveInterval &li = *I;
+    LLVM_DEBUG(li.dump());
 
     SSIntervals.push_back(&li);
     OrigAlignments[FI] = MFI->getObjectAlign(FI);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMarkLastScratchLoad.cpp b/llvm/lib/Target/AMDGPU/AMDGPUMarkLastScratchLoad.cpp
index 9b6bb56c85d24..2dcf695e9c583 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUMarkLastScratchLoad.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUMarkLastScratchLoad.cpp
@@ -102,15 +102,15 @@ bool AMDGPUMarkLastScratchLoad::run(MachineFunction &MF) {
 
   bool Changed = false;
 
-  for (auto &[SS, LI] : *LS) {
-    for (const LiveRange::Segment &Segment : LI.segments) {
+  for (auto *LI : *LS) {
+    for (const LiveRange::Segment &Segment : LI->segments) {
 
       // Ignore segments that run to the end of basic block because in this case
       // slot is still live at the end of it.
       if (Segment.end.isBlock())
         continue;
 
-      const int FrameIndex = LI.reg().stackSlotIndex();
+      const int FrameIndex = LI->reg().stackSlotIndex();
       MachineInstr *LastLoad = nullptr;
 
       MachineInstr *MISegmentEnd = SI->getInstructionFromIndex(Segment.end);



More information about the llvm-commits mailing list