forked from OSchip/llvm-project
Factor MergeBlockIntoPredecessor out into BasicBlockUtils.
llvm-svn: 53705
This commit is contained in:
parent
97adf60418
commit
c062381c7b
|
@ -25,6 +25,10 @@ namespace llvm {
|
|||
class Instruction;
|
||||
class Pass;
|
||||
|
||||
/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
|
||||
/// if possible. The return value indicates success or failure.
|
||||
bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P);
|
||||
|
||||
// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
|
||||
// with a value, then remove and delete the original instruction.
|
||||
//
|
||||
|
|
|
@ -1125,7 +1125,10 @@ bool GVN::runOnFunction(Function& F) {
|
|||
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ) {
|
||||
BasicBlock* BB = FI;
|
||||
++FI;
|
||||
changed |= mergeBlockIntoPredecessor(BB);
|
||||
bool removedBlock = MergeBlockIntoPredecessor(BB, this);
|
||||
if (removedBlock) NumGVNBlocks++;
|
||||
|
||||
changed |= removedBlock;
|
||||
}
|
||||
|
||||
while (shouldContinue) {
|
||||
|
@ -1336,56 +1339,6 @@ bool GVN::performPRE(Function& F) {
|
|||
return changed;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// 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
|
||||
|
|
|
@ -23,6 +23,58 @@
|
|||
#include <algorithm>
|
||||
using namespace llvm;
|
||||
|
||||
/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
|
||||
/// if possible. The return value indicates success or failure.
|
||||
bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
|
||||
// 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.
|
||||
if (P) {
|
||||
if (DominatorTree* DT = P->getAnalysisToUpdate<DominatorTree>()) {
|
||||
DomTreeNode* DTN = DT->getNode(BB);
|
||||
DomTreeNode* PredDTN = DT->getNode(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();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
|
||||
/// with a value, then remove and delete the original instruction.
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue