Avoid generating arity-adapting zero-value conts where possible
authorAndy Wingo <wingo@igalia.com>
Thu, 30 Nov 2017 17:42:35 +0000 (18:42 +0100)
committerAndy Wingo <wingo@igalia.com>
Fri, 1 Dec 2017 10:01:39 +0000 (11:01 +0100)
* module/language/tree-il/compile-cps.scm (adapt-arity, convert): Avoid
  generating arity-adapting continuations for nullary continuations.

module/language/tree-il/compile-cps.scm

index 4c71dc7d991128308914e9856530e10628b64d69..6afbc17d888acdb2df1c783e8168136c36fd9273 100644 (file)
                          ($continue k src ($values (unspecified))))))
           (letk kvoid ($kargs () () ,body))
           kvoid))
+       (($ $kargs ()) (with-cps cps k))
        (($ $kreceive arity kargs)
         (match arity
           (($ $arity () () (not #f) () #f)
 
 ;; cps exp k-name alist -> cps term
 (define (convert cps exp k subst)
+  (define (zero-valued? exp)
+    (match exp
+      ((or ($ <module-set>) ($ <toplevel-set>) ($ <toplevel-define>)
+           ($ <lexical-set>))
+       #t)
+      (($ <let> src names syms vals body) (zero-valued? body))
+      ;; Can't use <fix> here as the hack that <fix> uses to convert its
+      ;; functions relies on continuation being single-valued.
+      ;; (($ <fix> src names syms vals body) (zero-valued? body))
+      (($ <let-values> src exp body) (zero-valued? body))
+      (($ <seq> src head tail) (zero-valued? tail))
+      (($ <primcall> src name args)
+       (match (prim-instruction name)
+         (#f #f)
+         (inst
+          (match (prim-arity inst)
+            ((out . in)
+             (and (eqv? out 0)
+                  (eqv? in (length args))))))))
+      (_ #f)))
   (define (single-valued? exp)
     (match exp
       ((or ($ <void>) ($ <const>) ($ <primitive-ref>) ($ <module-ref>)
       (($ <let> src names syms vals body) (single-valued? body))
       (($ <fix> src names syms vals body) (single-valued? body))
       (($ <let-values> src exp body) (single-valued? body))
+      (($ <seq> src head tail) (single-valued? tail))
       (($ <primcall> src name args)
        (match (prim-instruction name)
          (#f #f)
                 ($continue k src ($primcall 'box-set! (box exp))))))))))
 
     (($ <seq> src head tail)
-     (with-cps cps
-       (let$ tail (convert tail k subst))
-       (letv vals)
-       (letk kseq ($kargs ('vals) (vals) ,tail))
-       (letk kreceive ($kreceive '() 'vals kseq))
-       ($ (convert head kreceive subst))))
+     (if (zero-valued? head)
+         (with-cps cps
+           (let$ tail (convert tail k subst))
+           (letk kseq ($kargs () () ,tail))
+           ($ (convert head kseq subst)))
+         (with-cps cps
+           (let$ tail (convert tail k subst))
+           (letv vals)
+           (letk kseq ($kargs ('vals) (vals) ,tail))
+           (letk kreceive ($kreceive '() 'vals kseq))
+           ($ (convert head kreceive subst)))))
 
     (($ <let> src names syms vals body)
      (let lp ((cps cps) (names names) (syms syms) (vals vals))