Don't perform an extra traversal of the function just to do cleanup. We can safely...
[oota-llvm.git] / lib / Transforms / Scalar / CorrelatedValuePropagation.cpp
1 //===- CorrelatedValuePropagation.cpp - Propagate CFG-derived info --------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Correlated Value Propagation pass.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "correlated-value-propagation"
15 #include "llvm/Transforms/Scalar.h"
16 #include "llvm/Function.h"
17 #include "llvm/Instructions.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Analysis/LazyValueInfo.h"
20 #include "llvm/Transforms/Utils/Local.h"
21 #include "llvm/ADT/Statistic.h"
22 using namespace llvm;
23
24 STATISTIC(NumPhis,    "Number of phis propagated");
25 STATISTIC(NumSelects, "Number of selects propagated");
26
27 namespace {
28   class CorrelatedValuePropagation : public FunctionPass {
29     LazyValueInfo *LVI;
30     
31     bool processSelect(SelectInst *SI);
32     bool processPHI(PHINode *P);
33     
34   public:
35     static char ID;
36     CorrelatedValuePropagation(): FunctionPass(ID) { }
37     
38     bool runOnFunction(Function &F);
39     
40     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
41       AU.addRequired<LazyValueInfo>();
42     }
43   };
44 }
45
46 char CorrelatedValuePropagation::ID = 0;
47 INITIALIZE_PASS(CorrelatedValuePropagation, "correlated-propagation",
48                 "Value Propagation", false, false);
49
50 // Public interface to the Value Propagation pass
51 Pass *llvm::createCorrelatedValuePropagationPass() {
52   return new CorrelatedValuePropagation();
53 }
54
55 bool CorrelatedValuePropagation::processSelect(SelectInst *S) {
56   if (S->getType()->isVectorTy()) return false;
57   
58   Constant *C = LVI->getConstant(S->getOperand(0), S->getParent());
59   if (!C) return false;
60   
61   ConstantInt *CI = dyn_cast<ConstantInt>(C);
62   if (!CI) return false;
63   
64   S->replaceAllUsesWith(S->getOperand(CI->isOne() ? 1 : 2));
65   S->eraseFromParent();
66
67   ++NumSelects;
68   
69   return true;
70 }
71
72 bool CorrelatedValuePropagation::processPHI(PHINode *P) {
73   bool Changed = false;
74   
75   BasicBlock *BB = P->getParent();
76   for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) {
77     Value *Incoming = P->getIncomingValue(i);
78     if (isa<Constant>(Incoming)) continue;
79     
80     Constant *C = LVI->getConstantOnEdge(P->getIncomingValue(i),
81                                          P->getIncomingBlock(i),
82                                          BB);
83     if (!C) continue;
84     
85     P->setIncomingValue(i, C);
86     Changed = true;
87   }
88   
89   if (Value *ConstVal = P->hasConstantValue()) {
90     P->replaceAllUsesWith(ConstVal);
91     P->eraseFromParent();
92     Changed = true;
93   }
94   
95   ++NumPhis;
96   
97   return Changed;
98 }
99
100 bool CorrelatedValuePropagation::runOnFunction(Function &F) {
101   LVI = &getAnalysis<LazyValueInfo>();
102   
103   bool Changed = false;
104   
105   for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
106     for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) {
107       Instruction *II = BI++;
108       if (SelectInst *SI = dyn_cast<SelectInst>(II))
109         Changed |= processSelect(SI);
110       else if (PHINode *P = dyn_cast<PHINode>(II))
111         Changed |= processPHI(P);
112     }
113     
114     SimplifyInstructionsInBlock(FI);
115   }
116   
117   return Changed;
118 }