summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp
AgeCommit message (Collapse)Author
2025-11-04[LoopUnroll] Prevent LoopFullUnrollPass from performing partial unrolling ↵Ivan Kelarev
when trip counts are unknown (#165013) Currently, `LoopFullUnrollPass` incorrectly performs partial unrolling when `#pragma unroll` is specified and both `TripCount` and `MaxTripCount` are unknown. This patch adds a check to prevent partial unrolling when `OnlyFullUnroll` parameter is true and both trip count values are zero.
2025-09-09[AArch64] Enable RT and partial unrolling with reductions for Apple CPUs. ↵Florian Hahn
(#149699) Update unrolling preferences for Apple Silicon CPUs to enable partial unrolling and runtime unrolling for small loops with reductions. This builds on top of unroller changes to introduce parallel reduction phis, if possible: https://github.com/llvm/llvm-project/pull/149470. PR: https://github.com/llvm/llvm-project/pull/149699
2025-07-14[llvm] Remove unused includes (NFC) (#148768)Kazu Hirata
These are identified by misc-include-cleaner. I've filtered out those that break builds. Also, I'm staying away from llvm-config.h, config.h, and Compiler.h, which likely cause platform- or compiler-specific build failures.
2025-06-17[DebugInfo][RemoveDIs] Remove a swathe of debug-intrinsic code (#144389)Jeremy Morse
Seeing how we can't generate any debug intrinsics any more: delete a variety of codepaths where they're handled. For the most part these are plain deletions, in others I've tweaked comments to remain coherent, or added a type to (what was) type-generic-lambdas. This isn't all the DbgInfoIntrinsic call sites but it's most of the simple scenarios. Co-authored-by: Nikita Popov <github@npopov.com>
2025-05-28Reapply "[LoopPeel] Remove known trip count restriction when peeling last. ↵Florian Hahn
(#140792)" This reverts commit 580454526b936f7a576ddbc9bb932cf9be376ec4. The recommitted version contains an extra check to not peel if the latch exit is controlled by a pointer induction. Original message: Remove the restriction that the loop must be known to execute at least 2 iterations when peeling the last iteration. If we cannot prove at least 2 iterations are executed, a check and branch to skip the peeled loop is inserted. PR: https://github.com/llvm/llvm-project/pull/140792
2025-05-27Revert "[LoopPeel] Remove known trip count restriction when peeling last. ↵Florian Hahn
(#140792)" This reverts commit 24b97756decb7bf0e26dcf0e30a7a9aaf27f417c. Also reverts ac9a466e39bf97ffeab127982aa7c405cb257551. Building CMake triggers a crash with the patch, revert while I investigate.
2025-05-26[LoopPeel] Remove known trip count restriction when peeling last. (#140792)Florian Hahn
Remove the restriction that the loop must be known to execute at least 2 iterations when peeling the last iteration. If we cannot prove at least 2 iterations are executed, a check and branch to skip the peeled loop is inserted. PR: https://github.com/llvm/llvm-project/pull/140792
2025-05-17Reapply "[LoopPeel] Implement initial peeling off the last loop iteration. ↵Florian Hahn
(#139551)" This reverts the revert commit bf92b127d2637948f53d11a187e865aa10e2e74c. This adds missing initialization of PeelLast in gatherPeelingPreferences. Original message: Generalize countToEliminateCompares to also consider peeling off the last iteration if it eliminates a compare. At the moment, codegen for peeling off the last iteration is quite restrictive and callers have to make sure that the exit condition can be adjusted when peeling and that the loop executes at least 2 iterations. Both will be relaxed in follow-ups. PR: https://github.com/llvm/llvm-project/pull/139551
2025-05-16Revert "[LoopPeel] Implement initial peeling off the last loop iteration. ↵Florian Hahn
(#139551)" This reverts commit bb10c3ba7f77d40a7fbfd4ac815015d3a4ae476a. Also reverts 4f663cca15f2b53c2bc6a84d1b1f5bd81679356d: Revert "[LoopPeel] Make sure PeelLast is always initialized." Revert for now to bring msan bots back to green https://lab.llvm.org/buildbot/#/builders/164/builds/9992 https://lab.llvm.org/buildbot/#/builders/94/builds/7158
2025-05-15[LoopPeel] Implement initial peeling off the last loop iteration. (#139551)Florian Hahn
Generalize countToEliminateCompares to also consider peeling off the last iteration if it eliminates a compare. At the moment, codegen for peeling off the last iteration is quite restrictive and callers have to make sure that the exit condition can be adjusted when peeling and that the loop executes at least 2 iterations. Both will be relaxed in follow-ups. PR: https://github.com/llvm/llvm-project/pull/139551
2025-05-05[ErrorHandling] Add reportFatalInternalError + reportFatalUsageError (NFC) ↵Nikita Popov
(#138251) This implements the result of the discussion at: https://discourse.llvm.org/t/rfc-report-fatal-error-and-the-default-value-of-gencrashdialog/73587 There are two different use cases for report_fatal_error, so replace it with two functions reportFatalInternalError() and reportFatalUsageError(). The former indicates a bug in LLVM and generates a crash dialog. The latter does not. The names have been suggested by rnk and people seemed to like them. This replaces a lot of the usages that passed an explicit value for GenCrashDiag. I did not bulk replace remaining report_fatal_error usage -- they probably require case by case review for which function to use.
2025-04-23[CostModel] Remove optional from InstructionCost::getValue() (#135596)David Green
InstructionCost is already an optional value, containing an Invalid state that can be checked with isValid(). There is little point in returning another optional from getValue(). Most uses do not make use of it being a std::optional, dereferencing the value directly (either isValid has been checked previously or the Cost is assumed to be valid). The one case that does in AMDGPU used value_or which has been replaced by a isValid() check.
2025-03-19[Transforms] Use *Set::insert_range (NFC) (#132056)Kazu Hirata
DenseSet, SmallPtrSet, SmallSet, SetVector, and StringSet recently gained C++23-style insert_range. This patch replaces: Dest.insert(Src.begin(), Src.end()); with: Dest.insert_range(Src); This patch does not touch custom begin like succ_begin for now.
2025-01-27[LoopUnroll] Add RuntimeUnrollMultiExit to loop unroll options (NFC) (#124462)Florian Hahn
Add an extra knob to RuntimeUnrollMultiExit to let backends control whether to allow multi-exit unrolling on a per-loop basis. This gives backends more fine-grained control on deciding if multi-exit unrolling is profitable for a given loop and uarch. Similar to 4226e0a0c75. PR: https://github.com/llvm/llvm-project/pull/124462
2025-01-08[LLVM] Fix various cl::desc typos and whitespace issues (NFC) (#121955)Ryan Mansfield
2024-12-02[TTI] Add SCEVExpansionBudget to loop unrolling options. (#118316)Florian Hahn
Add an extra know to UnrollingPreferences to let backends control the maximum budget for SCEV expansions. This gives backends more fine-grained control on the cost of the runtime checks for runtime unrolling. PR: https://github.com/llvm/llvm-project/pull/118316
2024-11-02[Scalar] Remove unused includes (NFC) (#114645)Kazu Hirata
Identified with misc-include-cleaner.
2024-06-06[LoopUnroll] Consider convergence control tokens when unrolling (#91715)Sameer Sahasrabuddhe
- There is no restriction on a loop with controlled convergent operations when the relevant tokens are defined and used within the loop. - When a token defined outside a loop is used inside (also called a loop convergence heart), unrolling is allowed only in the absence of remainder or runtime checks. - When a token defined inside a loop is used outside, such a loop is said to be "extended". This loop can only be unrolled by also duplicating the extended part lying outside the loop. Such unrolling is disabled for now. - Clean up loop hearts: When unrolling a loop with a heart, duplicating the heart will introduce multiple static uses of a convergence control token in a cycle that does not contain its definition. This violates the static rules for tokens, and needs to be cleaned up into a single occurrence of the intrinsic. - Spell out the initializer for UnrollLoopOptions to improve readability. Original implementation [D85605] by Nicolai Haehnle <nicolai.haehnle@amd.com>.
2024-05-02[LoopUnroll] Add CSE to remove redundant loads after unrolling. (#83860)Florian Hahn
This patch adds loadCSE support to simplifyLoopAfterUnroll. It is based on EarlyCSE's implementation using ScopeHashTable and is using SCEV for accessed pointers to check to find redundant loads after unrolling. This applies to the late unroll pass only, for full unrolling those redundant loads will be cleaned up by the regular pipeline. The current approach constructs MSSA on-demand per-loop, but there is still small but notable compile-time impact: stage1-O3 +0.04% stage1-ReleaseThinLTO +0.06% stage1-ReleaseLTO-g +0.05% stage1-O0-g +0.02% stage2-O3 +0.09% stage2-O0-g +0.04% stage2-clang +0.02% https://llvm-compile-time-tracker.com/compare.php?from=c089fa5a729e217d0c0d4647656386dac1a1b135&to=ec7c0f27cb5c12b600d9adfc8543d131765ec7be&stat=instructions:u This benefits some workloads with runtime-unrolling disabled, where users use pragmas to force unrolling, as well as with runtime unrolling enabled. On SPEC/MultiSource, this removes a number of loads after unrolling on AArch64 with runtime unrolling enabled. ``` External/S...te/526.blender_r/526.blender_r 96 MultiSourc...rks/mediabench/gsm/toast/toast 39 SingleSource/Benchmarks/Misc/ffbench 4 External/SPEC/CINT2006/403.gcc/403.gcc 18 MultiSourc.../Applications/JM/ldecod/ldecod 4 MultiSourc.../mediabench/jpeg/jpeg-6a/cjpeg 6 MultiSourc...OE-ProxyApps-C/miniGMG/miniGMG 9 MultiSourc...e/Applications/ClamAV/clamscan 4 MultiSourc.../MallocBench/espresso/espresso 3 MultiSourc...dence-flt/LinearDependence-flt 2 MultiSourc...ch/office-ispell/office-ispell 4 MultiSourc...ch/consumer-jpeg/consumer-jpeg 6 MultiSourc...ench/security-sha/security-sha 11 MultiSourc...chmarks/McCat/04-bisect/bisect 3 SingleSour...tTests/2020-01-06-coverage-009 12 MultiSourc...ench/telecomm-gsm/telecomm-gsm 39 MultiSourc...lds-flt/CrossingThresholds-flt 24 MultiSourc...dence-dbl/LinearDependence-dbl 2 External/S...C/CINT2006/445.gobmk/445.gobmk 6 MultiSourc...enchmarks/mafft/pairlocalalign 53 External/S...31.deepsjeng_r/531.deepsjeng_r 3 External/S...rate/510.parest_r/510.parest_r 58 External/S...NT2006/464.h264ref/464.h264ref 29 External/S...NT2017rate/502.gcc_r/502.gcc_r 45 External/S...C/CINT2006/456.hmmer/456.hmmer 6 External/S...te/538.imagick_r/538.imagick_r 18 External/S.../CFP2006/447.dealII/447.dealII 4 MultiSourc...OE-ProxyApps-C++/miniFE/miniFE 12 External/S...2017rate/525.x264_r/525.x264_r 36 MultiSourc...Benchmarks/7zip/7zip-benchmark 33 MultiSourc...hmarks/ASC_Sequoia/AMGmk/AMGmk 2 MultiSourc...chmarks/VersaBench/8b10b/8b10b 1 MultiSourc.../Applications/JM/lencod/lencod 116 MultiSourc...lds-dbl/CrossingThresholds-dbl 24 MultiSource/Benchmarks/McCat/05-eks/eks 15 ``` PR: https://github.com/llvm/llvm-project/pull/83860
2024-02-06[LoopUnroll] Consider simplified operands while retrieving TTI instruction ↵Sergey Kachkov
cost (#70929) Get more precise cost of instruction after LoopUnroll considering that some operands of it can be simplified, e.g. induction variable will be replaced by constant after full unrolling.
2024-02-05[LoopUnroll] Introduce PragmaUnrollFullMaxIterations as a hard cap on how ↵modiking
many iterations we try to unroll (#78648) Fixes [PR77842](https://github.com/llvm/llvm-project/issues/77842) where UBSAN causes pragma full unroll to try and unroll INT_MAX times. This sets a cap to make sure we don't attempt this and crash the compiler. Testing: ninja check-all with new test --------- Co-authored-by: Nikita Popov <github@npopov.com>
2023-12-21[LoopUnroll] Make UnrollMaxUpperBound to be overridable by target (#76029)boxu.zhang
The UnrollMaxUpperBound should be target dependent, since different chips provide different register set which brings different ability of storing more temporary values of a program. So I add a MaxUpperBound value in UnrollingPreference which can be override by targets. All uses of UnrollMaxUpperBound are replaced with UP.MaxUpperBound. The default value is still 8 and the command line argument '--unroll-max-upperbound' takes final effect if provided.
2023-12-08[LoopUnroll] Make use of MaxTripCount for loops with "#pragma unroll" (#74703)XiangZhang
Fix loop unroll fail caused by branches folding. For example: SimplifyCFG foldloop branches then cause loop unroll failed for "#program unroll" loop. ``` #program unroll for (int I = 0; I < ConstNum; ++I) { // folding "I < ConstNum" and "Cond2" if (Cond2) { break; } xxx loop body; } ``` The pragma unroll metadata only takes effect if there is an exact trip count, but not if there is an upper bound trip count. This patch make it work with an upper bound trip count as well in shouldPragmaUnroll(). Loop unroll is important in stack nervous devices (e.g. GPU, and that is why a lot of GPU code mark loop with "#program unroll"). It usually much simplify the address (offset) calculations in old iterations, then we can do a lot of others optimizations, e.g, SROA, for these simplifed address (escape alloca the whole aggregates).
2023-09-27[LoopUnroll] Store more information in UnrollCostEstimator (NFCI)Nikita Popov
Instead of having ApproximateLoopSize() use a bunch of out parameters, from which we later construct an UnrollCostEstimator, directly construct UnrollCostEstimator which holds all the information derived from loop analysis. This makes it easier to add additional metrics in the future.
2023-06-10[Transforms] Remove unused function createSimpleLoopUnrollPassKazu Hirata
The last use was removed by: commit d623b2f95fd559901f008a0588dddd0949a8db01 Author: Arthur Eubanks <aeubanks@google.com> Date: Fri Mar 10 17:24:19 2023 -0800
2023-06-05Revert "[LCSSA] Remove unused ScalarEvolution argument (NFC)"Nikita Popov
This reverts commit 5362a0d859d8e96b3f7c0437b7866e17a818a4f7. In preparation for reverting a dependent revision.
2023-05-02[LCSSA] Remove unused ScalarEvolution argument (NFC)Nikita Popov
After D149435, LCSSA formation no longer needs access to ScalarEvolution, so remove the argument from the utilities.
2023-04-13[LoopUnroll] Prevent LoopFullUnrollPass to perform partial/runtime unrollingYashwant Singh
FullLoopUnroll was performing runtime unrolling in certain cases when '#pragma unroll' was specified. Patch to fix this by introducing new parameter to tryToUnrollLoop() to differentiate between LoopUnrollPass and FullLoopUnrollPass. Based on the discussion here (https://discourse.llvm.org/t/loop-unroller-fails-to-unroll-loop/69834) Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D148071
2023-02-22[NFC] Use single quotes for single char output during `printPipline`Liren Peng
Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D144365
2022-12-19[LoopPeel] Expose ValueMap of last peeled iteration. NFCAnna Thomas
The value map of last peeled iteration is computed within peelLoop API. This patch exposes it for callers of peelLoop. While this is not currently used by upstream passes, we have a usecase downstream which benefits from this API update. Future users of peelLoop can also use the ValueMap if needed. Similar value maps are exposed by other loop utilities such as loop cloning. Differential Revision: https://reviews.llvm.org/D138228
2022-12-16[Transforms,CodeGen] std::optional::value => operator*/operator->Fangrui Song
value() has undesired exception checking semantics and calls __throw_bad_optional_access in libc++. Moreover, the API is unavailable without _LIBCPP_NO_EXCEPTIONS on older Mach-O platforms (see _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS).
2022-12-14Don't include Optional.hKazu Hirata
These files no longer use llvm::Optional.
2022-12-13[Transforms/Scalar] llvm::Optional => std::optionalFangrui Song
2022-12-12Transforms/Utils: llvm::Optional => std::optionalFangrui Song
2022-12-10Don't include None.h (NFC)Kazu Hirata
I've converted all known uses of None to std::nullopt, so we no longer need to include None.h. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-08[llvm] Use std::nullopt instead of None in comments (NFC)Kazu Hirata
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-02[Transforms] Use std::nullopt instead of None (NFC)Kazu Hirata
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-11-26[Scalar] Use std::optional in LoopUnrollPass.cpp (NFC)Kazu Hirata
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-09-26LoopUnroll: Pass through AssumptionCache (NFC)Matt Arsenault
Using these queries with a context instruction and without a cache seems to be about 2x slower than with it so this theoretically improves compile time.
2022-08-26[TTI] NFC: Reduce InstructionCost::getValue() usage...Daniil Fukalov
in order to propagate `InstructionCost` value upper. Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D103406
2022-08-18[CostModel] Replace getUserCost with getInstructionCostSimon Pilgrim
* Replace getUserCost with getInstructionCost, covering all cost kinds. * Remove getInstructionLatency, it's not implemented by any backends, and we should fold the functionality into getUserCost (now getInstructionCost) to make it easier for targets to handle the cost kinds with their existing cost callbacks. Original Patch by @samparker (Sam Parker) Differential Revision: https://reviews.llvm.org/D79483
2022-08-14[Transforms] Qualify auto in range-based for loops (NFC)Kazu Hirata
Identified with readability-qualified-auto.
2022-08-07[Transforms] Fix comment typos (NFC)Kazu Hirata
2022-07-13[llvm] Use value instead of getValue (NFC)Kazu Hirata
2022-06-25[llvm] Don't use Optional::hasValue (NFC)Kazu Hirata
This patch replaces Optional::hasValue with the implicit cast to bool in conditionals only.
2022-06-25Revert "Don't use Optional::hasValue (NFC)"Kazu Hirata
This reverts commit aa8feeefd3ac6c78ee8f67bf033976fc7d68bc6d.
2022-06-25Don't use Optional::hasValue (NFC)Kazu Hirata
2022-06-09Plumb InstructionCost through unroll costingPhilip Reames
Teach the unroller(s) how to handle an invalid cost. This avoids crashes when the backend can't provide a cost due to either a fundemental limitation or an unimplemented cost model case. Differential Revision: https://reviews.llvm.org/D127305
2022-06-09Pipe potentially invalid InstructionCost through CodeMetricsPhilip Reames
Per the documentation in Support/InstructionCost.h, the purpose of an invalid cost is so that clients can change behavior on impossible to cost inputs. CodeMetrics was instead asserting that invalid costs never occurred. On a target with an incomplete cost model - e.g. RISCV - this means that transformations would crash on (falsely) invalid constructs - e.g. scalable vectors. While we certainly should improve the cost model - and I plan to do so in the near future - we also shouldn't be crashing. This violates the explicitly stated purpose of an invalid InstructionCost. I updated all of the "easy" consumers where bailouts were locally obvious. I plan to follow up with loop unroll in a following change. Differential Revision: https://reviews.llvm.org/D127131
2022-06-03[llvm] Remove unneeded cl::ZeroOrMore for cl::opt options. NFCFangrui Song
Some cl::ZeroOrMore were added to avoid the `may only occur zero or one times!` error. More were added due to cargo cult. Since the error has been removed, cl::ZeroOrMore is unneeded. Also remove cl::init(false) while touching the lines.