[llvm-commits] [llvm] r53615 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp

Chris Lattner clattner at apple.com
Tue Jul 15 09:59:49 PDT 2008


On Jul 15, 2008, at 9:28 AM, Owen Anderson wrote:

> +// mergeBlockIntoPredecessor - If this block is the only successor
> +// of its predecessor, and the edge is non-critical,
> +// fold it into that predecessor.
> +bool GVN::mergeBlockIntoPredecessor(BasicBlock* BB) {

Hey Owen,

Can you move this to transform utils?

-Chris

>
> +  // Can't merge the entry block.
> +  if (pred_begin(BB) == pred_end(BB)) return false;
> +  // Can't merge if there are multiple preds.
> +  if (++pred_begin(BB) != pred_end(BB)) return false;
> +
> +  BasicBlock* PredBB = *pred_begin(BB);
> +
> +  // Can't merge if the edge is critical.
> +  if (PredBB->getTerminator()->getNumSuccessors() != 1) return false;
> +
> +  // Begin by getting rid of unneeded PHIs.
> +  while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
> +    PN->replaceAllUsesWith(PN->getIncomingValue(0));
> +    BB->getInstList().pop_front();  // Delete the phi node...
> +  }
> +
> +  // Delete the unconditional branch from the predecessor...
> +  PredBB->getInstList().pop_back();
> +
> +  // Move all definitions in the successor to the predecessor...
> +  PredBB->getInstList().splice(PredBB->end(), BB->getInstList());
> +
> +  // Make all PHI nodes that referred to BB now refer to Pred as  
> their
> +  // source...
> +  BB->replaceAllUsesWith(PredBB);
> +
> +  // Finally, erase the old block and update dominator info.
> +  DominatorTree& DT = getAnalysis<DominatorTree>();
> +  DomTreeNode* DTN = DT[BB];
> +  DomTreeNode* PredDTN = DT[PredBB];
> +
> +  if (DTN) {
> +    SmallPtrSet<DomTreeNode*, 8> Children(DTN->begin(), DTN->end());
> +    for (SmallPtrSet<DomTreeNode*, 8>::iterator DI =  
> Children.begin(),
> +         DE = Children.end(); DI != DE; ++DI)
> +      DT.changeImmediateDominator(*DI, PredDTN);
> +
> +    DT.eraseNode(BB);
> +  }
> +
> +  BB->eraseFromParent();
> +
> +  NumGVNBlocks++;
> +  return true;
> +}
> +
> +// iterateOnFunction - Executes one iteration of GVN
> bool GVN::iterateOnFunction(Function &F) {
>   // Clean out global sets from any previous functions
>   VN.clear();
>   phiMap.clear();
>
> +  // Merge unconditional branches, allowing PRE to catch more
> +  // optimization opportunities.
> +  bool mergedBlocks = false;
> +  for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ) {
> +    BasicBlock* BB = FI;
> +    ++FI;
> +    mergedBlocks |= mergeBlockIntoPredecessor(BB);
> +  }
> +
>   for (DenseMap<BasicBlock*, ValueNumberScope*>::iterator
>        I = localAvail.begin(), E = localAvail.end(); I != E; ++I)
>     delete I->second;
> @@ -1346,5 +1407,5 @@
>   if (EnablePRE)
>     changed |= performPRE(F);
>
> -  return changed;
> +  return changed || mergedBlocks;
> }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list