summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2015-08-31 18:31:48 +0000
committerPhilip Reames <listmail@philipreames.com>2015-08-31 18:31:48 +0000
commitbb11d62a5a84877145c0e44cdd936e97d5b600e1 (patch)
tree5ea3282054f156399d202afbde3acbf025e59399 /llvm/lib/Analysis/LazyValueInfo.cpp
parentd3cc1678e806c4a6719bcfa4e92f372506af9b92 (diff)
downloadbcm5719-llvm-bb11d62a5a84877145c0e44cdd936e97d5b600e1.tar.gz
bcm5719-llvm-bb11d62a5a84877145c0e44cdd936e97d5b600e1.zip
[LazyValueInfo] Look through Phi nodes when trying to prove a predicate
If asked to prove a predicate about a value produced by a PHI node, LazyValueInfo was unable to do so even if the predicate was known to be true for each input to the PHI. This prevented JumpThreading from eliminating a provably redundant branch. The problematic test case looks something like this: ListNode *p = ...; while (p != null) { if (!p) return; x = g->x; // unrelated p = p->next } The null check at the top of the loop is redundant since the value of 'p' is null checked on entry to the loop and before executing the backedge. This resulted in us a) executing an extra null check per iteration and b) not being able to LICM unrelated loads after the check since we couldn't prove they would execute or that their dereferenceability wasn't effected by the null check on the first iteration. Differential Revision: http://reviews.llvm.org/D12383 llvm-svn: 246465
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp40
1 files changed, 35 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index abc0ac8ceaf..7fc3e5afe48 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1274,14 +1274,44 @@ LazyValueInfo::getPredicateAt(unsigned Pred, Value *V, Constant *C,
// than re-queried on each call. This would also allow us to merge the
// underlying lattice values to get more information.
if (CxtI) {
+ BasicBlock *BB = CxtI->getParent();
+
+ // Function entry or an unreachable block. Bail to avoid confusing
+ // analysis below.
+ pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
+ if (PI == PE)
+ return Unknown;
+
+ // If V is a PHI node in the same block as the context, we need to ask
+ // questions about the predicate as applied to the incoming value along
+ // each edge. This is useful for eliminating cases where the predicate is
+ // known along all incoming edges.
+ if (auto *PHI = dyn_cast<PHINode>(V))
+ if (PHI->getParent() == BB) {
+ Tristate Baseline = Unknown;
+ for (unsigned i = 0, e = PHI->getNumIncomingValues(); i < e; i++) {
+ Value *Incoming = PHI->getIncomingValue(i);
+ BasicBlock *PredBB = PHI->getIncomingBlock(i);
+ // Note that PredBB may be BB itself.
+ Tristate Result = getPredicateOnEdge(Pred, Incoming, C, PredBB, BB,
+ CxtI);
+
+ // Keep going as long as we've seen a consistent known result for
+ // all inputs.
+ Baseline = (i == 0) ? Result /* First iteration */
+ : (Baseline == Result ? Baseline : Unknown); /* All others */
+ if (Baseline == Unknown)
+ break;
+ }
+ if (Baseline != Unknown)
+ return Baseline;
+ }
+
// For a comparison where the V is outside this block, it's possible
// that we've branched on it before. Look to see if the value is known
// on all incoming edges.
- BasicBlock *BB = CxtI->getParent();
- pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
- if (PI != PE &&
- (!isa<Instruction>(V) ||
- cast<Instruction>(V)->getParent() != BB)) {
+ if (!isa<Instruction>(V) ||
+ cast<Instruction>(V)->getParent() != BB) {
// For predecessor edge, determine if the comparison is true or false
// on that edge. If they're all true or all false, we can conclude
// the value of the comparison in this block.
OpenPOWER on IntegriCloud