diff --git a/llvm/include/llvm/CodeGen/SlotIndexes.h b/llvm/include/llvm/CodeGen/SlotIndexes.h index 2b32a4d30dff2..243fc2164f6f9 100644 --- a/llvm/include/llvm/CodeGen/SlotIndexes.h +++ b/llvm/include/llvm/CodeGen/SlotIndexes.h @@ -637,8 +637,9 @@ class raw_ostream; renumberIndexes(newItr); llvm::sort(idx2MBBMap, less_first()); } - }; + void packIndexes(); + }; // Specialize IntervalMapInfo for half-open slot index intervals. template <> struct IntervalMapInfo : IntervalMapHalfOpenInfo { diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index 91e5665d3f086..b29ae21edf52a 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -149,6 +149,11 @@ static cl::opt cl::desc("Simplify costs in greedy register allocation."), cl::init(false)); +static cl::opt + PackIndexes("pack-indexes", + cl::desc("Pack indexes during register allocation."), + cl::init(false)); + static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator", createGreedyRegisterAllocator); @@ -3237,6 +3242,10 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { getAnalysis(), getAnalysis()); Indexes = &getAnalysis(); + // Renumber to get accurate and consistent results from + // SlotIndexes::getApproxInstrDistance. + if (PackIndexes) + Indexes->packIndexes(); MBFI = &getAnalysis(); DomTree = &getAnalysis(); ORE = &getAnalysis().getORE(); diff --git a/llvm/lib/CodeGen/SlotIndexes.cpp b/llvm/lib/CodeGen/SlotIndexes.cpp index 9fff873324d0d..5079794c931c1 100644 --- a/llvm/lib/CodeGen/SlotIndexes.cpp +++ b/llvm/lib/CodeGen/SlotIndexes.cpp @@ -234,6 +234,33 @@ void SlotIndexes::repairIndexesInRange(MachineBasicBlock *MBB, } } +void SlotIndexes::packIndexes() { + unsigned Index = 0; + MachineBasicBlock *MBB; + // Iterate over basic blocks in slot index order. + for (auto &v : idx2MBBMap) { + // Update entries for each instruction in the block and the dummy entry for + // the end of the block. + MBB = v.second; + auto MBBStartIdx = MBBRanges[MBB->getNumber()].first; + auto MBBEndIdx = MBBRanges[MBB->getNumber()].second; + for (auto I = MBBStartIdx.listEntry()->getIterator(), + E = MBBEndIdx.listEntry()->getIterator(); + I++ != E;) { + if (I == E || I->getInstr()) { + Index += SlotIndex::InstrDist; + I->setIndex(Index); + } else { + // LiveIntervals may still refer to entries for instructions that have + // been erased. We have to update these entries but we don't want them + // to affect the rest of the slot numbering, so set them to half way + // between the neighboring real instrucion indexes. + I->setIndex(Index + SlotIndex::InstrDist / 2); + } + } + } +} + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void SlotIndexes::dump() const { for (IndexList::const_iterator itr = indexList.begin();