Skip to content

Commit

Permalink
[layout] Pack slot indexes before register allocation
Browse files Browse the repository at this point in the history
Applies:
llvm#66334
llvm#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: systems-nuts/unifico#291
  • Loading branch information
blackgeorge-boom committed Sep 29, 2023
1 parent 1f5413f commit d7d0aaa
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
3 changes: 2 additions & 1 deletion llvm/include/llvm/CodeGen/SlotIndexes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<SlotIndex> : IntervalMapHalfOpenInfo<SlotIndex> {
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/CodeGen/RegAllocGreedy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ static cl::opt<bool>
cl::desc("Simplify costs in greedy register allocation."),
cl::init(false));

static cl::opt<bool>
PackIndexes("pack-indexes",
cl::desc("Pack indexes during register allocation."),
cl::init(false));

static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator",
createGreedyRegisterAllocator);

Expand Down Expand Up @@ -3237,6 +3242,10 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
getAnalysis<LiveIntervals>(),
getAnalysis<LiveRegMatrix>());
Indexes = &getAnalysis<SlotIndexes>();
// Renumber to get accurate and consistent results from
// SlotIndexes::getApproxInstrDistance.
if (PackIndexes)
Indexes->packIndexes();
MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
DomTree = &getAnalysis<MachineDominatorTree>();
ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
Expand Down
27 changes: 27 additions & 0 deletions llvm/lib/CodeGen/SlotIndexes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit d7d0aaa

Please sign in to comment.