diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-07-13 17:19:57 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-07-13 17:19:57 +0000 | 
| commit | 66e41e3c6e8b8fbc48d5d3b4d2bd9ce0be4ecb75 (patch) | |
| tree | 9de1c5f67a98cd0e73c60838396486c984f63ac2 /lib/CodeGen/MachineBasicBlock.cpp | |
| parent | abdf259d487163e72081a8cf4991b1617206b41e (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/MachineBasicBlock.cpp')
| -rw-r--r-- | lib/CodeGen/MachineBasicBlock.cpp | 129 | 
1 files changed, 118 insertions, 11 deletions
| diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index eaaa1f85b5639..a27ee479433be 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -13,7 +13,10 @@  #include "llvm/CodeGen/MachineBasicBlock.h"  #include "llvm/BasicBlock.h" +#include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/MachineDominators.h"  #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineLoopInfo.h"  #include "llvm/MC/MCAsmInfo.h"  #include "llvm/MC/MCContext.h"  #include "llvm/Target/TargetRegisterInfo.h" @@ -136,6 +139,13 @@ void ilist_traits<MachineInstr>::deleteNode(MachineInstr* MI) {    Parent->getParent()->DeleteMachineInstr(MI);  } +MachineBasicBlock::iterator MachineBasicBlock::getFirstNonPHI() { +  iterator I = begin(); +  while (I != end() && I->isPHI()) +    ++I; +  return I; +} +  MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {    iterator I = end();    while (I != begin() && (--I)->getDesc().isTerminator()) @@ -245,6 +255,7 @@ void MachineBasicBlock::updateTerminator() {    MachineBasicBlock *TBB = 0, *FBB = 0;    SmallVector<MachineOperand, 4> Cond; +  DebugLoc dl;  // FIXME: this is nowhere    bool B = TII->AnalyzeBranch(*this, TBB, FBB, Cond);    (void) B;    assert(!B && "UpdateTerminators requires analyzable predecessors!"); @@ -259,7 +270,7 @@ void MachineBasicBlock::updateTerminator() {        // its layout successor, insert a branch.        TBB = *succ_begin();        if (!isLayoutSuccessor(TBB)) -        TII->InsertBranch(*this, TBB, 0, Cond); +        TII->InsertBranch(*this, TBB, 0, Cond, dl);      }    } else {      if (FBB) { @@ -270,10 +281,10 @@ void MachineBasicBlock::updateTerminator() {          if (TII->ReverseBranchCondition(Cond))            return;          TII->RemoveBranch(*this); -        TII->InsertBranch(*this, FBB, 0, Cond); +        TII->InsertBranch(*this, FBB, 0, Cond, dl);        } else if (isLayoutSuccessor(FBB)) {          TII->RemoveBranch(*this); -        TII->InsertBranch(*this, TBB, 0, Cond); +        TII->InsertBranch(*this, TBB, 0, Cond, dl);        }      } else {        // The block has a fallthrough conditional branch. @@ -284,14 +295,14 @@ void MachineBasicBlock::updateTerminator() {          if (TII->ReverseBranchCondition(Cond)) {            // We can't reverse the condition, add an unconditional branch.            Cond.clear(); -          TII->InsertBranch(*this, MBBA, 0, Cond); +          TII->InsertBranch(*this, MBBA, 0, Cond, dl);            return;          }          TII->RemoveBranch(*this); -        TII->InsertBranch(*this, MBBA, 0, Cond); +        TII->InsertBranch(*this, MBBA, 0, Cond, dl);        } else if (!isLayoutSuccessor(MBBA)) {          TII->RemoveBranch(*this); -        TII->InsertBranch(*this, TBB, MBBA, Cond); +        TII->InsertBranch(*this, TBB, MBBA, Cond, dl);        }      }    } @@ -331,12 +342,32 @@ void MachineBasicBlock::transferSuccessors(MachineBasicBlock *fromMBB) {    if (this == fromMBB)      return; -  for (MachineBasicBlock::succ_iterator I = fromMBB->succ_begin(),  -       E = fromMBB->succ_end(); I != E; ++I) -    addSuccessor(*I); +  while (!fromMBB->succ_empty()) { +    MachineBasicBlock *Succ = *fromMBB->succ_begin(); +    addSuccessor(Succ); +    fromMBB->removeSuccessor(Succ); +  } +} + +void +MachineBasicBlock::transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB) { +  if (this == fromMBB) +    return; -  while (!fromMBB->succ_empty()) -    fromMBB->removeSuccessor(fromMBB->succ_begin()); +  while (!fromMBB->succ_empty()) { +    MachineBasicBlock *Succ = *fromMBB->succ_begin(); +    addSuccessor(Succ); +    fromMBB->removeSuccessor(Succ); + +    // Fix up any PHI nodes in the successor. +    for (MachineBasicBlock::iterator MI = Succ->begin(), ME = Succ->end(); +         MI != ME && MI->isPHI(); ++MI) +      for (unsigned i = 2, e = MI->getNumOperands()+1; i != e; i += 2) { +        MachineOperand &MO = MI->getOperand(i); +        if (MO.getMBB() == fromMBB) +          MO.setMBB(this); +      } +  }  }  bool MachineBasicBlock::isSuccessor(const MachineBasicBlock *MBB) const { @@ -395,6 +426,82 @@ bool MachineBasicBlock::canFallThrough() {    return FBB == 0;  } +MachineBasicBlock * +MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) { +  MachineFunction *MF = getParent(); +  DebugLoc dl;  // FIXME: this is nowhere + +  // We may need to update this's terminator, but we can't do that if AnalyzeBranch +  // fails. If this uses a jump table, we won't touch it. +  const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); +  MachineBasicBlock *TBB = 0, *FBB = 0; +  SmallVector<MachineOperand, 4> Cond; +  if (TII->AnalyzeBranch(*this, TBB, FBB, Cond)) +    return NULL; + +  MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(); +  MF->insert(llvm::next(MachineFunction::iterator(this)), NMBB); +  DEBUG(dbgs() << "PHIElimination splitting critical edge:" +        " BB#" << getNumber() +        << " -- BB#" << NMBB->getNumber() +        << " -- BB#" << Succ->getNumber() << '\n'); + +  ReplaceUsesOfBlockWith(Succ, NMBB); +  updateTerminator(); + +  // Insert unconditional "jump Succ" instruction in NMBB if necessary. +  NMBB->addSuccessor(Succ); +  if (!NMBB->isLayoutSuccessor(Succ)) { +    Cond.clear(); +    MF->getTarget().getInstrInfo()->InsertBranch(*NMBB, Succ, NULL, Cond, dl); +  } + +  // Fix PHI nodes in Succ so they refer to NMBB instead of this +  for (MachineBasicBlock::iterator i = Succ->begin(), e = Succ->end(); +       i != e && i->isPHI(); ++i) +    for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2) +      if (i->getOperand(ni+1).getMBB() == this) +        i->getOperand(ni+1).setMBB(NMBB); + +  if (LiveVariables *LV = +        P->getAnalysisIfAvailable<LiveVariables>()) +    LV->addNewBlock(NMBB, this, Succ); + +  if (MachineDominatorTree *MDT = +        P->getAnalysisIfAvailable<MachineDominatorTree>()) +    MDT->addNewBlock(NMBB, this); + +  if (MachineLoopInfo *MLI = +        P->getAnalysisIfAvailable<MachineLoopInfo>()) +    if (MachineLoop *TIL = MLI->getLoopFor(this)) { +      // If one or the other blocks were not in a loop, the new block is not +      // either, and thus LI doesn't need to be updated. +      if (MachineLoop *DestLoop = MLI->getLoopFor(Succ)) { +        if (TIL == DestLoop) { +          // Both in the same loop, the NMBB joins loop. +          DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase()); +        } else if (TIL->contains(DestLoop)) { +          // Edge from an outer loop to an inner loop.  Add to the outer loop. +          TIL->addBasicBlockToLoop(NMBB, MLI->getBase()); +        } else if (DestLoop->contains(TIL)) { +          // Edge from an inner loop to an outer loop.  Add to the outer loop. +          DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase()); +        } else { +          // Edge from two loops with no containment relation.  Because these +          // are natural loops, we know that the destination block must be the +          // header of its loop (adding a branch into a loop elsewhere would +          // create an irreducible loop). +          assert(DestLoop->getHeader() == Succ && +                 "Should not create irreducible loops!"); +          if (MachineLoop *P = DestLoop->getParentLoop()) +            P->addBasicBlockToLoop(NMBB, MLI->getBase()); +        } +      } +    } + +  return NMBB; +} +  /// removeFromParent - This method unlinks 'this' from the containing function,  /// and returns it, but does not delete it.  MachineBasicBlock *MachineBasicBlock::removeFromParent() { | 
