aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/MemoryDependenceAnalysis.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-11-27 19:11:31 +0000
committerChris Lattner <sabre@nondot.org>2009-11-27 19:11:31 +0000
commit11c6bab704a0f82f59dcb2f409f7d6ac3b1821f1 (patch)
tree274b2352759e9308594b6c57ff1ce1c014bab7ad /lib/Analysis/MemoryDependenceAnalysis.cpp
parent9a5c22cc5e741bc3022366e85825ba99236027ed (diff)
add support for recursive phi translation and phi
translation of add with immediate. This allows us to optimize this function: void test(int N, double* G) { long j; G[1] = 1; for (j = 1; j < N - 1; j++) G[j+1] = G[j] + G[j+1]; } to only do one load every iteration of the loop. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90013 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/MemoryDependenceAnalysis.cpp')
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp77
1 files changed, 67 insertions, 10 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index f958e75040..e87b4cdaa6 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -694,17 +694,31 @@ static bool isPHITranslatable(Instruction *Inst) {
// We can handle bitcast of a PHI, but the PHI needs to be in the same block
// as the bitcast.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst))
+ // FIXME: Allow any phi translatable operand.
if (PHINode *PN = dyn_cast<PHINode>(BC->getOperand(0)))
if (PN->getParent() == BC->getParent())
return true;
- // We can translate a GEP that uses a PHI in the current block for at least
- // one of its operands.
+ // We can translate a GEP if all of its operands defined in this block are phi
+ // translatable.
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
- for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i)
- if (PHINode *PN = dyn_cast<PHINode>(GEP->getOperand(i)))
- if (PN->getParent() == GEP->getParent())
- return true;
+ for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
+ Instruction *GEPOpI = dyn_cast<Instruction>(GEP->getOperand(i));
+ if (GEPOpI == 0 || GEPOpI->getParent() != Inst->getParent())
+ continue;
+
+ if (!isPHITranslatable(GEPOpI))
+ return false;
+ }
+ return true;
+ }
+
+ if (Inst->getOpcode() == Instruction::Add &&
+ isa<ConstantInt>(Inst->getOperand(1))) {
+ Instruction *GEPOpI = dyn_cast<Instruction>(Inst->getOperand(0));
+ if (GEPOpI == 0 || GEPOpI->getParent() != Inst->getParent())
+ return true;
+ return isPHITranslatable(GEPOpI);
}
// cerr << "MEMDEP: Could not PHI translate: " << *Pointer;
@@ -731,6 +745,7 @@ PHITranslatePointer(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred,
// Handle bitcast of PHI.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
+ // FIXME: Recurse!
PHINode *BCPN = cast<PHINode>(BC->getOperand(0));
Value *PHIIn = BCPN->getIncomingValueForBlock(Pred);
@@ -749,7 +764,7 @@ PHITranslatePointer(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred,
return 0;
}
- // Handle getelementptr with at least one PHI operand.
+ // Handle getelementptr with at least one PHI translatable operand.
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
SmallVector<Value*, 8> GEPOps;
BasicBlock *CurBB = GEP->getParent();
@@ -764,8 +779,8 @@ PHITranslatePointer(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred,
}
// If the operand is a phi node, do phi translation.
- if (PHINode *PN = dyn_cast<PHINode>(GEPOp)) {
- GEPOps.push_back(PN->getIncomingValueForBlock(Pred));
+ if (Value *InOp = PHITranslatePointer(GEPOp, CurBB, Pred, TD)) {
+ GEPOps.push_back(InOp);
continue;
}
@@ -778,7 +793,6 @@ PHITranslatePointer(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred,
if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD))
return V;
-
// Scan to see if we have this GEP available.
Value *APHIOp = GEPOps[0];
for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end();
@@ -800,6 +814,49 @@ PHITranslatePointer(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred,
return 0;
}
+ // Handle add with a constant RHS.
+ if (Inst->getOpcode() == Instruction::Add &&
+ isa<ConstantInt>(Inst->getOperand(1))) {
+ // PHI translate the LHS.
+ Value *LHS;
+ Constant *RHS = cast<ConstantInt>(Inst->getOperand(1));
+ Instruction *OpI = dyn_cast<Instruction>(Inst->getOperand(0));
+ bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
+ bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();
+
+ if (OpI == 0 || OpI->getParent() != Inst->getParent())
+ LHS = Inst->getOperand(0);
+ else {
+ LHS = PHITranslatePointer(Inst->getOperand(0), CurBB, Pred, TD);
+ if (LHS == 0)
+ return 0;
+ }
+
+ // If the PHI translated LHS is an add of a constant, fold the immediates.
+ if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(LHS))
+ if (BOp->getOpcode() == Instruction::Add)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
+ LHS = BOp->getOperand(0);
+ RHS = ConstantExpr::getAdd(RHS, CI);
+ isNSW = isNUW = false;
+ }
+
+ // See if the add simplifies away.
+ if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD))
+ return Res;
+
+ // Otherwise, see if we have this add available somewhere.
+ for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end();
+ UI != E; ++UI) {
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*UI))
+ if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
+ BO->getParent()->getParent() == CurBB->getParent())
+ return BO;
+ }
+
+ return 0;
+ }
+
return 0;
}