One module with an interface, n conforming impl structs, and a generic computeMain<T : IOp>. The driver's specialize mode compiles one variant per impl through IEntryPoint::specialize — the application pattern where one kernel is stamped out per material/config type, stressing specialization + link cost per variant.
bucket: api_overhead · compile mode: api · flags: (none) · default N: 60
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.
Overall apiTotal: 248.8 → 237.2 ms -4.6% (2026-07-30 7c58a326b → 2026-08-29 28c755b09)
Contributors — the mutually-exclusive phase buckets (named leaves + (self) residuals) that tile apiTotal; 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 |
|---|---|---|---|
| apiGetCode | -8.4 ms | -6.7% | -3.4pp |
| apiTotal (self) | -2.3 ms | -55.5% | -0.9pp |
| apiLoadModule | -0.7 ms | -4.9% | -0.3pp |
| (remaining 5 buckets) | -0.1 ms | – | -0.1pp |
Largest day steps (≥5% of the previous day, both directions; bisect with git log <c0>..<c1> -- source/):
| boundary | % vs prev day | commits | top buckets (own %) |
|---|---|---|---|
| none | |||
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 api_specialize --label repro --gen-dir repro-api_specialize
the complete compiled source (N = 60), shown in full
// AUTO-GENERATED by perf-suite/workloads.py - do not edit by hand.
module spec_root;
public interface IOp
{
static float eval(float x);
}
public struct Impl_0 : IOp
{
public static float eval(float x) { return sin(x * 1.0) + x * 0.0; }
}
public struct Impl_1 : IOp
{
public static float eval(float x) { return sin(x * 1.01) + x * 0.1; }
}
public struct Impl_2 : IOp
{
public static float eval(float x) { return sin(x * 1.02) + x * 0.2; }
}
public struct Impl_3 : IOp
{
public static float eval(float x) { return sin(x * 1.03) + x * 0.3; }
}
public struct Impl_4 : IOp
{
public static float eval(float x) { return sin(x * 1.04) + x * 0.4; }
}
public struct Impl_5 : IOp
{
public static float eval(float x) { return sin(x * 1.05) + x * 0.5; }
}
public struct Impl_6 : IOp
{
public static float eval(float x) { return sin(x * 1.06) + x * 0.6; }
}
public struct Impl_7 : IOp
{
public static float eval(float x) { return sin(x * 1.07) + x * 0.7; }
}
public struct Impl_8 : IOp
{
public static float eval(float x) { return sin(x * 1.08) + x * 0.8; }
}
public struct Impl_9 : IOp
{
public static float eval(float x) { return sin(x * 1.09) + x * 0.9; }
}
public struct Impl_10 : IOp
{
public static float eval(float x) { return sin(x * 1.1) + x * 1.0; }
}
public struct Impl_11 : IOp
{
public static float eval(float x) { return sin(x * 1.11) + x * 1.1; }
}
public struct Impl_12 : IOp
{
public static float eval(float x) { return sin(x * 1.12) + x * 1.2; }
}
public struct Impl_13 : IOp
{
public static float eval(float x) { return sin(x * 1.13) + x * 1.3; }
}
public struct Impl_14 : IOp
{
public static float eval(float x) { return sin(x * 1.1400000000000001) + x * 1.4; }
}
public struct Impl_15 : IOp
{
public static float eval(float x) { return sin(x * 1.15) + x * 1.5; }
}
public struct Impl_16 : IOp
{
public static float eval(float x) { return sin(x * 1.16) + x * 1.6; }
}
public struct Impl_17 : IOp
{
public static float eval(float x) { return sin(x * 1.17) + x * 1.7; }
}
public struct Impl_18 : IOp
{
public static float eval(float x) { return sin(x * 1.18) + x * 1.8; }
}
public struct Impl_19 : IOp
{
public static float eval(float x) { return sin(x * 1.19) + x * 1.9; }
}
public struct Impl_20 : IOp
{
public static float eval(float x) { return sin(x * 1.2) + x * 2.0; }
}
public struct Impl_21 : IOp
{
public static float eval(float x) { return sin(x * 1.21) + x * 2.1; }
}
public struct Impl_22 : IOp
{
public static float eval(float x) { return sin(x * 1.22) + x * 2.2; }
}
public struct Impl_23 : IOp
{
public static float eval(float x) { return sin(x * 1.23) + x * 2.3; }
}
public struct Impl_24 : IOp
{
public static float eval(float x) { return sin(x * 1.24) + x * 2.4; }
}
public struct Impl_25 : IOp
{
public static float eval(float x) { return sin(x * 1.25) + x * 2.5; }
}
public struct Impl_26 : IOp
{
public static float eval(float x) { return sin(x * 1.26) + x * 2.6; }
}
public struct Impl_27 : IOp
{
public static float eval(float x) { return sin(x * 1.27) + x * 2.7; }
}
public struct Impl_28 : IOp
{
public static float eval(float x) { return sin(x * 1.28) + x * 2.8; }
}
public struct Impl_29 : IOp
{
public static float eval(float x) { return sin(x * 1.29) + x * 2.9; }
}
public struct Impl_30 : IOp
{
public static float eval(float x) { return sin(x * 1.3) + x * 3.0; }
}
public struct Impl_31 : IOp
{
public static float eval(float x) { return sin(x * 1.31) + x * 0.0; }
}
public struct Impl_32 : IOp
{
public static float eval(float x) { return sin(x * 1.32) + x * 0.1; }
}
public struct Impl_33 : IOp
{
public static float eval(float x) { return sin(x * 1.33) + x * 0.2; }
}
public struct Impl_34 : IOp
{
public static float eval(float x) { return sin(x * 1.34) + x * 0.3; }
}
public struct Impl_35 : IOp
{
public static float eval(float x) { return sin(x * 1.35) + x * 0.4; }
}
public struct Impl_36 : IOp
{
public static float eval(float x) { return sin(x * 1.3599999999999999) + x * 0.5; }
}
public struct Impl_37 : IOp
{
public static float eval(float x) { return sin(x * 1.37) + x * 0.6; }
}
public struct Impl_38 : IOp
{
public static float eval(float x) { return sin(x * 1.38) + x * 0.7; }
}
public struct Impl_39 : IOp
{
public static float eval(float x) { return sin(x * 1.3900000000000001) + x * 0.8; }
}
public struct Impl_40 : IOp
{
public static float eval(float x) { return sin(x * 1.4) + x * 0.9; }
}
public struct Impl_41 : IOp
{
public static float eval(float x) { return sin(x * 1.41) + x * 1.0; }
}
public struct Impl_42 : IOp
{
public static float eval(float x) { return sin(x * 1.42) + x * 1.1; }
}
public struct Impl_43 : IOp
{
public static float eval(float x) { return sin(x * 1.43) + x * 1.2; }
}
public struct Impl_44 : IOp
{
public static float eval(float x) { return sin(x * 1.44) + x * 1.3; }
}
public struct Impl_45 : IOp
{
public static float eval(float x) { return sin(x * 1.45) + x * 1.4; }
}
public struct Impl_46 : IOp
{
public static float eval(float x) { return sin(x * 1.46) + x * 1.5; }
}
public struct Impl_47 : IOp
{
public static float eval(float x) { return sin(x * 1.47) + x * 1.6; }
}
public struct Impl_48 : IOp
{
public static float eval(float x) { return sin(x * 1.48) + x * 1.7; }
}
public struct Impl_49 : IOp
{
public static float eval(float x) { return sin(x * 1.49) + x * 1.8; }
}
public struct Impl_50 : IOp
{
public static float eval(float x) { return sin(x * 1.5) + x * 1.9; }
}
public struct Impl_51 : IOp
{
public static float eval(float x) { return sin(x * 1.51) + x * 2.0; }
}
public struct Impl_52 : IOp
{
public static float eval(float x) { return sin(x * 1.52) + x * 2.1; }
}
public struct Impl_53 : IOp
{
public static float eval(float x) { return sin(x * 1.53) + x * 2.2; }
}
public struct Impl_54 : IOp
{
public static float eval(float x) { return sin(x * 1.54) + x * 2.3; }
}
public struct Impl_55 : IOp
{
public static float eval(float x) { return sin(x * 1.55) + x * 2.4; }
}
public struct Impl_56 : IOp
{
public static float eval(float x) { return sin(x * 1.56) + x * 2.5; }
}
public struct Impl_57 : IOp
{
public static float eval(float x) { return sin(x * 1.5699999999999998) + x * 2.6; }
}
public struct Impl_58 : IOp
{
public static float eval(float x) { return sin(x * 1.58) + x * 2.7; }
}
public struct Impl_59 : IOp
{
public static float eval(float x) { return sin(x * 1.5899999999999999) + x * 2.8; }
}
RWStructuredBuffer<float> outBuf;
[shader("compute")]
[numthreads(1,1,1)]
void computeMain<T : IOp>()
{
outBuf[0] = T.eval(outBuf[0]);
}