14 #define DEBUG_TYPE "correlated-value-propagation"
29 STATISTIC(NumPhis,
"Number of phis propagated");
30 STATISTIC(NumSelects,
"Number of selects propagated");
31 STATISTIC(NumMemAccess,
"Number of memory access targets propagated");
32 STATISTIC(NumCmps,
"Number of comparisons propagated");
33 STATISTIC(NumDeadCases,
"Number of switch cases removed");
61 "Value Propagation",
false,
false)
68 return new CorrelatedValuePropagation();
71 bool CorrelatedValuePropagation::processSelect(
SelectInst *S) {
73 if (isa<Constant>(S->
getOperand(0)))
return false;
79 if (!CI)
return false;
94 bool CorrelatedValuePropagation::processPHI(
PHINode *
P) {
100 if (isa<Constant>(Incoming))
continue;
120 DEBUG(
dbgs() <<
"CVP: Threading PHI over " << *SI <<
'\n');
140 bool CorrelatedValuePropagation::processMemAccess(
Instruction *
I) {
142 if (
LoadInst *L = dyn_cast<LoadInst>(I))
143 Pointer = L->getPointerOperand();
147 if (isa<Constant>(Pointer))
return false;
150 if (!C)
return false;
162 bool CorrelatedValuePropagation::processCmp(
CmpInst *C) {
164 if (isa<Instruction>(Op0) &&
169 if (!Op1)
return false;
172 if (PI == PE)
return false;
182 if (Res != Result)
return false;
205 bool CorrelatedValuePropagation::processSwitch(
SwitchInst *SI) {
211 if (isa<Instruction>(Cond) && cast<Instruction>(Cond)->
getParent() == BB)
216 if (PB == PE)
return false;
220 bool Changed =
false;
231 Cond, Case, *PI, BB);
247 if (Value != State) {
255 CI.getCaseSuccessor()->removePredecessor(BB);
283 bool CorrelatedValuePropagation::runOnFunction(
Function &
F) {
284 LVI = &getAnalysis<LazyValueInfo>();
286 bool FnChanged =
false;
289 bool BBChanged =
false;
294 BBChanged |= processSelect(cast<SelectInst>(II));
297 BBChanged |= processPHI(cast<PHINode>(II));
299 case Instruction::ICmp:
300 case Instruction::FCmp:
301 BBChanged |= processCmp(cast<CmpInst>(II));
305 BBChanged |= processMemAccess(II);
312 case Instruction::Switch:
313 BBChanged |= processSwitch(cast<SwitchInst>(Term));
317 FnChanged |= BBChanged;
static ConstantInt * getFalse(LLVMContext &Context)
Abstract base class of comparison instructions.
static PassRegistry * getPassRegistry()
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static Value * getPointerOperand(Instruction &Inst)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
ID
LLVM Calling Convention Representation.
void replaceAllUsesWith(Value *V)
unsigned getNumIncomingValues() const
void replaceUsesOfWith(Value *From, Value *To)
Pass * createCorrelatedValuePropagationPass()
LLVM Basic Block Representation.
LLVM Constant Representation.
Interval::pred_iterator pred_begin(Interval *I)
BasicBlock * getIncomingBlock(unsigned i) const
Value * getOperand(unsigned i) const
Interval::pred_iterator pred_end(Interval *I)
Predicate getPredicate() const
Return the predicate for this instruction.
static UndefValue * get(Type *T)
Value * SimplifyInstruction(Instruction *I, const DataLayout *TD=0, const TargetLibraryInfo *TLI=0, const DominatorTree *DT=0)
LLVMContext & getContext() const
All values hold a context through their type.
const Value * getTrueValue() const
Tristate
Tristate - This is used to return true/false/dunno results.
Class for constant integers.
void initializeCorrelatedValuePropagationPass(PassRegistry &)
Value * getIncomingValue(unsigned i) const
bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=0)
static ConstantInt * getTrue(LLVMContext &Context)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Value * getCondition() const
void setCondition(Value *V)
void removeCase(CaseIt i)
unsigned getNumCases() const
LLVM Value Representation.
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
static const Function * getParent(const Value *V)
const Value * getFalseValue() const
void setIncomingValue(unsigned i, Value *V)
const BasicBlock * getParent() const
bool isOne() const
Determine if the value is one.