[llvm] [LoopVectorize] Add support for vectorisation of simple early exit loops (PR #88385)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 24 02:14:01 PDT 2024
================
@@ -8592,6 +8595,63 @@ ScalarEvolution::BackedgeTakenInfo::getExact(const Loop *L, ScalarEvolution *SE,
return SE->getUMinFromMismatchedTypes(Ops, /* Sequential */ true);
}
+void ScalarEvolution::BackedgeTakenInfo::getCountableExitingBlocks(
+ const Loop *L, ScalarEvolution *SE,
+ SmallVector<BasicBlock *, 4> *Blocks) const {
+ // All exiting blocks we have collected must dominate the only backedge.
+ const BasicBlock *Latch = L->getLoopLatch();
+ if (!Latch || !hasAnyInfo())
+ return;
+
+ for (const auto &ENT : ExitNotTaken) {
+ const SCEV *BECount = ENT.ExactNotTaken;
+ if (BECount == SE->getCouldNotCompute())
+ continue;
+ Blocks->push_back(ENT.ExitingBlock);
+ }
+
+ return;
+}
+
+const SCEV *ScalarEvolution::BackedgeTakenInfo::getSpeculative(
+ const Loop *L, ScalarEvolution *SE,
+ SmallVector<const SCEVPredicate *, 4> *Preds) const {
+ // All exiting blocks we have collected must dominate the only backedge.
+ const BasicBlock *Latch = L->getLoopLatch();
+ if (!Latch || !hasAnyInfo())
+ return SE->getCouldNotCompute();
+
+ // All exiting blocks we have gathered dominate loop's latch, so speculative
+ // trip count is simply a minimum out of all these calculated exit counts.
+ SmallVector<const SCEV *, 2> Ops;
+ bool FoundLatch = false;
+ for (const auto &ENT : ExitNotTaken) {
+ const SCEV *BECount = ENT.ExactNotTaken;
+ if (BECount == SE->getCouldNotCompute())
+ continue;
+
+ assert(SE->DT.dominates(ENT.ExitingBlock, Latch) &&
+ "We should only have known counts for exiting blocks that dominate "
+ "latch!");
+ Ops.push_back(BECount);
+ if (Preds)
+ for (const auto *P : ENT.Predicates)
+ Preds->push_back(P);
+ assert((Preds || ENT.hasAlwaysTruePredicate()) &&
+ "Predicate should be always true!");
+ if (ENT.ExitingBlock == Latch)
+ FoundLatch = true;
+ }
+
+ if (!FoundLatch)
+ return SE->getCouldNotCompute();
+
+ // If an earlier exit exits on the first iteration (exit count zero), then
+ // a later poison exit count should not propagate into the result. This are
+ // exactly the semantics provided by umin_seq.
+ return SE->getUMinFromMismatchedTypes(Ops, /* Sequential */ true);
+}
----------------
david-arm wrote:
I've tried posting a new commit that teaches getPredicatedBackedgeTakenCount to use a version of getSymbolicMax that accepts predicates, provided we have an exact count for the latch. Hopefully this makes better reuse of the code.
https://github.com/llvm/llvm-project/pull/88385
More information about the llvm-commits
mailing list