From c277eaa41eb2ed6ab70855e170c07a17059c2bf3 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 21 Mar 2003 21:43:19 +0000 Subject: [PATCH] Move BreakCriticalEdges pass to lib/Transforms/Utils git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5754 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/BreakCriticalEdges.cpp | 155 ------------------- 1 file changed, 155 deletions(-) delete mode 100644 lib/Transforms/Scalar/BreakCriticalEdges.cpp diff --git a/lib/Transforms/Scalar/BreakCriticalEdges.cpp b/lib/Transforms/Scalar/BreakCriticalEdges.cpp deleted file mode 100644 index c44f9d324ec..00000000000 --- a/lib/Transforms/Scalar/BreakCriticalEdges.cpp +++ /dev/null @@ -1,155 +0,0 @@ -//===- BreakCriticalEdges.cpp - Critical Edge Elimination Pass ------------===// -// -// BreakCriticalEdges pass - Break all of the critical edges in the CFG by -// inserting a dummy basic block. This pass may be "required" by passes that -// cannot deal with critical edges. For this usage, the structure type is -// forward declared. This pass obviously invalidates the CFG, but can update -// forward dominator (set, immediate dominators, and tree) information. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Transforms/Scalar.h" -#include "llvm/Analysis/Dominators.h" -#include "llvm/Function.h" -#include "llvm/iTerminators.h" -#include "llvm/iPHINode.h" -#include "llvm/Support/CFG.h" -#include "Support/Statistic.h" - -namespace { - Statistic<> NumBroken("break-crit-edges", "Number of blocks inserted"); - - struct BreakCriticalEdges : public FunctionPass { - virtual bool runOnFunction(Function &F); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreservedID(LoopPreheadersID); // No preheaders deleted. - } - }; - - RegisterOpt X("break-crit-edges", - "Break critical edges in CFG"); -} - -// Publically exposed interface to pass... -const PassInfo *BreakCriticalEdgesID = X.getPassInfo(); -Pass *createBreakCriticalEdgesPass() { return new BreakCriticalEdges(); } - - -// isCriticalEdge - Return true if the specified edge is a critical edge. -// Critical edges are edges from a block with multiple successors to a block -// with multiple predecessors. -// -bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum) { - assert(SuccNum < TI->getNumSuccessors() && "Illegal edge specification!"); - if (TI->getNumSuccessors() == 1) return false; - - const BasicBlock *Dest = TI->getSuccessor(SuccNum); - pred_const_iterator I = pred_begin(Dest), E = pred_end(Dest); - - // If there is more than one predecessor, this is a critical edge... - assert(I != E && "No preds, but we have an edge to the block?"); - ++I; // Skip one edge due to the incoming arc from TI. - return I != E; -} - -// SplitCriticalEdge - Insert a new node node to split the critical edge. This -// will update DominatorSet, ImmediateDominator and DominatorTree information if -// it is available, thus calling this pass will not invalidate either of them. -// -void SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P) { - assert(isCriticalEdge(TI, SuccNum) && - "Cannot break a critical edge, if it isn't a critical edge"); - BasicBlock *TIBB = TI->getParent(); - BasicBlock *DestBB = TI->getSuccessor(SuccNum); - - // Create a new basic block, linking it into the CFG. - BasicBlock *NewBB = new BasicBlock(TIBB->getName() + "." + - DestBB->getName() + "_crit_edge"); - // Create our unconditional branch... - BranchInst *BI = new BranchInst(DestBB); - NewBB->getInstList().push_back(BI); - - // Branch to the new block, breaking the edge... - TI->setSuccessor(SuccNum, NewBB); - - // Insert the block into the function... right after the block TI lives in. - Function &F = *TIBB->getParent(); - F.getBasicBlockList().insert(TIBB->getNext(), NewBB); - - // If there are any PHI nodes in DestBB, we need to update them so that they - // merge incoming values from NewBB instead of from TIBB. - // - for (BasicBlock::iterator I = DestBB->begin(); - PHINode *PN = dyn_cast(&*I); ++I) { - // We no longer enter through TIBB, now we come in through NewBB. - PN->replaceUsesOfWith(TIBB, NewBB); - } - - // If we don't have a pass object, we can't update anything... - if (P == 0) return; - - // Now update analysis information. These are the analyses that we are - // currently capable of updating... - // - - // Should we update DominatorSet information? - if (DominatorSet *DS = P->getAnalysisToUpdate()) { - // The blocks that dominate the new one are the blocks that dominate TIBB - // plus the new block itself. - DominatorSet::DomSetType DomSet = DS->getDominators(TIBB); - DomSet.insert(NewBB); // A block always dominates itself. - DS->addBasicBlock(NewBB, DomSet); - } - - // Should we update ImmdediateDominator information? - if (ImmediateDominators *ID = P->getAnalysisToUpdate()) { - // TIBB is the new immediate dominator for NewBB. NewBB doesn't dominate - // anything. - ID->addNewBlock(NewBB, TIBB); - } - - // Should we update DominatorTree information? - if (DominatorTree *DT = P->getAnalysisToUpdate()) { - DominatorTree::Node *TINode = DT->getNode(TIBB); - - // The new block is not the immediate dominator for any other nodes, but - // TINode is the immediate dominator for the new node. - // - if (TINode) // Don't break unreachable code! - DT->createNewNode(NewBB, TINode); - } - - // Should we update DominanceFrontier information? - if (DominanceFrontier *DF = P->getAnalysisToUpdate()) { - // Since the new block is dominated by its only predecessor TIBB, - // it cannot be in any block's dominance frontier. Its dominance - // frontier is {DestBB}. - DominanceFrontier::DomSetType NewDFSet; - NewDFSet.insert(DestBB); - DF->addBasicBlock(NewBB, NewDFSet); - } -} - -// runOnFunction - Loop over all of the edges in the CFG, breaking critical -// edges as they are found. -// -bool BreakCriticalEdges::runOnFunction(Function &F) { - bool Changed = false; - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { - TerminatorInst *TI = I->getTerminator(); - if (TI->getNumSuccessors() > 1) - for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) - if (isCriticalEdge(TI, i)) { - SplitCriticalEdge(TI, i, this); - ++NumBroken; - Changed = true; - } - } - - return Changed; -}