See through or/and in truthy-elision (#224)

A loop test like (or (>= i cap) (> ... 4.0)) desugars to
(let* [g (>= i cap)] (if (truthy? g) g (> ... 4.0))) and the whole thing was
wrapped in jolt-truthy? because returns-scheme-bool? only looked at :const and
:invoke nodes, not the let*/if an or/and expands to. The wrapper defeats Chez's
branch inlining on the hot loop edge.

Make returns-scheme-bool? recursive over :if (both branches bool), :let (body
bool, tracking which bound locals hold a Scheme boolean), and :local (in that
set). or/and over bool-returning ops then read as Scheme booleans and the outer
wrapper drops. Still sound: eliding only when the value is provably #t/#f — a
jolt-nil is a truthy record in Chez, so a false positive would be a real bug, and
the recursion only proves bool-ness through ops already known to return one.

No bench regression; the win lands on hinted float loops where the branch, not
boxed arithmetic, is the cost.

Co-authored-by: Yogthos <yogthos@gmail.com>
This commit is contained in:
Dmitri Sotnikov 2026-06-26 06:11:35 +00:00 committed by GitHub
parent 0a7e818700
commit 93be40f3fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 131 additions and 113 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -566,14 +566,32 @@
core)))
;; Does this IR node emit to an expression that yields a Scheme boolean? Used to
;; drop the redundant jolt-truthy? on an :if test.
(defn- returns-scheme-bool? [node]
(cond
(and (= :const (:op node)) (boolean? (:val node))) true
(= :invoke (:op node))
(let [nop (native-op (:fn node) (count (:args node)))]
(if (and nop (bool-returning-ops nop)) true false))
:else false))
;; drop the redundant jolt-truthy? on an :if test. Sees through the let*/if an
;; (or ...)/(and ...) of bool-returning ops desugars to: `or` is
;; (let* [g E1] (if (truthy? g) g E2)), `and` is (let* [g E1] (if (truthy? g) E2 g))
;; — both return a Scheme boolean when E1/E2 are bool ops, since the value yielded
;; is always one of the (boolean) operand results. `bools` tracks let-bound locals
;; proven to hold a Scheme boolean.
(defn- returns-scheme-bool?
([node] (returns-scheme-bool? node #{}))
([node bools]
(cond
(and (= :const (:op node)) (boolean? (:val node))) true
(= :invoke (:op node))
(let [nop (native-op (:fn node) (count (:args node)))]
(boolean (and nop (bool-returning-ops nop))))
(= :local (:op node)) (contains? bools (:name node))
(= :if (:op node))
(and (returns-scheme-bool? (:then node) bools)
(returns-scheme-bool? (:else node) bools))
(= :let (:op node))
(let [bools' (reduce (fn [s b]
(if (returns-scheme-bool? (nth b 1) s)
(conj s (nth b 0))
(disj s (nth b 0))))
bools (:bindings node))]
(returns-scheme-bool? (:body node) bools'))
:else false)))
(defn emit [node]
(case (:op node)