[llvm] Update Fork to newest version of main (PR #131045)
Corey O'Malley via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 12 16:51:56 PDT 2025
https://github.com/omalley242 created https://github.com/llvm/llvm-project/pull/131045
None
>From 86d90f177cd021bb51f8c51553faff108ab0a233 Mon Sep 17 00:00:00 2001
From: Corey O'Malley <omalley242 at gmail.com>
Date: Mon, 10 Feb 2025 06:12:20 +0000
Subject: [PATCH 1/2] feat: adding extra comments to Loop Vectorization
Legality
---
.../Vectorize/LoopVectorizationLegality.cpp | 16 ++++++++++++++++
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 4 +++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 1c82fd174dbec..dcaef19d10c43 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -1579,8 +1579,12 @@ bool LoopVectorizationLegality::canVectorizeLoopNestCFG(
return Result;
}
+// ==FYP== Early Exit Check
bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
+ // ==FYP== Get Nodes that return to the loop header
BasicBlock *LatchBB = TheLoop->getLoopLatch();
+
+ // ==FYP== If no nodes return to the header we cannot vectorise (may be handled by the SLP Vectorizer)
if (!LatchBB) {
reportVectorizationFailure("Loop does not have a latch",
"Cannot vectorize early exit loop",
@@ -1588,6 +1592,8 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
return false;
}
+ // ==FYP== if there are any reduction variables or FixedOrderRecurrences Do Not Vectorize
+ // ==FYP== A reduction variable / Fixed Order Recurrance is a form of cross-iteration dependacy
if (Reductions.size() || FixedOrderRecurrences.size()) {
reportVectorizationFailure(
"Found reductions or recurrences in early-exit loop",
@@ -1596,17 +1602,24 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
return false;
}
+ // ==FYP== Get a list of all exiting blocks
+ // ==FYP (blocks that have control flow to reach a block outside the loop)
SmallVector<BasicBlock *, 8> ExitingBlocks;
TheLoop->getExitingBlocks(ExitingBlocks);
// Keep a record of all the exiting blocks.
SmallVector<const SCEVPredicate *, 4> Predicates;
for (BasicBlock *BB : ExitingBlocks) {
+ // ==FYP== Calculate the amount of times the backedge is taken before this exit block within the loop
+ // ==FYP== Using a set of predicates (assumptions) about the scalar evolution
const SCEV *EC =
PSE.getSE()->getPredicatedExitCount(TheLoop, BB, &Predicates);
+
+ // ==FYP== If the amount of iterations cannot be computed add this block to the UncountableExitingBlocks
if (isa<SCEVCouldNotCompute>(EC)) {
UncountableExitingBlocks.push_back(BB);
+ // ==FYP== check if the currently tested exiting block has two successors if it does not have 2
SmallVector<BasicBlock *, 2> Succs(successors(BB));
if (Succs.size() != 2) {
reportVectorizationFailure(
@@ -1616,6 +1629,8 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
return false;
}
+ // ==FYP== Look at the exit blocks of the exiting block currently being reviewed one of them must
+ // ==FYP== not be within the loop for it to be exiting, add the Exit block to the UncountableExitBlocks list
BasicBlock *ExitBlock;
if (!TheLoop->contains(Succs[0]))
ExitBlock = Succs[0];
@@ -1625,6 +1640,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
}
UncountableExitBlocks.push_back(ExitBlock);
} else
+ // ==FYP== If the Exiting block has a countable SCEV add it to the countableExitingBlocks list
CountableExitingBlocks.push_back(BB);
}
// We can safely ignore the predicates here because when vectorizing the loop
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index ad963137f1af1..7cc8944e583c7 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -10362,6 +10362,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
return false;
}
+ // ==FYP== May need to be modifed for allowing early exit loops
if (LVL.hasUncountableEarlyExit() && !EnableEarlyExitVectorization) {
reportVectorizationFailure("Auto-vectorization of loops with uncountable "
"early exit is not enabled",
@@ -10658,7 +10659,7 @@ bool LoopVectorizePass::processLoop(Loop *L) {
});
} else {
// If we decided that it is *legal* to vectorize the loop, then do it.
-
+ // ==FYP== Loop Vectorization Occurs here
VPlan &BestPlan = LVP.getPlanFor(VF.Width);
// Consider vectorizing the epilogue too if it's profitable.
VectorizationFactor EpilogueVF =
@@ -10816,6 +10817,7 @@ PreservedAnalyses LoopVectorizePass::run(Function &F,
BFI = nullptr;
if (PSI && PSI->hasProfileSummary())
BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
+ // ==FYP== Run the Transformation on the function
LoopVectorizeResult Result = runImpl(F);
if (!Result.MadeAnyChange)
return PreservedAnalyses::all();
>From 23c11985e3fd1ea32f533e3c5a5c7fb0a0d0f764 Mon Sep 17 00:00:00 2001
From: Corey O'Malley <omalley242 at gmail.com>
Date: Mon, 3 Mar 2025 10:05:10 +0000
Subject: [PATCH 2/2] feat: add partial vec counter
---
.../Vectorize/LoopVectorizationLegality.cpp | 49 +++++++++++++++++--
1 file changed, 45 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index dcaef19d10c43..4085fae1e9345 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -27,6 +27,7 @@
#include "llvm/IR/PatternMatch.h"
#include "llvm/Transforms/Utils/SizeOpts.h"
#include "llvm/Transforms/Vectorize/LoopVectorize.h"
+#include <string>
using namespace llvm;
using namespace PatternMatch;
@@ -1579,12 +1580,18 @@ bool LoopVectorizationLegality::canVectorizeLoopNestCFG(
return Result;
}
+static int PARTIAL_VECTORIZABLE_LOOP_COUNT = 0;
+static int TOTAL_LOOP_COUNT = 0;
+
// ==FYP== Early Exit Check
bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
+ TOTAL_LOOP_COUNT += 1;
+
// ==FYP== Get Nodes that return to the loop header
BasicBlock *LatchBB = TheLoop->getLoopLatch();
// ==FYP== If no nodes return to the header we cannot vectorise (may be handled by the SLP Vectorizer)
+ // ==FYP== Non-Partially vectorizable loop
if (!LatchBB) {
reportVectorizationFailure("Loop does not have a latch",
"Cannot vectorize early exit loop",
@@ -1594,16 +1601,18 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
// ==FYP== if there are any reduction variables or FixedOrderRecurrences Do Not Vectorize
// ==FYP== A reduction variable / Fixed Order Recurrance is a form of cross-iteration dependacy
+ // ==FYP== Partially Vectorizable
if (Reductions.size() || FixedOrderRecurrences.size()) {
reportVectorizationFailure(
"Found reductions or recurrences in early-exit loop",
"Cannot vectorize early exit loop with reductions or recurrences",
"RecurrencesInEarlyExitLoop", ORE, TheLoop);
+ PARTIAL_VECTORIZABLE_LOOP_COUNT += 1;
return false;
}
- // ==FYP== Get a list of all exiting blocks
- // ==FYP (blocks that have control flow to reach a block outside the loop)
+ // ==FYP== Get a list of all exiting blocks
+ // ==FYP== (blocks that have control flow to reach a block outside the loop)
SmallVector<BasicBlock *, 8> ExitingBlocks;
TheLoop->getExitingBlocks(ExitingBlocks);
@@ -1611,7 +1620,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
SmallVector<const SCEVPredicate *, 4> Predicates;
for (BasicBlock *BB : ExitingBlocks) {
// ==FYP== Calculate the amount of times the backedge is taken before this exit block within the loop
- // ==FYP== Using a set of predicates (assumptions) about the scalar evolution
+ // ==FYP== Using a set of predicates (assumptions) about the scalar evolution
const SCEV *EC =
PSE.getSE()->getPredicatedExitCount(TheLoop, BB, &Predicates);
@@ -1620,6 +1629,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
UncountableExitingBlocks.push_back(BB);
// ==FYP== check if the currently tested exiting block has two successors if it does not have 2
+ // ==FYP== Currently ignores early exit blocks with more than 1 branch
SmallVector<BasicBlock *, 2> Succs(successors(BB));
if (Succs.size() != 2) {
reportVectorizationFailure(
@@ -1629,7 +1639,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
return false;
}
- // ==FYP== Look at the exit blocks of the exiting block currently being reviewed one of them must
+ // ==FYP== Look at the exit blocks of the exiting block currently being reviewed one of them must
// ==FYP== not be within the loop for it to be exiting, add the Exit block to the UncountableExitBlocks list
BasicBlock *ExitBlock;
if (!TheLoop->contains(Succs[0]))
@@ -1649,32 +1659,41 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
// PSE.getSymbolicMaxBackedgeTakenCount() below.
Predicates.clear();
+ // ==FYP== With FlexVec we may be able to increase this
+ // ==FYPTODO== increase the amount of accepted early exits
// We only support one uncountable early exit.
if (getUncountableExitingBlocks().size() != 1) {
reportVectorizationFailure(
"Loop has too many uncountable exits",
"Cannot vectorize early exit loop with more than one early exit",
"TooManyUncountableEarlyExits", ORE, TheLoop);
+ PARTIAL_VECTORIZABLE_LOOP_COUNT += 1; // ==FYP COUNT==
return false;
}
// The only supported early exit loops so far are ones where the early
// exiting block is a unique predecessor of the latch block.
+ // ==FYP== only able to vectorize early exits that come before the latch block
+ // ==FYP== and are the only block before the latch block
BasicBlock *LatchPredBB = LatchBB->getUniquePredecessor();
if (LatchPredBB != getUncountableEarlyExitingBlock()) {
reportVectorizationFailure("Early exit is not the latch predecessor",
"Cannot vectorize early exit loop",
"EarlyExitNotLatchPredecessor", ORE, TheLoop);
+ PARTIAL_VECTORIZABLE_LOOP_COUNT += 1; // ==FYP COUNT==
return false;
}
// The latch block must have a countable exit.
+ // ==FYP== If we do not know the total amount of iterations we cannot vectorize
+ // ==FYPTODO== This is possible with FlexVec
if (isa<SCEVCouldNotCompute>(
PSE.getSE()->getPredicatedExitCount(TheLoop, LatchBB, &Predicates))) {
reportVectorizationFailure(
"Cannot determine exact exit count for latch block",
"Cannot vectorize early exit loop",
"UnknownLatchExitCountEarlyExitLoop", ORE, TheLoop);
+ PARTIAL_VECTORIZABLE_LOOP_COUNT += 1; // ==FYP COUNT==
return false;
}
assert(llvm::is_contained(CountableExitingBlocks, LatchBB) &&
@@ -1682,6 +1701,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
// Check to see if there are instructions that could potentially generate
// exceptions or have side-effects.
+ // ==FYP== Define function to check if an instruction is safe to speculate
auto IsSafeOperation = [](Instruction *I) -> bool {
switch (I->getOpcode()) {
case Instruction::Load:
@@ -1695,15 +1715,24 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
}
};
+
+ // ==FYP== Iterate Over each code block
for (auto *BB : TheLoop->blocks())
+ // ==FYP== Iterate Iterate over each instruction within each block
for (auto &I : *BB) {
+ // ==FYP== if there is a write to memory within the loop dont vectorize
+ // ==FYP== This should become possible with FlexVec
if (I.mayWriteToMemory()) {
// We don't support writes to memory.
reportVectorizationFailure(
"Writes to memory unsupported in early exit loops",
"Cannot vectorize early exit loop with writes to memory",
"WritesInEarlyExitLoop", ORE, TheLoop);
+ PARTIAL_VECTORIZABLE_LOOP_COUNT += 1; // ==FYP COUNT==
return false;
+
+ // ==FYP== if the Instruction is unsafe dont attempt to vectorize
+ // ==FYP== Not partially vectorizable
} else if (!IsSafeOperation(&I)) {
reportVectorizationFailure("Early exit loop contains operations that "
"cannot be speculatively executed",
@@ -1719,12 +1748,17 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
// TODO: Handle loops that may fault.
Predicates.clear();
+
+ // ==FYP== Return true if the loop cannot fault on any iteration and only
+ // ==FYP== contains read-only memory accesses.
+ // ==FYP== Should be partially vectorizable if we use valid faulting instructions
if (!isDereferenceableReadOnlyLoop(TheLoop, PSE.getSE(), DT, AC,
&Predicates)) {
reportVectorizationFailure(
"Loop may fault",
"Cannot vectorize potentially faulting early exit loop",
"PotentiallyFaultingEarlyExitLoop", ORE, TheLoop);
+ PARTIAL_VECTORIZABLE_LOOP_COUNT += 1;
return false;
}
@@ -1801,6 +1835,8 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
HasUncountableEarlyExit = false;
if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount())) {
HasUncountableEarlyExit = true;
+ // ==FYP== check early exit legality
+ // Report the Partial Vectorization count here
if (!isVectorizableEarlyExitLoop()) {
UncountableExitingBlocks.clear();
HasUncountableEarlyExit = false;
@@ -1809,6 +1845,11 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
else
return false;
}
+
+ // ==FYP== Report
+ auto count_string = std::to_string(PARTIAL_VECTORIZABLE_LOOP_COUNT);
+ reportVectorizationFailure("FYP Partially Vectorizable Early Exit Count: " + count_string, "FYP", ORE, TheLoop);
+ // ==FYP==
}
// Go over each instruction and look at memory deps.
More information about the llvm-commits
mailing list