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() - : nullptr) {} + explicit LiveRange(bool UseSegmentSet = false) + : segmentSet(UseSegmentSet ? std::make_unique() : nullptr) { + } /// Constructs a new LiveRange object by copying segments and valnos from /// another LiveRange. 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; - SS2IntervalMap S2IMap; - - /// S2RCMap - Stack slot indices to register class mapping. - std::map S2RCMap; + int StartIdx = -1; + SmallVector S2LI; + SmallVector S2RC; public: - using iterator = SS2IntervalMap::iterator; - using const_iterator = SS2IntervalMap::const_iterator; + using iterator = SmallVector::iterator; + using const_iterator = SmallVector::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::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/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 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..5db53f08959a7 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h @@ -183,7 +183,8 @@ 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); } @@ -191,9 +192,9 @@ 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)), - SG, I, Callback)) + if (auto Err = iterateOneModule( + Input, withLabelWidth(HeaderScope, NumDigitsBase10(I)), SG, I, + Callback)) return Err; ++I; diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h index 7bbf1b3aab761..161886cafb2e6 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/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(); + 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/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 @@ -221,6 +222,12 @@ void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{ if (SO.StackID != 0) OS << "id=" << static_cast(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; diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp index 0f93822d9792b..b2a2e3d8713dd 100644 --- a/llvm/lib/CodeGen/StackColoring.cpp +++ b/llvm/lib/CodeGen/StackColoring.cpp @@ -396,21 +396,18 @@ class StackColoring { /// Which slots are marked as LIVE_OUT, coming out of each basic block. BitVector LiveOut; - }; - /// Maps active slots (per bit) for each basic block. - using LivenessMap = DenseMap; - LivenessMap BlockLiveness; + bool isEmpty() { return Begin.empty(); } + }; - /// Maps serial numbers to basic blocks. - DenseMap BasicBlocks; + SmallVector BlockLiveness; /// Maps basic blocks to a serial number. SmallVector BasicBlockNumbering; /// 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, 16> Intervals; + SmallVector, 16> Intervals; /// Maps slots to the points where they can become in-use. SmallVector, 16> LiveStarts; @@ -441,14 +438,10 @@ class StackColoring { bool run(MachineFunction &Func); private: - /// Used in collectMarkers - using BlockBitVecMap = DenseMap; - /// Debug. 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. @@ -532,18 +525,43 @@ 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 { - 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); @@ -561,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 @@ -627,7 +651,7 @@ bool StackColoring::isLifetimeStartOrEnd(const MachineInstr &MI, unsigned StackColoring::collectMarkers(unsigned NumSlot) { unsigned MarkersFound = 0; - BlockBitVecMap SeenStartMap; + SmallVector SeenStartMap; InterestingSlots.clear(); InterestingSlots.resize(NumSlot); ConservativeSlots.clear(); @@ -637,6 +661,8 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) { SmallVector NumStartLifetimes(NumSlot, 0); SmallVector NumEndLifetimes(NumSlot, 0); + SeenStartMap.resize(MF->getNumBlockIDs()); + // Step 1: collect markers and populate the "InterestingSlots" // and "ConservativeSlots" sets. for (MachineBasicBlock *MBB : depth_first(MF)) { @@ -645,10 +671,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; } } @@ -694,7 +721,7 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) { } } } - BitVector &SeenStart = SeenStartMap[MBB]; + BitVector &SeenStart = SeenStartMap[MBB->getNumber()]; SeenStart |= BetweenStartEnd; } if (!MarkersFound) { @@ -721,17 +748,17 @@ 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 // 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. - BlockLifetimeInfo &BlockInfo = BlockLiveness[MBB]; + BlockLifetimeInfo &BlockInfo = BlockLiveness[MBB->getNumber()]; BlockInfo.Begin.resize(NumSlot); BlockInfo.End.resize(NumSlot); @@ -788,19 +815,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 @@ -844,7 +871,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); @@ -1039,7 +1066,7 @@ void StackColoring::remapInstructions(DenseMap &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."); } @@ -1159,7 +1186,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(); @@ -1211,7 +1238,6 @@ bool StackColoring::run(MachineFunction &Func) { MF = &Func; MFI = &MF->getFrameInfo(); BlockLiveness.clear(); - BasicBlocks.clear(); BasicBlockNumbering.clear(); Markers.clear(); Intervals.clear(); @@ -1252,7 +1278,7 @@ bool StackColoring::run(MachineFunction &Func) { } for (unsigned i=0; i < NumSlots; ++i) { - std::unique_ptr LI(new LiveInterval(i, 0)); + std::unique_ptr LI(new LiveRange()); LI->getNextValue(Indexes->getZeroIndex(), VNInfoAllocator); Intervals.push_back(std::move(LI)); SortedSlots.push_back(i); @@ -1322,8 +1348,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"); diff --git a/llvm/lib/CodeGen/StackSlotColoring.cpp b/llvm/lib/CodeGen/StackSlotColoring.cpp index 2f81bea4e86ba..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::value_type; - - SmallVector 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); @@ -369,7 +359,6 @@ bool StackSlotColoring::ColorSlots(MachineFunction &MF) { SmallVector SlotMapping(NumObjs, -1); SmallVector SlotWeights(NumObjs, 0.0); SmallVector, 16> RevMap(NumObjs); - BitVector UsedColors(NumObjs); LLVM_DEBUG(dbgs() << "Color spill slot intervals:\n"); bool Changed = false; @@ -380,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); } 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/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); 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..5ddc0db8a34c6 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 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,8 @@ 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); @@ -1221,8 +1222,8 @@ static void dumpPartialTypeStream(LinePrinter &Printer, TypeReferenceTracker *RefTracker, TpiStream &Stream, ArrayRef TiList, bool Bytes, bool Extras, bool Deps) { - uint32_t Width = - NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords()); + uint32_t Width = 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(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::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