summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/ADCE.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-12-12 23:40:17 +0000
committerChris Lattner <sabre@nondot.org>2004-12-12 23:40:17 +0000
commit387bc135758ed35b6a69bb2b060a066bdfcd3457 (patch)
treec944eecdfb441c3a305a39aa4b5845dff77cd94b /lib/Transforms/Scalar/ADCE.cpp
parent46356794ab144371e1fea50362b371f88790c12f (diff)
downloadllvm-387bc135758ed35b6a69bb2b060a066bdfcd3457.tar.gz
llvm-387bc135758ed35b6a69bb2b060a066bdfcd3457.tar.bz2
llvm-387bc135758ed35b6a69bb2b060a066bdfcd3457.tar.xz
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
Diffstat (limited to 'lib/Transforms/Scalar/ADCE.cpp')
-rw-r--r--lib/Transforms/Scalar/ADCE.cpp140
1 files changed, 43 insertions, 97 deletions
diff --git a/lib/Transforms/Scalar/ADCE.cpp b/lib/Transforms/Scalar/ADCE.cpp
index 43471341f4..2e0a3b64d2 100644
--- a/lib/Transforms/Scalar/ADCE.cpp
+++ b/lib/Transforms/Scalar/ADCE.cpp
@@ -14,9 +14,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Constant.h"
+#include "llvm/Constants.h"
#include "llvm/Instructions.h"
-#include "llvm/Type.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Support/CFG.h"
@@ -83,10 +82,10 @@ private:
void markBlockAlive(BasicBlock *BB);
- // dropReferencesOfDeadInstructionsInLiveBlock - Loop over all of the
- // instructions in the specified basic block, dropping references on
- // instructions that are dead according to LiveSet.
- bool dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB);
+ // deleteDeadInstructionsInLiveBlock - Loop over all of the instructions in
+ // the specified basic block, deleting ones that are dead according to
+ // LiveSet.
+ bool deleteDeadInstructionsInLiveBlock(BasicBlock *BB);
TerminatorInst *convertToUnconditionalBranch(TerminatorInst *TI);
@@ -128,31 +127,25 @@ void ADCE::markBlockAlive(BasicBlock *BB) {
markTerminatorLive(BB);
}
-// dropReferencesOfDeadInstructionsInLiveBlock - Loop over all of the
-// instructions in the specified basic block, dropping references on
-// instructions that are dead according to LiveSet.
-bool ADCE::dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB) {
+// deleteDeadInstructionsInLiveBlock - Loop over all of the instructions in the
+// specified basic block, deleting ones that are dead according to LiveSet.
+bool ADCE::deleteDeadInstructionsInLiveBlock(BasicBlock *BB) {
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?
- I->dropAllReferences(); // Nope, drop references...
- if (PHINode *PN = dyn_cast<PHINode>(I)) {
- // 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()));
+ if (!I->use_empty())
+ I->replaceAllUsesWith(UndefValue::get(I->getType()));
- // Delete the instruction...
- ++I;
- BB->getInstList().erase(PN);
- Changed = true;
+ // Nope... remove the instruction from it's basic block...
+ if (isa<CallInst>(I))
+ ++NumCallRemoved;
+ else
++NumInstRemoved;
- } else {
- ++I;
- }
- } else {
- ++I;
+ BB->getInstList().erase(I);
+ Changed = true;
}
+ }
return Changed;
}
@@ -317,12 +310,9 @@ bool ADCE::doADCE() {
//
if (AliveBlocks.size() == Func->size()) { // No dead blocks?
for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I) {
- // Loop over all of the instructions in the function, telling dead
- // instructions to drop their references. This is so that the next sweep
- // over the program can safely delete dead instructions without other dead
- // instructions still referring to them.
- //
- dropReferencesOfDeadInstructionsInLiveBlock(I);
+ // Loop over all of the instructions in the function deleting instructions
+ // to drop their references.
+ deleteDeadInstructionsInLiveBlock(I);
// 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
@@ -438,84 +428,40 @@ bool ADCE::doADCE() {
}
}
- // Now loop over all of the instructions in the basic block, telling
- // dead instructions to drop their references. This is so that the next
- // sweep over the program can safely delete dead instructions without
- // other dead instructions still referring to them.
+ // Now loop over all of the instructions in the basic block, deleting
+ // dead instructions. This is so that the next sweep over the program
+ // can safely delete dead instructions without other dead instructions
+ // 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
// the dead basic blocks. We must do this after the previous step to avoid
// dropping references to PHIs which still have entries...
//
+ std::vector<BasicBlock*> DeadBlocks;
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();
+ MadeChanges = true;
+ DeadBlocks.push_back(BB);
+ }
+
+ NumBlockRemoved += DeadBlocks.size();
// 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
- // (because they have dropped all of their references... we also remove dead
- // instructions from alive blocks.
- //
- for (Function::iterator BI = Func->begin(); BI != Func->end(); )
- 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...
- }
+ // (because they have dropped all of their references).
+ for (std::vector<BasicBlock*>::iterator I = DeadBlocks.begin(),
+ E = DeadBlocks.end(); I != E; ++I)
+ Func->getBasicBlockList().erase(*I);
return MadeChanges;
}