[llvm-commits] [llvm] r112994 - in /llvm/trunk: lib/Analysis/LazyValueInfo.cpp lib/Transforms/Scalar/CorrelatedValuePropagation.cpp test/Transforms/CorrelatedValuePropagation/basic.ll
Owen Anderson
resistor at mac.com
Fri Sep 3 12:08:37 PDT 2010
Author: resistor
Date: Fri Sep 3 14:08:37 2010
New Revision: 112994
URL: http://llvm.org/viewvc/llvm-project?rev=112994&view=rev
Log:
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.
Modified:
llvm/trunk/lib/Analysis/LazyValueInfo.cpp
llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
llvm/trunk/test/Transforms/CorrelatedValuePropagation/basic.ll
Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=112994&r1=112993&r2=112994&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Fri Sep 3 14:08:37 2010
@@ -452,14 +452,15 @@
// If this is a pointer, and there's a load from that pointer in this BB,
// then we know that the pointer can't be NULL.
+ bool NotNull = false;
if (Val->getType()->isPointerTy()) {
- const PointerType *PTy = cast<PointerType>(Val->getType());
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();BI != BE;++BI){
LoadInst *L = dyn_cast<LoadInst>(BI);
if (L && L->getPointerAddressSpace() == 0 &&
L->getPointerOperand()->getUnderlyingObject() ==
Val->getUnderlyingObject()) {
- return LVILatticeVal::getNot(ConstantPointerNull::get(PTy));
+ NotNull = true;
+ break;
}
}
}
@@ -475,11 +476,19 @@
if (Result.isOverdefined()) {
DEBUG(dbgs() << " compute BB '" << BB->getName()
<< "' - overdefined because of pred.\n");
+ // If we previously determined that this is a pointer that can't be null
+ // then return that rather than giving up entirely.
+ if (NotNull) {
+ const PointerType *PTy = cast<PointerType>(Val->getType());
+ Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy));
+ }
+
return Result;
}
++NumPreds;
}
+
// If this is the entry block, we must be asking about an argument. The
// value is overdefined.
if (NumPreds == 0 && BB == &BB->getParent()->front()) {
Modified: llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp?rev=112994&r1=112993&r2=112994&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp Fri Sep 3 14:08:37 2010
@@ -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 @@
bool processSelect(SelectInst *SI);
bool processPHI(PHINode *P);
+ bool processMemAccess(Instruction *I);
public:
static char ID;
@@ -54,6 +56,7 @@
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 @@
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 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.
Modified: llvm/trunk/test/Transforms/CorrelatedValuePropagation/basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CorrelatedValuePropagation/basic.ll?rev=112994&r1=112993&r2=112994&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/CorrelatedValuePropagation/basic.ll (original)
+++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/basic.ll Fri Sep 3 14:08:37 2010
@@ -39,3 +39,21 @@
; CHECK: ret i1 %res
ret i1 %res
}
+
+; PR4855
+ at gv = internal constant i8 7
+; CHECK: @test3
+define i8 @test3(i8* %a) nounwind {
+entry:
+ %cond = icmp eq i8* %a, @gv
+ br i1 %cond, label %bb2, label %bb
+
+bb: ; preds = %entry
+ ret i8 0
+
+bb2: ; preds = %entry
+; CHECK-NOT: load i8* %a
+ %should_be_const = load i8* %a
+; CHECK: ret i8 7
+ ret i8 %should_be_const
+}
\ No newline at end of file
More information about the llvm-commits
mailing list