1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[SlotIndexes] Fix and simplify basic block splitting

Remove the InsertionPoint argument from SlotIndexes::insertMBBInMaps
because it was confusing: what does it mean to insert a new block
between two instructions, in the middle of an existing block?

Instead, support the case that MachineBasicBlock::splitAt really needs,
where the new block contains some instructions that are already in the
maps because they have been moved there from the tail of the previous
block.

In all other use cases the new block is empty.

Based on work by Carl Ritson!

Differential Revision: https://reviews.llvm.org/D94311
This commit is contained in:
Jay Foad 2021-01-08 13:40:29 +00:00
parent 09dcbafb1d
commit f1bab75f10
4 changed files with 60 additions and 31 deletions

View File

@ -256,9 +256,8 @@ class VirtRegMap;
return Indexes->getMBBFromIndex(index);
}
void insertMBBInMaps(MachineBasicBlock *MBB,
MachineInstr *InsertionPoint = nullptr) {
Indexes->insertMBBInMaps(MBB, InsertionPoint);
void insertMBBInMaps(MachineBasicBlock *MBB) {
Indexes->insertMBBInMaps(MBB);
assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
"Blocks must be added in order.");
RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));

View File

@ -604,38 +604,27 @@ class raw_ostream;
}
/// Add the given MachineBasicBlock into the maps.
/// If \p InsertionPoint is specified then the block will be placed
/// before the given machine instr, otherwise it will be placed
/// before the next block in MachineFunction insertion order.
void insertMBBInMaps(MachineBasicBlock *mbb,
MachineInstr *InsertionPoint = nullptr) {
MachineFunction::iterator nextMBB =
std::next(MachineFunction::iterator(mbb));
/// If it contains any instructions then they must already be in the maps.
/// This is used after a block has been split by moving some suffix of its
/// instructions into a newly created block.
void insertMBBInMaps(MachineBasicBlock *mbb) {
assert(mbb != &mbb->getParent()->front() &&
"Can't insert a new block at the beginning of a function.");
auto prevMBB = std::prev(MachineFunction::iterator(mbb));
IndexListEntry *startEntry = nullptr;
IndexListEntry *endEntry = nullptr;
IndexList::iterator newItr;
if (InsertionPoint) {
startEntry = createEntry(nullptr, 0);
endEntry = getInstructionIndex(*InsertionPoint).listEntry();
newItr = indexList.insert(endEntry->getIterator(), startEntry);
} else if (nextMBB == mbb->getParent()->end()) {
startEntry = &indexList.back();
endEntry = createEntry(nullptr, 0);
newItr = indexList.insertAfter(startEntry->getIterator(), endEntry);
} else {
startEntry = createEntry(nullptr, 0);
endEntry = getMBBStartIdx(&*nextMBB).listEntry();
newItr = indexList.insert(endEntry->getIterator(), startEntry);
}
// Create a new entry to be used for the start of mbb and the end of
// prevMBB.
IndexListEntry *startEntry = createEntry(nullptr, 0);
IndexListEntry *endEntry = getMBBEndIdx(&*prevMBB).listEntry();
IndexListEntry *insEntry =
mbb->empty() ? endEntry
: getInstructionIndex(mbb->front()).listEntry();
IndexList::iterator newItr =
indexList.insert(insEntry->getIterator(), startEntry);
SlotIndex startIdx(startEntry, SlotIndex::Slot_Block);
SlotIndex endIdx(endEntry, SlotIndex::Slot_Block);
MachineFunction::iterator prevMBB(mbb);
assert(prevMBB != mbb->getParent()->end() &&
"Can't insert a new block at the beginning of a function.");
--prevMBB;
MBBRanges[prevMBB->getNumber()].second = startIdx;
assert(unsigned(mbb->getNumber()) == MBBRanges.size() &&

View File

@ -980,7 +980,7 @@ MachineBasicBlock *MachineBasicBlock::splitAt(MachineInstr &MI,
addLiveIns(*SplitBB, LiveRegs);
if (LIS)
LIS->insertMBBInMaps(SplitBB, &MI);
LIS->insertMBBInMaps(SplitBB);
return SplitBB;
}

View File

@ -149,6 +149,19 @@ static void testHandleMoveIntoNewBundle(MachineFunction &MF, LiveIntervals &LIS,
LIS.handleMoveIntoNewBundle(*BundleStart, true);
}
/**
* Split block numbered \p BlockNum at instruction \p SplitAt using
* MachineBasicBlock::splitAt updating liveness intervals.
*/
static void testSplitAt(MachineFunction &MF, LiveIntervals &LIS,
unsigned SplitAt, unsigned BlockNum) {
MachineInstr &SplitInstr = getMI(MF, SplitAt, BlockNum);
MachineBasicBlock &MBB = *SplitInstr.getParent();
// Split block and update live intervals
MBB.splitAt(SplitInstr, false, &LIS);
}
static void liveIntervalTest(StringRef MIRFunc, LiveIntervalTest T) {
LLVMContext Context;
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
@ -608,6 +621,34 @@ TEST(LiveIntervalTest, BundleSubRegDef) {
});
}
TEST(LiveIntervalTest, SplitAtOneInstruction) {
liveIntervalTest(R"MIR(
successors: %bb.1
%0 = IMPLICIT_DEF
S_BRANCH %bb.1
bb.1:
S_NOP 0
)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
testSplitAt(MF, LIS, 1, 0);
});
}
TEST(LiveIntervalTest, SplitAtMultiInstruction) {
liveIntervalTest(R"MIR(
successors: %bb.1
%0 = IMPLICIT_DEF
S_NOP 0
S_NOP 0
S_NOP 0
S_NOP 0
S_BRANCH %bb.1
bb.1:
S_NOP 0
)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
testSplitAt(MF, LIS, 0, 0);
});
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
initLLVM();