← back

loop_unroll

A force-unrolled loop of `n` iterations. Stresses loop unrolling (unrollLoopsInModule) and the downstream SSA simplify on the unrolled body. Scaling null: the unrolled output is O(n), so ideal cost is linear in n (linear in output size).

bucket: loop_unroll  ·  compile mode: target  ·  flags: -target spirv -emit-spirv-directly  ·  default N: 300

Phase composition across releases

Full sub-counter decomposition of compileInner — named leaf timers plus (self) residuals (a parent's time not covered by a named child, e.g. the autodiff transform in linkAndOptimizeIR (self)). Topmost band traces compileInner; hover a band for its phase.

Across releases

loop_unroll — Across releases (median ms) loop_unroll 0.23× 0.0 513 1025 25.12 25.13 25.14 25.15 25.16 25.17 25.18 25.19 25.20 25.21 25.22 25.23 25.24 26.1 26.2 26.3 26.4 26.5 26.7 26.8 26.9 26.10 26.11 26.12 26.13 26.13.1 26.14 26.14.1 26.16 26.16.1 loop_unroll — parseTranslationUnit loop_unroll — SemanticChecking loop_unroll — generateIR loop_unroll — frontEndExecute (self) loop_unroll — specializeModule loop_unroll — simplifyIR loop_unroll — linkIR loop_unroll — unrollLoopsInModule loop_unroll — legalizeResourceTypes loop_unroll — legalizeExistentialTypeLayout loop_unroll — performMandatoryEarlyInlining loop_unroll — performForceInlining loop_unroll — linkAndOptimizeIR (self) loop_unroll — generateOutput (self) loop_unroll — compileInner (self) phase buckets parseTranslationUnit SemanticChecking generateIR frontEndExecute (self) specializeModule simplifyIR linkIR unrollLoopsInModule legalizeResourceTypes legalizeExistentialTypeLayout performMandatoryEarlyInlining performForceInlining linkAndOptimizeIR (self) emitEntryPointsSourceFromIR generateOutput (self) compileInner (self)

Daily tip-of-tree (last 30 days)

loop_unroll — Daily tip-of-tree (last 30 days) (median ms) loop_unroll 0.80× 0.0 150 300 07-30 07-31 08-01 08-02 08-03 08-04 08-05 08-06 08-07 08-08 08-09 08-10 08-11 08-12 08-13 08-14 08-15 08-15 08-18 08-19 08-20 08-21 08-22 08-23 08-24 08-25 08-26 08-27 08-28 08-29 loop_unroll — parseTranslationUnit loop_unroll — SemanticChecking loop_unroll — generateIR loop_unroll — frontEndExecute (self) loop_unroll — specializeModule loop_unroll — simplifyIR loop_unroll — linkIR loop_unroll — unrollLoopsInModule loop_unroll — legalizeResourceTypes loop_unroll — legalizeExistentialTypeLayout loop_unroll — performMandatoryEarlyInlining loop_unroll — performForceInlining loop_unroll — generateOutput (self) loop_unroll — compileInner (self) phase buckets parseTranslationUnit SemanticChecking generateIR frontEndExecute (self) specializeModule simplifyIR linkIR unrollLoopsInModule legalizeResourceTypes legalizeExistentialTypeLayout performMandatoryEarlyInlining performForceInlining linkAndOptimizeIR (self) emitEntryPointsSourceFromIR generateOutput (self) compileInner (self)

Daily window progress

Overall compileInner: 270.2 → 216.8 ms  -19.7%  (2026-07-30 7c58a326b → 2026-08-29 28c755b09)

Contributors — the mutually-exclusive phase buckets (named leaves + (self) residuals) that tile compileInner; the pp column sums to the overall %. Buckets moving the total by ≥0.2% are listed, the rest fold into the remainder row. Below them, every other reported counter (nested/overlapping, e.g. serialized-module reads — own change only):

counterΔown %of total
legalizeResourceTypes-13.4 ms-98.0%-5.0pp
legalizeExistentialTypeLayout-13.3 ms-97.9%-4.9pp
specializeModule-11.9 ms-11.6%-4.4pp
unrollLoopsInModule-10.1 ms-11.4%-3.7pp
simplifyIR-3.3 ms-12.2%-1.2pp
generateOutput (self)-0.9 ms-7.7%-0.3pp
(remaining 8 buckets)-0.5 ms-0.2pp
readSerializedModuleAST+1.0 ms+3.1%

Largest day steps (≥5% of the previous day, both directions; bisect with git log <c0>..<c1> -- source/):

boundary% vs prev daycommitstop buckets (own %)
2026-08-04 → 2026-08-05-19.7%0864e60e6..ff45b15edlegalizeExistentialTypeLayout -98%, legalizeResourceTypes -98%, specializeModule -12%

Reproduce

Run from the slang repo root. This regenerates the sources below and re-runs this workload's measurement; --gen-dir keeps the generated files (they go to a tempdir and are deleted otherwise).

python3 tools/compile-perf/bench.py --slangc /path/to/slangc --only loop_unroll --label repro --gen-dir repro-loop_unroll

Compiled Slang source

the complete compiled source (N = 300), shown in full

loop_unroll.slang (12 lines)

// AUTO-GENERATED by perf-suite/workloads.py - do not edit by hand.
RWStructuredBuffer<float> outBuf;

[shader("compute")]
[numthreads(1,1,1)]
void computeMain(uint3 tid : SV_DispatchThreadID)
{
    float acc = outBuf[tid.x];
    [ForceUnroll] for (int i = 0; i < 300; ++i)
        acc = acc * 1.0009 + sin(acc + float(i)) * 0.5 - cos(acc * 0.5);
    outBuf[0] = acc;
}