Devirtualize monomorphic protocol calls (#227)
When the inference proves a protocol call's receiver is one record type, the back end resolves the impl by that static tag (find-protocol-method) instead of routing through the protocol var -> jolt-invoke -> protocol-resolve, which re-derives the tag and walks the type table. Same table lookup, minus the var-deref, the rest-cons, and the receiver-type computation. Fires only on a monomorphic site: a megamorphic receiver joins to :any and carries no :devirt-type, so it keeps ordinary dispatch (the dispatch bench is unaffected). The annotation comes from the whole-program fixpoint typing a reduce/HOF element or a ctor return as a specific record. Modest on the dispatch benchmarks (~6% on mono-dispatch) — float boxing in the reduce accumulator dominates there, a separate numeric lever — but it removes the dispatch overhead wherever a typed receiver is known. run-devirt.ss gate: emitted form uses find-protocol-method, and evaluating it matches ordinary dispatch for an inline impl, an extend-type impl, and the non-devirt path. make test / shakesmoke green, 0 new divergences. Co-authored-by: Yogthos <yogthos@gmail.com>
This commit is contained in:
parent
09712ec575
commit
af11aaa7ff
4 changed files with 167 additions and 78 deletions
|
|
@ -498,6 +498,18 @@
|
|||
(fn [[f & as]]
|
||||
(str "(jolt-invoke " f (if (seq as) (str " " (str/join " " as)) "") ")"))))]
|
||||
(cond
|
||||
;; devirtualized protocol call: the inference proved the receiver (arg 0) is
|
||||
;; one record type, so resolve the impl by that static tag instead of routing
|
||||
;; through the protocol var -> jolt-invoke -> protocol-resolve (which recomputes
|
||||
;; the tag and walks the type table). find-protocol-method does the same table
|
||||
;; lookup the dispatch would, but with no var-deref, no rest-cons, and no
|
||||
;; receiver-type computation. Fires only on a monomorphic site (a megamorphic
|
||||
;; receiver joins to :any and carries no :devirt-type).
|
||||
(:devirt-type node)
|
||||
(order-args (fn [as]
|
||||
(str "((find-protocol-method " (chez-str-lit (:devirt-type node)) " "
|
||||
(chez-str-lit (:devirt-proto node)) " " (chez-str-lit (:devirt-method node))
|
||||
") " (str/join " " as) ")")))
|
||||
;; hint-directed fast arithmetic: jolt.passes.numeric proved every operand a
|
||||
;; flonum (^double) or fixnum (^long), so emit the Chez fl*/fx* op.
|
||||
(:num-kind node) (emit-numeric (:num-kind node) (:name fnode) args order-args)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue