mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-30 15:22:41 +00:00
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
This commit is contained in:
parent
cc3d0eb483
commit
304076268a
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user