lower_roots.pl
Shared lowers: a derived pointer's lowers[] entry is its lower root's (docs/lowers.md). Opt-in as --lowers=shared; the default, own, gives every pointer temporary an entry of its own.
A capability's lower never changes, and a flight with lowerP has P's lower, whatever its address. So a flight needs no entry of its own when the entry of the pointer it derives from still holds that lower wherever the flight is live; nor does a phi whose inputs all have one lower root. This module chooses those pointers (the producer); frame_slots.pl keeps each root's entry for as long as any of its derived pointers is live; filc_amd64.pl emits no lower load or store for a flight whose donor's entry is its own, nor for a phi whose inputs' entries are all its own; and lowers_check.pl validates the resulting frame, so none of these is trusted for the GC-root contract.
The rule
| Term | Means |
|---|---|
D-R in Derived | the pointer tmpD shares the entry of its lower root tmpR |
It is FilPizlonator's computeLowerRoots (staging 18b6663, FilPizlonator.cpp:2914-3004) for nanofil's two derivations. Every pointer starts as its own root; then, until nothing changes, in reachable blocks and for names with one definition:
- a flight
flighttmpD, Op, Args, lowertmpPhas P's root; - a phi of class p has the root C of its inputs when all of them are temporaries with one definition, every input other than the phi itself has root C, and C is a parameter or is defined in another block that dominates the phi's. Without that, C could be defined in the phi's own loop, after it, and be written again while the phi still holds C's previous lower.
Definitions are counted on the liveness view (fused accesses bare, uses/2 unwrapped), so a fused pointer load cannot hide a second definition (docs/perf.md item 17's review). Functions with setjmp are left alone: longjmp restores lowers[] (docs/setjmp.md). If the roots have not settled after 32 rounds, nothing is shared.
Mode is NANOFIL_LOWERS (main.pl's --lowers=): own, the default, or shared.
Derived maps each pointer D that shares its root's lowers[] entry to that root R (the rule above). Empty for a function with setjmp.
a single-definition flight with a single-definition donor, or a single-definition pointer phi of block L whose inputs are all single-definition temporaries.
the fixpoint of one pass over the candidates, each pointing at the root its rule gives; fails after 32 rounds.