1010// lifetime markers machine instructions (LIFETIME_START and LIFETIME_END),
1111// which represent the possible lifetime of stack slots. It attempts to
1212// merge disjoint stack slots and reduce the used stack space.
13- // NOTE: This pass is not StackSlotColoring, which optimizes spill slots.
14- //
15- // TODO: In the future we plan to improve stack coloring in the following ways:
16- // 1. Allow merging multiple small slots into a single larger slot at different
17- // offsets.
18- // 2. Merge this pass with StackSlotColoring and allow merging of allocas with
19- // spill slots.
13+ // NOTE: This pass is not StackSlotColoring, which optimizes only spill slots.
2014//
2115// ===----------------------------------------------------------------------===//
2216
2519#include " llvm/ADT/DenseMap.h"
2620#include " llvm/ADT/DepthFirstIterator.h"
2721#include " llvm/ADT/SmallPtrSet.h"
28- #include " llvm/ADT/SmallSet.h"
2922#include " llvm/ADT/SmallVector.h"
3023#include " llvm/ADT/Statistic.h"
3124#include " llvm/Analysis/ValueTracking.h"
@@ -100,9 +93,8 @@ static cl::opt<bool> UseNewStackColoring(
10093 " new-stack-coloring" , cl::init(false ), cl::Hidden,
10194 cl::desc(" Use a better logic to try to reduce stack usage" ));
10295
103- static constexpr unsigned MaxCandidatesToConsiderDefault = 5 ;
104- static cl::opt<unsigned > MaxCandidatesToConsider (
105- " stackcoloring-max-candidates" , cl::init(MaxCandidatesToConsiderDefault),
96+ static cl::opt<unsigned > MaxCandidatesOpt (
97+ " stackcoloring-max-candidates" , cl::init(0 ),
10698 cl::Hidden,
10799 cl::desc(
108100 " Max number of candidates that will be evaluated, 0 means no limit" ));
@@ -656,7 +648,7 @@ LLVM_DUMP_METHOD void StackColoring::SlotInfo::dump(const StackColoring* State)
656648 Slot = this - State->Slot2Info .data ();
657649 dbgs () << " fi#" << Slot;
658650 } else
659- dbgs () << " SlotInfo" ;
651+ dbgs () << " SlotInfo" ;
660652 dbgs () << " :" ;
661653 if (Offset != InvalidIdx)
662654 dbgs () << " offset=" << Offset;
@@ -665,10 +657,8 @@ LLVM_DUMP_METHOD void StackColoring::SlotInfo::dump(const StackColoring* State)
665657 dbgs () << " \" " << State->MFI ->getObjectAllocation (Slot)->getName () << " \" " ;
666658 if (State->MFI ->isSpillSlotObjectIndex (Slot))
667659 dbgs () << " spill" ;
668- }
660+ }
669661 dbgs () << " size=" << Size << " align=" << Align.value () << ' \n ' ;
670- if (IndexBasedLiveRange)
671- dbgs () << " Index: " << *IndexBasedLiveRange << " \n " ;
672662 dumpBV (" LIVENESS " , Liveness);
673663 BitVector Start;
674664 Start.resize (Liveness.size ());
@@ -973,6 +963,13 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
973963 unsigned SpillChangeCounter = 0 ;
974964
975965 if (LS && LS->getNumIntervals ()) {
966+ // Here we prepare Spill slots lifetime informations
967+ // Live ranges in the LiveStacks seem to be slightly outdated in many small
968+ // ways. this is not an issue for stack-slot-coloring, because its only
969+ // operating on LiveRange form LiveStack, but it is an issue here,
970+ // So we only rely on LiveStack, to give us live edges, and conservatively
971+ // re-construct in-block liveness changes
972+
976973 for (const MachineBasicBlock &MBB : *MF) {
977974 BlockLifetimeInfo &MBBLiveness = BlockLiveness[MBB.getNumber ()];
978975 MBBLiveness.LiveIn .resize (NumSlots);
@@ -1015,14 +1012,6 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
10151012 unsigned Slot = PSV->getFrameIndex ();
10161013 if (!LS->hasInterval (Slot))
10171014 continue ;
1018- // if (Slot == 17) {
1019- // dbgs() << "MI: " << MI;
1020- // dbgs() << "MBB: " << MBB.getName() << "\n";
1021- // dbgs() << "MBB range:" << Indexes->getMBBRange(&MBB).first << "-"
1022- // << Indexes->getMBBRange(&MBB).second << "\n";
1023- // dbgs() << "slot range: " << LS->getInterval(Slot) << "\n";
1024- // dbgs() << "\n";
1025- // }
10261015 assert (MMO->isStore () != MMO->isLoad ());
10271016 if (MMO->isStore ()) {
10281017 if (!IsStoredTo[Slot]) {
@@ -1048,6 +1037,8 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
10481037 /* IsStart=*/ false , Slot});
10491038 }
10501039
1040+ // Ensure that the changes are in the same order they will be found and
1041+ // need to be processed in
10511042 std::stable_sort (MidBlockSpillChanges.begin () + SizeOnStart,
10521043 MidBlockSpillChanges.end (),
10531044 [&](SplitSlotChanges Lhs, SplitSlotChanges Rhs) -> bool {
@@ -1081,6 +1072,8 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
10811072
10821073 bool StartedSinceInc = false ;
10831074 auto EndRangeFor = [&](int Slot) {
1075+ // The less index the better, so we only increase if the ranges would not
1076+ // be accurate without
10841077 if (StartIdx[Slot] == CurrIdx || StartedSinceInc) {
10851078 CurrIdx++;
10861079 StartedSinceInc = false ;
@@ -1101,9 +1094,6 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
11011094 continue ;
11021095 SlotIndex ThisIndex = Indexes->getInstructionIndex (MI);
11031096 auto OnChange = [&](unsigned Slot, bool IsStart) {
1104- // if (Slot == 3) {
1105- // outs() << "HERE\n";
1106- // }
11071097 if (IsStart) {
11081098 StartedSinceInc = true ;
11091099 // If a slot is already definitely in use, we don't have to emit
@@ -1209,7 +1199,6 @@ void StackColoring::remapInstructions(DenseMap<int, int>& SlotRemap, int MergedS
12091199 continue ;
12101200 int Slot = VI.getStackSlot ();
12111201 if (Slot >= 0 && Slot2Info[Slot].Offset != InvalidIdx) {
1212- // FIXME: properly update the offset into MergedSlot debug
12131202 VI.updateStackSlot (MergedSlot);
12141203 }
12151204 if (auto It = SlotRemap.find (Slot); It != SlotRemap.end ()) {
@@ -1585,7 +1574,7 @@ unsigned StackColoring::doMerging(unsigned NumSlots) {
15851574 SlotInfo* LastQueryLhs = nullptr ;
15861575 SlotInfo* LastQueryRhs = nullptr ;
15871576 bool LastQueryRes = false ;
1588- // TODO: Real caching ?
1577+ // Maybe there should be real caching here
15891578 auto HasOverlapCached = [&](SlotInfo &Lhs, SlotInfo &Rhs) {
15901579 if (&Lhs == LastQueryLhs && LastQueryRhs == &Rhs)
15911580 return LastQueryRes;
@@ -1616,8 +1605,10 @@ unsigned StackColoring::doMerging(unsigned NumSlots) {
16161605
16171606 // The slots in the linked-list are always kept in ascending order, so the
16181607 // earliest slot has the lowest offset
1619- // This loop handles cases where the latest slot doesn't cannot be both live
1620- // because of the CFG, so even if there lifetime overlap, they can overlap
1608+ // This loop handles cases where this slot and the latest slot doesn't
1609+ // cannot be both live because of the CFG, so even if there lifetime
1610+ // overlap, they can overlap
1611+ // See comment about implementation higher in the file
16211612 while (LLVM_UNLIKELY (Last->Slot != InvalidIdx &&
16221613 !HasOverlapCached (Info, Slot2Info[Last->Slot ])))
16231614 Last = &OlderStatus[Last->Prev ];
@@ -1638,7 +1629,7 @@ unsigned StackColoring::doMerging(unsigned NumSlots) {
16381629 return ;
16391630 }
16401631
1641- // Insure ordering of slots
1632+ // Ensure ordering of slots
16421633 Status* Inserted = &OlderStatus.back ();
16431634 Inserted->Offset = Offset;
16441635 Inserted->Slot = &Info - Slot2Info.data ();
@@ -1651,9 +1642,10 @@ unsigned StackColoring::doMerging(unsigned NumSlots) {
16511642 Curr->Prev = Idx;
16521643 };
16531644
1654- SmallVector<unsigned , MaxCandidatesToConsiderDefault> Candidates;
1655- unsigned MaxCandidates =
1656- MaxCandidatesToConsider == 0 ? ~0u : MaxCandidatesToConsider;
1645+ // This is a vector but element ordering is not relevant
1646+ SmallVector<unsigned > Candidates;
1647+
1648+ unsigned MaxCandidates = MaxCandidatesOpt == 0 ? ~0u : MaxCandidatesOpt;
16571649 for (unsigned I = 0 ; I < MaxCandidates; I++) {
16581650 if (SlotStack.empty ())
16591651 break ;
@@ -1666,7 +1658,7 @@ unsigned StackColoring::doMerging(unsigned NumSlots) {
16661658 unsigned BestIdx = InvalidIdx;
16671659 unsigned BestOffset = InvalidIdx;
16681660
1669- LLVM_DEBUG (dbgs () << " top= " << WorseCaseOffset << " choosing: " );
1661+ LLVM_DEBUG (dbgs () << " Worse is at " << WorseCaseOffset << " , choosing: " );
16701662 for (unsigned K = 0 ; K < Candidates.size (); K++) {
16711663 SlotInfo &Info = Slot2Info[Candidates[K]];
16721664 unsigned Offset = 0 ;
@@ -1705,7 +1697,8 @@ unsigned StackColoring::doMerging(unsigned NumSlots) {
17051697 if (Other.SlotPriority != Info.SlotPriority )
17061698 return Other.SlotPriority < Info.SlotPriority ;
17071699
1708- // Both are always stored in Slot2Info, so this is deterministic
1700+ // Both are always stored in Slot2Info, so this is equivalent to
1701+ // FrameIndex comparaison
17091702 return &Other < &Info;
17101703 }();
17111704
@@ -1783,10 +1776,10 @@ bool StackColoring::run(MachineFunction &Func) {
17831776 VNInfoAllocator.Reset ();
17841777 Slot2Info.clear ();
17851778
1786- unsigned NumSlots = MFI->getObjectIndexEnd ();
1779+ if (!UseNewStackColoring)
1780+ LS = nullptr ;
17871781
1788- // if (MF->getName() == "_ZL9transformPjS_Rm")
1789- // outs() << "HERE\n";
1782+ unsigned NumSlots = MFI->getObjectIndexEnd ();
17901783
17911784 // If there are no stack slots then there are no markers to remove.
17921785 if (NumSlots < 2 || DisableColoring)
@@ -1898,22 +1891,10 @@ bool StackColoring::run(MachineFunction &Func) {
18981891 auto &SecondS = LiveStarts[SecondSlot];
18991892 assert (!First->empty () && !Second->empty () && " Found an empty range" );
19001893
1901- bool OldNoOverlap = !First->isLiveAtIndexes (SecondS) &&
1902- !Second->isLiveAtIndexes (FirstS);
1903-
1904- SlotInfo &FSlot = Slot2Info[FirstSlot];
1905- SlotInfo &SSlot = Slot2Info[SecondSlot];
1906- bool NewNoOverlap = !FSlot.hasOverlap (SSlot);
1907-
1908- // if (NewNoOverlap != OldNoOverlap) {
1909- // LLVM_DEBUG(dbgs() << "OldNoOverlap=" << OldNoOverlap
1910- // << " NewNoOverlap=" << NewNoOverlap << "\n");
1911- // }
1912- // assert(OldNoOverlap == NewNoOverlap);
1913-
19141894 // Merge disjoint slots. This is a little bit tricky - see the
19151895 // Implementation Notes section for an explanation.
1916- if (OldNoOverlap) {
1896+ if (!First->isLiveAtIndexes (SecondS) &&
1897+ !Second->isLiveAtIndexes (FirstS)) {
19171898 Changed = true ;
19181899 First->MergeSegmentsInAsValue (*Second, First->getValNumInfo (0 ));
19191900
@@ -1922,8 +1903,6 @@ bool StackColoring::run(MachineFunction &Func) {
19221903 auto Mid = FirstS.begin () + OldSize;
19231904 std::inplace_merge (FirstS.begin (), Mid, FirstS.end ());
19241905
1925- // FSlot.Liveness |= SSlot.Liveness;
1926-
19271906 SlotRemap[SecondSlot] = FirstSlot;
19281907 SortedSlots[J] = -1 ;
19291908 LLVM_DEBUG (dbgs () << " Merging #" << FirstSlot << " and slots #"
0 commit comments