mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 22:24:07 +00:00
Tighten up the erase/remove API for bundled instructions.
Most code is oblivious to bundles and uses the MBB::iterator which only visits whole bundles. MBB::erase() operates on whole bundles at a time as before. MBB::remove() now refuses to remove bundled instructions. It is not safe to remove all instructions in a bundle without deleting them since there is no way of returning pointers to all the removed instructions. MBB::remove_instr() and MBB::erase_instr() will now update bundle flags correctly, lifting individual instructions out of bundles while leaving the remaining bundle intact. The MachineInstr convenience functions are updated so eraseFromParent() erases a whole bundle as before eraseFromBundle() erases a single instruction, leaving the rest of its bundle. removeFromParent() refuses to operate on bundled instructions, and removeFromBundle() lifts a single instruction out of its bundle. These functions will no longer accidentally split or coalesce bundles - bundle flags are updated to preserve the existing bundling, and explicit bundleWith* / unbundleFrom* functions should be used to change the instruction bundling. This API update is still a work in progress. I am going to update APIs first so they maintain bundle flags automatically when possible. Then I'll add stricter verification of the bundle flags. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170384 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -788,27 +788,30 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
|
||||
return NMBB;
|
||||
}
|
||||
|
||||
MachineBasicBlock::iterator
|
||||
MachineBasicBlock::erase(MachineBasicBlock::iterator I) {
|
||||
if (I->isBundle()) {
|
||||
MachineBasicBlock::iterator E = llvm::next(I);
|
||||
return Insts.erase(I.getInstrIterator(), E.getInstrIterator());
|
||||
}
|
||||
|
||||
return Insts.erase(I.getInstrIterator());
|
||||
/// Prepare MI to be removed from its bundle. This fixes bundle flags on MI's
|
||||
/// neighboring instructions so the bundle won't be broken by removing MI.
|
||||
static void unbundleSingleMI(MachineInstr *MI) {
|
||||
// Removing the first instruction in a bundle.
|
||||
if (MI->isBundledWithSucc() && !MI->isBundledWithPred())
|
||||
MI->unbundleFromSucc();
|
||||
// Removing the last instruction in a bundle.
|
||||
if (MI->isBundledWithPred() && !MI->isBundledWithSucc())
|
||||
MI->unbundleFromPred();
|
||||
// If MI is not bundled, or if it is internal to a bundle, the neighbor flags
|
||||
// are already fine.
|
||||
}
|
||||
|
||||
MachineInstr *MachineBasicBlock::remove(MachineInstr *I) {
|
||||
if (I->isBundle()) {
|
||||
instr_iterator MII = llvm::next(I);
|
||||
iterator E = end();
|
||||
while (MII != E && MII->isInsideBundle()) {
|
||||
MachineInstr *MI = &*MII++;
|
||||
Insts.remove(MI);
|
||||
}
|
||||
}
|
||||
MachineBasicBlock::instr_iterator
|
||||
MachineBasicBlock::erase(MachineBasicBlock::instr_iterator I) {
|
||||
unbundleSingleMI(I);
|
||||
return Insts.erase(I);
|
||||
}
|
||||
|
||||
return Insts.remove(I);
|
||||
MachineInstr *MachineBasicBlock::remove_instr(MachineInstr *MI) {
|
||||
unbundleSingleMI(MI);
|
||||
MI->clearFlag(MachineInstr::BundledPred);
|
||||
MI->clearFlag(MachineInstr::BundledSucc);
|
||||
return Insts.remove(MI);
|
||||
}
|
||||
|
||||
void MachineBasicBlock::splice(MachineBasicBlock::iterator where,
|
||||
|
Reference in New Issue
Block a user