diff options
| author | Dan Gohman <gohman@apple.com> | 2010-08-14 00:29:42 +0000 | 
|---|---|---|
| committer | Dan Gohman <gohman@apple.com> | 2010-08-14 00:29:42 +0000 | 
| commit | 4a63fad976c8cf3bcdc1bbc3927668164890ecb8 (patch) | |
| tree | e6591471e46231800e73582000d2b83f65c0e505 /llvm/lib/Transforms/Utils | |
| parent | a030fa529701850bc299a486b05e8f1bd4911ada (diff) | |
| download | bcm5719-llvm-4a63fad976c8cf3bcdc1bbc3927668164890ecb8.tar.gz bcm5719-llvm-4a63fad976c8cf3bcdc1bbc3927668164890ecb8.zip  | |
Teach SimplifyCFG how to simplify indirectbr instructions.
 - Eliminate redundant successors.
 - Convert an indirectbr with one successor into a direct branch.
Also, generalize SimplifyCFG to be able to be run on a function entry block.
It knows quite a few simplifications which are applicable to the entry
block, and it only needs a few checks to avoid trouble with the entry block.
llvm-svn: 111060
Diffstat (limited to 'llvm/lib/Transforms/Utils')
| -rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 53 | 
2 files changed, 43 insertions, 13 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 8e9113871f4..52f0499f39b 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -490,6 +490,9 @@ static bool CanPropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {  /// rewriting all the predecessors to branch to the successor block and return  /// true.  If we can't transform, return false.  bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) { +  assert(BB != &BB->getParent()->getEntryBlock() && +         "TryToSimplifyUncondBranchFromEmptyBlock called on entry block!"); +    // We can't eliminate infinite loops.    BasicBlock *Succ = cast<BranchInst>(BB->getTerminator())->getSuccessor(0);    if (BB == Succ) return false; diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 36a245ff8c9..db719a0ce4d 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1724,12 +1724,12 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {    assert(BB && BB->getParent() && "Block not embedded in function!");    assert(BB->getTerminator() && "Degenerate basic block encountered!"); -  assert(&BB->getParent()->getEntryBlock() != BB && -         "Can't Simplify entry block!"); -  // Remove basic blocks that have no predecessors... or that just have themself -  // as a predecessor.  These are unreachable. -  if (pred_begin(BB) == pred_end(BB) || BB->getSinglePredecessor() == BB) { +  // Remove basic blocks that have no predecessors (except the entry block)... +  // or that just have themself as a predecessor.  These are unreachable. +  if ((pred_begin(BB) == pred_end(BB) && +       &BB->getParent()->getEntryBlock() != BB) || +      BB->getSinglePredecessor() == BB) {      DEBUG(dbgs() << "Removing BB: \n" << *BB);      DeleteDeadBlock(BB);      return true; @@ -1880,8 +1880,9 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {        while (isa<DbgInfoIntrinsic>(BBI))          ++BBI;        if (BBI->isTerminator()) // Terminator is the only non-phi instruction! -        if (TryToSimplifyUncondBranchFromEmptyBlock(BB)) -          return true; +        if (BB != &BB->getParent()->getEntryBlock()) +          if (TryToSimplifyUncondBranchFromEmptyBlock(BB)) +            return true;      } else {  // Conditional branch        if (isValueEqualityComparison(BI)) { @@ -2049,12 +2050,37 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {        }        // If this block is now dead, remove it. -      if (pred_begin(BB) == pred_end(BB)) { +      if (pred_begin(BB) == pred_end(BB) && +          BB != &BB->getParent()->getEntryBlock()) {          // We know there are no successors, so just nuke the block.          M->getBasicBlockList().erase(BB);          return true;        }      } +  } else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(BB->getTerminator())) { +    // Eliminate redundant destinations. +    SmallPtrSet<Value *, 8> Succs; +    for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) { +      BasicBlock *Dest = IBI->getDestination(i); +      if (!Succs.insert(Dest)) { +        Dest->removePredecessor(BB); +        IBI->removeDestination(i); +        --i; --e; +        Changed = true; +      } +    }  + +    if (IBI->getNumDestinations() == 0) { +      // If the indirectbr has no successors, change it to unreachable. +      new UnreachableInst(IBI->getContext(), IBI); +      IBI->eraseFromParent(); +      Changed = true; +    } else if (IBI->getNumDestinations() == 1) { +      // If the indirectbr has one successor, change it to a direct branch. +      BranchInst::Create(IBI->getDestination(0), IBI); +      IBI->eraseFromParent(); +      Changed = true; +    }    }    // Merge basic blocks into their predecessor if there is only one distinct @@ -2068,12 +2094,15 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {    // is a conditional branch, see if we can hoist any code from this block up    // into our predecessor.    pred_iterator PI(pred_begin(BB)), PE(pred_end(BB)); -  BasicBlock *OnlyPred = *PI++; -  for (; PI != PE; ++PI)  // Search all predecessors, see if they are all same -    if (*PI != OnlyPred) { +  BasicBlock *OnlyPred = 0; +  for (; PI != PE; ++PI) { // Search all predecessors, see if they are all same +    if (!OnlyPred) +      OnlyPred = *PI; +    else if (*PI != OnlyPred) {        OnlyPred = 0;       // There are multiple different predecessors...        break;      } +  }    if (OnlyPred)      if (BranchInst *BI = dyn_cast<BranchInst>(OnlyPred->getTerminator())) @@ -2172,8 +2201,6 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {  /// eliminates unreachable basic blocks, and does other "peephole" optimization  /// of the CFG.  It returns true if a modification was made.  /// -/// WARNING:  The entry node of a function may not be simplified. -///  bool llvm::SimplifyCFG(BasicBlock *BB, const TargetData *TD) {    return SimplifyCFGOpt(TD).run(BB);  }  | 

