Commit 3fe83fe
authored
IxVM: cut Aiur-kernel ingress cost (per-pass width + CheckEnv ingest-once) (#432)
* IxVM: cut ingress/conversion circuit width in the Aiur kernel
FFT-cost optimizations on the kernel's ingress + Ixon-to-kernel-type
conversion path (the dominant cost when verifying a whole environment of
many constants).
Measured with `ix check --ixe arena.ixe --claim <digest>` over the
TutorialDefs arena env (780 constants): total Aiur FFT cost
7,159,028,984 -> 6,196,095,030 (-13.5%). No behavior change: the
check-env claim typechecks identically and the rbtree-map test passes.
convert_expr: pass the expression by pointer
- convert_expr / ctx_convert_expr take `e: &Expr` and `load` inside,
instead of receiving the Expr flattened by value on every call. An
enum-valued argument is laid out at its widest constructor, so this cuts
inputSize: width 112 -> 68 (~-39% on that circuit). Recursive arms
forward child pointers directly and the Share arm forwards the interned
pointer (dropping a load). Memoization identity is preserved, since a
pointer and its interned value coincide.
RBTreeMap: one comparison per node instead of two
- lookup / lookup_or_default / ins replace the second `u32_less_than(k, key)`
with a field equality `key - k == 0`. By field trichotomy this is
equivalent, and it saves +12 aux / +6 lookups per node (u32_less_than is
the expensive gadget). lookup_or_default 85 -> 62w, ins 98 -> 75w.
RBTreeMap: factor the cold rebalance path out of balance
- rbtree_map_balance becomes a narrow color dispatch; the four wide
Okasaki rebalance cases (red-grandchild deref + 3-node rebuild) move to
rbtree_map_balance_fix. Aiur lays a function's width as the max over its
match arms, so the red-parent hot path no longer carries the rebalance
machinery: balance 122 -> 32w.
lookup_addr_pos: O(log) fast path with a sound content fallback
- The ref-address -> kernel-position lookup was an O(N) linear address_eq
scan (the largest single ingress hotspot). It now first probes an
interned ptr_val-keyed map (build_addr_pos_map, value = pos+1 so the
default 0 means absent) and only falls back to the content-based
address_eq scan (lookup_addr_pos_linear) on a miss. This is sound: a
ptr_val hit implies content equality (the positive direction), and a
de-interned pointer or a non-constant blob ref simply misses and takes
the content scan, which returns 0 if truly absent. Honest constant refs
hit the tree, so the linear scan is reduced to blob/fallback rows.
Consolidate the two ptr_val membership/position maps into one
- Delete build_addr_set: addr_pos_map already keys every constant address,
so is_blob becomes a presence test against it (present iff constant; the
stored position is irrelevant there). This removes a whole map build from
ingress. The de-intern direction stays conservative -- a de-interned
constant reads as a blob, which is content-bound and harmless. Also
removes now-dead helpers find_block_addr_from_refs,
find_matching_block_addr, count_block_ctors, recr_rule_count and
count_recr_rules (only self-recursive; the recursor block is resolved via
rec_typ_to_inductive_addr).
Document the ptr_val-key soundness invariant on build_addr_pos_map: a
pointer maps to exactly one stored value, so distinct contents can never be
conflated; a de-intern only ever makes a present key read as absent. Hence
ptr_val keys are safe only where a false "absent" is conservative -- which
is why lookup_addr_pos keeps its content-based fallback.
* IxVM: CheckEnv ingests the env once instead of per leaf
`check_env_iter` re-ran the full `ingress_with_primitives(leaf)` pipeline
for every env leaf, re-deriving the layout/positioning/convert/addr-table
passes over each leaf's (heavily overlapping) closure. Those passes are
keyed by per-leaf list arguments, so Aiur's content-memoization did not
collapse them across leaves — only the content-keyed `load_verified_*` /
`convert_*` were deduped. So the addressing machinery ran ~N times over
overlapping data.
Ingress the union closure of all env leaves ONCE (one `load_with_deps`
with leaves[0] as target and the rest as the initial worklist), then check
every constant via the same `check_all_skipping` path `run_check` already
uses. Factor the shared post-load pipeline into `finish_ingress` and add
`ingress_env`; `run_check_env` now mirrors `run_check` over a closure that
happens to be the whole env.
Soundness: unchanged checking. Every constant is still checked once
(`check_const` runs 711×, = env consts + primitives), and the single
`check_canonical_block_sort(top)` over the union is a stronger global order
than the per-leaf closures it replaces — refs resolve by content, so the
union check cannot accept what a per-leaf check would reject. The adversarial
arena BAD fixtures still reject.
Measured with `ix check --ixe arena.ixe --claim <CheckEnv-digest>` over the
TutorialDefs arena (694 consts): total Aiur FFT cost
6,196,095,030 -> 3,319,451,741 (-46.4%). `lake test -- --ignored ixvm`:
297 pass, 0 fail.1 parent 11996af commit 3fe83fe
4 files changed
Lines changed: 191 additions & 211 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
136 | 136 | | |
137 | 137 | | |
138 | 138 | | |
139 | | - | |
| 139 | + | |
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
144 | 144 | | |
145 | 145 | | |
146 | | - | |
| 146 | + | |
147 | 147 | | |
148 | 148 | | |
149 | 149 | | |
| |||
161 | 161 | | |
162 | 162 | | |
163 | 163 | | |
164 | | - | |
| 164 | + | |
165 | 165 | | |
166 | 166 | | |
167 | 167 | | |
| |||
177 | 177 | | |
178 | 178 | | |
179 | 179 | | |
180 | | - | |
| 180 | + | |
181 | 181 | | |
182 | 182 | | |
183 | 183 | | |
184 | 184 | | |
185 | | - | |
| 185 | + | |
186 | 186 | | |
187 | 187 | | |
188 | 188 | | |
189 | 189 | | |
190 | | - | |
| 190 | + | |
191 | 191 | | |
192 | 192 | | |
193 | 193 | | |
194 | 194 | | |
195 | | - | |
| 195 | + | |
196 | 196 | | |
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
202 | | - | |
203 | | - | |
| 202 | + | |
204 | 203 | | |
205 | 204 | | |
206 | 205 | | |
207 | | - | |
| 206 | + | |
208 | 207 | | |
209 | 208 | | |
210 | 209 | | |
| |||
226 | 225 | | |
227 | 226 | | |
228 | 227 | | |
229 | | - | |
| 228 | + | |
230 | 229 | | |
231 | 230 | | |
232 | 231 | | |
| |||
245 | 244 | | |
246 | 245 | | |
247 | 246 | | |
248 | | - | |
| 247 | + | |
249 | 248 | | |
250 | 249 | | |
251 | 250 | | |
| |||
266 | 265 | | |
267 | 266 | | |
268 | 267 | | |
269 | | - | |
| 268 | + | |
270 | 269 | | |
271 | 270 | | |
272 | 271 | | |
273 | 272 | | |
274 | 273 | | |
275 | 274 | | |
276 | 275 | | |
277 | | - | |
| 276 | + | |
278 | 277 | | |
279 | 278 | | |
280 | 279 | | |
| |||
283 | 282 | | |
284 | 283 | | |
285 | 284 | | |
286 | | - | |
| 285 | + | |
287 | 286 | | |
288 | 287 | | |
289 | 288 | | |
| |||
296 | 295 | | |
297 | 296 | | |
298 | 297 | | |
299 | | - | |
| 298 | + | |
300 | 299 | | |
301 | 300 | | |
302 | 301 | | |
| |||
306 | 305 | | |
307 | 306 | | |
308 | 307 | | |
309 | | - | |
| 308 | + | |
310 | 309 | | |
311 | 310 | | |
312 | 311 | | |
| |||
0 commit comments