Fil-C on Nix

Filnix wiki

mbrock/filnix/nanofil

local_storage.pl

Nonescaping memory that remains after scalar promotion.

local_storage_module/2 replaces an entry allocation and its address chain with a named local object and fixed-offset accesses. A local object's address is not a value: it cannot become a heap lower, a call argument or a stored pointer. Pointer *contents* still have ordinary Fil-C capabilities.

Selection is deliberately smaller than escape classification: strict SSA, no returns-twice operation, a constant entry size, and all accesses within the exact size. Heap allocations have rounded bounds; selecting an access in their padding would change the IR's meaning. Overlapping and misaligned accesses remain, with all their checks. Local payload/aux storage is limited to 4096 bytes per function; larger objects and the remainder keep the heap fallback. Plain-mode and checked modules are unchanged.

useslists
usesassoc
usesir
usescfg
usesescape
usespromotestrict_ssa/3
local_storage_module+M0, -Mdet

M has named local objects for the eligible allocations of M0.

31local_storage_moduleM0, M ←
module_modeM0, filc
module_stageM0, unchecked
→
legacy_contextM0, moduleItems0
code_itemsItems0, Code
maplistlocal_itemItems0, Code, Groups
appendGroups, Items
M = moduleItems
else
M = M0
39local_itemAll, F0, Items ←
F0 = funcN, _, _, _, _
context_recordsAll, N, Rs0
local_contextF0, Rs0, F, Rs
with_contextF, Rs, Items
42local_item_, dataN, L, A, Is, dataN, L, A, Is
local_storage_func+F0, -Fdet

F0 is an unchecked Fil-C function. Unknown or unsupported allocation uses keep their heap representation.

48local_storage_funcF0, F ←
local_contextF0, [], F, _
50local_contextF0, Rs0, F, Rs ←
F0 = funcN, L, R, Ps, Bs0
func_cfgBs0, Cfg
cfg_idomsCfg, Idom
strict_ssaF0, Cfg, Idom
address_tempsF0, Addresses
local_objectsF0, Addresses, Objects
Objects ≢ []
→
maplistlocal_blockObjects, Addresses, Bs0, Bs, Maps
appendMaps, Map
remap_sitesRs0, Map, Rs
F = funcN, L, R, Ps, Bs
else
F = F0
Rs = Rs0

Only in-bounds accesses qualify, but not necessarily disjoint ones: those are the objects promote could not turn into SSA values.

65local_objectsF, Addresses, Objects ←
F = func_, _, _, _, Blocks
Blocks = block_, _, Entry, _|_
alloc_classesF, Classes
escape's fixed-slot vocabulary currently excludes float loads.
Missing access events are not evidence that an object is unused.
findallA,
memberblock_, _, Is, _, Blocks
memberlet_, _, loadT, tmpP, Is
get_assocP, Addresses, A−_
,
Unsupported
findallA−Size,
memberA−localconstSize, Accesses, Classes
integerSize
Size ≥ 0
¬memberchkA, Unsupported
memberchklettmpA, p, alloc_, constSize, Entry
maplistaccess_insideSize, Accesses
,
Candidates
within_budgetCandidates, 4096, Objects

Payload and aux round to 16; reserve a header, a root, and alignment slack too. This is selection policy, not a relaxation of local bounds.

87within_budget[], _, []
88within_budgetA−Size|As, Budget, Objects ←
Cost is 2 × Size + 15//16 × 16 + 32
Cost ≤ Budget
→
Objects = A−Size|Rest
Remaining is Budget−Cost
else
Objects = Rest
Remaining = Budget
within_budgetAs, Remaining, Rest
95access_insideSize, accOff, Width ←
width_bytesWidth, Bytes
Off ≥ 0
Off + Bytes ≤ Size
99local_blockObjects, Addresses, blockL, Phis, Is0, Jump, blockL, Phis, Is, Jump, Map ←
local_instsIs0, Objects, Addresses, Is, L, 0, 0, Map
103local_insts[], _, _, [], _, _, _, []
104local_instsI0|Is0, Objects, Addresses, Is, L, Old, New, Map ←
I0 = lettmpA, p, alloc_, constSize
memberchkA−Size, Objects
→
Out = local_allocA, Size
local_accessI0, Objects, Addresses, I
→
Out = I
I0 = lettmpD, p, _, _
get_assocD, Addresses, A−_
memberchkA−_, Objects
→
Out = []
else
Out = I0
appendOut, Rest, Is
emission_sitesL, Old, New, Out, Map, Maps, Next
Old1 is Old + 1
local_instsIs0, Objects, Addresses, Rest, L, Old1, Next, Maps
119local_accessletD, K, loadT, tmpP, Objects, Addresses, local_loadD, K, T, A, Off ←
get_assocP, Addresses, A−Off
memberchkA−_, Objects
122local_accessstoreW, V, tmpP, Objects, Addresses, local_storeW, V, A, Off ←
get_assocP, Addresses, A−Off
memberchkA−_, Objects