chicken-hackers
[Top][All Lists]
Advanced

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

[Chicken-hackers] [PATCH] remove unboxing


From: Felix
Subject: [Chicken-hackers] [PATCH] remove unboxing
Date: Wed, 21 Dec 2011 21:37:22 +0100 (CET)

The attached patch removes the unboxing pass from the compiler.  It
never worked reliably and has evolved into an unmaintainable
mess. This will result in a reduction of runtime performance for
unsafe floating-point intensive code.

>From 477976e29fa7ba09f86bff410f6747c9d0ebd822 Mon Sep 17 00:00:00 2001
From: felix <address@hidden>
Date: Wed, 21 Dec 2011 09:03:53 +0100
Subject: [PATCH] removed unboxing completely

---
 batch-driver.scm           |    7 -
 c-platform.scm             |    2 +-
 chicken.scm                |    4 +-
 compiler-namespace.scm     |    1 -
 csc.scm                    |    3 +-
 distribution/manifest      |    3 -
 manual/Using the compiler  |    6 +-
 rules.make                 |    2 +-
 support.scm                |    2 -
 tests/compiler-tests-3.scm |   52 ----
 tests/runtests.bat         |    6 -
 tests/runtests.sh          |    4 -
 unboxing.scm               |  559 --------------------------------------------
 13 files changed, 6 insertions(+), 645 deletions(-)
 delete mode 100644 tests/compiler-tests-3.scm
 delete mode 100644 unboxing.scm

diff --git a/batch-driver.scm b/batch-driver.scm
index cd1cd60..0521c74 100644
--- a/batch-driver.scm
+++ b/batch-driver.scm
@@ -90,7 +90,6 @@
        (uunit (memq 'unit options))
        (a-only (memq 'analyze-only options))
        (dynamic (memq 'dynamic options))
-       (unbox (memq 'unboxing options))
        (do-scrutinize (memq 'scrutinize options))
        (dumpnodes #f)
        (start-time #f)
@@ -649,12 +648,6 @@
                                       (> (- (cputime) start-time) 
funny-message-timeout))
                              (display "(don't worry - still compiling...)\n") )
                            (print-node "closure-converted" '|9| node2)
-                           (when (and unbox unsafe)
-                             (debugging 'p "performing unboxing")
-                             (begin-time)
-                             (perform-unboxing! node2)
-                             (end-time "unboxing")
-                             (print-node "unboxing" '|U| node2) )
                            (when a-only (exit 0))
                            (begin-time)
                            (receive 
diff --git a/c-platform.scm b/c-platform.scm
index fb9c4bd..b2161d4 100644
--- a/c-platform.scm
+++ b/c-platform.scm
@@ -93,7 +93,7 @@
     no-parentheses-synonyms no-symbol-escape r5rs-syntax 
emit-all-import-libraries
     strict-types clustering
     lambda-lift                                ; OBSOLETE
-    setup-mode unboxing no-module-registration) )
+    setup-mode no-module-registration) )
 
 (define valid-compiler-options-with-argument
   '(debug 
diff --git a/chicken.scm b/chicken.scm
index e353a3e..1bf2591 100644
--- a/chicken.scm
+++ b/chicken.scm
@@ -28,7 +28,7 @@
 (declare
   (uses chicken-syntax chicken-ffi-syntax 
        srfi-1 srfi-4 utils files extras data-structures support
-       compiler optimizer unboxing compiler-syntax scrutinizer driver platform 
backend 
+       compiler optimizer compiler-syntax scrutinizer driver platform backend 
        srfi-69))
 
 
@@ -104,7 +104,6 @@
                             'inline 
                             'inline-global
                             'specialize
-                            'unboxing 
                             ;XXX 'clustering
                             'local 'unsafe
                             options) ) )
@@ -123,7 +122,6 @@
                               'inline
                               'inline-global
                               'clustering
-                              'unboxing
                               options) ) ) ) )
                 (loop (cdr rest)) ) )
              ((eq? 'debug-level o)
diff --git a/compiler-namespace.scm b/compiler-namespace.scm
index 9cf865f..de11811 100644
--- a/compiler-namespace.scm
+++ b/compiler-namespace.scm
@@ -222,7 +222,6 @@
  perform-high-level-optimizations
  perform-inlining!
  perform-pre-optimization!
- perform-unboxing!
  posq
  postponed-initforms
  pprint-expressions-to-file
diff --git a/csc.scm b/csc.scm
index 88992ca..e479ae7 100644
--- a/csc.scm
+++ b/csc.scm
@@ -137,7 +137,7 @@
     -analyze-only -keep-shadowed-macros -inline-global -ignore-repository
     -no-symbol-escape -no-parentheses-synonyms -r5rs-syntax
     -no-argc-checks -no-bound-checks -no-procedure-checks -no-compiler-syntax
-    -emit-all-import-libraries -setup-mode -unboxing -no-elevation 
-no-module-registration
+    -emit-all-import-libraries -setup-mode -no-elevation 
-no-module-registration
     -no-procedure-checks-for-usual-bindings -module
     -specialize -strict-types -clustering
     -lambda-lift                       ; OBSOLETE
@@ -383,7 +383,6 @@ Usage: #{csc} FILENAME | OPTION ...
     -inline                        enable inlining
     -inline-limit LIMIT            set inlining threshold
     -inline-global                 enable cross-module inlining
-    -unboxing                      use unboxed temporaries if possible
     -specialize                    perform type-based specialization of 
primitive calls
     -n -emit-inline-file FILENAME  generate file with globally inlinable
                                     procedures (implies -inline -local)
diff --git a/distribution/manifest b/distribution/manifest
index 03d9e35..6c02c34 100644
--- a/distribution/manifest
+++ b/distribution/manifest
@@ -27,7 +27,6 @@ lolevel.c
 optimizer.c
 compiler-syntax.c
 scrutinizer.c
-unboxing.c
 irregex.c
 posixunix.c
 posixwin.c
@@ -76,7 +75,6 @@ lolevel.scm
 optimizer.scm
 compiler-syntax.scm
 scrutinizer.scm
-unboxing.scm
 irregex.scm
 irregex-core.scm
 irregex-utils.scm
@@ -109,7 +107,6 @@ tests/arithmetic-test.32.expected
 tests/arithmetic-test.64.expected
 tests/library-tests.scm
 tests/compiler-tests.scm
-tests/compiler-tests-3.scm
 tests/inlining-tests.scm
 tests/locative-stress-test.scm
 tests/r4rstest.scm
diff --git a/manual/Using the compiler b/manual/Using the compiler
index fbc1cab..0d4c09a 100644
--- a/manual/Using the compiler 
+++ b/manual/Using the compiler 
@@ -125,8 +125,8 @@ the source text should be read from standard input.
      -optimize-level 1          is equivalent to -optimize-leaf-routines
      -optimize-level 2          is equivalent to -optimize-leaf-routines 
-inline
      -optimize-level 3          is equivalent to -optimize-leaf-routines 
-local -inline -inline-global -specialize
-     -optimize-level 4          is equivalent to -optimize-leaf-routines 
-local -inline -inline-global -unboxing -specialize -unsafe
-     -optimize-level 5          is equivalent to -optimize-leaf-routines 
-block -inline -inline-global -unboxing -specialize -unsafe -disable-interrupts 
-no-trace -no-lambda-info
+     -optimize-level 4          is equivalent to -optimize-leaf-routines 
-local -inline -inline-global -specialize -unsafe
+     -optimize-level 5          is equivalent to -optimize-leaf-routines 
-block -inline -inline-global -specialize -unsafe -disable-interrupts -no-trace 
-no-lambda-info
 
 ; -output-file FILENAME : Specifies the pathname of the generated C file. 
Default is {{FILENAME.c}}.
 
@@ -161,8 +161,6 @@ the source text should be read from standard input.
 
 ; -to-stdout : Write compiled code to standard output instead of creating a 
{{.c}} file.
 
-; -unboxing : try to use unboxed temporaries for numerical operations. This 
optimization is only effective in unsafe mode.
-
 ; -unit NAME : Compile this file as a library unit. Equivalent to {{-prelude 
"(declare (unit NAME))"}}
 
 ; -unsafe : Disable runtime safety checks.
diff --git a/rules.make b/rules.make
index f19972f..7ec8613 100644
--- a/rules.make
+++ b/rules.make
@@ -44,7 +44,7 @@ LIBCHICKEN_SHARED_OBJECTS = $(LIBCHICKEN_OBJECTS_1:=$(O))
 LIBCHICKEN_STATIC_OBJECTS = $(LIBCHICKEN_OBJECTS_1:=-static$(O))
 
 COMPILER_OBJECTS_1 = \
-       chicken batch-driver compiler optimizer compiler-syntax scrutinizer 
unboxing support \
+       chicken batch-driver compiler optimizer compiler-syntax scrutinizer 
support \
        c-platform c-backend
 COMPILER_OBJECTS        = $(COMPILER_OBJECTS_1:=$(O))
 COMPILER_STATIC_OBJECTS = $(COMPILER_OBJECTS_1:=-static$(O))
diff --git a/support.scm b/support.scm
index 97ba03a..c02dc89 100644
--- a/support.scm
+++ b/support.scm
@@ -1670,7 +1670,6 @@ Usage: chicken FILENAME OPTION ...
     -inline-limit LIMIT          set inlining threshold
     -inline-global               enable cross-module inlining
     -specialize                  perform type-based specialization of 
primitive calls
-    -unboxing                    use unboxed temporaries if possible
     -emit-inline-file FILENAME   generate file with globally inlinable
                                   procedures (implies -inline -local)
     -consult-inline-file FILENAME  explicitly load inline file
@@ -1740,7 +1739,6 @@ Available debugging options:
      S          show applications of compiler syntax
      T          show expressions after converting to node tree
      P          show expressions after specialization
-     U          show expressions after unboxing
      M          show syntax-/runtime-requirements
      1          show source expressions
      2          show canonicalized expressions
diff --git a/tests/compiler-tests-3.scm b/tests/compiler-tests-3.scm
deleted file mode 100644
index 65164d1..0000000
--- a/tests/compiler-tests-3.scm
+++ /dev/null
@@ -1,52 +0,0 @@
-;;; compiler-tests-3.scm - tests for unboxing
-
-
-;;; unboxing introduced binding in test-position of conditional
-
-;;; MBROT -- Generation of Mandelbrot set fractal.
-
-(define (count r i step x y)
-
-  (let ((max-count 64)
-        (radius^2  16.0))
-
-    (let ((cr (fp+ r (fp* (exact->inexact x) step)))
-          (ci (fp+ i (fp* (exact->inexact y) step))))
-      
-      (let loop ((zr cr)
-                 (zi ci)
-                 (c 0))
-        (if (= c max-count)
-          c
-          (let ((zr^2 (fp* zr zr))
-                (zi^2 (fp* zi zi)))
-            (if (fp> (fp+ zr^2 zi^2) radius^2)
-              c
-              (let ((new-zr (fp+ (fp- zr^2 zi^2) cr))
-                    (new-zi (fp+ (fp* 2.0 (fp* zr zi)) ci)))
-                (loop new-zr new-zi (+ c 1))))))))))
-
-(define (mbrot matrix r i step n)
-  (let loop1 ((y (- n 1)))
-    (if (>= y 0)
-      (let loop2 ((x (- n 1)))
-        (if (>= x 0)
-          (begin
-            (vector-set! (vector-ref matrix x) y (count r i step x y))
-            (loop2 (- x 1)))
-          (loop1 (- y 1)))))))
-
-(define (test n)
-  (let ((matrix (make-vector n)))
-    (let loop ((i (- n 1)))
-      (if (>= i 0)
-        (begin
-          (vector-set! matrix i (make-vector n))
-          (loop (- i 1)))))
-    (mbrot matrix -1.0 -0.5 0.005 n)
-    (vector-ref (vector-ref matrix 0) 0)))
-
-(define (main . args)
-  (let ((r (test 75)))
-    (unless (equal? r 5)
-    (error "incorrect result: " r))))
diff --git a/tests/runtests.bat b/tests/runtests.bat
index 1b82aa9..3e8e7ab 100644
--- a/tests/runtests.bat
+++ b/tests/runtests.bat
@@ -27,12 +27,6 @@ if errorlevel 1 exit /b 1
 a.out
 if errorlevel 1 exit /b 1
 
-echo ======================================== compiler tests (unboxing) ...
-%compile% compiler-tests-3.scm -unsafe -unboxing
-if errorlevel 1 exit /b 1
-a.out
-if errorlevel 1 exit /b 1
-
 echo ======================================== compiler inlining tests  ...
 %compile% inlining-tests.scm -optimize-level 3
 if errorlevel 1 exit /b 1
diff --git a/tests/runtests.sh b/tests/runtests.sh
index dc5b3dd..a629ffc 100644
--- a/tests/runtests.sh
+++ b/tests/runtests.sh
@@ -63,10 +63,6 @@ echo "======================================== compiler 
tests ..."
 $compile compiler-tests.scm
 ./a.out
 
-echo "======================================== compiler tests (unboxing) ..."
-$compile compiler-tests-3.scm -unsafe -unboxing
-./a.out
-
 echo "======================================== compiler inlining tests  ..."
 $compile inlining-tests.scm -optimize-level 3
 ./a.out
diff --git a/unboxing.scm b/unboxing.scm
deleted file mode 100644
index a6da5d3..0000000
--- a/unboxing.scm
+++ /dev/null
@@ -1,559 +0,0 @@
-;;;; unboxing.scm - The CHICKEN Scheme compiler (local flow-analysis with 
number boxing/unboxing)
-;
-; Copyright (c) 2009-2011, The Chicken Team
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following
-; conditions are met:
-;
-;   Redistributions of source code must retain the above copyright notice, 
this list of conditions and the following
-;     disclaimer. 
-;   Redistributions in binary form must reproduce the above copyright notice, 
this list of conditions and the following
-;     disclaimer in the documentation and/or other materials provided with the 
distribution. 
-;   Neither the name of the author nor the names of its contributors may be 
used to endorse or promote
-;     products derived from this software without specific prior written 
permission. 
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS
-; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
OF MERCHANTABILITY
-; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
COPYRIGHT HOLDERS OR
-; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR
-; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
SUBSTITUTE GOODS OR
-; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
(INCLUDING NEGLIGENCE OR
-; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
ADVISED OF THE
-; POSSIBILITY OF SUCH DAMAGE.
-
-
-;; I don't understand this code anymore. It needs cleanup and simplification.
-
-
-(declare
-  (unit unboxing)
-  (hide d-depth))
-
-
-(include "compiler-namespace")
-(include "tweaks")
-
-
-(define d-depth 0)
-
-(define (d fstr . args)
-  (when (##sys#fudge 13)
-    (printf "[debug] ~a~?~%" (make-string d-depth #\space) fstr args)) )
-
-(define-syntax d (syntax-rules () ((_ . _) (void))))
-
-
-(define (perform-unboxing! node)
-  (let ((stats (make-vector 301 '()))
-       (any-rewrites #f))
-
-    ;; walk nodes in lambda and mark unboxed variables
-    (define (walk-lambda id e body)
-      (let ((ae '()))
-
-       (define (boxed! v)              ; boxed is sticky
-         (d "boxing ~a" v )
-         (cond ((assq v e) =>
-                (lambda (a)
-                  (set-cdr! a #f) ) )
-               (else (set! e (alist-cons v #f e)))))
-
-       (define (unboxed! v t)
-         (d "unboxing ~a -> ~a" v t)
-         (cond ((assq v e) =>
-                (lambda (a)
-                  (if (cdr a)
-                      (let ((t2 (and (eq? (cdr a) t) t)))
-                        (if t2
-                            (set-cdr! a t2)
-                            (set! e (alist-cons v #f e))))
-                      (set-cdr! e (alist-cons v #f e)))))
-               (else
-                (set! ae (alist-cons v (gensym "tu") ae))
-                (set! e (alist-cons v t e)))))
-
-       (define (unboxed? v)
-         (and-let* ((a (assq v e)))
-           (cdr a)))
-
-       (define (unboxed-value? x)
-         (and x (cdr x)))
-
-       (define (invalidate r) ; if result is variable, mark it boxed
-         (when (and (pair? r) (car r))
-           (boxed! (car r))))
-
-       (define (literal-type x)
-         (cond ((char? x) 'char)
-               ((flonum? x) 'flonum)
-               ((fixnum? x) 'fixnum)
-               ((boolean? x) 'bool)
-               (else #f)))
-
-       (define (unboxed-literal x)
-         (cond ((char? x)
-                (sprintf "\'\\~a\'" (string-pad (number->string (char->integer 
x) 8) 3 #\0)))
-               ((number? x) (number->string x))
-               ((boolean? x) (if x "1" "0"))
-               (else (bomb "(unboxing) unexpected literal type" x))))
-
-       (define (alias v)
-         (alist-ref v ae eq? v) )
-
-       ;; merge results at control-flow join (i.e. conditional)
-       (define (merge r1 r2)
-         (cond ((or (not r1) (not (cdr r1)))
-                (invalidate r2)
-                #f)
-               ((or (not r2) (not (cdr r2)))
-                (invalidate r1)
-                #f)
-               ((equal? r1 r2) r1)
-               ((eq? (cdr r1) (cdr r2))
-                (cons #f (cdr r1)))
-               (else #f)))
-
-       (define (rewrite! n alt anodes avals atypes0 rtype dest)
-         (d "rewrite: ~a -> ~a  (dest: ~a)" (first (node-parameters n)) alt 
dest)
-         (let ((s (symbolify alt)))
-           (set! any-rewrites #t)
-           (##sys#hash-table-set! 
-            stats s (add1 (or (##sys#hash-table-ref stats s) 0))))
-         (copy-node!
-          (let loop ((args avals) (anodes anodes) (atypes atypes0) (iargs '()))
-            (cond ((null? args) 
-                   (let ((n2 (straighten-form!
-                              (make-node
-                               '##core#inline_unboxed (list alt)
-                               (reverse iargs)))))
-                     (if (and dest (cdr dest))
-                         n2
-                         (let ((tmp (gensym "tu")))
-                           ;; introduce unboxed temporary for result
-                           (make-node
-                            '##core#let_unboxed (list tmp rtype)
-                            (list
-                             n2
-                             (case rtype
-                               ((flonum)
-                                (make-node
-                                 '##core#inline_allocate (list "C_a_i_flonum" 
4) ; hardcoded size
-                                 (list (make-node '##core#unboxed_ref (list 
tmp rtype) '()))))
-                               ((int)
-                                (make-node
-                                 '##core#inline_allocate (list 
"C_a_int_to_num" 4) ; hardcoded size
-                                 (list (make-node '##core#unboxed_ref (list 
tmp rtype) '()))))
-                               ((pointer)
-                                (make-node
-                                 '##core#inline_allocate (list 
"C_a_i_mpointer" 2) ; hardcoded size
-                                 (list (make-node '##core#unboxed_ref (list 
tmp rtype) '()))))
-                               ((char fixnum)
-                                (make-node
-                                  '##core#inline
-                                  (list (if (eq? rtype 'char) 
"C_make_character" "C_fix"))
-                                  (list (make-node
-                                         '##core#unboxed_ref
-                                         (list tmp rtype) '()))))
-                               ((bool)
-                                (make-node
-                                 '##core#inline '("C_mk_bool")
-                                 (list
-                                  (make-node '##core#unboxed_ref (list tmp 
rtype) '()))))
-                               ((*) (bomb "unboxed type `*' not allowed as 
result"))
-                               (else (bomb "invalid unboxed type" 
rtype))))))))) 
-                  ((or (eq? (car atypes) '*) ; already unboxed argument -> 
just pass it unchanged
-                       (unboxed-value? (car args)))
-                   (loop (cdr args)
-                         (cdr anodes)
-                         (cdr atypes)
-                         (cons (car anodes) iargs)))
-                  ;; if literal of correct type, pass directly as 
##core#unboxed_ref
-                  ((and (eq? (node-class (car anodes)) 'quote)
-                        (eq? (literal-type (first (node-parameters (car 
anodes)))) (car atypes)))
-                   ;;XXX what if type does not match? error? warning?
-                   (loop (cdr args)
-                         (cdr anodes)
-                         (cdr atypes)
-                         (cons (make-node
-                                '##core#unboxed_ref 
-                                (list (unboxed-literal (first (node-parameters 
(car anodes))))
-                                      (car atypes))
-                                '())
-                               iargs)))
-                  (else
-                   ;; introduce unboxed temporary for argument
-                   ;;
-                   ;;XXX this is suboptimal: we could reuse unboxed temporaries
-                   ;;    that are in scope. Currently the same are will be 
unboxed
-                   ;;    repeatedly.
-                   ;;    (But we must make sure there are not intermediate side
-                   ;;    effects - possibly only reuse unboxed value if 
unassigned
-                   ;;    local or lexical variable ref, or literal)
-                   ;;
-                   ;;    (See also comment below, after "walk-lambda")
-                   (let ((tmp (gensym "tu")))
-                     (make-node
-                      '##core#let_unboxed (list tmp (car atypes))
-                      (list (make-node
-                             '##core#inline 
-                             (list (case (car atypes)
-                                     ((char) "C_character_code")
-                                     ((fixnum) "C_unfix")
-                                     ((flonum) "C_flonum_magnitude")
-                                     ((int) "C_num_to_int")
-                                     ((pointer) "C_pointer_address")
-                                     ((bool) "C_truep")
-                                     ((*) "C_id")
-                                     (else 
-                                      (bomb "invalid unboxed argument type" 
(car atypes)))))
-                             (list (car anodes)))
-                            (loop (cdr args)
-                                  (cdr anodes)
-                                  (cdr atypes)
-                                  (cons (make-node '##core#unboxed_ref (list 
tmp (car atypes)) '())
-                                        iargs))))))))
-          n)
-         (straighten-binding! n))
-
-       (define (rebind-unboxed! n t)
-         (let ((var (alias (first (node-parameters n)))))
-           (node-class-set! n '##core#let_unboxed)
-           (node-parameters-set! n (list var t))
-           (straighten-binding! n) ))
-
-       (define (straighten! n)
-         (case (node-class n)
-           ((let ##core#let_unboxed) (straighten-binding! n))
-           ((if) (straighten-conditional! n))
-           (else (straighten-form! n))))
-
-       (define (straighten-binding! n)
-         ;; change `(let ((<v> (let (...) <x2>))) <x>)' into 
-         ;;        `(let (...) (let ((<v> <x2>)) <x>))'
-         ;; (also for "##core#let_unboxed")
-         (let* ((subs (node-subexpressions n))
-                (bnode (first subs))
-                (bcl (node-class bnode)))
-           (when (memq bcl '(let ##core#let_unboxed))
-             (d "straightening binding: ~a -> ~a" (node-parameters n) 
(node-parameters bnode))
-             (copy-node!
-              (make-node
-               bcl
-               (node-parameters bnode)
-               (let ((bsubs (node-subexpressions bnode)))
-                 (list (first bsubs)
-                       (make-node
-                        (node-class n)
-                        (node-parameters n)
-                        (list (second bsubs)
-                              (second subs))))))
-              n)
-             ;;(pp (build-expression-tree n))
-             (straighten-binding! n)
-             (straighten-binding! (second (node-subexpressions n))))
-           n))
-
-       (define (straighten-conditional! n)
-         ;; change `(if (let (...) <x1>) <x2> <x3>)' into 
-         ;;        `(let (...) (if <x1> <x2> <x3>))'
-         ;; (also for "##core#let_unboxed")
-         (let* ((subs (node-subexpressions n))
-                (bnode (first subs))
-                (bcl (node-class bnode)))
-           (when (memq bcl '(let ##core#let_unboxed))
-             (d "straightening conditional: ~a" (node-parameters bnode))
-             (copy-node!
-              (make-node
-               bcl
-               (node-parameters bnode)
-               (let ((bsubs (node-subexpressions bnode)))
-                 (list (first bsubs)
-                       (make-node
-                        (node-class n)
-                        (node-parameters n)
-                        (cons (second bsubs) (cdr subs))))))
-              n)
-             (straighten-conditional! (second (node-subexpressions n)))
-             ;;(pp (build-expression-tree n))
-             (straighten-binding! n))))
-
-       (define (straighten-form! n)
-         ;; change `(<form> ... (let (...) <x>) ...)' to
-         ;;        `(let (...) (<form> ... <x> ...))'
-         ;; - also for `##core#let_unboxed'
-         (let ((class (node-class n))
-               (subs (node-subexpressions n))
-               (params (node-parameters n))
-               (f #f))
-           (let loop ((args subs) (newargs '()) (wrap identity))
-             (cond ((null? args)
-                    (let ((n2 (wrap
-                               ((if f straighten! identity)
-                                (make-node class params (reverse newargs))))))
-                      (when f
-                        (d "straightening form (~a): ~a" class params)
-                        (let ((n2 (straighten-binding! n2)))
-#|
-                          (print "---\n") ;XXX
-                          (pp (build-expression-tree n))
-                          (print " ->\n")
-|#
-                          (copy-node! n2 n)
-#|
-                          (pp (build-expression-tree n))
-                          (print "---\n")
-|#
-                          ))
-                      n))
-                   ((memq (node-class (car args)) '(let ##core#let_unboxed))
-                    (let* ((arg (car args))
-                           (subs2 (node-subexpressions arg)))
-                      (set! f #t)
-                      (loop (cdr args)
-                            (cons (second subs2) newargs)
-                            (lambda (body)
-                              (wrap
-                               (make-node
-                                (node-class arg)
-                                (node-parameters arg)
-                                (list (first subs2) body)))))))
-                   (else (loop (cdr args) (cons (car args) newargs) wrap))))))
-
-       ;; walk node and return either "(<var> . <type>)" or #f
-       ;; - at second pass: rewrite "##core#inline[_allocate]" nodes
-       (define (walk n dest udest pass2?)
-         (let ((subs (node-subexpressions n))
-               (params (node-parameters n))
-               (class (node-class n)) )
-           (d "walk: (~a) ~a ~a" (if pass2? 2 1) class params)
-           (set! d-depth (add1 d-depth))
-           (let ((result
-                  (case class
-                    
-                    ((##core#undefined
-                      ##core#proc
-                      ##core#inline_ref
-                      ##core#inline_loc_ref) #f)
-
-                    ((##core#lambda ##core#direct_lambda)
-                     (decompose-lambda-list
-                      (third params)
-                      (lambda (vars argc rest)
-                        (unless pass2?
-                          (walk-lambda
-                           (first params) 
-                           (map (cut cons <> #f) vars)
-                           (first subs)) )
-                        #f)))
-
-                    ((##core#variable)
-                     (let* ((v (first params))
-                            (a (assq v e)))
-                       (cond (pass2?
-                              (when (and a (cdr a))
-                                (copy-node!
-                                 (make-node
-                                  '##core#unboxed_ref
-                                  (list (alias v) (cdr a))
-                                  '())
-                                 n)))
-                             ((not a) #f) ; global
-                             ((not udest) (boxed! v)))
-                       a))
-
-                    ((##core#inline ##core#inline_allocate 
##core#inline_unboxed)
-                     (let* ((rw1 (##sys#get (symbolify (first params)) 
'##compiler#unboxed-op))
-                            (rw (and unsafe rw1))
-                            (args (map (cut walk <> #f rw pass2?) subs)))
-                       ;; rewrite inline operation to unboxed one, if possible
-                       (cond ((not rw)
-                              (straighten-form! n)
-                              #f)
-                             ((or (not pass2?)
-                                  (and dest (unboxed? dest))
-                                  (any unboxed-value? args))
-                              (let ((alt (first rw))
-                                    (atypes (second rw))
-                                    (rtype (third rw)))
-                                ;; result or arguments are unboxed - rewrite 
node to alternative
-                                (when pass2?
-                                  (rewrite! 
-                                   n alt subs args atypes rtype 
-                                   (and dest (assq dest e))))
-                                (cons #f rtype)) )
-                             (else
-                              (let ((rtype (third rw)))
-                                ;; mark argument-vars and dest as unboxed if 
alternative exists
-                                (cond ((not pass2?)
-                                       (for-each
-                                        (lambda (a)
-                                          (when (and a (car a) (cdr a))
-                                            (unboxed! (car a) (cdr a))))
-                                        args)
-                                       (when dest
-                                         (unboxed! dest rtype)))
-                                      (else (straighten-form! n)))
-                                (cons #f rtype))))))
-
-                    ((let)
-                     (let* ((v (first params))
-                            (r1 (walk (first subs) v #t pass2?)))
-                       (when (and (not pass2?) r1 (cdr r1))
-                         (unboxed! (first params) (cdr r1)))
-                       (let ((r (walk (second subs) dest udest pass2?)))
-                         (when pass2?
-                           (let ((a (assq v e)))
-                             (if (and a (cdr a))
-                                 (rebind-unboxed! n (cdr a))
-                                 (straighten-binding! n))))
-                         r)))
-
-                    ((set!)
-                     (let* ((var (first params))
-                            (a (assq var e))
-                            (val (walk (first subs) var (and a (cdr a)) 
pass2?)))
-                       (cond (pass2?
-                              (cond ((and a (cdr a)) ; may have mutated in 
walk above
-                                     (copy-node!
-                                      (make-node
-                                       '##core#unboxed_set! (list (alias var) 
(cdr a)) subs)
-                                      n)
-                                     (straighten-form! n))
-                                    (else
-                                     (straighten-form! n))))
-                             ((and a val (cdr val))
-                              (unboxed! var (cdr val)))
-                             (else 
-                              (boxed! var)
-                              (invalidate val) ) )
-                       #f))
-
-                    ((quote) #f)
-
-                    ((if ##core#cond)
-                     (invalidate (walk (first subs) #f #f pass2?))
-                     (straighten-conditional! n)
-                     (let ((r1 (walk (second subs) dest udest pass2?))
-                           (r2 (walk (third subs) dest udest pass2?)))
-                       (merge r1 r2)))
-
-                    ((##core#switch)
-                     (invalidate (walk (first subs) #f #f pass2?))
-                     (do ((clauses (cdr subs) (cddr clauses))
-                          (r 'none 
-                             (if (eq? r 'none)
-                                 (walk (second clauses) dest udest pass2?)
-                                 (merge r (walk (second clauses) dest udest 
pass2?)))))
-                         ((null? (cdr clauses))
-                          (merge r (walk (car clauses) dest udest pass2?))) ) )
-
-                    ((##core#call ##core#direct_call)
-                     (for-each (o invalidate (cut walk <> #f #f pass2?)) subs)
-                     (when pass2?
-                       (straighten-form! n))
-                     #f)
-
-                    (else
-                     (for-each (o invalidate (cut walk <> #f #f pass2?)) subs)
-                     #f))))
-
-             (set! d-depth (sub1 d-depth))
-             result)))
-
-       (d "walk lambda: ~a (pass 1)" id)
-       ;; walk once and mark boxed/unboxed variables in environment
-       (walk body #f #f #f)
-       ;; walk a second time and rewrite
-       (d "walk lambda: ~a (pass 2)" id)
-       (walk body #f #f #t)))
-
-    ;;XXX Note: lexical references ("##core#ref" nodes) are unboxed
-    ;;    repeatedly which is sub-optimal: the unboxed temporaries bound
-    ;;    via "##core#let_unboxed" could be re-used in many cases.
-    ;;    One possible approach would be an additional "cleanup" pass
-    ;;    that replaces
-    ;;
-    ;;    (##core#let_unboxed (TU TYPE) X (##core#ref VAR (SLOT)) Y)
-    ;;
-    ;;    with
-    ;;
-    ;;    (##core#let_unboxed (TU TYPE) (##core#unboxed_ref TU1) Y)
-    
-    (walk-lambda #f '() node)
-    (when (and any-rewrites
-              (debugging 'o "unboxed rewrites:"))
-      (##sys#hash-table-for-each
-       (lambda (k v)
-        (printf "  ~a\t~a~%" k v) )
-       stats))))
-
-(define-syntax define-unboxed-ops
-  (syntax-rules ()
-    ((_ (name atypes rtype alt) ...)
-     (begin
-       (register-unboxed-op 'name 'atypes 'rtype 'alt) ...))))
-
-(define (register-unboxed-op name atypes rtype alt)
-  (##sys#put! (symbolify name) '##compiler#unboxed-op (list alt atypes rtype)))
-
-
-;;; unboxed rewrites
-
-;; arithmetic
-(define-unboxed-ops 
-  (C_a_i_flonum_plus (flonum flonum) flonum "C_ub_i_flonum_plus")
-  (C_a_i_flonum_difference (flonum flonum) flonum "C_ub_i_flonum_difference")
-  (C_a_i_flonum_times (flonum flonum) flonum "C_ub_i_flonum_times") 
-  (C_a_i_flonum_quotient (flonum flonum) flonum "C_ub_i_flonum_quotient") 
-  (C_a_i_flonum_quotient_checked (flonum flonum) flonum 
"C_ub_i_flonum_quotient_checked") 
-  (C_u_i_fpintegerp (flonum) bool "C_ub_i_fpintegerp")
-  (C_flonum_equalp (flonum flonum) bool "C_ub_i_flonum_equalp")
-  (C_flonum_greaterp (flonum flonum) bool "C_ub_i_flonum_greaterp")
-  (C_flonum_lessp (flonum flonum) bool "C_ub_i_flonum_lessp")
-  (C_flonum_greater_or_equal_p (flonum flonum) bool 
"C_ub_i_flonum_greater_or_equal_p")
-  (C_flonum_less_or_equal_p (flonum flonum) bool 
"C_ub_i_flonum_less_or_equal_p")
-  (C_a_i_flonum_sin (flonum) flonum "C_sin")
-  (C_a_i_flonum_cos (flonum) flonum "C_cos")
-  (C_a_i_flonum_tan (flonum) flonum "C_tab")
-  (C_a_i_flonum_asin (flonum) flonum "C_asin")
-  (C_a_i_flonum_acos (flonum) flonum "C_acos")
-  (C_a_i_flonum_atan (flonum) flonum "C_atan")
-  (C_a_i_flonum_atan2 (flonum flonum) flonum "C_atan2")
-  (C_a_i_flonum_exp (flonum) flonum "C_exp")
-  (C_a_i_flonum_expt (flonum flonum) flonum "C_pow")
-  (C_a_i_flonum_log (flonum) flonum "C_log")
-  (C_a_i_flonum_sqrt (flonum) flonum "C_sqrt")
-  (C_a_i_flonum_abs (flonum) flonum "C_fabs")
-  (C_a_i_flonum_truncate (flonum) flonum "C_trunc")
-  (C_a_i_flonum_ceiling (flonum) flonum "C_ceil")
-  (C_a_i_flonum_floor (flonum) flonum "C_floor")
-  (C_a_i_flonum_round (flonum) flonum "C_round")
-  (C_a_i_fix_to_flo (fixnum) flonum "C_cast_to_flonum"))
-
-;; others
-(define-unboxed-ops 
-  (C_u_i_f32vector_set (* fixnum flonum) fixnum "C_ub_i_f32vector_set")
-  (C_u_i_f64vector_set (* fixnum flonum) fixnum "C_ub_i_f64vector_set")
-  (C_a_i_f32vector_ref (* fixnum) flonum "C_ub_i_f32vector_ref")
-  (C_a_i_f64vector_ref (* fixnum) flonum "C_ub_i_f64vector_ref")
-  (C_a_u_i_pointer_inc (pointer fixnum) pointer "C_ub_i_pointer_inc")
-  (C_pointer_eqp (pointer pointer) bool "C_ub_i_pointer_eqp")
-  (C_u_i_pointer_u8_ref (pointer) fixnum "C_ub_i_pointer_u8_ref")
-  (C_u_i_pointer_s8_ref (pointer) fixnum "C_ub_i_pointer_s8_ref")
-  (C_u_i_pointer_u16_ref (pointer) fixnum "C_ub_i_pointer_u16_ref")
-  (C_u_i_pointer_s16_ref (pointer) fixnum "C_ub_i_pointer_s16_ref")
-  (C_u_i_pointer_u32_ref (pointer) fixnum "C_ub_i_pointer_u32_ref")
-  (C_u_i_pointer_s32_ref (pointer) fixnum "C_ub_i_pointer_s32_ref")
-  (C_u_i_pointer_f32_ref (pointer) flonum "C_ub_i_pointer_f32_ref")
-  (C_u_i_pointer_f64_ref (pointer) flonum "C_ub_i_pointer_f64_ref")
-  (C_u_i_pointer_u8_set (pointer fixnum) fixnum "C_ub_i_pointer_u8_set")
-  (C_u_i_pointer_s8_set (pointer fixnum) fixnum "C_ub_i_pointer_s8_set")
-  (C_u_i_pointer_u16_set (pointer fixnum) fixnum "C_ub_i_pointer_u16_set")
-  (C_u_i_pointer_s16_set (pointer fixnum) fixnum "C_ub_i_pointer_s16_set")
-  (C_u_i_pointer_u32_set (pointer fixnum) fixnum "C_ub_i_pointer_u32_set")
-  (C_u_i_pointer_s32_set (pointer fixnum) fixnum "C_ub_i_pointer_s32_set")
-  (C_u_i_pointer_f32_set (pointer flonum) flonum "C_ub_i_pointer_f32_set")
-  (C_u_i_pointer_f64_set (pointer flonum) flonum "C_ub_i_pointer_f64_set")
-  (C_null_pointerp (pointer) bool "C_ub_i_null_pointerp"))
-- 
1.7.6.msysgit.0


reply via email to

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