perf: structural type inference (RFC 0005) — nested access typed, hint-free
Replace the ad-hoc inference lattice (a flat :struct-map tag plus {:vec ELEM})
with one recursive structural type: {:struct {field -> T}}, {:vec T}, {:set T},
scalar tags, and :any. A keyword lookup now returns its field's type, so nested
access like (:r (:direction ray)) is typed end to end and drops its guard. join
is field-wise and element-wise with a depth cap of 4 so the inter-procedural
fixpoint still terminates.
The back end honors a struct hint on any subject node, not just locals, so an
inferred field type on a nested lookup specializes. The orchestrator's fixpoint
joins through the portable join-types so compound types no longer collapse to
:any.
Ray tracer goes 12.8s to 11.0s with no hints, matching the explicit ^:struct
version (10.9s). Render checksum unchanged (1915337), full gate green,
conformance x3 modes pass.
jolt-5uj
This commit is contained in:
parent
e7473f38cf
commit
9bc7b27245
4 changed files with 127 additions and 36 deletions
|
|
@ -29,11 +29,12 @@
|
|||
(def report (backend/infer-unit! ctx "p1"))
|
||||
|
||||
# --- the fixpoint computed the right param types -----------------------------
|
||||
# rd's param v flows from mk's struct-map result (mk inlines to a struct literal
|
||||
# in drv) and stays struct across the recursive self-call -> :struct-map
|
||||
(assert (= :struct-map (in (get report "p1/rd") 0)) (string "rd param v: " (in (get report "p1/rd") 0)))
|
||||
# rd's param v flows from mk's struct result (mk inlines to a struct literal in
|
||||
# drv) and stays struct across the recursive self-call -> a {:struct ...} type
|
||||
(defn struct-type? [t] (truthy? (get t :struct)))
|
||||
(assert (struct-type? (in (get report "p1/rd") 0)) (string "rd param v: " (in (get report "p1/rd") 0)))
|
||||
# esc escaped (passed to mapv) -> param stays unknown (:any / nil), NOT struct
|
||||
(assert (not= :struct-map (in (get report "p1/esc") 0)) "escaping fn param not inferred struct")
|
||||
(assert (not (struct-type? (in (get report "p1/esc") 0))) "escaping fn param not inferred struct")
|
||||
|
||||
# --- the seeded re-inference drops the guard for a struct param --------------
|
||||
# (on a FRESH analysis, since infer-unit! re-stashes the already-specialized body)
|
||||
|
|
@ -42,7 +43,7 @@
|
|||
(def rd-def (backend/analyze-form ctx (reader/parse-string "(defn rdx [v n] (if (< n 1) (:r v) (rdx v (dec n))))")))
|
||||
(defn guards-seeded [ptmap]
|
||||
(length (string/find-all ":jolt/type" (string/format "%p" (backend/emit-ir ctx ((types/var-get reinfer) rd-def ptmap))))))
|
||||
(assert (= 0 (guards-seeded @{"v" :struct-map})) "struct param -> bare lookup")
|
||||
(assert (= 0 (guards-seeded @{"v" {:struct {}}})) "struct param -> bare lookup")
|
||||
(assert (= 1 (guards-seeded @{})) "no param type -> guard kept")
|
||||
|
||||
# --- correctness: recompiled unit still computes the same --------------------
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@
|
|||
|
||||
# a reduce closure's element param gets the vector's element type
|
||||
(def red "(defn f [coll] (reduce (fn [acc h] (+ acc (:r h))) 0 coll))")
|
||||
(assert (= 0 (guards red @{"coll" {:vec :struct-map}})) "reduce element typed -> bare lookup in closure")
|
||||
(assert (= 0 (guards red @{"coll" {:vec {:struct {}}}})) "reduce element typed -> bare lookup in closure")
|
||||
(assert (= 1 (guards red @{"coll" {:vec :any}})) "reduce over vector of unknown -> guard kept")
|
||||
(assert (= 1 (guards red @{})) "untyped coll -> guard kept")
|
||||
|
||||
# mapv over a vector-of-structs types the closure element too
|
||||
(def mp "(defn g [coll] (mapv (fn [h] (:r h)) coll))")
|
||||
(assert (= 0 (guards mp @{"coll" {:vec :struct-map}})) "mapv element typed -> bare lookup")
|
||||
(assert (= 0 (guards mp @{"coll" {:vec {:struct {}}}})) "mapv element typed -> bare lookup")
|
||||
(assert (= 1 (guards mp @{"coll" {:vec :any}})) "mapv over unknown element -> guard")
|
||||
|
||||
# element type is DERIVED, not just seeded: a vector literal of structs, reduced
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue