X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FScalar%2FCorrelatedValuePropagation.cpp;h=b1809b7fae08caa80e0e4caa24a226e5b83b14c6;hb=cf0db29df20d9c665da7e82bb261bdd7cf7f1b2b;hp=075c0351534dc1d196c0a59dc61075a661d8bd7a;hpb=851b04c9208732b502156a66893fd83ca24c5b69;p=oota-llvm.git diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 075c0351534..b1809b7fae0 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -55,7 +56,7 @@ namespace { AU.addRequired(); } }; -} +} // namespace char CorrelatedValuePropagation::ID = 0; INITIALIZE_PASS_BEGIN(CorrelatedValuePropagation, "correlated-propagation", @@ -73,7 +74,7 @@ bool CorrelatedValuePropagation::processSelect(SelectInst *S) { if (S->getType()->isVectorTy()) return false; if (isa(S->getOperand(0))) return false; - Constant *C = LVI->getConstant(S->getOperand(0), S->getParent()); + Constant *C = LVI->getConstant(S->getOperand(0), S->getParent(), S); if (!C) return false; ConstantInt *CI = dyn_cast(C); @@ -100,34 +101,55 @@ bool CorrelatedValuePropagation::processPHI(PHINode *P) { Value *Incoming = P->getIncomingValue(i); if (isa(Incoming)) continue; - Value *V = LVI->getConstantOnEdge(Incoming, P->getIncomingBlock(i), BB); + Value *V = LVI->getConstantOnEdge(Incoming, P->getIncomingBlock(i), BB, P); - // Look if the incoming value is a select with a constant but LVI tells us - // that the incoming value can never be that constant. In that case replace - // the incoming value with the other value of the select. This often allows - // us to remove the select later. + // Look if the incoming value is a select with a scalar condition for which + // LVI can tells us the value. In that case replace the incoming value with + // the appropriate value of the select. This often allows us to remove the + // select later. if (!V) { SelectInst *SI = dyn_cast(Incoming); if (!SI) continue; - Constant *C = dyn_cast(SI->getFalseValue()); - if (!C) continue; + Value *Condition = SI->getCondition(); + if (!Condition->getType()->isVectorTy()) { + if (Constant *C = LVI->getConstantOnEdge( + Condition, P->getIncomingBlock(i), BB, P)) { + if (C->isOneValue()) { + V = SI->getTrueValue(); + } else if (C->isZeroValue()) { + V = SI->getFalseValue(); + } + // Once LVI learns to handle vector types, we could also add support + // for vector type constants that are not all zeroes or all ones. + } + } - if (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, - P->getIncomingBlock(i), BB) != - LazyValueInfo::False) - continue; + // Look if the select has a constant but LVI tells us that the incoming + // value can never be that constant. In that case replace the incoming + // value with the other value of the select. This often allows us to + // remove the select later. + if (!V) { + Constant *C = dyn_cast(SI->getFalseValue()); + if (!C) continue; + + if (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, + P->getIncomingBlock(i), BB, P) != + LazyValueInfo::False) + continue; + V = SI->getTrueValue(); + } DEBUG(dbgs() << "CVP: Threading PHI over " << *SI << '\n'); - V = SI->getTrueValue(); } P->setIncomingValue(i, V); Changed = true; } - // FIXME: Provide DL, TLI, DT, AT to SimplifyInstruction. - if (Value *V = SimplifyInstruction(P)) { + // FIXME: Provide TLI, DT, AT to SimplifyInstruction. + const DataLayout &DL = BB->getModule()->getDataLayout(); + if (Value *V = SimplifyInstruction(P, DL)) { P->replaceAllUsesWith(V); P->eraseFromParent(); Changed = true; @@ -148,7 +170,7 @@ bool CorrelatedValuePropagation::processMemAccess(Instruction *I) { if (isa(Pointer)) return false; - Constant *C = LVI->getConstant(Pointer, I->getParent()); + Constant *C = LVI->getConstant(Pointer, I->getParent(), I); if (!C) return false; ++NumMemAccess; @@ -174,13 +196,15 @@ bool CorrelatedValuePropagation::processCmp(CmpInst *C) { if (PI == PE) return false; LazyValueInfo::Tristate Result = LVI->getPredicateOnEdge(C->getPredicate(), - C->getOperand(0), Op1, *PI, C->getParent()); + C->getOperand(0), Op1, *PI, + C->getParent(), C); if (Result == LazyValueInfo::Unknown) return false; ++PI; while (PI != PE) { LazyValueInfo::Tristate Res = LVI->getPredicateOnEdge(C->getPredicate(), - C->getOperand(0), Op1, *PI, C->getParent()); + C->getOperand(0), Op1, *PI, + C->getParent(), C); if (Res != Result) return false; ++PI; } @@ -230,7 +254,8 @@ bool CorrelatedValuePropagation::processSwitch(SwitchInst *SI) { for (pred_iterator PI = PB; PI != PE; ++PI) { // Is the switch condition equal to the case value? LazyValueInfo::Tristate Value = LVI->getPredicateOnEdge(CmpInst::ICMP_EQ, - Cond, Case, *PI, BB); + Cond, Case, *PI, + BB, SI); // Give up on this case if nothing is known. if (Value == LazyValueInfo::Unknown) { State = LazyValueInfo::Unknown;