summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-11-27 00:07:37 +0000
committerChris Lattner <sabre@nondot.org>2009-11-27 00:07:37 +0000
commit304076268a342b2b15e1af2e678d101af3165f4c (patch)
tree58266c04d67e0b0061e07450b23c5adcbd09591a /lib
parentcc3d0eb483d17154fe00f68726c097546b7c9352 (diff)
downloadllvm-304076268a342b2b15e1af2e678d101af3165f4c.tar.gz
llvm-304076268a342b2b15e1af2e678d101af3165f4c.tar.bz2
llvm-304076268a342b2b15e1af2e678d101af3165f4c.tar.xz
teach memdep to do trivial PHI translation of GEPs. More to
come. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89979 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index 780d73ec23..6bffca61e0 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -697,7 +697,14 @@ static bool isPHITranslatable(Instruction *Inst) {
if (PN->getParent() == BC->getParent())
return true;
- // TODO: GEP, ...
+ // We can translate a GEP that uses a PHI in the current block for at least
+ // one of its operands.
+ 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;
+ }
// cerr << "MEMDEP: Could not PHI translate: " << *Pointer;
// if (isa<BitCastInst>(PtrInst) || isa<GetElementPtrInst>(PtrInst))
@@ -713,6 +720,7 @@ static Value *PHITranslateForPred(Instruction *Inst, BasicBlock *Pred) {
if (PHINode *PN = dyn_cast<PHINode>(Inst))
return PN->getIncomingValueForBlock(Pred);
+ // Handle bitcast of PHI.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
PHINode *BCPN = cast<PHINode>(BC->getOperand(0));
Value *PHIIn = BCPN->getIncomingValueForBlock(Pred);
@@ -732,6 +740,39 @@ static Value *PHITranslateForPred(Instruction *Inst, BasicBlock *Pred) {
return 0;
}
+ // Handle getelementptr with at least one PHI operand.
+ if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
+ SmallVector<Value*, 8> GEPOps;
+ Value *APHIOp = 0;
+ for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) {
+ GEPOps.push_back(GEP->getOperand(i));
+ if (PHINode *PN = dyn_cast<PHINode>(GEP->getOperand(i)))
+ if (PN->getParent() == GEP->getParent())
+ GEPOps.back() = APHIOp = PN->getIncomingValueForBlock(Pred);
+ }
+
+ // TODO: Simplify the GEP to handle 'gep x, 0' -> x etc.
+
+ // Scan to see if we have this GEP available.
+ for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end();
+ UI != E; ++UI) {
+ if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
+ if (GEPI->getType() == GEPI->getType() &&
+ GEPI->getNumOperands() == GEPOps.size() &&
+ GEPI->getParent()->getParent() == Inst->getParent()->getParent()) {
+ bool Mismatch = false;
+ for (unsigned i = 0, e = GEPOps.size(); i != e; ++i)
+ if (GEPI->getOperand(i) != GEPOps[i]) {
+ Mismatch = true;
+ break;
+ }
+ if (!Mismatch)
+ return GEPI;
+ }
+ }
+ return 0;
+ }
+
return 0;
}