[LoopFusion] Add a Cost Model to LoopFusion
Co-authored by @madhur13490
Summary
This RFC proposes an initial cost model for LoopFusion, requiring either same-iteration read-after-write (RAW) reuse or exact same-address affine read-after-read (RAR) reuse before fusion.
This patch is intended as an initial, low-cost step rather than a complete cost model. The intention is to provide a foundation for incrementally adding heuristics for register pressure, vectorisation compatibility, the strength of memory-locality benefits, and others that would benefit LoopFusion’s cost model, provided that they reuse existing analyses or remain cheap enough to avoid significant compile-time overhead.
1. Problem
LoopFusion currently has legality checks but no implemented cost model (issue #189117). Because of this, when fusion is enabled, every legal candidate is fused regardless of whether fusion is expected to be beneficial. While fusion can improve locality, it can also combine unrelated loops, increase register pressure, or inhibit later optimisations.
To capture the impact of this behaviour, the full C/C++ LLVM Test Suite benchmark scope was run, with runtime measured for selected fusion-affected tests. Among those measurements, the Test Suite for Vectorizing Compilers (TSVC) provides the most significant results:
The current behaviour upstream (unrestricted fusion) does improve the LoopRestructuring kernels, which include loop-interchange cases, by ~8%, but regresses the Packing kernels by 13.54%. The former contains exact cross-loop memory reuse, while the latter fuses unrelated setup loops. This motivates demonstrated cross-loop reuse as a low-cost first profitability signal.
2. Proposal
To begin cost model work on LoopFusion with the following memory reuse heuristic as an initial step towards a more complete cost model:
- Require at least one distinct value reused at corresponding iterations between two otherwise-legal fusion candidates.
- Recognise same-iteration RAW reuse through the existing dependence analysis and exact same-address affine RAR reuse through SCEV.
This accepts producer-consumer loops and exact corresponding-address shared reads while rejecting legal fusion pairs with no demonstrated memory reuse. - Use this as a foundation for incrementally adding other low-cost signals, such as vectorization compatibility, register pressure, and the strength of locality benefits.
3. Design and Implementation
- RAW reuse is collected from the dependence queries already performed for legality. A producer instruction in the first loop is counted when DependenceAnalysis reports a non-confused flow dependence whose direction at the candidate-loop level is
EQ, meaning the second loop reads its result at the corresponding iteration. - RAR reuse requires matching affine load keys
(type, start, step), derived from the pointer recurrence reported by SCEV. Loads from the first loop are indexed in aSmallDenseMap; loads from the second loop perform direct lookups. ForR0andR1reads in the first and second loops, this gives an average O(R0 + R1) collection instead of O(R0 × R1) pairwise read-read dependence queries. The intention is to keep compile time low as we build out the cost model. - A set of producer instructions tracks distinct reused values, and collection stops once the default threshold of one is met.
- SCEV is used only to identify profitable reuse. The existing DependenceAnalysis checks continue to determine whether fusion is legal as before.
4. Evaluation
In order to evaluate the impact of this initial cost model, evaluation was conducted combining a full-suite analysis of fusion coverage with runtime measurements for selected fusion-affected tests across the C/C++ LLVM Test Suite
All measurements compare the same three configurations:
- Fusion off: LoopFusion is disabled.
- Unrestricted fusion: LoopFusion is enabled without the cost model (current upstream behaviour)
- Cost model: LoopFusion is enabled with our proposed initial cost model.
4.1 Full C/C++ LLVM Test Suite fusion coverage
Fusion coverage was measured at three levels across the C/C++ LLVM Test Suite build:
- Successful fusion transformations count passed
FuseCounterremarks, which are emitted once immediately before each fusion is performed. - Unique reported fusion locations deduplicates successful remarks by their reported source file, line, and column.
- Benchmark directories with fusion counts build-tree benchmark directories containing at least one successful fusion.
| Metric | Fusion off | Unrestricted fusion | Cost model | Cost-model reduction vs unrestricted |
|---|---|---|---|---|
| Successful fusion transformations | 0 | 8,342 | 81 | 99.03% |
| Unique reported fusion locations | 0 | 512 | 23 | 95.51% |
| Benchmark directories with fusion | 0 | 58 | 13 | 77.59% |
The proposed model is intentionally conservative and reduces fusion transformations by 99.03% and the benchmark directories containing fusion from 58 to 13. Section 4.2 examines whether this selectivity keeps useful fusions while avoiding clear regressions in the measured cases.
4.2 Application and TSVC runtime
Runtime was measured for 12 selected tests. The table presents the three TSVC executables with the clearest connection between fusion decisions and performance. Each executable contains a group of kernels, and the fusion columns count transformations performed while building the executable rather than runtime executions. The -dbl and -flt variants use double- and single-precision element types respectively. The first table reports the number of successful fusions performed while building each executable.
| Benchmark | Fusion off | Unrestricted fusion | Cost model |
|---|---|---|---|
| LoopRestructuring-dbl | 0 | 227 | 1 |
| LoopRestructuring-flt | 0 | 227 | 1 |
| Packing-dbl | 0 | 225 | 0 |
The next table reports five-run median execution times in seconds. Fusion off is the baseline, and negative changes indicate improvements.
| Benchmark | Fusion off | Unrestricted fusion | Cost model | Unrestricted change vs fusion off | Cost-model change vs fusion off |
|---|---|---|---|---|---|
| LoopRestructuring-dbl | 2.3153 s | 2.1218 s | 2.1610 s | -8.36% | -6.66% |
| LoopRestructuring-flt | 2.0513 s | 1.8802 s | 1.9052 s | -8.34% | -7.12% |
| Packing-dbl | 1.7037 s | 1.9343 s | 1.7110 s | +13.54% | +0.43% |
For each LoopRestructuring variant, the cost model keeps one fusion in s233, where both loops read cc[j][i], which alone recovers most of unrestricted fusion’s improvement. It rejects s2233, where the second access is transposed. For Packing, the proposed model performs no fusions and remains close to fusion-off, while unrestricted fusion performs 225 transformations and regresses by 13.54%. The accepted transformations include unrelated setup loops with no cross-loop reuse. These results support demonstrated cross-loop reuse as a useful initial signal, while the broader excluded set still contains neutral changes and some small improvements that future heuristics may recover.
4.3 LoopVectorization microbenchmarks
Five selected LoopVectorization microbenchmarks were measured to test whether accepted reuse-driven fusions were consistently profitable. The first table reports fusion coverage across the complete LoopVectorization build.
| Metric | Fusion off | Unrestricted fusion | Cost model |
|---|---|---|---|
| Number of fusions | 0 | 90 | 36 |
The cost model substantially reduces fusion in this benchmark group, but its kept set still includes the truncation/extension case below.
The next table shows the largest measured regression. Values are five-run median times in nanoseconds. ‘Fusion off’ is the baseline.
| Microbenchmark | Fusion off | Unrestricted fusion | Cost model | Unrestricted change vs fusion off | Cost-model change vs fusion off |
|---|---|---|---|---|---|
| trunc/zext VW16 uint64_t to uint8_t | 996.766 ns | 1,062.536 ns | 1,061.759 ns | +6.60% | +6.52% |
Both unrestricted fusion and the cost model fuse this case and regress by approximately 6.5%. This shows that exact RAR reuse is not sufficient by itself to guarantee profitable fusion and motivates further work on this such as the vectorisation-compatibility work described in the next sections.
4.4 Preliminary compile-time check
Compilation CPU time is summed user time from 2,014 matched object-file compilations.
| Configuration | Compilation CPU time | Proposed model vs configuration |
|---|---|---|
| Fusion off | 549.455 s | +3.05% |
| Unrestricted fusion | 766.333 s | -26.11% |
| Proposed model | 566.209 s | - |
This shows no large compile-time regression, but the 3.05% value is preliminary and will be re-ran with the compile time tracker
5. Next Steps:
Both unrestricted fusion and the proposed model fuse the LoopVectorization truncation/extension case, and both regress by approximately 6.5%. This is a reproducible weakness of accepting exact RAR without considering the effect on vectorisation. A potential follow-up could have us first investigate a cheap vectorisation-compatibility heuristic. More data-driven heuristics could also be used to address register pressure and also distinguish stronger from weaker locality benefits.
Disclaimer: Generation of this RFC was partly assisted by AI tools.