teach memdep to do trivial PHI translation of GEPs. More to

come.

llvm-svn: 89979
This commit is contained in:
Chris Lattner 2009-11-27 00:07:37 +00:00
parent 9bd2136ca3
commit 4c88e814b8
2 changed files with 69 additions and 2 deletions

View File

@ -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;
}

View File

@ -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
}