diff options
author | Owen Anderson <resistor@mac.com> | 2010-09-03 19:08:37 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2010-09-03 19:08:37 +0000 |
commit | 1593dd6779d7ab1db13c44f32f987c32aff2b54b (patch) | |
tree | cd9e61db505f08b161f4fe3d43666844560b681c /lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | |
parent | ac530614641a3702a90702b78acb6b9d8588881b (diff) | |
download | llvm-1593dd6779d7ab1db13c44f32f987c32aff2b54b.tar.gz llvm-1593dd6779d7ab1db13c44f32f987c32aff2b54b.tar.bz2 llvm-1593dd6779d7ab1db13c44f32f987c32aff2b54b.tar.xz |
Add support for simplifying a load from a computed value to a load from a global when it
is provable that they're equivalent. This fixes PR4855.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112994 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/CorrelatedValuePropagation.cpp')
-rw-r--r-- | lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index c673b0b332..2fd3c8dcb9 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -21,8 +21,9 @@ #include "llvm/ADT/Statistic.h" using namespace llvm; -STATISTIC(NumPhis, "Number of phis propagated"); -STATISTIC(NumSelects, "Number of selects propagated"); +STATISTIC(NumPhis, "Number of phis propagated"); +STATISTIC(NumSelects, "Number of selects propagated"); +STATISTIC(NumMemAccess, "Number of memory access targets propagated"); namespace { class CorrelatedValuePropagation : public FunctionPass { @@ -30,6 +31,7 @@ namespace { bool processSelect(SelectInst *SI); bool processPHI(PHINode *P); + bool processMemAccess(Instruction *I); public: static char ID; @@ -54,6 +56,7 @@ 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; @@ -97,6 +100,23 @@ bool CorrelatedValuePropagation::processPHI(PHINode *P) { return Changed; } +bool CorrelatedValuePropagation::processMemAccess(Instruction *I) { + Value *Pointer = 0; + if (LoadInst *L = dyn_cast<LoadInst>(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; +} + bool CorrelatedValuePropagation::runOnFunction(Function &F) { LVI = &getAnalysis<LazyValueInfo>(); @@ -106,10 +126,18 @@ bool CorrelatedValuePropagation::runOnFunction(Function &F) { bool BBChanged = false; for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) { Instruction *II = BI++; - if (SelectInst *SI = dyn_cast<SelectInst>(II)) - BBChanged |= processSelect(SI); - else if (PHINode *P = dyn_cast<PHINode>(II)) - BBChanged |= processPHI(P); + switch (II->getOpcode()) { + case Instruction::Select: + BBChanged |= processSelect(cast<SelectInst>(II)); + break; + case Instruction::PHI: + BBChanged |= processPHI(cast<PHINode>(II)); + break; + case Instruction::Load: + case Instruction::Store: + BBChanged |= processMemAccess(II); + break; + } } // Propagating correlated values might leave cruft around. |