diff options
author | Chris Lattner <sabre@nondot.org> | 2009-11-27 00:07:37 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-11-27 00:07:37 +0000 |
commit | 304076268a342b2b15e1af2e678d101af3165f4c (patch) | |
tree | 58266c04d67e0b0061e07450b23c5adcbd09591a | |
parent | cc3d0eb483d17154fe00f68726c097546b7c9352 (diff) | |
download | external_llvm-304076268a342b2b15e1af2e678d101af3165f4c.zip external_llvm-304076268a342b2b15e1af2e678d101af3165f4c.tar.gz external_llvm-304076268a342b2b15e1af2e678d101af3165f4c.tar.bz2 |
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
-rw-r--r-- | lib/Analysis/MemoryDependenceAnalysis.cpp | 43 | ||||
-rw-r--r-- | test/Transforms/GVN/rle-phi-translate.ll | 28 |
2 files changed, 69 insertions, 2 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; } diff --git a/test/Transforms/GVN/rle-phi-translate.ll b/test/Transforms/GVN/rle-phi-translate.ll index 89f5ac3..ac9e7aa 100644 --- a/test/Transforms/GVN/rle-phi-translate.ll +++ b/test/Transforms/GVN/rle-phi-translate.ll @@ -54,9 +54,35 @@ bb2: %d = phi i32* [ %c, %bb1 ], [ %b, %bb ] %d1 = bitcast i32* %d to i8* %dv = load i8* %d1 -; CHECK: %dv = phi i8 +; CHECK: %dv = phi i8 [ 92, %bb1 ], [ 4, %bb ] ; CHECK-NOT: load ; CHECK: ret i8 %dv ret i8 %dv } +define i32 @test3(i1 %cond, i32* %b, i32* %c) nounwind { +; CHECK: @test3 +entry: + br i1 %cond, label %bb, label %bb1 + +bb: + %b1 = getelementptr i32* %b, i32 17 + store i32 4, i32* %b1 + br label %bb2 + +bb1: + %c1 = getelementptr i32* %c, i32 7 + store i32 82, i32* %c1 + br label %bb2 + +bb2: + %d = phi i32* [ %c, %bb1 ], [ %b, %bb ] + %i = phi i32 [ 7, %bb1 ], [ 17, %bb ] + %d1 = getelementptr i32* %d, i32 %i + %dv = load i32* %d1 +; CHECK: %dv = phi i32 [ 82, %bb1 ], [ 4, %bb ] +; CHECK-NOT: load +; CHECK: ret i32 %dv + ret i32 %dv +} + |