diff options
| author | Sjoerd Meijer <smeijer@nvidia.com> | 2025-07-18 13:42:25 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-18 13:42:25 +0100 |
| commit | a9f81430725cb3d9a776d9b743078a452cd8e3aa (patch) | |
| tree | e97221374526d273ad82dd2c652c345c7209d952 /llvm/lib/Transforms/Scalar/LoopInterchange.cpp | |
| parent | 4c701956341ff88f580d240be072461a1ba6d7f5 (diff) | |
[LoopInterchange] Ignore the cost-model, force interchange if legal (#148858)
This is and has been proven useful for testing purposes, to get more
test coverage.
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopInterchange.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopInterchange.cpp | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index a0f9f3c4a35a..70e9eee5339a 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -78,6 +78,7 @@ enum class RuleTy { PerLoopCacheAnalysis, PerInstrOrderCost, ForVectorization, + Ignore }; } // end anonymous namespace @@ -106,14 +107,20 @@ static cl::list<RuleTy> Profitabilities( clEnumValN(RuleTy::PerInstrOrderCost, "instorder", "Prioritize the IVs order of each instruction"), clEnumValN(RuleTy::ForVectorization, "vectorize", - "Prioritize vectorization"))); + "Prioritize vectorization"), + clEnumValN(RuleTy::Ignore, "ignore", + "Ignore profitability, force interchange (does not " + "work with other options)"))); #ifndef NDEBUG -static bool noDuplicateRules(ArrayRef<RuleTy> Rules) { +static bool noDuplicateRulesAndIgnore(ArrayRef<RuleTy> Rules) { SmallSet<RuleTy, 4> Set; - for (RuleTy Rule : Rules) + for (RuleTy Rule : Rules) { if (!Set.insert(Rule).second) return false; + if (Rule == RuleTy::Ignore) + return false; + } return true; } @@ -1357,6 +1364,13 @@ std::optional<bool> LoopInterchangeProfitability::isProfitableForVectorization( bool LoopInterchangeProfitability::isProfitable( const Loop *InnerLoop, const Loop *OuterLoop, unsigned InnerLoopId, unsigned OuterLoopId, CharMatrix &DepMatrix, CacheCostManager &CCM) { + + // Return true if interchange is forced and the cost-model ignored. + if (Profitabilities.size() == 1 && Profitabilities[0] == RuleTy::Ignore) + return true; + assert(noDuplicateRulesAndIgnore(Profitabilities) && + "Duplicate rules and option 'ignore' are not allowed"); + // isProfitable() is structured to avoid endless loop interchange. If the // highest priority rule (isProfitablePerLoopCacheAnalysis by default) could // decide the profitability then, profitability check will stop and return the @@ -1365,7 +1379,6 @@ bool LoopInterchangeProfitability::isProfitable( // second highest priority rule (isProfitablePerInstrOrderCost by default). // Likewise, if it failed to analysis the profitability then only, the last // rule (isProfitableForVectorization by default) will decide. - assert(noDuplicateRules(Profitabilities) && "Detect duplicate rules"); std::optional<bool> shouldInterchange; for (RuleTy RT : Profitabilities) { switch (RT) { @@ -1382,6 +1395,9 @@ bool LoopInterchangeProfitability::isProfitable( shouldInterchange = isProfitableForVectorization(InnerLoopId, OuterLoopId, DepMatrix); break; + case RuleTy::Ignore: + llvm_unreachable("Option 'ignore' is not supported with other options"); + break; } // If this rule could determine the profitability, don't call subsequent |
