summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2010-09-03 19:08:37 +0000
committerOwen Anderson <resistor@mac.com>2010-09-03 19:08:37 +0000
commit1593dd6779d7ab1db13c44f32f987c32aff2b54b (patch)
treecd9e61db505f08b161f4fe3d43666844560b681c /lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
parentac530614641a3702a90702b78acb6b9d8588881b (diff)
downloadllvm-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.cpp40
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.