Skip to content

Commit

Permalink
[SCEV][NFC] Introduce isBasicBlockEntryGuardedByCond
Browse files Browse the repository at this point in the history
Currently, we have `isLoopEntryGuardedByCond` method in SCEV, which
checks that some fact is true if we enter the loop. In fact, this is just a
particular case of more general concept `isBasicBlockEntryGuardedByCond`
applied to given loop's header. In fact, the logic if this code is largely
independent on the given loop and only cares code above it.

This patch makes this generalization. Now we can query it for any block,
and `isBasicBlockEntryGuardedByCond` is just a particular case.

Differential Revision: https://reviews.llvm.org/D87828
Reviewed By: fhahn
  • Loading branch information
xortator committed Sep 29, 2020
1 parent eb9f7c2 commit 9100bd7
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 21 deletions.
6 changes: 6 additions & 0 deletions llvm/include/llvm/Analysis/ScalarEvolution.h
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,12 @@ class ScalarEvolution {
bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS);

/// Test whether entry to the basic block is protected by a conditional
/// between LHS and RHS.
bool isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
ICmpInst::Predicate Pred, const SCEV *LHS,
const SCEV *RHS);

/// Test whether the backedge of the loop is protected by a conditional
/// between LHS and RHS. This is used to eliminate casts.
bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
Expand Down
53 changes: 32 additions & 21 deletions llvm/lib/Analysis/ScalarEvolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9492,24 +9492,14 @@ ScalarEvolution::isLoopBackedgeGuardedByCond(const Loop *L,
return false;
}

bool
ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS) {
// Interpret a null as meaning no loop, where there is obviously no guard
// (interprocedural conditions notwithstanding).
if (!L) return false;

bool ScalarEvolution::isBasicBlockEntryGuardedByCond(const BasicBlock *BB,
ICmpInst::Predicate Pred,
const SCEV *LHS,
const SCEV *RHS) {
if (VerifyIR)
assert(!verifyFunction(*L->getHeader()->getParent(), &dbgs()) &&
assert(!verifyFunction(*BB->getParent(), &dbgs()) &&
"This cannot be done on broken IR!");

// Both LHS and RHS must be available at loop entry.
assert(isAvailableAtLoopEntry(LHS, L) &&
"LHS is not available at Loop Entry");
assert(isAvailableAtLoopEntry(RHS, L) &&
"RHS is not available at Loop Entry");

if (isKnownViaNonRecursiveReasoning(Pred, LHS, RHS))
return true;

Expand Down Expand Up @@ -9566,13 +9556,17 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
return false;
};

// Starting at the loop predecessor, climb up the predecessor chain, as long
// Starting at the block's predecessor, climb up the predecessor chain, as long
// as there are predecessors that can be found that have unique successors
// leading to the original header.
for (std::pair<const BasicBlock *, const BasicBlock *> Pair(
L->getLoopPredecessor(), L->getHeader());
// leading to the original block.
const Loop *ContainingLoop = LI.getLoopFor(BB);
const BasicBlock *PredBB;
if (ContainingLoop && ContainingLoop->getHeader() == BB)
PredBB = ContainingLoop->getLoopPredecessor();
else
PredBB = BB->getSinglePredecessor();
for (std::pair<const BasicBlock *, const BasicBlock *> Pair(PredBB, BB);
Pair.first; Pair = getPredecessorWithUniqueSuccessorForBB(Pair.first)) {

if (ProveViaGuard(Pair.first))
return true;

Expand All @@ -9592,7 +9586,7 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
if (!AssumeVH)
continue;
auto *CI = cast<CallInst>(AssumeVH);
if (!DT.dominates(CI, L->getHeader()))
if (!DT.dominates(CI, BB))
continue;

if (ProveViaCond(CI->getArgOperand(0), false))
Expand All @@ -9602,6 +9596,23 @@ ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
return false;
}

bool ScalarEvolution::isLoopEntryGuardedByCond(const Loop *L,
ICmpInst::Predicate Pred,
const SCEV *LHS,
const SCEV *RHS) {
// Interpret a null as meaning no loop, where there is obviously no guard
// (interprocedural conditions notwithstanding).
if (!L)
return false;

// Both LHS and RHS must be available at loop entry.
assert(isAvailableAtLoopEntry(LHS, L) &&
"LHS is not available at Loop Entry");
assert(isAvailableAtLoopEntry(RHS, L) &&
"RHS is not available at Loop Entry");
return isBasicBlockEntryGuardedByCond(L->getHeader(), Pred, LHS, RHS);
}

bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS,
const SCEV *RHS,
const Value *FoundCondValue, bool Inverse) {
Expand Down

0 comments on commit 9100bd7

Please sign in to comment.