CorrelatedValuePropagation.cpp revision 243830
1212793Sdim//===- CorrelatedValuePropagation.cpp - Propagate CFG-derived info --------===//
2212793Sdim//
3212793Sdim//                     The LLVM Compiler Infrastructure
4212793Sdim//
5212793Sdim// This file is distributed under the University of Illinois Open Source
6212793Sdim// License. See LICENSE.TXT for details.
7212793Sdim//
8212793Sdim//===----------------------------------------------------------------------===//
9212793Sdim//
10212793Sdim// This file implements the Correlated Value Propagation pass.
11212793Sdim//
12212793Sdim//===----------------------------------------------------------------------===//
13212793Sdim
14212793Sdim#define DEBUG_TYPE "correlated-value-propagation"
15212793Sdim#include "llvm/Transforms/Scalar.h"
16221345Sdim#include "llvm/Constants.h"
17212793Sdim#include "llvm/Function.h"
18212793Sdim#include "llvm/Instructions.h"
19212793Sdim#include "llvm/Pass.h"
20218893Sdim#include "llvm/Analysis/InstructionSimplify.h"
21212793Sdim#include "llvm/Analysis/LazyValueInfo.h"
22212793Sdim#include "llvm/Support/CFG.h"
23212793Sdim#include "llvm/Transforms/Utils/Local.h"
24212793Sdim#include "llvm/ADT/Statistic.h"
25212793Sdimusing namespace llvm;
26212793Sdim
27212793SdimSTATISTIC(NumPhis,      "Number of phis propagated");
28212793SdimSTATISTIC(NumSelects,   "Number of selects propagated");
29212793SdimSTATISTIC(NumMemAccess, "Number of memory access targets propagated");
30212793SdimSTATISTIC(NumCmps,      "Number of comparisons propagated");
31234353SdimSTATISTIC(NumDeadCases, "Number of switch cases removed");
32212793Sdim
33212793Sdimnamespace {
34212793Sdim  class CorrelatedValuePropagation : public FunctionPass {
35212793Sdim    LazyValueInfo *LVI;
36218893Sdim
37212793Sdim    bool processSelect(SelectInst *SI);
38212793Sdim    bool processPHI(PHINode *P);
39212793Sdim    bool processMemAccess(Instruction *I);
40212793Sdim    bool processCmp(CmpInst *C);
41234353Sdim    bool processSwitch(SwitchInst *SI);
42218893Sdim
43212793Sdim  public:
44212793Sdim    static char ID;
45218893Sdim    CorrelatedValuePropagation(): FunctionPass(ID) {
46218893Sdim     initializeCorrelatedValuePropagationPass(*PassRegistry::getPassRegistry());
47218893Sdim    }
48218893Sdim
49212793Sdim    bool runOnFunction(Function &F);
50218893Sdim
51212793Sdim    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
52212793Sdim      AU.addRequired<LazyValueInfo>();
53212793Sdim    }
54212793Sdim  };
55212793Sdim}
56212793Sdim
57212793Sdimchar CorrelatedValuePropagation::ID = 0;
58218893SdimINITIALIZE_PASS_BEGIN(CorrelatedValuePropagation, "correlated-propagation",
59218893Sdim                "Value Propagation", false, false)
60218893SdimINITIALIZE_PASS_DEPENDENCY(LazyValueInfo)
61218893SdimINITIALIZE_PASS_END(CorrelatedValuePropagation, "correlated-propagation",
62218893Sdim                "Value Propagation", false, false)
63212793Sdim
64212793Sdim// Public interface to the Value Propagation pass
65212793SdimPass *llvm::createCorrelatedValuePropagationPass() {
66212793Sdim  return new CorrelatedValuePropagation();
67212793Sdim}
68212793Sdim
69212793Sdimbool CorrelatedValuePropagation::processSelect(SelectInst *S) {
70212793Sdim  if (S->getType()->isVectorTy()) return false;
71212793Sdim  if (isa<Constant>(S->getOperand(0))) return false;
72218893Sdim
73212793Sdim  Constant *C = LVI->getConstant(S->getOperand(0), S->getParent());
74212793Sdim  if (!C) return false;
75218893Sdim
76212793Sdim  ConstantInt *CI = dyn_cast<ConstantInt>(C);
77212793Sdim  if (!CI) return false;
78218893Sdim
79218893Sdim  Value *ReplaceWith = S->getOperand(1);
80218893Sdim  Value *Other = S->getOperand(2);
81218893Sdim  if (!CI->isOne()) std::swap(ReplaceWith, Other);
82218893Sdim  if (ReplaceWith == S) ReplaceWith = UndefValue::get(S->getType());
83218893Sdim
84218893Sdim  S->replaceAllUsesWith(ReplaceWith);
85212793Sdim  S->eraseFromParent();
86212793Sdim
87212793Sdim  ++NumSelects;
88218893Sdim
89212793Sdim  return true;
90212793Sdim}
91212793Sdim
92212793Sdimbool CorrelatedValuePropagation::processPHI(PHINode *P) {
93212793Sdim  bool Changed = false;
94218893Sdim
95212793Sdim  BasicBlock *BB = P->getParent();
96212793Sdim  for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) {
97212793Sdim    Value *Incoming = P->getIncomingValue(i);
98212793Sdim    if (isa<Constant>(Incoming)) continue;
99218893Sdim
100212793Sdim    Constant *C = LVI->getConstantOnEdge(P->getIncomingValue(i),
101212793Sdim                                         P->getIncomingBlock(i),
102212793Sdim                                         BB);
103212793Sdim    if (!C) continue;
104218893Sdim
105212793Sdim    P->setIncomingValue(i, C);
106212793Sdim    Changed = true;
107212793Sdim  }
108218893Sdim
109218893Sdim  if (Value *V = SimplifyInstruction(P)) {
110218893Sdim    P->replaceAllUsesWith(V);
111212793Sdim    P->eraseFromParent();
112212793Sdim    Changed = true;
113212793Sdim  }
114218893Sdim
115234353Sdim  if (Changed)
116234353Sdim    ++NumPhis;
117218893Sdim
118212793Sdim  return Changed;
119212793Sdim}
120212793Sdim
121212793Sdimbool CorrelatedValuePropagation::processMemAccess(Instruction *I) {
122212793Sdim  Value *Pointer = 0;
123212793Sdim  if (LoadInst *L = dyn_cast<LoadInst>(I))
124212793Sdim    Pointer = L->getPointerOperand();
125212793Sdim  else
126212793Sdim    Pointer = cast<StoreInst>(I)->getPointerOperand();
127218893Sdim
128212793Sdim  if (isa<Constant>(Pointer)) return false;
129218893Sdim
130212793Sdim  Constant *C = LVI->getConstant(Pointer, I->getParent());
131212793Sdim  if (!C) return false;
132218893Sdim
133212793Sdim  ++NumMemAccess;
134212793Sdim  I->replaceUsesOfWith(Pointer, C);
135212793Sdim  return true;
136212793Sdim}
137212793Sdim
138212793Sdim/// processCmp - If the value of this comparison could be determined locally,
139212793Sdim/// constant propagation would already have figured it out.  Instead, walk
140212793Sdim/// the predecessors and statically evaluate the comparison based on information
141212793Sdim/// available on that edge.  If a given static evaluation is true on ALL
142212793Sdim/// incoming edges, then it's true universally and we can simplify the compare.
143212793Sdimbool CorrelatedValuePropagation::processCmp(CmpInst *C) {
144212793Sdim  Value *Op0 = C->getOperand(0);
145212793Sdim  if (isa<Instruction>(Op0) &&
146212793Sdim      cast<Instruction>(Op0)->getParent() == C->getParent())
147212793Sdim    return false;
148218893Sdim
149212793Sdim  Constant *Op1 = dyn_cast<Constant>(C->getOperand(1));
150212793Sdim  if (!Op1) return false;
151218893Sdim
152212793Sdim  pred_iterator PI = pred_begin(C->getParent()), PE = pred_end(C->getParent());
153212793Sdim  if (PI == PE) return false;
154218893Sdim
155218893Sdim  LazyValueInfo::Tristate Result = LVI->getPredicateOnEdge(C->getPredicate(),
156212793Sdim                                    C->getOperand(0), Op1, *PI, C->getParent());
157212793Sdim  if (Result == LazyValueInfo::Unknown) return false;
158212793Sdim
159212793Sdim  ++PI;
160212793Sdim  while (PI != PE) {
161218893Sdim    LazyValueInfo::Tristate Res = LVI->getPredicateOnEdge(C->getPredicate(),
162212793Sdim                                    C->getOperand(0), Op1, *PI, C->getParent());
163212793Sdim    if (Res != Result) return false;
164212793Sdim    ++PI;
165212793Sdim  }
166218893Sdim
167212793Sdim  ++NumCmps;
168218893Sdim
169212793Sdim  if (Result == LazyValueInfo::True)
170212793Sdim    C->replaceAllUsesWith(ConstantInt::getTrue(C->getContext()));
171212793Sdim  else
172212793Sdim    C->replaceAllUsesWith(ConstantInt::getFalse(C->getContext()));
173218893Sdim
174212793Sdim  C->eraseFromParent();
175212793Sdim
176212793Sdim  return true;
177212793Sdim}
178212793Sdim
179234353Sdim/// processSwitch - Simplify a switch instruction by removing cases which can
180234353Sdim/// never fire.  If the uselessness of a case could be determined locally then
181234353Sdim/// constant propagation would already have figured it out.  Instead, walk the
182234353Sdim/// predecessors and statically evaluate cases based on information available
183234353Sdim/// on that edge.  Cases that cannot fire no matter what the incoming edge can
184234353Sdim/// safely be removed.  If a case fires on every incoming edge then the entire
185234353Sdim/// switch can be removed and replaced with a branch to the case destination.
186234353Sdimbool CorrelatedValuePropagation::processSwitch(SwitchInst *SI) {
187234353Sdim  Value *Cond = SI->getCondition();
188234353Sdim  BasicBlock *BB = SI->getParent();
189234353Sdim
190234353Sdim  // If the condition was defined in same block as the switch then LazyValueInfo
191234353Sdim  // currently won't say anything useful about it, though in theory it could.
192234353Sdim  if (isa<Instruction>(Cond) && cast<Instruction>(Cond)->getParent() == BB)
193234353Sdim    return false;
194234353Sdim
195234353Sdim  // If the switch is unreachable then trying to improve it is a waste of time.
196234353Sdim  pred_iterator PB = pred_begin(BB), PE = pred_end(BB);
197234353Sdim  if (PB == PE) return false;
198234353Sdim
199234353Sdim  // Analyse each switch case in turn.  This is done in reverse order so that
200234353Sdim  // removing a case doesn't cause trouble for the iteration.
201234353Sdim  bool Changed = false;
202234353Sdim  for (SwitchInst::CaseIt CI = SI->case_end(), CE = SI->case_begin(); CI-- != CE;
203234353Sdim       ) {
204234353Sdim    ConstantInt *Case = CI.getCaseValue();
205234353Sdim
206234353Sdim    // Check to see if the switch condition is equal to/not equal to the case
207234353Sdim    // value on every incoming edge, equal/not equal being the same each time.
208234353Sdim    LazyValueInfo::Tristate State = LazyValueInfo::Unknown;
209234353Sdim    for (pred_iterator PI = PB; PI != PE; ++PI) {
210234353Sdim      // Is the switch condition equal to the case value?
211234353Sdim      LazyValueInfo::Tristate Value = LVI->getPredicateOnEdge(CmpInst::ICMP_EQ,
212234353Sdim                                                              Cond, Case, *PI, BB);
213234353Sdim      // Give up on this case if nothing is known.
214234353Sdim      if (Value == LazyValueInfo::Unknown) {
215234353Sdim        State = LazyValueInfo::Unknown;
216234353Sdim        break;
217234353Sdim      }
218234353Sdim
219234353Sdim      // If this was the first edge to be visited, record that all other edges
220234353Sdim      // need to give the same result.
221234353Sdim      if (PI == PB) {
222234353Sdim        State = Value;
223234353Sdim        continue;
224234353Sdim      }
225234353Sdim
226234353Sdim      // If this case is known to fire for some edges and known not to fire for
227234353Sdim      // others then there is nothing we can do - give up.
228234353Sdim      if (Value != State) {
229234353Sdim        State = LazyValueInfo::Unknown;
230234353Sdim        break;
231234353Sdim      }
232234353Sdim    }
233234353Sdim
234234353Sdim    if (State == LazyValueInfo::False) {
235234353Sdim      // This case never fires - remove it.
236234353Sdim      CI.getCaseSuccessor()->removePredecessor(BB);
237234353Sdim      SI->removeCase(CI); // Does not invalidate the iterator.
238243830Sdim
239243830Sdim      // The condition can be modified by removePredecessor's PHI simplification
240243830Sdim      // logic.
241243830Sdim      Cond = SI->getCondition();
242243830Sdim
243234353Sdim      ++NumDeadCases;
244234353Sdim      Changed = true;
245234353Sdim    } else if (State == LazyValueInfo::True) {
246234353Sdim      // This case always fires.  Arrange for the switch to be turned into an
247234353Sdim      // unconditional branch by replacing the switch condition with the case
248234353Sdim      // value.
249234353Sdim      SI->setCondition(Case);
250234353Sdim      NumDeadCases += SI->getNumCases();
251234353Sdim      Changed = true;
252234353Sdim      break;
253234353Sdim    }
254234353Sdim  }
255234353Sdim
256234353Sdim  if (Changed)
257234353Sdim    // If the switch has been simplified to the point where it can be replaced
258234353Sdim    // by a branch then do so now.
259234353Sdim    ConstantFoldTerminator(BB);
260234353Sdim
261234353Sdim  return Changed;
262234353Sdim}
263234353Sdim
264212793Sdimbool CorrelatedValuePropagation::runOnFunction(Function &F) {
265212793Sdim  LVI = &getAnalysis<LazyValueInfo>();
266218893Sdim
267212793Sdim  bool FnChanged = false;
268218893Sdim
269212793Sdim  for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
270212793Sdim    bool BBChanged = false;
271212793Sdim    for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) {
272212793Sdim      Instruction *II = BI++;
273212793Sdim      switch (II->getOpcode()) {
274212793Sdim      case Instruction::Select:
275212793Sdim        BBChanged |= processSelect(cast<SelectInst>(II));
276212793Sdim        break;
277212793Sdim      case Instruction::PHI:
278212793Sdim        BBChanged |= processPHI(cast<PHINode>(II));
279212793Sdim        break;
280212793Sdim      case Instruction::ICmp:
281212793Sdim      case Instruction::FCmp:
282212793Sdim        BBChanged |= processCmp(cast<CmpInst>(II));
283212793Sdim        break;
284212793Sdim      case Instruction::Load:
285212793Sdim      case Instruction::Store:
286212793Sdim        BBChanged |= processMemAccess(II);
287212793Sdim        break;
288212793Sdim      }
289212793Sdim    }
290218893Sdim
291234353Sdim    Instruction *Term = FI->getTerminator();
292234353Sdim    switch (Term->getOpcode()) {
293234353Sdim    case Instruction::Switch:
294234353Sdim      BBChanged |= processSwitch(cast<SwitchInst>(Term));
295234353Sdim      break;
296234353Sdim    }
297234353Sdim
298212793Sdim    FnChanged |= BBChanged;
299212793Sdim  }
300218893Sdim
301212793Sdim  return FnChanged;
302212793Sdim}
303