← 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.13.1, median ms) resource_aggregate 6.4× over N 80→640 0.0 176 352 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–640110.990.999513261.99×

Growth attribution (N=80 → N=640)

compileInner grows by 275 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)1070+6022%1.06×1.05
specializeModule646+4015%1.00×1.00
SemanticChecking1347+3412%0.83×0.83
linkAndOptimizeIR (self)536+3111%1.03×1.03
generateIR636+3011%0.96×0.94

Also growing (below top-5): simplifyIR (+24 ms, 9%), legalizeResourceTypes (+20 ms, 7%), compileInner (self) (+9 ms, 3%), frontEndExecute (self) (+7 ms, 3%).

Near-constant (≤2% of growth each): legalizeExistentialTypeLayout (1→6 ms), performMandatoryEarlyInlining (0→5 ms), linkIR (1→5 ms), performForceInlining (0→3 ms), parseTranslationUnit (1→3 ms), unrollLoopsInModule (0→0 ms).

Sweep numbers (median ms)

NcompileInnerlegalizeResourceTypeslinkAndOptimizeIR
8051118
16088335
320163771
64032621149