Hintless whole-program double inference (#230)
The closed-world fixpoint (#226) flowed record types across fn boundaries; this adds a numeric refinement so a hintless fn whose every call site passes a flonum has its param unboxed to fl-ops, no ^double hint needed. Lattice gains :double, a flonum refinement of :num: two doubles join to :double, a double joined with anything else widens to :num — so a param is :double only when every contributing value is a flonum, which is what makes the fl-op sound. infer types a flonum literal and flonum arithmetic (+ - * / min max inc dec over double/int-literal operands) as :double, and the fixpoint joins those across call sites and return types like any other lattice value. The bridge to the existing hint-directed pass is a synthetic [param :double] nhint: wp-infer! stashes the :double params separately from the structural seeds, and run-passes injects them as nhints before numeric/annotate, so the fl-op emission and the exact->inexact entry coercion (a no-op on a proven flonum) apply unchanged. Sound subset only: :double, never :long — an untyped integer can be a bignum and fx-ops would overflow/diverge from jolt's arbitrary precision. So an integer caller leaves a param generic; an escaped fn (unknown callers) keeps :any. run-numwp.ss gate: cross-fn :double propagation incl. through a flonum-returning helper, the integer-caller and escape negatives, and the full run-passes path emitting fl* + entry coercion. make test / shakesmoke green, selfhost holds, 0 new divergences. Co-authored-by: Yogthos <yogthos@gmail.com>
This commit is contained in:
parent
e6e3612332
commit
8ae45057d6
6 changed files with 453 additions and 268 deletions
|
|
@ -22,7 +22,7 @@
|
|||
set-rtenv! set-vtypes! join-types
|
||||
set-record-shapes! set-map-shapes! set-protocol-methods!
|
||||
reset-escapes! collected-escapes
|
||||
wp-infer! param-seeds-for
|
||||
wp-infer! param-seeds-for param-num-seeds-for
|
||||
set-check-mode! take-diags!]]))
|
||||
|
||||
;; Cap on inline -> flatten -> scalar-replace -> const-fold iterations. Each pass
|
||||
|
|
@ -40,6 +40,22 @@
|
|||
(let [a (first (:arities (:init node)))]
|
||||
{:params (:params a) :body (:body a) :nhints (:nhints a) :ret (:ret-nhint a)}))
|
||||
|
||||
(defn inject-wp-nhints
|
||||
"Merge the whole-program :double param seeds into a def's arity :nhints as
|
||||
synthetic ^double hints, so the numeric pass unboxes a hintless fn whose callers
|
||||
all pass flonums (the entry coercion exact->inexact is a no-op on a proven
|
||||
flonum). Only un-hinted params are added — an explicit hint wins. A no-op unless
|
||||
the closed-world fixpoint typed a param :double (param-num-seeds-for)."
|
||||
[node]
|
||||
(let [seeds (when (= :def (:op node)) (param-num-seeds-for (str (:ns node) "/" (:name node))))
|
||||
f (:init node)]
|
||||
(if (and seeds (= :fn (:op f)) (= 1 (count (:arities f))))
|
||||
(let [a (first (:arities f))
|
||||
have (into #{} (map first (:nhints a)))
|
||||
add (for [[p k] seeds :when (not (have p))] [p k])]
|
||||
(assoc node :init (assoc f :arities [(assoc a :nhints (vec (concat (:nhints a) add)))])))
|
||||
node)))
|
||||
|
||||
(defn run-passes
|
||||
"All passes, in order. The back end applies this to every analyzed form. When
|
||||
inlining is enabled for the unit (user code under direct-linking),
|
||||
|
|
@ -75,6 +91,7 @@
|
|||
;; everything else takes the ordinary per-form inference.
|
||||
seeds (when (= :def (:op opt)) (param-seeds-for (str (:ns opt) "/" (:name opt))))]
|
||||
;; a final const-fold after inference propagates any predicate folded to a
|
||||
;; constant, collapsing the `if` it gates to the taken branch.
|
||||
(const-fold (if seeds (reinfer-def opt seeds) (run-inference opt))))
|
||||
;; constant, collapsing the `if` it gates to the taken branch; then inject
|
||||
;; any whole-program :double param hints for the numeric pass that follows.
|
||||
(inject-wp-nhints (const-fold (if seeds (reinfer-def opt seeds) (run-inference opt)))))
|
||||
(const-fold node))))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue