summaryrefslogtreecommitdiffstats
path: root/lib/Analysis/MemoryDependenceAnalysis.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-11-27 08:25:10 +0000
committerChris Lattner <sabre@nondot.org>2009-11-27 08:25:10 +0000
commit616613d7a4ddc7cefce53b2bfe3fdcdec6b032c2 (patch)
treea21c2231efa530622c802a2907533ef4beb023c4 /lib/Analysis/MemoryDependenceAnalysis.cpp
parentd280d85791c1fad9e625a5e2f472092b0c81c14e (diff)
downloadexternal_llvm-616613d7a4ddc7cefce53b2bfe3fdcdec6b032c2.zip
external_llvm-616613d7a4ddc7cefce53b2bfe3fdcdec6b032c2.tar.gz
external_llvm-616613d7a4ddc7cefce53b2bfe3fdcdec6b032c2.tar.bz2
teach GVN's load PRE to insert computations of the address in predecessors
where it is not available. It's unclear how to get this inserted computation into GVN's scalar availability sets, Owen, help? :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89997 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/MemoryDependenceAnalysis.cpp')
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp72
1 files changed, 67 insertions, 5 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index bb5b76c..95e9437 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -752,19 +752,35 @@ PHITranslatePointer(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred,
// Handle getelementptr with at least one PHI operand.
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
SmallVector<Value*, 8> GEPOps;
- Value *APHIOp = 0;
BasicBlock *CurBB = GEP->getParent();
for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
- GEPOps.push_back(GEP->getOperand(i)->DoPHITranslation(CurBB, Pred));
- if (!isa<Constant>(GEPOps.back()))
- APHIOp = GEPOps.back();
+ Value *GEPOp = GEP->getOperand(i);
+ // No PHI translation is needed of operands whose values are live in to
+ // the predecessor block.
+ if (!isa<Instruction>(GEPOp) ||
+ cast<Instruction>(GEPOp)->getParent() != CurBB) {
+ GEPOps.push_back(GEPOp);
+ continue;
+ }
+
+ // If the operand is a phi node, do phi translation.
+ if (PHINode *PN = dyn_cast<PHINode>(GEPOp)) {
+ GEPOps.push_back(PN->getIncomingValueForBlock(Pred));
+ continue;
+ }
+
+ // Otherwise, we can't PHI translate this random value defined in this
+ // block.
+ return 0;
}
// Simplify the GEP to handle 'gep x, 0' -> x etc.
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();
UI != E; ++UI) {
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
@@ -787,6 +803,52 @@ PHITranslatePointer(Value *InVal, BasicBlock *CurBB, BasicBlock *Pred,
return 0;
}
+/// InsertPHITranslatedPointer - Insert a computation of the PHI translated
+/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
+/// block.
+///
+/// This is only called when PHITranslatePointer returns a value that doesn't
+/// dominate the block, so we don't need to handle the trivial cases here.
+Value *MemoryDependenceAnalysis::
+InsertPHITranslatedPointer(Value *InVal, BasicBlock *CurBB,
+ BasicBlock *PredBB, const TargetData *TD) const {
+ // If the input value isn't an instruction in CurBB, it doesn't need phi
+ // translation.
+ Instruction *Inst = cast<Instruction>(InVal);
+ assert(Inst->getParent() == CurBB && "Doesn't need phi trans");
+
+ // Handle bitcast of PHI.
+ if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
+ PHINode *BCPN = cast<PHINode>(BC->getOperand(0));
+ Value *PHIIn = BCPN->getIncomingValueForBlock(PredBB);
+
+ // Otherwise insert a bitcast at the end of PredBB.
+ return new BitCastInst(PHIIn, InVal->getType(),
+ InVal->getName()+".phi.trans.insert",
+ PredBB->getTerminator());
+ }
+
+ // Handle getelementptr with at least one PHI operand.
+ if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
+ SmallVector<Value*, 8> GEPOps;
+ Value *APHIOp = 0;
+ BasicBlock *CurBB = GEP->getParent();
+ for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
+ GEPOps.push_back(GEP->getOperand(i)->DoPHITranslation(CurBB, PredBB));
+ if (!isa<Constant>(GEPOps.back()))
+ APHIOp = GEPOps.back();
+ }
+
+ GetElementPtrInst *Result =
+ GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(),
+ InVal->getName()+".phi.trans.insert",
+ PredBB->getTerminator());
+ Result->setIsInBounds(GEP->isInBounds());
+ return Result;
+ }
+
+ return 0;
+}
/// getNonLocalPointerDepFromBB - Perform a dependency query based on
/// pointer/pointeesize starting at the end of StartBB. Add any clobber/def