guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 02/03: Primcall inlining in eval.scm, lazy function body


From: Andy Wingo
Subject: [Guile-commits] 02/03: Primcall inlining in eval.scm, lazy function body compilation
Date: Thu, 12 Mar 2015 13:32:49 +0000

wingo pushed a commit to branch master
in repository guile.

commit d76d80d23cc001c6582fa5ca40e552815311335a
Author: Andy Wingo <address@hidden>
Date:   Thu Mar 12 14:06:15 2015 +0100

    Primcall inlining in eval.scm, lazy function body compilation
    
    * module/ice-9/eval.scm (primitive-eval): Lazily compile lambda bodies.
      Special-case calls to top-level or module variables, and recognize
      some of those calls as primcalls.  In that case, emit closures with
      the primcalls.
---
 module/ice-9/eval.scm |  125 +++++++++++++++++++++++++++++++++++++------------
 1 files changed, 95 insertions(+), 30 deletions(-)

diff --git a/module/ice-9/eval.scm b/module/ice-9/eval.scm
index 225a4bc..89e667c 100644
--- a/module/ice-9/eval.scm
+++ b/module/ice-9/eval.scm
@@ -111,26 +111,60 @@
          (or (memoized-typecode (syntax->datum #'type))
              (error "not a typecode" (syntax->datum #'type)))))))
 
+  (define-syntax-rule (lazy (arg ...) exp)
+    (letrec ((proc (lambda (arg ...)
+                     (set! proc exp)
+                     (proc arg ...))))
+      (lambda (arg ...)
+        (proc arg ...))))
+
   (define (compile-lexical-ref depth width)
     (lambda (env)
       (env-ref env depth width)))
 
-  (define (compile-call f args)
-    (let ((f (compile f)))
+  (define (compile-top-call cenv loc args)
+    (let* ((module (env-toplevel cenv))
+           (var (%resolve-variable loc module)))
+      (define (primitive=? name)
+        "Return true if VAR is the same as the primitive bound to NAME."
+        (match loc
+          ((mode . loc)
+           (and (match loc
+                  ((mod name* . public?) (eq? name* name))
+                  (_ (eq? loc name)))
+                ;; `module' can be #f if the module system was not yet
+                ;; booted when the environment was captured.
+                (or (not module)
+                    (eq? var (module-local-variable the-root-module name)))))))
+      (define-syntax-rule (maybe-primcall (prim ...) arg ...)
+        (cond
+         ((primitive=? 'prim) (lambda (env) (prim (arg env) ...)))
+         ...
+         (else (lambda (env) ((variable-ref var) (arg env) ...)))))
       (match args
-        (() (lambda (env) ((f env))))
+        (()
+         (lambda (env) ((variable-ref var))))
         ((a)
          (let ((a (compile a)))
-           (lambda (env) ((f env) (a env)))))
+           (maybe-primcall
+            (null? nil? pair? struct? string? vector? symbol?
+             keyword? variable? bitvector? char? zero?
+             1+ 1- car cdr lognot not vector-length
+             variable-ref string-length struct-vtable)
+            a)))
         ((a b)
          (let ((a (compile a))
                (b (compile b)))
-           (lambda (env) ((f env) (a env) (b env)))))
+           (maybe-primcall
+            (+ - * / eq? eqv? equal? = < > <= >=
+               ash logand logior logxor logtest logbit?
+               cons vector-ref struct-ref allocate-struct variable-set!)
+            a b)))
         ((a b c)
          (let ((a (compile a))
                (b (compile b))
                (c (compile c)))
-           (lambda (env) ((f env) (a env) (b env) (c env)))))
+           (maybe-primcall (vector-set! struct-set!) a b c)))
         ((a b c . args)
          (let ((a (compile a))
                (b (compile b))
@@ -140,22 +174,57 @@
                            '()
                            (cons (compile (car args)) (lp (cdr args)))))))
            (lambda (env)
-             (apply (f env) (a env) (b env) (c env)
+             (apply (variable-ref var) (a env) (b env) (c env)
                     (let lp ((args args))
                       (if (null? args)
                           '()
                           (cons ((car args) env) (lp (cdr args))))))))))))
 
-  (define (compile-box-ref box)
+  (define (compile-call f args)
+    (match f
+      ((,(typecode box-ref) . (,(typecode resolve) . loc))
+       (lazy (env) (compile-top-call env loc args)))
+      (_
+       (match args
+         (()
+          (let ((f (compile f)))
+            (lambda (env) ((f env)))))
+         ((a)
+          (let ((f (compile f))
+                (a (compile a)))
+            (lambda (env) ((f env) (a env)))))
+         ((a b)
+          (let ((f (compile f))
+                (a (compile a))
+                (b (compile b)))
+            (lambda (env) ((f env) (a env) (b env)))))
+         ((a b c)
+          (let ((f (compile f))
+                (a (compile a))
+                (b (compile b))
+                (c (compile c)))
+            (lambda (env) ((f env) (a env) (b env) (c env)))))
+         ((a b c . args)
+          (let ((f (compile f))
+                (a (compile a))
+                (b (compile b))
+                (c (compile c))
+                (args (let lp ((args args))
+                        (if (null? args)
+                            '()
+                            (cons (compile (car args)) (lp (cdr args)))))))
+            (lambda (env)
+              (apply (f env) (a env) (b env) (c env)
+                     (let lp ((args args))
+                       (if (null? args)
+                           '()
+                           (cons ((car args) env) (lp (cdr args)))))))))))))
+
+  (define (compile-box-ref cenv box)
     (match box
-      ((,(typecode resolve) . var-or-loc)
-       (lambda (env)
-         (cond
-          ((variable? var-or-loc) (variable-ref var-or-loc))
-          (else
-           (set! var-or-loc
-                 (%resolve-variable var-or-loc (env-toplevel env)))
-           (variable-ref var-or-loc)))))
+      ((,(typecode resolve) . loc)
+       (let ((var (%resolve-variable loc (env-toplevel cenv))))
+         (lambda (env) (variable-ref var))))
       ((,(typecode lexical-ref) depth . width)
        (lambda (env)
          (variable-ref (env-ref env depth width))))
@@ -164,13 +233,9 @@
          (lambda (env)
            (variable-ref (box env)))))))
 
-  (define (compile-resolve var-or-loc)
-    (lambda (env)
-      (cond
-       ((variable? var-or-loc) var-or-loc)
-       (else
-        (set! var-or-loc (%resolve-variable var-or-loc (env-toplevel env)))
-        var-or-loc))))
+  (define (compile-resolve cenv loc)
+    (let ((var (%resolve-variable loc (env-toplevel cenv))))
+      (lambda (env) var)))
 
   (define (compile-if test consequent alternate)
     (let ((test (compile test))
@@ -477,7 +542,7 @@
                                (let ((proc (proc env)))
                                  (set-procedure-property! proc prop val)
                                  proc))))))
-    (let ((body (compile body)))
+    (let ((body (lazy (env) (compile body))))
       (set-procedure-meta
        meta
        (match tail
@@ -560,10 +625,10 @@
        (compile-call f args))
       
       ((,(typecode box-ref) . box)
-       (compile-box-ref box))
+       (lazy (env) (compile-box-ref env box)))
 
-      ((,(typecode resolve) . var-or-loc)
-       (compile-resolve var-or-loc))
+      ((,(typecode resolve) . loc)
+       (lazy (env) (compile-resolve env loc)))
 
       ((,(typecode if) test consequent . alternate)
        (compile-if test consequent alternate))
@@ -604,10 +669,10 @@
       ((,(typecode call/cc) . proc)
        (compile-call/cc proc))))
 
-  (let ((proc (compile
-               (memoize-expression 
+  (let ((eval (compile
+               (memoize-expression
                 (if (macroexpanded? exp)
                     exp
                     ((module-transformer (current-module)) exp)))))
         (env #f))
-    (proc env)))
+    (eval env)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]