From d7d0aaa5c534acbc22d3944c13b2965a1d4d1fd2 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogeorgis Date: Fri, 29 Sep 2023 17:28:02 +0100 Subject: [PATCH] [layout] Pack slot indexes before register allocation Applies: https://github.com/llvm/llvm-project/pull/66334 https://github.com/llvm/llvm-project/pull/67038 Packing the slot indexes before register allocation is useful for us because it evens the gaps between slots after all the optimization passes that happen before `greedy` and may have removed a different number of instructions between AArch64 and X86. This leads to different slot gaps and, hence, slightly different regalloc in some cases. We backport the above patches for our LLVM, with the main difference being the absence of some convenient data structure iterators, which we had to convert to be compatible with our ADT infrastructure. We add the `-pack-indexes` flag to activate this. Addressses: https://github.com/systems-nuts/unifico/issues/291 --- llvm/include/llvm/CodeGen/SlotIndexes.h | 3 ++- llvm/lib/CodeGen/RegAllocGreedy.cpp | 9 +++++++++ llvm/lib/CodeGen/SlotIndexes.cpp | 27 +++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) 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();