The generic_nesting chain with a method REQUIRED by the constraint interface and called recursively through the witnesses (`first.eval() + second.eval()`), so overload resolution and inheritance-witness lookup run at every nesting level instead of only type checking the aliases. Same depth axis as generic_nesting, much steeper constant: measured ~2.9x per level when added (2026-07), vs ~3-4x per level from substitution alone but starting an order of magnitude higher at equal depth. Scaling null: each level adds O(1) declarations and one call site, so ideal front-end cost is O(n). The ladder tops out below generic_nesting's because the per-level multiplier bites sooner.
bucket: sema · compile mode: module · flags: (none) · default N: 12
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 compileInner: 4.2 → 4.2 ms -1.9% (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 |
|---|---|---|---|
| frontEndExecute (self) | -0.1 ms | -59.6% | -2.4pp |
| generateIR | +0.0 ms | +3.6% | +0.9pp |
| generateOutput (self) | +0.0 ms | +1.8% | +0.5pp |
| compileInner (self) | -0.0 ms | – | -0.5pp |
| SemanticChecking | -0.0 ms | -1.3% | -0.5pp |
| (remaining 1 buckets) | +0.0 ms | – | +0.0pp |
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 %) |
|---|---|---|---|
| 2026-08-01 → 2026-08-02 | +7.6% | d3ec9cc49..53b76e6d3 | |
| 2026-08-02 → 2026-08-03 | -6.6% | 53b76e6d3..53b76e6d3 |
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 generic_nesting_eval --label repro --gen-dir repro-generic_nesting_eval
the complete compiled source (N = 12), shown in full
// AUTO-GENERATED by perf-suite/workloads.py - do not edit by hand.
interface IBase {}
interface IModel : IBase { float eval(); }
struct Leaf : IModel { float eval() { return 1.0; } }
struct Pair<First : IModel, Second : IModel> : IModel
{
First first;
Second second;
float eval() { return first.eval() + second.eval(); }
}
typealias T0 = Leaf;
typealias T1 = Pair<Leaf, T0>;
typealias T2 = Pair<Leaf, T1>;
typealias T3 = Pair<Leaf, T2>;
typealias T4 = Pair<Leaf, T3>;
typealias T5 = Pair<Leaf, T4>;
typealias T6 = Pair<Leaf, T5>;
typealias T7 = Pair<Leaf, T6>;
typealias T8 = Pair<Leaf, T7>;
typealias T9 = Pair<Leaf, T8>;
typealias T10 = Pair<Leaf, T9>;
typealias T11 = Pair<Leaf, T10>;
typealias T12 = Pair<Leaf, T11>;
RWStructuredBuffer<float> outBuf;
[shader("compute")]
[numthreads(1, 1, 1)]
void computeMain() { T12 v; outBuf[0] = v.eval(); }