Add support for printing out statistics information when -stats is added to
[oota-llvm.git] / lib / Transforms / Scalar / DCE.cpp
1 //===- DCE.cpp - Code to perform dead code elimination --------------------===//
2 //
3 // This file implements dead inst elimination and dead code elimination.
4 //
5 // Dead Inst Elimination performs a single pass over the function removing
6 // instructions that are obviously dead.  Dead Code Elimination is similar, but
7 // it rechecks instructions that were used by removed instructions to see if
8 // they are newly dead.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #include "llvm/Transforms/Scalar.h"
13 #include "llvm/Transforms/Utils/Local.h"
14 #include "llvm/Instruction.h"
15 #include "llvm/Pass.h"
16 #include "llvm/Support/InstIterator.h"
17 #include "Support/StatisticReporter.h"
18 #include <set>
19
20 static Statistic<> DIEEliminated("die\t\t- Number of insts removed");
21 static Statistic<> DCEEliminated("dce\t\t- Number of insts removed");
22
23 //===----------------------------------------------------------------------===//
24 // DeadInstElimination pass implementation
25 //
26
27 namespace {
28   struct DeadInstElimination : public BasicBlockPass {
29     const char *getPassName() const { return "Dead Instruction Elimination"; }
30     
31     virtual bool runOnBasicBlock(BasicBlock *BB) {
32       BasicBlock::InstListType &Vals = BB->getInstList();
33       bool Changed = false;
34       for (BasicBlock::iterator DI = Vals.begin(); DI != Vals.end(); )
35         if (dceInstruction(Vals, DI)) {
36           Changed = true;
37           ++DIEEliminated;
38         } else
39           ++DI;
40       return Changed;
41     }
42
43     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
44       AU.preservesCFG();
45     }
46   };
47 }
48
49 Pass *createDeadInstEliminationPass() {
50   return new DeadInstElimination();
51 }
52
53
54
55 //===----------------------------------------------------------------------===//
56 // DeadCodeElimination pass implementation
57 //
58
59 namespace {
60   struct DCE : public FunctionPass {
61     const char *getPassName() const { return "Dead Code Elimination"; }
62
63     virtual bool runOnFunction(Function *F);
64
65      virtual void getAnalysisUsage(AnalysisUsage &AU) const {
66       AU.preservesCFG();
67     }
68  };
69 }
70
71 bool DCE::runOnFunction(Function *F) {
72   // Start out with all of the instructions in the worklist...
73   std::vector<Instruction*> WorkList(inst_begin(F), inst_end(F));
74   std::set<Instruction*> DeadInsts;
75   
76   // Loop over the worklist finding instructions that are dead.  If they are
77   // dead make them drop all of their uses, making other instructions
78   // potentially dead, and work until the worklist is empty.
79   //
80   while (!WorkList.empty()) {
81     Instruction *I = WorkList.back();
82     WorkList.pop_back();
83     
84     if (isInstructionTriviallyDead(I)) {       // If the instruction is dead...
85       // Loop over all of the values that the instruction uses, if there are
86       // instructions being used, add them to the worklist, because they might
87       // go dead after this one is removed.
88       //
89       for (User::use_iterator UI = I->use_begin(), UE = I->use_end();
90            UI != UE; ++UI)
91         if (Instruction *Used = dyn_cast<Instruction>(*UI))
92           WorkList.push_back(Used);
93
94       // Tell the instruction to let go of all of the values it uses...
95       I->dropAllReferences();
96
97       // Keep track of this instruction, because we are going to delete it later
98       DeadInsts.insert(I);
99     }
100   }
101
102   // If we found no dead instructions, we haven't changed the function...
103   if (DeadInsts.empty()) return false;
104
105   // Otherwise, loop over the program, removing and deleting the instructions...
106   for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
107     BasicBlock::InstListType &BBIL = (*I)->getInstList();
108     for (BasicBlock::iterator BI = BBIL.begin(); BI != BBIL.end(); )
109       if (DeadInsts.count(*BI)) {            // Is this instruction dead?
110         delete BBIL.remove(BI);              // Yup, remove and delete inst
111         ++DCEEliminated;
112       } else {                               // This instruction is not dead
113         ++BI;                                // Continue on to the next one...
114       }
115   }
116
117   return true;
118 }
119
120 Pass *createDeadCodeEliminationPass() {
121   return new DCE();
122 }