diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-12-17 23:55:38 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-12-17 23:55:38 +0000 |
commit | 9f4692d2953b47e9037ccfe5709a6e75de3911d4 (patch) | |
tree | 10b9b7ebaddc5933c8ddaefdd9b2d5a7a6c0eb30 /lib/CodeGen/MachineBasicBlock.cpp | |
parent | 082b7e6d367df15abf604b91739bedafe6c84c17 (diff) | |
download | llvm-9f4692d2953b47e9037ccfe5709a6e75de3911d4.tar.gz llvm-9f4692d2953b47e9037ccfe5709a6e75de3911d4.tar.bz2 llvm-9f4692d2953b47e9037ccfe5709a6e75de3911d4.tar.xz |
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
Diffstat (limited to 'lib/CodeGen/MachineBasicBlock.cpp')
-rw-r--r-- | lib/CodeGen/MachineBasicBlock.cpp | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index 48008537e7..b4ff6b4fcf 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -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, |