diff options
Diffstat (limited to 'lib/Transforms/Scalar/CorrelatedValuePropagation.cpp')
-rw-r--r-- | lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 0d4e45de34664..be12973b645fe 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -16,6 +16,7 @@ #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" +#include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LazyValueInfo.h" #include "llvm/Support/CFG.h" #include "llvm/Transforms/Utils/Local.h" @@ -30,18 +31,20 @@ STATISTIC(NumCmps, "Number of comparisons propagated"); namespace { class CorrelatedValuePropagation : public FunctionPass { LazyValueInfo *LVI; - + bool processSelect(SelectInst *SI); bool processPHI(PHINode *P); bool processMemAccess(Instruction *I); bool processCmp(CmpInst *C); - + public: static char ID; - CorrelatedValuePropagation(): FunctionPass(ID) { } - + CorrelatedValuePropagation(): FunctionPass(ID) { + initializeCorrelatedValuePropagationPass(*PassRegistry::getPassRegistry()); + } + bool runOnFunction(Function &F); - + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<LazyValueInfo>(); } @@ -49,8 +52,11 @@ namespace { } char CorrelatedValuePropagation::ID = 0; -INITIALIZE_PASS(CorrelatedValuePropagation, "correlated-propagation", - "Value Propagation", false, false); +INITIALIZE_PASS_BEGIN(CorrelatedValuePropagation, "correlated-propagation", + "Value Propagation", false, false) +INITIALIZE_PASS_DEPENDENCY(LazyValueInfo) +INITIALIZE_PASS_END(CorrelatedValuePropagation, "correlated-propagation", + "Value Propagation", false, false) // Public interface to the Value Propagation pass Pass *llvm::createCorrelatedValuePropagationPass() { @@ -60,46 +66,51 @@ Pass *llvm::createCorrelatedValuePropagationPass() { bool CorrelatedValuePropagation::processSelect(SelectInst *S) { if (S->getType()->isVectorTy()) return false; if (isa<Constant>(S->getOperand(0))) return false; - + Constant *C = LVI->getConstant(S->getOperand(0), S->getParent()); if (!C) return false; - + ConstantInt *CI = dyn_cast<ConstantInt>(C); if (!CI) return false; - - S->replaceAllUsesWith(S->getOperand(CI->isOne() ? 1 : 2)); + + Value *ReplaceWith = S->getOperand(1); + Value *Other = S->getOperand(2); + if (!CI->isOne()) std::swap(ReplaceWith, Other); + if (ReplaceWith == S) ReplaceWith = UndefValue::get(S->getType()); + + S->replaceAllUsesWith(ReplaceWith); S->eraseFromParent(); ++NumSelects; - + return true; } bool CorrelatedValuePropagation::processPHI(PHINode *P) { bool Changed = false; - + BasicBlock *BB = P->getParent(); for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) { Value *Incoming = P->getIncomingValue(i); if (isa<Constant>(Incoming)) continue; - + Constant *C = LVI->getConstantOnEdge(P->getIncomingValue(i), P->getIncomingBlock(i), BB); if (!C) continue; - + P->setIncomingValue(i, C); Changed = true; } - - if (Value *ConstVal = P->hasConstantValue()) { - P->replaceAllUsesWith(ConstVal); + + if (Value *V = SimplifyInstruction(P)) { + P->replaceAllUsesWith(V); P->eraseFromParent(); Changed = true; } - + ++NumPhis; - + return Changed; } @@ -109,12 +120,12 @@ bool CorrelatedValuePropagation::processMemAccess(Instruction *I) { Pointer = L->getPointerOperand(); else Pointer = cast<StoreInst>(I)->getPointerOperand(); - + if (isa<Constant>(Pointer)) return false; - + Constant *C = LVI->getConstant(Pointer, I->getParent()); if (!C) return false; - + ++NumMemAccess; I->replaceUsesOfWith(Pointer, C); return true; @@ -130,32 +141,32 @@ bool CorrelatedValuePropagation::processCmp(CmpInst *C) { if (isa<Instruction>(Op0) && cast<Instruction>(Op0)->getParent() == C->getParent()) return false; - + Constant *Op1 = dyn_cast<Constant>(C->getOperand(1)); if (!Op1) return false; - + pred_iterator PI = pred_begin(C->getParent()), PE = pred_end(C->getParent()); if (PI == PE) return false; - - LazyValueInfo::Tristate Result = LVI->getPredicateOnEdge(C->getPredicate(), + + LazyValueInfo::Tristate Result = LVI->getPredicateOnEdge(C->getPredicate(), C->getOperand(0), Op1, *PI, C->getParent()); if (Result == LazyValueInfo::Unknown) return false; ++PI; while (PI != PE) { - LazyValueInfo::Tristate Res = LVI->getPredicateOnEdge(C->getPredicate(), + LazyValueInfo::Tristate Res = LVI->getPredicateOnEdge(C->getPredicate(), C->getOperand(0), Op1, *PI, C->getParent()); if (Res != Result) return false; ++PI; } - + ++NumCmps; - + if (Result == LazyValueInfo::True) C->replaceAllUsesWith(ConstantInt::getTrue(C->getContext())); else C->replaceAllUsesWith(ConstantInt::getFalse(C->getContext())); - + C->eraseFromParent(); return true; @@ -163,9 +174,9 @@ bool CorrelatedValuePropagation::processCmp(CmpInst *C) { bool CorrelatedValuePropagation::runOnFunction(Function &F) { LVI = &getAnalysis<LazyValueInfo>(); - + bool FnChanged = false; - + for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { bool BBChanged = false; for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) { @@ -187,14 +198,9 @@ bool CorrelatedValuePropagation::runOnFunction(Function &F) { break; } } - - // Propagating correlated values might leave cruft around. - // Try to clean it up before we continue. - if (BBChanged) - SimplifyInstructionsInBlock(FI); - + FnChanged |= BBChanged; } - + return FnChanged; } |