[llvm] r298217 - [JumpThreading] Perform phi-translation in SimplifyPartiallyRedundantLoad.
Xin Tong via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 19 08:30:54 PDT 2017
Author: trentxintong
Date: Sun Mar 19 10:30:53 2017
New Revision: 298217
URL: http://llvm.org/viewvc/llvm-project?rev=298217&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll
Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=298217&r1=298216&r2=298217&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Sun Mar 19 10:30:53 2017
@@ -931,6 +931,14 @@ bool JumpThreadingPass::ProcessImpliedCo
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::SimplifyPartiall
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::SimplifyPartiall
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::SimplifyPartiall
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);
Modified: llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll?rev=298217&r1=298216&r2=298217&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll (original)
+++ llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll Sun Mar 19 10:30:53 2017
@@ -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"}
More information about the llvm-commits
mailing list