diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachineBasicBlock.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineBasicBlock.cpp | 93 |
1 files changed, 40 insertions, 53 deletions
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp index 9abd24e..e848741 100644 --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -559,7 +559,11 @@ void MachineBasicBlock::moveAfter(MachineBasicBlock *NewBefore) { getParent()->splice(++NewBefore->getIterator(), getIterator()); } -void MachineBasicBlock::updateTerminator() { +void MachineBasicBlock::updateTerminator( + MachineBasicBlock *PreviousLayoutSuccessor) { + LLVM_DEBUG(dbgs() << "Updating terminators on " << printMBBReference(*this) + << "\n"); + const TargetInstrInfo *TII = getParent()->getSubtarget().getInstrInfo(); // A block with no successors has no concerns with fall-through edges. if (this->succ_empty()) @@ -578,25 +582,21 @@ void MachineBasicBlock::updateTerminator() { if (isLayoutSuccessor(TBB)) TII->removeBranch(*this); } else { - // The block has an unconditional fallthrough. If its successor is not its - // layout successor, insert a branch. First we have to locate the only - // non-landing-pad successor, as that is the fallthrough block. - for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) { - if ((*SI)->isEHPad()) - continue; - assert(!TBB && "Found more than one non-landing-pad successor!"); - TBB = *SI; - } - - // If there is no non-landing-pad successor, the block has no fall-through - // edges to be concerned with. - if (!TBB) + // The block has an unconditional fallthrough, or the end of the block is + // unreachable. + + // Unfortunately, whether the end of the block is unreachable is not + // immediately obvious; we must fall back to checking the successor list, + // and assuming that if the passed in block is in the succesor list and + // not an EHPad, it must be the intended target. + if (!PreviousLayoutSuccessor || !isSuccessor(PreviousLayoutSuccessor) || + PreviousLayoutSuccessor->isEHPad()) return; - // Finally update the unconditional successor to be reached via a branch - // if it would not be reached by fallthrough. - if (!isLayoutSuccessor(TBB)) - TII->insertBranch(*this, TBB, nullptr, Cond, DL); + // If the unconditional successor block is not the current layout + // successor, insert a branch to jump to it. + if (!isLayoutSuccessor(PreviousLayoutSuccessor)) + TII->insertBranch(*this, PreviousLayoutSuccessor, nullptr, Cond, DL); } return; } @@ -617,38 +617,20 @@ void MachineBasicBlock::updateTerminator() { return; } - // Walk through the successors and find the successor which is not a landing - // pad and is not the conditional branch destination (in TBB) as the - // fallthrough successor. - MachineBasicBlock *FallthroughBB = nullptr; - for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) { - if ((*SI)->isEHPad() || *SI == TBB) - continue; - assert(!FallthroughBB && "Found more than one fallthrough successor."); - FallthroughBB = *SI; - } - - if (!FallthroughBB) { - if (canFallThrough()) { - // We fallthrough to the same basic block as the conditional jump targets. - // Remove the conditional jump, leaving unconditional fallthrough. - // FIXME: This does not seem like a reasonable pattern to support, but it - // has been seen in the wild coming out of degenerate ARM test cases. - TII->removeBranch(*this); - - // Finally update the unconditional successor to be reached via a branch if - // it would not be reached by fallthrough. - if (!isLayoutSuccessor(TBB)) - TII->insertBranch(*this, TBB, nullptr, Cond, DL); - return; - } + // We now know we're going to fallthrough to PreviousLayoutSuccessor. + assert(PreviousLayoutSuccessor); + assert(!PreviousLayoutSuccessor->isEHPad()); + assert(isSuccessor(PreviousLayoutSuccessor)); - // We enter here iff exactly one successor is TBB which cannot fallthrough - // and the rest successors if any are EHPads. In this case, we need to - // change the conditional branch into unconditional branch. + if (PreviousLayoutSuccessor == TBB) { + // We had a fallthrough to the same basic block as the conditional jump + // targets. Remove the conditional jump, leaving an unconditional + // fallthrough or an unconditional jump. TII->removeBranch(*this); - Cond.clear(); - TII->insertBranch(*this, TBB, nullptr, Cond, DL); + if (!isLayoutSuccessor(TBB)) { + Cond.clear(); + TII->insertBranch(*this, TBB, nullptr, Cond, DL); + } return; } @@ -657,14 +639,14 @@ void MachineBasicBlock::updateTerminator() { if (TII->reverseBranchCondition(Cond)) { // We can't reverse the condition, add an unconditional branch. Cond.clear(); - TII->insertBranch(*this, FallthroughBB, nullptr, Cond, DL); + TII->insertBranch(*this, PreviousLayoutSuccessor, nullptr, Cond, DL); return; } TII->removeBranch(*this); - TII->insertBranch(*this, FallthroughBB, nullptr, Cond, DL); - } else if (!isLayoutSuccessor(FallthroughBB)) { + TII->insertBranch(*this, PreviousLayoutSuccessor, nullptr, Cond, DL); + } else if (!isLayoutSuccessor(PreviousLayoutSuccessor)) { TII->removeBranch(*this); - TII->insertBranch(*this, TBB, FallthroughBB, Cond, DL); + TII->insertBranch(*this, TBB, PreviousLayoutSuccessor, Cond, DL); } } @@ -908,6 +890,7 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge( return nullptr; MachineFunction *MF = getParent(); + MachineBasicBlock *PrevFallthrough = getNextNode(); DebugLoc DL; // FIXME: this is nowhere MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(); @@ -978,7 +961,11 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge( Terminators.push_back(&*I); } - updateTerminator(); + // Since we replaced all uses of Succ with NMBB, that should also be treated + // as the fallthrough successor + if (Succ == PrevFallthrough) + PrevFallthrough = NMBB; + updateTerminator(PrevFallthrough); if (Indexes) { SmallVector<MachineInstr*, 4> NewTerminators; |