[llvm-branch-commits] [llvm] 10ae227 - Revert "[LoopUnroll] Remove `computeUnrollCount()`'s return value (#184529)"
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Mar 17 07:58:01 PDT 2026
Author: Justin Fargnoli
Date: 2026-03-17T07:57:57-07:00
New Revision: 10ae227f523096905386976455b5d68d7f6f4519
URL: https://github.com/llvm/llvm-project/commit/10ae227f523096905386976455b5d68d7f6f4519
DIFF: https://github.com/llvm/llvm-project/commit/10ae227f523096905386976455b5d68d7f6f4519.diff
LOG: Revert "[LoopUnroll] Remove `computeUnrollCount()`'s return value (#184529)"
This reverts commit c9a2f0b72c08c4ead0d359b2d7aa7ea34708cc5a.
Added:
Modified:
llvm/include/llvm/Transforms/Utils/UnrollLoop.h
llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
llvm/lib/Transforms/Utils/LoopUnroll.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/Utils/UnrollLoop.h b/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
index 6171f3391cb2d..3cff29629207e 100644
--- a/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -124,15 +124,19 @@ LLVM_ABI MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name);
// returned.
LLVM_ABI MDNode *getUnrollMetadataForLoop(const Loop *L, StringRef Name);
-struct UnrollPragmaInfo {
- UnrollPragmaInfo(const Loop *L);
- const bool UserUnrollCount;
- const bool PragmaFullUnroll;
- const unsigned PragmaCount;
- const bool PragmaEnableUnroll;
- const bool PragmaRuntimeUnrollDisable;
- const bool ExplicitUnroll;
-};
+// Returns true if the loop has an unroll(full) pragma.
+LLVM_ABI bool hasUnrollFullPragma(const Loop *L);
+
+// Returns true if the loop has an unroll(enable) pragma. This metadata is used
+// for both "#pragma unroll" and "#pragma clang loop unroll(enable)" directives.
+LLVM_ABI bool hasUnrollEnablePragma(const Loop *L);
+
+// Returns true if the loop has an runtime unroll(disable) pragma.
+LLVM_ABI bool hasRuntimeUnrollDisablePragma(const Loop *L);
+
+// If loop has an unroll_count pragma return the (necessarily
+// positive) value from the pragma. Otherwise return 0.
+LLVM_ABI unsigned unrollCountPragmaValue(const Loop *L);
LLVM_ABI TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences(
Loop *L, ScalarEvolution &SE, const TargetTransformInfo &TTI,
@@ -172,7 +176,7 @@ class UnrollCostEstimator {
unsigned CountOverwrite = 0) const;
};
-LLVM_ABI void
+LLVM_ABI bool
computeUnrollCount(Loop *L, const TargetTransformInfo &TTI, DominatorTree &DT,
LoopInfo *LI, AssumptionCache *AC, ScalarEvolution &SE,
const SmallPtrSetImpl<const Value *> &EphValues,
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
index 9a9d0c0fda5e4..a91922a95a306 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
@@ -269,10 +269,11 @@ void AMDGPUTTIImpl::getUnrollingPreferences(
if (L->isInnermost() && BB->size() < UnrollMaxBlockToAnalyze)
UP.MaxIterationsCountToAnalyze = 32;
}
+ const unsigned PragmaCount = unrollCountPragmaValue(L);
+ const bool PragmaEnableUnroll = hasUnrollEnablePragma(L);
// If a user provided an explicit unroll pragma (with or without count),
// override expensive trip count checks
- UnrollPragmaInfo PInfo(L);
- if (PInfo.PragmaEnableUnroll || PInfo.PragmaCount > 0)
+ if (PragmaEnableUnroll || PragmaCount > 0)
UP.AllowExpensiveTripCount = true;
}
diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
index d346a81c149e3..a382bf03b0a8d 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp
@@ -153,9 +153,18 @@ static bool computeUnrollAndJamCount(
// unrolling we leave to the unroller. This uses UP.Threshold /
// UP.PartialThreshold / UP.MaxCount to come up with sensible loop values.
// We have already checked that the loop has no unroll.* pragmas.
- computeUnrollCount(L, TTI, DT, LI, AC, SE, EphValues, ORE, OuterTripCount,
- /*MaxTripCount*/ 0, /*MaxOrZero*/ false, OuterTripMultiple,
- OuterUCE, UP, PP);
+ bool ExplicitUnroll =
+ computeUnrollCount(L, TTI, DT, LI, AC, SE, EphValues, ORE, OuterTripCount,
+ /*MaxTripCount*/ 0, /*MaxOrZero*/ false,
+ OuterTripMultiple, OuterUCE, UP, PP);
+ if (ExplicitUnroll) {
+ // If the user explicitly set the loop as unrolled, dont UnJ it. Leave it
+ // for the unroller instead.
+ LLVM_DEBUG(dbgs() << "Won't unroll-and-jam; explicit count set by "
+ "computeUnrollCount\n");
+ UP.Count = 0;
+ return false;
+ }
// Override with any explicit Count from the "unroll-and-jam-count" option.
bool UserUnrollCount = UnrollAndJamCount.getNumOccurrences() > 0;
diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
index 5142f90ac7079..18003c21a0e8d 100644
--- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
@@ -329,6 +329,16 @@ struct EstimatedUnrollCost {
unsigned RolledDynamicCost;
};
+struct PragmaInfo {
+ PragmaInfo(bool UUC, bool PFU, unsigned PC, bool PEU)
+ : UserUnrollCount(UUC), PragmaFullUnroll(PFU), PragmaCount(PC),
+ PragmaEnableUnroll(PEU) {}
+ const bool UserUnrollCount;
+ const bool PragmaFullUnroll;
+ const unsigned PragmaCount;
+ const bool PragmaEnableUnroll;
+};
+
} // end anonymous namespace
/// Figure out if the loop is worth full unrolling.
@@ -741,46 +751,6 @@ uint64_t UnrollCostEstimator::getUnrolledLoopSize(
return static_cast<uint64_t>(LS - UP.BEInsns) * UP.Count + UP.BEInsns;
}
-// Returns true if the loop has an unroll(full) pragma.
-static bool hasUnrollFullPragma(const Loop *L) {
- return getUnrollMetadataForLoop(L, "llvm.loop.unroll.full");
-}
-
-// Returns true if the loop has an unroll(enable) pragma. This metadata is used
-// for both "#pragma unroll" and "#pragma clang loop unroll(enable)" directives.
-static bool hasUnrollEnablePragma(const Loop *L) {
- return getUnrollMetadataForLoop(L, "llvm.loop.unroll.enable");
-}
-
-// Returns true if the loop has an runtime unroll(disable) pragma.
-static bool hasRuntimeUnrollDisablePragma(const Loop *L) {
- return getUnrollMetadataForLoop(L, "llvm.loop.unroll.runtime.disable");
-}
-
-// If loop has an unroll_count pragma return the (necessarily
-// positive) value from the pragma. Otherwise return 0.
-static unsigned unrollCountPragmaValue(const Loop *L) {
- MDNode *MD = getUnrollMetadataForLoop(L, "llvm.loop.unroll.count");
- if (MD) {
- assert(MD->getNumOperands() == 2 &&
- "Unroll count hint metadata should have two operands.");
- unsigned Count =
- mdconst::extract<ConstantInt>(MD->getOperand(1))->getZExtValue();
- assert(Count >= 1 && "Unroll count must be positive.");
- return Count;
- }
- return 0;
-}
-
-UnrollPragmaInfo::UnrollPragmaInfo(const Loop *L)
- : UserUnrollCount(UnrollCount.getNumOccurrences() > 0),
- PragmaFullUnroll(hasUnrollFullPragma(L)),
- PragmaCount(unrollCountPragmaValue(L)),
- PragmaEnableUnroll(hasUnrollEnablePragma(L)),
- PragmaRuntimeUnrollDisable(hasRuntimeUnrollDisablePragma(L)),
- ExplicitUnroll(PragmaCount > 0 || PragmaFullUnroll ||
- PragmaEnableUnroll || UserUnrollCount) {}
-
// Computes the boosting factor for complete unrolling.
// If fully unrolling the loop would save a lot of RolledDynamicCost, it would
// be beneficial to fully unroll the loop even if unrolledcost is large. We
@@ -799,7 +769,7 @@ static unsigned getFullUnrollBoostingFactor(const EstimatedUnrollCost &Cost,
}
static std::optional<unsigned>
-shouldPragmaUnroll(Loop *L, const UnrollPragmaInfo &PInfo,
+shouldPragmaUnroll(Loop *L, const PragmaInfo &PInfo,
const unsigned TripMultiple, const unsigned TripCount,
unsigned MaxTripCount, const UnrollCostEstimator UCE,
const TargetTransformInfo::UnrollingPreferences &UP) {
@@ -971,6 +941,7 @@ shouldPartialUnroll(const unsigned LoopSize, const unsigned TripCount,
return count;
}
+// Returns true if unroll count was set explicitly.
// Calculates unroll count and writes it to UP.Count.
// Unless IgnoreUser is true, will also use metadata and command-line options
// that are specific to the LoopUnroll pass (which, for instance, are
@@ -978,7 +949,7 @@ shouldPartialUnroll(const unsigned LoopSize, const unsigned TripCount,
// FIXME: This function is used by LoopUnroll and LoopUnrollAndJam, but consumes
// many LoopUnroll-specific options. The shared functionality should be
// refactored into it own function.
-void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
+bool llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
DominatorTree &DT, LoopInfo *LI,
AssumptionCache *AC, ScalarEvolution &SE,
const SmallPtrSetImpl<const Value *> &EphValues,
@@ -997,22 +968,31 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
<< (MaxOrZero ? " (MaxOrZero)" : "")
<< ", TripMultiple=" << TripMultiple << "\n");
- UnrollPragmaInfo PInfo(L);
+ const bool UserUnrollCount = UnrollCount.getNumOccurrences() > 0;
+ const bool PragmaFullUnroll = hasUnrollFullPragma(L);
+ const unsigned PragmaCount = unrollCountPragmaValue(L);
+ const bool PragmaEnableUnroll = hasUnrollEnablePragma(L);
+
+ const bool ExplicitUnroll = PragmaCount > 0 || PragmaFullUnroll ||
+ PragmaEnableUnroll || UserUnrollCount;
+
LLVM_DEBUG({
- if (PInfo.ExplicitUnroll) {
+ if (ExplicitUnroll) {
dbgs().indent(1) << "Explicit unroll requested:";
- if (PInfo.UserUnrollCount)
+ if (UserUnrollCount)
dbgs() << " user-count";
- if (PInfo.PragmaFullUnroll)
+ if (PragmaFullUnroll)
dbgs() << " pragma-full";
- if (PInfo.PragmaCount > 0)
- dbgs() << " pragma-count(" << PInfo.PragmaCount << ")";
- if (PInfo.PragmaEnableUnroll)
+ if (PragmaCount > 0)
+ dbgs() << " pragma-count(" << PragmaCount << ")";
+ if (PragmaEnableUnroll)
dbgs() << " pragma-enable";
dbgs() << "\n";
}
});
+ PragmaInfo PInfo(UserUnrollCount, PragmaFullUnroll, PragmaCount,
+ PragmaEnableUnroll);
// Use an explicit peel count that has been specified for testing. In this
// case it's not permitted to also specify an explicit unroll count.
if (PP.PeelCount) {
@@ -1024,7 +1004,7 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
<< "Using explicit peel count: " << PP.PeelCount << ".\n");
UP.Count = 1;
UP.Runtime = false;
- return;
+ return true;
}
// Check for explicit Count.
// 1st priority is unroll count set by "unroll-count" option.
@@ -1034,14 +1014,14 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
MaxTripCount, UCE, UP)) {
UP.Count = *UnrollFactor;
- if (PInfo.UserUnrollCount || (PInfo.PragmaCount > 0)) {
+ if (UserUnrollCount || (PragmaCount > 0)) {
UP.AllowExpensiveTripCount = true;
UP.Force = true;
}
- UP.Runtime |= (PInfo.PragmaCount > 0);
- return;
+ UP.Runtime |= (PragmaCount > 0);
+ return ExplicitUnroll;
} else {
- if (PInfo.ExplicitUnroll && TripCount != 0) {
+ if (ExplicitUnroll && TripCount != 0) {
// If the loop has an unrolling pragma, we want to be more aggressive with
// unrolling limits. Set thresholds to at least the PragmaUnrollThreshold
// value which is larger than the default limits.
@@ -1060,7 +1040,7 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
if (auto UnrollFactor = shouldFullUnroll(L, TTI, DT, SE, EphValues,
TripCount, UCE, UP)) {
UP.Count = *UnrollFactor;
- return;
+ return ExplicitUnroll;
}
}
@@ -1083,7 +1063,7 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
if (auto UnrollFactor = shouldFullUnroll(L, TTI, DT, SE, EphValues,
MaxTripCount, UCE, UP)) {
UP.Count = *UnrollFactor;
- return;
+ return ExplicitUnroll;
}
}
@@ -1095,13 +1075,13 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
<< "Peeling with count: " << PP.PeelCount << ".\n");
UP.Runtime = false;
UP.Count = 1;
- return;
+ return ExplicitUnroll;
}
// Before starting partial unrolling, set up.partial to true,
// if user explicitly asked for unrolling
if (TripCount)
- UP.Partial |= PInfo.ExplicitUnroll;
+ UP.Partial |= ExplicitUnroll;
// 6th priority is partial unrolling.
// Try partial unroll only when TripCount could be statically calculated.
@@ -1109,7 +1089,7 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
if (auto UnrollFactor = shouldPartialUnroll(LoopSize, TripCount, UCE, UP)) {
UP.Count = *UnrollFactor;
- if ((PInfo.PragmaFullUnroll || PInfo.PragmaEnableUnroll) && TripCount &&
+ if ((PragmaFullUnroll || PragmaEnableUnroll) && TripCount &&
UP.Count != TripCount)
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE,
@@ -1121,7 +1101,7 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
if (UP.PartialThreshold != NoThreshold) {
if (UP.Count == 0) {
- if (PInfo.PragmaEnableUnroll)
+ if (PragmaEnableUnroll)
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE,
"UnrollAsDirectedTooLarge",
@@ -1132,11 +1112,11 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
});
}
}
- return;
+ return ExplicitUnroll;
}
assert(TripCount == 0 &&
"All cases when TripCount is constant should be covered here.");
- if (PInfo.PragmaFullUnroll)
+ if (PragmaFullUnroll)
ORE->emit([&]() {
return OptimizationRemarkMissed(
DEBUG_TYPE, "CantFullUnrollAsDirectedRuntimeTripCount",
@@ -1149,11 +1129,11 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
// 7th priority is runtime unrolling.
LLVM_DEBUG(dbgs().indent(1) << "Trying runtime unroll...\n");
// Don't unroll a runtime trip count loop when it is disabled.
- if (PInfo.PragmaRuntimeUnrollDisable) {
+ if (hasRuntimeUnrollDisablePragma(L)) {
LLVM_DEBUG(dbgs().indent(2)
<< "Not runtime unrolling: disabled by pragma.\n");
UP.Count = 0;
- return;
+ return false;
}
// Don't unroll a small upper bound loop unless user or TTI asked to do so.
@@ -1162,26 +1142,25 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
<< "Not runtime unrolling: max trip count " << MaxTripCount
<< " is small (< " << UP.MaxUpperBound << ") and not forced.\n");
UP.Count = 0;
- return;
+ return false;
}
// Check if the runtime trip count is too small when profile is available.
if (L->getHeader()->getParent()->hasProfileData()) {
if (auto ProfileTripCount = getLoopEstimatedTripCount(L)) {
if (*ProfileTripCount < FlatLoopTripCountThreshold)
- return;
+ return false;
else
UP.AllowExpensiveTripCount = true;
}
}
- UP.Runtime |= PInfo.PragmaEnableUnroll || PInfo.PragmaCount > 0 ||
- PInfo.UserUnrollCount;
+ UP.Runtime |= PragmaEnableUnroll || PragmaCount > 0 || UserUnrollCount;
if (!UP.Runtime) {
LLVM_DEBUG(dbgs().indent(2)
<< "Will not try to unroll loop with runtime trip count "
<< "because -unroll-runtime not given\n");
UP.Count = 0;
- return;
+ return false;
}
if (UP.Count == 0)
UP.Count = UP.DefaultUnrollRuntimeCount;
@@ -1209,7 +1188,7 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
using namespace ore;
- if (PInfo.PragmaCount > 0 && !UP.AllowRemainder)
+ if (PragmaCount > 0 && !UP.AllowRemainder)
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE,
"DifferentUnrollCountFromDirected",
@@ -1234,7 +1213,7 @@ void llvm::computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
<< "Runtime unrolling with count: " << UP.Count << "\n");
if (UP.Count < 2)
UP.Count = 0;
- return;
+ return ExplicitUnroll;
}
static LoopUnrollResult
@@ -1385,8 +1364,9 @@ tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution &SE,
// computeUnrollCount() decides whether it is beneficial to use upper bound to
// fully unroll the loop.
- computeUnrollCount(L, TTI, DT, LI, &AC, SE, EphValues, &ORE, TripCount,
- MaxTripCount, MaxOrZero, TripMultiple, UCE, UP, PP);
+ bool IsCountSetExplicitly =
+ computeUnrollCount(L, TTI, DT, LI, &AC, SE, EphValues, &ORE, TripCount,
+ MaxTripCount, MaxOrZero, TripMultiple, UCE, UP, PP);
if (!UP.Count) {
LLVM_DEBUG(dbgs().indent(1)
<< "Not unrolling: no viable strategy found.\n");
@@ -1476,8 +1456,7 @@ tryToUnrollLoop(Loop *L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution &SE,
// If loop has an unroll count pragma or unrolled by explicitly set count
// mark loop as unrolled to prevent unrolling beyond that requested.
- if (UnrollResult != LoopUnrollResult::FullyUnrolled &&
- UnrollPragmaInfo(L).ExplicitUnroll)
+ if (UnrollResult != LoopUnrollResult::FullyUnrolled && IsCountSetExplicitly)
L->setLoopAlreadyUnrolled();
return UnrollResult;
diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
index 6a2ccbea996bf..718ebafb25b6b 100644
--- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
@@ -1261,6 +1261,37 @@ MDNode *llvm::getUnrollMetadataForLoop(const Loop *L, StringRef Name) {
return nullptr;
}
+// Returns true if the loop has an unroll(full) pragma.
+bool llvm::hasUnrollFullPragma(const Loop *L) {
+ return getUnrollMetadataForLoop(L, "llvm.loop.unroll.full");
+}
+
+// Returns true if the loop has an unroll(enable) pragma. This metadata is used
+// for both "#pragma unroll" and "#pragma clang loop unroll(enable)" directives.
+bool llvm::hasUnrollEnablePragma(const Loop *L) {
+ return getUnrollMetadataForLoop(L, "llvm.loop.unroll.enable");
+}
+
+// Returns true if the loop has an runtime unroll(disable) pragma.
+bool llvm::hasRuntimeUnrollDisablePragma(const Loop *L) {
+ return getUnrollMetadataForLoop(L, "llvm.loop.unroll.runtime.disable");
+}
+
+// If loop has an unroll_count pragma return the (necessarily
+// positive) value from the pragma. Otherwise return 0.
+unsigned llvm::unrollCountPragmaValue(const Loop *L) {
+ MDNode *MD = getUnrollMetadataForLoop(L, "llvm.loop.unroll.count");
+ if (MD) {
+ assert(MD->getNumOperands() == 2 &&
+ "Unroll count hint metadata should have two operands.");
+ unsigned Count =
+ mdconst::extract<ConstantInt>(MD->getOperand(1))->getZExtValue();
+ assert(Count >= 1 && "Unroll count must be positive.");
+ return Count;
+ }
+ return 0;
+}
+
std::optional<RecurrenceDescriptor>
llvm::canParallelizeReductionWhenUnrolling(PHINode &Phi, Loop *L,
ScalarEvolution *SE) {
More information about the llvm-branch-commits
mailing list