← all workloads

resource_aggregate

n resource-bundle structs (each holding two textures, a sampler and a StructuredBuffer) declared at global scope and all read in the entry point. Nesting resource handles inside an aggregate forces `legalizeResourceTypes` to flatten each struct's resource fields into individually-bound resources before a target can consume them — a pass no other workload triggers (every other workload's only resource is a bare RWStructuredBuffer). Resources are kept live (sampled / indexed into the output) so dead-code elimination can't drop them before legalization runs. Scales by breadth = number of bundles, i.e. the count of resource fields the pass must legalize; legalizeResourceTypes grows super-linearly in n. Scaling null: n scales resource-carrying structs, each O(1); ideal legalization cost is O(n) — the measured ~N^1.8 in legalizeResourceTypes is a genuine compiler finding, not a workload property.

bucket: resource_legalize  ·  mode: target  ·  flags: -target spirv -emit-spirv-directly

Phase composition vs N (stacked sub-counters)

compileInner split into phase buckets (named leaves + (self) residuals) stacked across the sweep sizes — the top edge is compileInner, so you can see which phase drives the scaling.

resource_aggregate — phase composition vs N (v2026.12, median ms) resource_aggregate 17.5× over N 80→640 0.0 628 1255 80 160 320 640 N resource_aggregate — parseTranslationUnit resource_aggregate — SemanticChecking resource_aggregate — generateIR resource_aggregate — frontEndExecute (self) resource_aggregate — specializeModule resource_aggregate — simplifyIR resource_aggregate — linkIR resource_aggregate — unrollLoopsInModule resource_aggregate — legalizeResourceTypes resource_aggregate — legalizeExistentialTypeLayout resource_aggregate — performMandatoryEarlyInlining resource_aggregate — performForceInlining resource_aggregate — linkAndOptimizeIR (self) resource_aggregate — generateOutput (self) resource_aggregate — compileInner (self) phase buckets parseTranslationUnit SemanticChecking generateIR frontEndExecute (self) specializeModule simplifyIR linkIR unrollLoopsInModule legalizeResourceTypes legalizeExistentialTypeLayout performMandatoryEarlyInlining performForceInlining linkAndOptimizeIR (self) emitEntryPointsSourceFromIR generateOutput (self) compileInner (self)

Scaling analysis

floor-subtracted power-law fit (t − floor) = a·Nk; floor = the minimal workload (fixed per-compile cost), k the global exponent, top-2× the local high-end doubling ratio.

N rangefloor (ms)k (work)fit R²t(Nmin)t(Nmax)top-2×
80–640141.490.9966611623.08×

Growth attribution (N=80 → N=640)

compileInner grows by 1096 ms across the sweep; the mutually-exclusive phase buckets below partition that growth exactly (no nested-timer double counting). × lin is the same metric as the top-level panels, per bucket: the end point vs a linear expectation anchored to the bucket's share of the minimal floor and fitted on the low-N half — 1.0 = grew exactly linearly, >1 bends up. The super-linearity lives where × lin (and k) are red.

buckett@N=80t@N=640Δ msshare× lin∝Nk
generateOutput (self)12264+25223%2.57×1.59
linkAndOptimizeIR (self)8230+22220%3.18×1.73
legalizeResourceTypes3208+20519%4.35×1.99
legalizeExistentialTypeLayout2126+12411%4.71×2.02
simplifyIR6101+969%2.05×1.42

Also growing (below top-5): specializeModule (+79 ms, 7%), generateIR (+54 ms, 5%), SemanticChecking (+34 ms, 3%).

Near-constant (≤2% of growth each): compileInner (self) (2→10 ms), frontEndExecute (self) (2→9 ms), linkIR (2→5 ms), performMandatoryEarlyInlining (0→5 ms), performForceInlining (0→4 ms), parseTranslationUnit (1→3 ms), unrollLoopsInModule (0→0 ms).

Sweep numbers (median ms)

NcompileInnerlegalizeResourceTypeslinkAndOptimizeIR
8066331
1601391375
32037754231
6401162208768