1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

[JumpThreading] Perform phi-translation in SimplifyPartiallyRedundantLoad.

Summary:
In case we are loading on a phi-load in SimplifyPartiallyRedundantLoad.
Try to phi translate it into incoming values in the predecessors before
we search for available loads.

This needs https://reviews.llvm.org/D30524

Reviewers: davide, sanjoy, efriedma, dberlin, rengolin

Reviewed By: dberlin

Subscribers: junbuml, llvm-commits

Differential Revision: https://reviews.llvm.org/D30543

llvm-svn: 298217
This commit is contained in:
Xin Tong 2017-03-19 15:30:53 +00:00
parent 7ed0553795
commit 92773d49ef
2 changed files with 67 additions and 17 deletions

View File

@ -931,6 +931,14 @@ bool JumpThreadingPass::ProcessImpliedCondition(BasicBlock *BB) {
return false;
}
/// Return true if Op is an instruction defined in the given block.
static bool isOpDefinedInBlock(Value *Op, BasicBlock *BB) {
if (Instruction *OpInst = dyn_cast<Instruction>(Op))
if (OpInst->getParent() == BB)
return true;
return false;
}
/// SimplifyPartiallyRedundantLoad - If LI is an obviously partially redundant
/// load instruction, eliminate it by replacing it with a PHI node. This is an
/// important optimization that encourages jump threading, and needs to be run
@ -953,11 +961,10 @@ bool JumpThreadingPass::SimplifyPartiallyRedundantLoad(LoadInst *LI) {
Value *LoadedPtr = LI->getOperand(0);
// If the loaded operand is defined in the LoadBB, it can't be available.
// TODO: Could do simple PHI translation, that would be fun :)
if (Instruction *PtrOp = dyn_cast<Instruction>(LoadedPtr))
if (PtrOp->getParent() == LoadBB)
return false;
// If the loaded operand is defined in the LoadBB and its not a phi,
// it can't be available in predecessors.
if (isOpDefinedInBlock(LoadedPtr, LoadBB) && !isa<PHINode>(LoadedPtr))
return false;
// Scan a few instructions up from the load, to see if it is obviously live at
// the entry to its block.
@ -1008,23 +1015,31 @@ bool JumpThreadingPass::SimplifyPartiallyRedundantLoad(LoadInst *LI) {
if (!PredsScanned.insert(PredBB).second)
continue;
// Scan the predecessor to see if the value is available in the pred.
BBIt = PredBB->end();
unsigned NumScanedInst = 0;
Value *PredAvailable = FindAvailableLoadedValue(
LI, PredBB, BBIt, DefMaxInstsToScan, AA, &IsLoadCSE, &NumScanedInst);
Value *PredAvailable = nullptr;
// NOTE: We don't CSE load that is volatile or anything stronger than
// unordered, that should have been checked when we entered the function.
assert(LI->isUnordered() && "Attempting to CSE volatile or atomic loads");
// If this is a load on a phi pointer, phi-translate it and search
// for available load/store to the pointer in predecessors.
Value *Ptr = LoadedPtr->DoPHITranslation(LoadBB, PredBB);
PredAvailable = FindAvailablePtrLoadStore(
Ptr, LI->getType(), LI->isAtomic(), PredBB, BBIt, DefMaxInstsToScan,
nullptr, &IsLoadCSE, &NumScanedInst);
// If PredBB has a single predecessor, continue scanning through the single
// predecessor.
// If PredBB has a single predecessor, continue scanning through the
// single precessor.
BasicBlock *SinglePredBB = PredBB;
while (!PredAvailable && SinglePredBB && BBIt == SinglePredBB->begin() &&
NumScanedInst < DefMaxInstsToScan) {
SinglePredBB = SinglePredBB->getSinglePredecessor();
if (SinglePredBB) {
BBIt = SinglePredBB->end();
PredAvailable = FindAvailableLoadedValue(
LI, SinglePredBB, BBIt, (DefMaxInstsToScan - NumScanedInst), AA,
&IsLoadCSE, &NumScanedInst);
PredAvailable = FindAvailablePtrLoadStore(
Ptr, LI->getType(), LI->isAtomic(), SinglePredBB, BBIt,
(DefMaxInstsToScan - NumScanedInst), nullptr, &IsLoadCSE,
&NumScanedInst);
}
}
@ -1087,10 +1102,10 @@ bool JumpThreadingPass::SimplifyPartiallyRedundantLoad(LoadInst *LI) {
if (UnavailablePred) {
assert(UnavailablePred->getTerminator()->getNumSuccessors() == 1 &&
"Can't handle critical edge here!");
LoadInst *NewVal =
new LoadInst(LoadedPtr, LI->getName() + ".pr", false,
LI->getAlignment(), LI->getOrdering(), LI->getSynchScope(),
UnavailablePred->getTerminator());
LoadInst *NewVal = new LoadInst(
LoadedPtr->DoPHITranslation(LoadBB, UnavailablePred),
LI->getName() + ".pr", false, LI->getAlignment(), LI->getOrdering(),
LI->getSynchScope(), UnavailablePred->getTerminator());
NewVal->setDebugLoc(LI->getDebugLoc());
if (AATags)
NewVal->setAAMetadata(AATags);

View File

@ -490,6 +490,41 @@ declare void @fn2(i64)
declare void @fn3(i64)
; Make sure we phi-translate and make the partially redundant load in
; merge fully redudant and then we can jump-thread the block with the
; store.
;
; CHECK-LABEL: define i32 @phi_translate_partial_redundant_loads(i32, i32*, i32*
; CHECK: merge.thread:
; CHECK: store
; CHECK: br label %left_x
;
; CHECK: left_x:
; CHECK-NEXT: ret i32 20
define i32 @phi_translate_partial_redundant_loads(i32, i32*, i32*) {
%cmp0 = icmp ne i32 %0, 0
br i1 %cmp0, label %left, label %right
left:
store i32 1, i32* %1, align 4
br label %merge
right:
br label %merge
merge:
%phiptr = phi i32* [ %1, %left ], [ %2, %right ]
%newload = load i32, i32* %phiptr, align 4
%cmp1 = icmp slt i32 %newload, 5
br i1 %cmp1, label %left_x, label %right_x
left_x:
ret i32 20
right_x:
ret i32 10
}
!0 = !{!3, !3, i64 0}
!1 = !{!"omnipotent char", !2}
!2 = !{!"Simple C/C++ TBAA"}