1 //===- CorrelatedValuePropagation.cpp - Propagate CFG-derived info --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Correlated Value Propagation pass.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "correlated-value-propagation"
15 #include "llvm/Transforms/Scalar.h"
16 #include "llvm/Constants.h"
17 #include "llvm/Function.h"
18 #include "llvm/Instructions.h"
19 #include "llvm/Pass.h"
20 #include "llvm/Analysis/InstructionSimplify.h"
21 #include "llvm/Analysis/LazyValueInfo.h"
22 #include "llvm/Support/CFG.h"
23 #include "llvm/Transforms/Utils/Local.h"
24 #include "llvm/ADT/Statistic.h"
27 STATISTIC(NumPhis
, "Number of phis propagated");
28 STATISTIC(NumSelects
, "Number of selects propagated");
29 STATISTIC(NumMemAccess
, "Number of memory access targets propagated");
30 STATISTIC(NumCmps
, "Number of comparisons propagated");
33 class CorrelatedValuePropagation
: public FunctionPass
{
36 bool processSelect(SelectInst
*SI
);
37 bool processPHI(PHINode
*P
);
38 bool processMemAccess(Instruction
*I
);
39 bool processCmp(CmpInst
*C
);
43 CorrelatedValuePropagation(): FunctionPass(ID
) {
44 initializeCorrelatedValuePropagationPass(*PassRegistry::getPassRegistry());
47 bool runOnFunction(Function
&F
);
49 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const {
50 AU
.addRequired
<LazyValueInfo
>();
55 char CorrelatedValuePropagation::ID
= 0;
56 INITIALIZE_PASS_BEGIN(CorrelatedValuePropagation
, "correlated-propagation",
57 "Value Propagation", false, false)
58 INITIALIZE_PASS_DEPENDENCY(LazyValueInfo
)
59 INITIALIZE_PASS_END(CorrelatedValuePropagation
, "correlated-propagation",
60 "Value Propagation", false, false)
62 // Public interface to the Value Propagation pass
63 Pass
*llvm::createCorrelatedValuePropagationPass() {
64 return new CorrelatedValuePropagation();
67 bool CorrelatedValuePropagation::processSelect(SelectInst
*S
) {
68 if (S
->getType()->isVectorTy()) return false;
69 if (isa
<Constant
>(S
->getOperand(0))) return false;
71 Constant
*C
= LVI
->getConstant(S
->getOperand(0), S
->getParent());
74 ConstantInt
*CI
= dyn_cast
<ConstantInt
>(C
);
75 if (!CI
) return false;
77 Value
*ReplaceWith
= S
->getOperand(1);
78 Value
*Other
= S
->getOperand(2);
79 if (!CI
->isOne()) std::swap(ReplaceWith
, Other
);
80 if (ReplaceWith
== S
) ReplaceWith
= UndefValue::get(S
->getType());
82 S
->replaceAllUsesWith(ReplaceWith
);
90 bool CorrelatedValuePropagation::processPHI(PHINode
*P
) {
93 BasicBlock
*BB
= P
->getParent();
94 for (unsigned i
= 0, e
= P
->getNumIncomingValues(); i
< e
; ++i
) {
95 Value
*Incoming
= P
->getIncomingValue(i
);
96 if (isa
<Constant
>(Incoming
)) continue;
98 Constant
*C
= LVI
->getConstantOnEdge(P
->getIncomingValue(i
),
99 P
->getIncomingBlock(i
),
103 P
->setIncomingValue(i
, C
);
107 if (Value
*V
= SimplifyInstruction(P
)) {
108 P
->replaceAllUsesWith(V
);
109 P
->eraseFromParent();
118 bool CorrelatedValuePropagation::processMemAccess(Instruction
*I
) {
120 if (LoadInst
*L
= dyn_cast
<LoadInst
>(I
))
121 Pointer
= L
->getPointerOperand();
123 Pointer
= cast
<StoreInst
>(I
)->getPointerOperand();
125 if (isa
<Constant
>(Pointer
)) return false;
127 Constant
*C
= LVI
->getConstant(Pointer
, I
->getParent());
128 if (!C
) return false;
131 I
->replaceUsesOfWith(Pointer
, C
);
135 /// processCmp - If the value of this comparison could be determined locally,
136 /// constant propagation would already have figured it out. Instead, walk
137 /// the predecessors and statically evaluate the comparison based on information
138 /// available on that edge. If a given static evaluation is true on ALL
139 /// incoming edges, then it's true universally and we can simplify the compare.
140 bool CorrelatedValuePropagation::processCmp(CmpInst
*C
) {
141 Value
*Op0
= C
->getOperand(0);
142 if (isa
<Instruction
>(Op0
) &&
143 cast
<Instruction
>(Op0
)->getParent() == C
->getParent())
146 Constant
*Op1
= dyn_cast
<Constant
>(C
->getOperand(1));
147 if (!Op1
) return false;
149 pred_iterator PI
= pred_begin(C
->getParent()), PE
= pred_end(C
->getParent());
150 if (PI
== PE
) return false;
152 LazyValueInfo::Tristate Result
= LVI
->getPredicateOnEdge(C
->getPredicate(),
153 C
->getOperand(0), Op1
, *PI
, C
->getParent());
154 if (Result
== LazyValueInfo::Unknown
) return false;
158 LazyValueInfo::Tristate Res
= LVI
->getPredicateOnEdge(C
->getPredicate(),
159 C
->getOperand(0), Op1
, *PI
, C
->getParent());
160 if (Res
!= Result
) return false;
166 if (Result
== LazyValueInfo::True
)
167 C
->replaceAllUsesWith(ConstantInt::getTrue(C
->getContext()));
169 C
->replaceAllUsesWith(ConstantInt::getFalse(C
->getContext()));
171 C
->eraseFromParent();
176 bool CorrelatedValuePropagation::runOnFunction(Function
&F
) {
177 LVI
= &getAnalysis
<LazyValueInfo
>();
179 bool FnChanged
= false;
181 for (Function::iterator FI
= F
.begin(), FE
= F
.end(); FI
!= FE
; ++FI
) {
182 bool BBChanged
= false;
183 for (BasicBlock::iterator BI
= FI
->begin(), BE
= FI
->end(); BI
!= BE
; ) {
184 Instruction
*II
= BI
++;
185 switch (II
->getOpcode()) {
186 case Instruction::Select
:
187 BBChanged
|= processSelect(cast
<SelectInst
>(II
));
189 case Instruction::PHI
:
190 BBChanged
|= processPHI(cast
<PHINode
>(II
));
192 case Instruction::ICmp
:
193 case Instruction::FCmp
:
194 BBChanged
|= processCmp(cast
<CmpInst
>(II
));
196 case Instruction::Load
:
197 case Instruction::Store
:
198 BBChanged
|= processMemAccess(II
);
203 FnChanged
|= BBChanged
;