From afb982b07a7fe3c8386b9414a37d70783543aede Mon Sep 17 00:00:00 2001 From: Peter Bex Date: Sun, 26 May 2019 22:19:26 +0200 Subject: [PATCH] Do not inject unnecessary let with extra variables in multi-arg boolean rewrite Instead of expanding (= a b) to (let ((x a) (y b)) (##core#inline "C_eqp" x y)), we expand to (##core#inline "C_eqp" a b) The extra let would cause a fast procedure call to be split up into CPS when the arguments are captured (this prevents the let from being dropped by the optimizer). We can only do this for the first and the last argument, because the intermediate ones are used twice in the expansion: (= a b c) => (let ((x b)) (##core#inline "C_and" (##core#inline "C_eqp" a x) (##core#inline "C_eqp" x c)) This was found while working on #1604. --- optimizer.scm | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/optimizer.scm b/optimizer.scm index abca38df..fa9d5850 100644 --- a/optimizer.scm +++ b/optimizer.scm @@ -1057,11 +1057,17 @@ (and (or (and unsafe (not (eq? number-type 'generic))) (and (eq? number-type 'fixnum) (third classargs)) (and (eq? number-type 'flonum) (fourth classargs)) ) - (let* ((names (map (lambda (z) (gensym)) callargs)) - (vars (map varnode names)) ) - (let loop ((callargs callargs) + ;; First and last arg are kept as-is because the + ;; injected let can't always be dropped. + (let* ((names (map (lambda (z) (gensym)) + (take (cdr callargs) + (- (length callargs) 2)))) + (vars (append (cons (car callargs) + (map varnode names)) + (list (last callargs))))) + (let loop ((callargs (cdr callargs)) (names names)) - (if (null? callargs) + (if (null? names) (make-node '##core#call (list #t) (list -- 2.11.0