//===-- BranchFolding.cpp - Fold machine code branch instructions ---------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This pass forwards branches to unconditional branches to make them branch
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/STLExtras.h"
using namespace llvm;
namespace {
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual const char *getPassName() const { return "Branch Folder"; }
private:
- bool OptimizeBlock(MachineBasicBlock *MBB, const TargetInstrInfo &TII);
-
+ bool OptimizeBlock(MachineFunction::iterator MBB,
+ const TargetInstrInfo &TII);
bool isUncondBranch(const MachineInstr *MI, const TargetInstrInfo &TII) {
return TII.isBarrier(MI->getOpcode()) && TII.isBranch(MI->getOpcode());
// If BB falls through into Old, insert an unconditional branch to New.
MachineFunction::iterator BBSucc = BB; ++BBSucc;
- if (&*BBSucc == Old)
+ if (BBSucc != BB->getParent()->end() && &*BBSucc == Old)
TII.insertGoto(*BB, *New);
std::vector<MachineBasicBlock*> Succs(BB->succ_begin(), BB->succ_end());
}
-bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB,
+bool BranchFolder::OptimizeBlock(MachineFunction::iterator MBB,
const TargetInstrInfo &TII) {
// If this block is empty, make everyone use it's fall-through, not the block
// explicitly.
if (MBB->empty()) {
if (MBB->pred_empty()) return false;
- MachineFunction::iterator FallThrough = MBB; ++FallThrough;
+ MachineFunction::iterator FallThrough =next(MBB);
assert(FallThrough != MBB->getParent()->end() &&
"Fell off the end of the function!");
while (!MBB->pred_empty()) {
// If MBB does not end with a barrier, add a goto instruction to the end.
if (Pred->empty() || !TII.isBarrier(Pred->back().getOpcode()))
- TII.insertGoto(*Pred, *++MachineFunction::iterator(MBB));
+ TII.insertGoto(*Pred, *next(MBB));
// Update the CFG now.
Pred->removeSuccessor(Pred->succ_begin());
assert(Br->getNumOperands() == 1 && Br->getOperand(0).isMachineBasicBlock()
&& "Uncond branch should take one MBB argument!");
MachineBasicBlock *Dest = Br->getOperand(0).getMachineBasicBlock();
-
+
while (!MBB->pred_empty()) {
MachineBasicBlock *Pred = *(MBB->pred_end()-1);
ReplaceUsesOfBlockWith(Pred, MBB, Dest, TII);
if (isUncondBranch(--MBB->end(), TII)) {
MachineBasicBlock::iterator MI = --MBB->end();
MachineInstr *UncondBr = MI;
- MachineFunction::iterator FallThrough = MBB; ++FallThrough;
+ MachineFunction::iterator FallThrough = next(MBB);
- MachineBasicBlock *UncondDest = MI->getOperand(0).getMachineBasicBlock();
- if (UncondDest == &*FallThrough) {
+ MachineFunction::iterator UncondDest =
+ MI->getOperand(0).getMachineBasicBlock();
+ if (UncondDest == FallThrough) {
// Just delete the branch. This does not effect the CFG.
MBB->erase(UncondBr);
return true;
// We assume that conditional branches always have the branch dest as the
// last operand. This could be generalized in the future if needed.
unsigned LastOpnd = MI->getNumOperands()-1;
- if (MI->getOperand(LastOpnd).getMachineBasicBlock() == &*FallThrough) {
+ if (MachineFunction::iterator(
+ MI->getOperand(LastOpnd).getMachineBasicBlock()) == FallThrough) {
// Change the cond branch to go to the uncond dest, nuke the uncond,
// then reverse the condition.
MI->getOperand(LastOpnd).setMachineBasicBlock(UncondDest);