More substantial simplifications and speedups. This makes ADCE about 20% faster

in some cases.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18842 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2004-12-12 23:40:17 +00:00
parent 46356794ab
commit 387bc13575

View File

@ -14,9 +14,8 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Constant.h" #include "llvm/Constants.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Type.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/PostDominators.h"
#include "llvm/Support/CFG.h" #include "llvm/Support/CFG.h"
@ -83,10 +82,10 @@ private:
void markBlockAlive(BasicBlock *BB); void markBlockAlive(BasicBlock *BB);
// dropReferencesOfDeadInstructionsInLiveBlock - Loop over all of the // deleteDeadInstructionsInLiveBlock - Loop over all of the instructions in
// instructions in the specified basic block, dropping references on // the specified basic block, deleting ones that are dead according to
// instructions that are dead according to LiveSet. // LiveSet.
bool dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB); bool deleteDeadInstructionsInLiveBlock(BasicBlock *BB);
TerminatorInst *convertToUnconditionalBranch(TerminatorInst *TI); TerminatorInst *convertToUnconditionalBranch(TerminatorInst *TI);
@ -128,31 +127,25 @@ void ADCE::markBlockAlive(BasicBlock *BB) {
markTerminatorLive(BB); markTerminatorLive(BB);
} }
// dropReferencesOfDeadInstructionsInLiveBlock - Loop over all of the // deleteDeadInstructionsInLiveBlock - Loop over all of the instructions in the
// instructions in the specified basic block, dropping references on // specified basic block, deleting ones that are dead according to LiveSet.
// instructions that are dead according to LiveSet. bool ADCE::deleteDeadInstructionsInLiveBlock(BasicBlock *BB) {
bool ADCE::dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB) {
bool Changed = false; bool Changed = false;
for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; ) for (BasicBlock::iterator II = BB->begin(), E = --BB->end(); II != E; ) {
Instruction *I = II++;
if (!LiveSet.count(I)) { // Is this instruction alive? if (!LiveSet.count(I)) { // Is this instruction alive?
I->dropAllReferences(); // Nope, drop references... if (!I->use_empty())
if (PHINode *PN = dyn_cast<PHINode>(I)) { I->replaceAllUsesWith(UndefValue::get(I->getType()));
// We don't want to leave PHI nodes in the program that have
// #arguments != #predecessors, so we remove them now.
//
PN->replaceAllUsesWith(Constant::getNullValue(PN->getType()));
// Delete the instruction... // Nope... remove the instruction from it's basic block...
++I; if (isa<CallInst>(I))
BB->getInstList().erase(PN); ++NumCallRemoved;
Changed = true; else
++NumInstRemoved; ++NumInstRemoved;
} else { BB->getInstList().erase(I);
++I; Changed = true;
}
} else {
++I;
} }
}
return Changed; return Changed;
} }
@ -317,12 +310,9 @@ bool ADCE::doADCE() {
// //
if (AliveBlocks.size() == Func->size()) { // No dead blocks? if (AliveBlocks.size() == Func->size()) { // No dead blocks?
for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I) { for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I) {
// Loop over all of the instructions in the function, telling dead // Loop over all of the instructions in the function deleting instructions
// instructions to drop their references. This is so that the next sweep // to drop their references.
// over the program can safely delete dead instructions without other dead deleteDeadInstructionsInLiveBlock(I);
// instructions still referring to them.
//
dropReferencesOfDeadInstructionsInLiveBlock(I);
// Check to make sure the terminator instruction is live. If it isn't, // Check to make sure the terminator instruction is live. If it isn't,
// this means that the condition that it branches on (we know it is not an // this means that the condition that it branches on (we know it is not an
@ -438,84 +428,40 @@ bool ADCE::doADCE() {
} }
} }
// Now loop over all of the instructions in the basic block, telling // Now loop over all of the instructions in the basic block, deleting
// dead instructions to drop their references. This is so that the next // dead instructions. This is so that the next sweep over the program
// sweep over the program can safely delete dead instructions without // can safely delete dead instructions without other dead instructions
// other dead instructions still referring to them. // still referring to them.
// //
dropReferencesOfDeadInstructionsInLiveBlock(BB); deleteDeadInstructionsInLiveBlock(BB);
} }
} }
// We make changes if there are any dead blocks in the function...
if (unsigned NumDeadBlocks = Func->size() - AliveBlocks.size()) {
MadeChanges = true;
NumBlockRemoved += NumDeadBlocks;
}
// Loop over all of the basic blocks in the function, removing control flow
// edges to live blocks (also eliminating any entries in PHI functions in
// referenced blocks).
//
for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB)
if (!AliveBlocks.count(BB)) {
// Remove all outgoing edges from this basic block and convert the
// terminator into a return instruction.
std::vector<BasicBlock*> Succs(succ_begin(BB), succ_end(BB));
if (!Succs.empty()) {
// Loop over all of the successors, removing this block from PHI node
// entries that might be in the block...
while (!Succs.empty()) {
Succs.back()->removePredecessor(BB);
Succs.pop_back();
}
// Delete the old terminator instruction...
const Type *TermTy = BB->getTerminator()->getType();
if (TermTy != Type::VoidTy)
BB->getTerminator()->replaceAllUsesWith(
Constant::getNullValue(TermTy));
BB->getInstList().pop_back();
const Type *RetTy = Func->getReturnType();
new ReturnInst(RetTy != Type::VoidTy ?
Constant::getNullValue(RetTy) : 0, BB);
}
}
// Loop over all of the basic blocks in the function, dropping references of // Loop over all of the basic blocks in the function, dropping references of
// the dead basic blocks. We must do this after the previous step to avoid // the dead basic blocks. We must do this after the previous step to avoid
// dropping references to PHIs which still have entries... // dropping references to PHIs which still have entries...
// //
std::vector<BasicBlock*> DeadBlocks;
for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB)
if (!AliveBlocks.count(BB)) if (!AliveBlocks.count(BB)) {
// Remove PHI node entries for this block in live successor blocks.
for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
if (!SI->empty() && isa<PHINode>(SI->front()) && AliveBlocks.count(*SI))
(*SI)->removePredecessor(BB);
BB->dropAllReferences(); BB->dropAllReferences();
MadeChanges = true;
DeadBlocks.push_back(BB);
}
NumBlockRemoved += DeadBlocks.size();
// Now loop through all of the blocks and delete the dead ones. We can safely // Now loop through all of the blocks and delete the dead ones. We can safely
// do this now because we know that there are no references to dead blocks // do this now because we know that there are no references to dead blocks
// (because they have dropped all of their references... we also remove dead // (because they have dropped all of their references).
// instructions from alive blocks. for (std::vector<BasicBlock*>::iterator I = DeadBlocks.begin(),
// E = DeadBlocks.end(); I != E; ++I)
for (Function::iterator BI = Func->begin(); BI != Func->end(); ) Func->getBasicBlockList().erase(*I);
if (!AliveBlocks.count(BI)) { // Delete dead blocks...
BI = Func->getBasicBlockList().erase(BI);
} else { // Scan alive blocks...
for (BasicBlock::iterator II = BI->begin(); II != --BI->end(); )
if (!LiveSet.count(II)) { // Is this instruction alive?
// Nope... remove the instruction from it's basic block...
if (isa<CallInst>(II))
++NumCallRemoved;
else
++NumInstRemoved;
II = BI->getInstList().erase(II);
MadeChanges = true;
} else {
++II;
}
++BI; // Increment iterator...
}
return MadeChanges; return MadeChanges;
} }