Skip to content

v0.14.0 default-on local promotion register-exhausts on denser functions (control_step) — compile FAILURE, was fine on 0.12.0; cost-gate needs reg-pressure awareness #474

Description

@avrabe

v0.14.0 default-on local promotion register-exhausts on control_step (compile FAILURE on a denser real function)

The local-promotion lever (v0.14.0 default-on, #462) is a net win on gust_mix (2 locals — confirmed −14% on G474RE silicon). But on a denser real function it turns a working compile into a hard failure.

Repro: gale's control_step_packed (the engine_control algorithm — table lookups + integer corrections + the spark/fuel packing; ~5 i32 locals, 14 loads/8 stores), dissolved wasm→loom→synth --target cortex-m3 --native-pointer-abi --shadow-stack-size 8192 --all-exports --relocatable:

synth 0.14.0 (default, promotion on):
  warning: skipping function 'control_step_packed': backend 'arm' failed:
  instruction selection failed: Synthesis failed: register exhaustion:
  all allocatable registers are live on the stack — function too complex
  for current register allocator
  Error: no functions compiled successfully — nothing to emit

synth 0.14.0 + SYNTH_NO_LOCAL_PROMOTE=1:
  Compiled 1 functions  (.text 534 B)   ← compiles fine

It compiled on v0.12.0 (pre-promotion). So default-on promotion regressed it from compilable to skipped. The cause is exactly what you flagged when handing me the lever: promotion claims callee-saved regs for the locals, and on a function with enough live values the allocator then has nowhere to spill → exhaustion. gust_mix (2 locals) had headroom; control_step doesn't.

Ask: make the promotion eligibility register-pressure-aware — decline (or partially promote) when promoting would push peak pressure past what the allocator can color, rather than failing instruction selection. The shadow allocator / peak-pressure analysis you already have (function_peak_pressure) is the natural gate: promote up to available_regs − reserved, frame-slot the rest. A compile failure on a real function is worse than the spill it was avoiding.

Workaround in the field: SYNTH_NO_LOCAL_PROMOTE=1 (or the escape-hatch env) restores the working lowering. gale's gust_control demonstrator (engine_control driven on the kiln stack) ships built with it for now.

Refs: synth#428 (lever tracker); the lever is #462/#458. I can re-check on the G474RE/ESP32-C3 once the cost-gate lands.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions