diff options
Diffstat (limited to 'lib/Analysis/MemoryDependenceAnalysis.cpp')
-rw-r--r-- | lib/Analysis/MemoryDependenceAnalysis.cpp | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 780d73e..6bffca6 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; } |