Update of /project/movitz/cvsroot/movitz
In directory common-lisp.net:/tmp/cvs-serv1888
Modified Files:
compiler.lisp
Log Message:
Improved compilation of dynamic-extent &rest arguments a
bit. Especially functions with unused &rest parameters should be improved.
Date: Fri Apr 23 10:58:53 2004
Author: ffjeld
Index: movitz/compiler.lisp
diff -u movitz/compiler.lisp:1.58 movitz/compiler.lisp:1.59
--- movitz/compiler.lisp:1.58 Wed Apr 21 11:06:16 2004
+++ movitz/compiler.lisp Fri Apr 23 10:58:52 2004
@@ -8,7 +8,7 @@
;;;; Created at: Wed Oct 25 12:30:49 2000
;;;; Distribution: See the accompanying file COPYING.
;;;;
-;;;; $Id: compiler.lisp,v 1.58 2004/04/21 15:06:16 ffjeld Exp $
+;;;; $Id: compiler.lisp,v 1.59 2004/04/23 14:58:52 ffjeld Exp $
;;;;
;;;;------------------------------------------------------------------
@@ -989,166 +989,163 @@
1))
(t (error "make-2req confused by loc0: ~W, loc1: ~W" location-0 location-1)))))
-#+ignore
-(defun make-compiled-function-body-1rest (form funobj env top-level-p)
- (when (and (null (required-vars env))
- (null (optional-vars env))
- (null (key-vars env))
- (rest-var env))
- (multiple-value-bind (code stack-frame-size use-stack-frame-p frame-map)
- (make-compiled-body form funobj env top-level-p)
- (let* ((rest-binding (movitz-binding (rest-var env) env nil))
- (edx-location (and (edx-var env)
- (new-binding-location (edx-var env) frame-map
- :default nil)))
- (edx-code (when edx-location
- `((:movl :edx (:ebp ,(stack-frame-offset edx-location)))))))
- (cond
- ((not (new-binding-located-p rest-binding frame-map))
- (append '(entry%1op
- entry%2op
- entry%3op)
- (when use-stack-frame-p
- +enter-stack-frame-code+)
- '(start-stack-frame-setup)
- (make-compiled-stack-frame-init stack-frame-size)
- edx-code
- code
- (make-compiled-function-postlude funobj env use-stack-frame-p)))
- (t ;; (new-binding-located-p rest-binding frame-map)
- (let ((rest-location (new-binding-location rest-binding frame-map)))
- (values (append +enter-stack-frame-code+
- '(start-stack-frame-setup)
- (make-compiled-stack-frame-init stack-frame-size)
- `((:movl :edi (:ebp ,(stack-frame-offset rest-location))))
- edx-code
- `((:testb :cl :cl)
- (:jz 'end-stack-frame-setup)
- (:js '(:sub-program (normalize-ecx)
- (:shrl 8 :ecx)
- (:jmp 'ecx-ok)))
- (:andl #x7f :ecx)
- ecx-ok
- (:xorl :edx :edx)
- (:call (:edi ,(global-constant-offset 'restify-dynamic-extent)))
- (:movl :eax (:ebp ,(stack-frame-offset rest-location)))
- (:jmp 'end-stack-frame-setup))
- `(entry%1op
- ,@+enter-stack-frame-code+
- ,@(make-compiled-stack-frame-init stack-frame-size)
- ,@edx-code
- (:andl -8 :esp)
- (:pushl :edi)
- (:pushl :eax)
- (:leal (:esp 1) :ecx)
- (:movl :ecx (:ebp ,(stack-frame-offset rest-location)))
- (:jmp 'end-stack-frame-setup))
- `(entry%2op
- ,@+enter-stack-frame-code+
- ,@(make-compiled-stack-frame-init stack-frame-size)
- ,@edx-code
- (:andl -8 :esp)
- (:pushl :edi)
- (:pushl :ebx)
- (:leal (:esp 1) :ecx)
- (:pushl :ecx)
- (:pushl :eax)
- (:leal (:esp 1) :ecx)
- (:movl :ecx (:ebp ,(stack-frame-offset rest-location)))
- (:jmp 'end-stack-frame-setup))
- '(end-stack-frame-setup)
- code
- (make-compiled-function-postlude funobj env t))
- use-stack-frame-p))))))))
+;;;(defun make-compiled-function-body-1rest (form funobj env top-level-p)
+;;; (when (and (null (required-vars env))
+;;; (null (optional-vars env))
+;;; (null (key-vars env))
+;;; (rest-var env))
+;;; (multiple-value-bind (code stack-frame-size use-stack-frame-p frame-map)
+;;; (make-compiled-body form funobj env top-level-p)
+;;; (let* ((rest-binding (movitz-binding (rest-var env) env nil))
+;;; (edx-location (and (edx-var env)
+;;; (new-binding-location (edx-var env) frame-map
+;;; :default nil)))
+;;; (edx-code (when edx-location
+;;; `((:movl :edx (:ebp ,(stack-frame-offset edx-location)))))))
+;;; (cond
+;;; ((not (new-binding-located-p rest-binding frame-map))
+;;; (append '(entry%1op
+;;; entry%2op
+;;; entry%3op)
+;;; (when use-stack-frame-p
+;;; +enter-stack-frame-code+)
+;;; '(start-stack-frame-setup)
+;;; (make-compiled-stack-frame-init stack-frame-size)
+;;; edx-code
+;;; code
+;;; (make-compiled-function-postlude funobj env use-stack-frame-p)))
+;;; (t ;; (new-binding-located-p rest-binding frame-map)
+;;; (let ((rest-location (new-binding-location rest-binding frame-map)))
+;;; (values (append +enter-stack-frame-code+
+;;; '(start-stack-frame-setup)
+;;; (make-compiled-stack-frame-init stack-frame-size)
+;;; `((:movl :edi (:ebp ,(stack-frame-offset rest-location))))
+;;; edx-code
+;;; `((:testb :cl :cl)
+;;; (:jz 'end-stack-frame-setup)
+;;; (:js '(:sub-program (normalize-ecx)
+;;; (:shrl 8 :ecx)
+;;; (:jmp 'ecx-ok)))
+;;; (:andl #x7f :ecx)
+;;; ecx-ok
+;;; (:xorl :edx :edx)
+;;; (:call (:edi ,(global-constant-offset 'restify-dynamic-extent)))
+;;; (:movl :eax (:ebp ,(stack-frame-offset rest-location)))
+;;; (:jmp 'end-stack-frame-setup))
+;;; `(entry%1op
+;;; ,@+enter-stack-frame-code+
+;;; ,@(make-compiled-stack-frame-init stack-frame-size)
+;;; ,@edx-code
+;;; (:andl -8 :esp)
+;;; (:pushl :edi)
+;;; (:pushl :eax)
+;;; (:leal (:esp 1) :ecx)
+;;; (:movl :ecx (:ebp ,(stack-frame-offset rest-location)))
+;;; (:jmp 'end-stack-frame-setup))
+;;; `(entry%2op
+;;; ,@+enter-stack-frame-code+
+;;; ,@(make-compiled-stack-frame-init stack-frame-size)
+;;; ,@edx-code
+;;; (:andl -8 :esp)
+;;; (:pushl :edi)
+;;; (:pushl :ebx)
+;;; (:leal (:esp 1) :ecx)
+;;; (:pushl :ecx)
+;;; (:pushl :eax)
+;;; (:leal (:esp 1) :ecx)
+;;; (:movl :ecx (:ebp ,(stack-frame-offset rest-location)))
+;;; (:jmp 'end-stack-frame-setup))
+;;; '(end-stack-frame-setup)
+;;; code
+;;; (make-compiled-function-postlude funobj env t))
+;;; use-stack-frame-p))))))))
-
-#+ignore
-(defun make-compiled-function-body-1req-1opt (form funobj env top-level-p)
- (when (and (= 1 (length (required-vars env)))
- (= 1 (length (optional-vars env)))
- (= 0 (length (key-vars env)))
- (null (rest-var env)))
- (let* ((opt-var (first (optional-vars env)))
- (opt-binding (movitz-binding opt-var env nil))
- (req-binding (movitz-binding (first (required-vars env)) env nil))
- (default-form (optional-function-argument-init-form opt-binding)))
- (compiler-values-bind (&code opt-default-code &producer opt-default-producer)
- (compiler-call #'compile-form
- :form default-form
- :result-mode :push
- :env env
- :funobj funobj)
- (cond
- ((eq 'compile-self-evaluating opt-default-producer)
- (multiple-value-bind (code stack-frame-size use-stack-frame-p frame-map)
- (make-compiled-body form funobj env top-level-p nil (list opt-default-code))
- (declare (ignore use-stack-frame-p))
- (let ((use-stack-frame-p t))
- (cond
- ((and (new-binding-located-p req-binding frame-map)
- (new-binding-located-p opt-binding frame-map))
- (multiple-value-bind (eax-ebx-code eax-ebx-stack-offset)
- (ecase (new-binding-location req-binding frame-map)
- ;; might well be more cases here, but let's wait till they show up..
- (:eax (values nil 0))
- (1 (values '((:pushl :eax)) 1)))
- ;; (warn "defc: ~S" opt-default-code)
- (let ((stack-init-size (- stack-frame-size eax-ebx-stack-offset))
- (installed-default-code (finalize-code opt-default-code funobj env frame-map)))
- (values (append `((:call (:edi ,(global-constant-offset 'decode-args-1or2)))
- entry%2op
- (:pushl :ebp)
- (:movl :esp :ebp)
- (:pushl :esi)
- start-stack-frame-setup
- ,@eax-ebx-code
- ,@(if (eql (1+ eax-ebx-stack-offset)
- (new-binding-location opt-binding frame-map))
- (append `((:pushl :ebx))
- (make-compiled-stack-frame-init (1- stack-init-size)))
- (append (make-compiled-stack-frame-init stack-init-size)
- `((:movl :ebx (:ebp ,(stack-frame-offset
- (new-binding-location opt-binding
- frame-map)))))))
- (:jmp 'arg-init-done)
- entry%1op
- (:pushl :ebp)
- (:movl :esp :ebp)
- (:pushl :esi)
- ,@eax-ebx-code
- ,@(if (eql (1+ eax-ebx-stack-offset)
- (new-binding-location opt-binding frame-map))
- (append installed-default-code
- (make-compiled-stack-frame-init (1- stack-init-size)))
- (append (make-compiled-stack-frame-init stack-init-size)
- installed-default-code
- `((:popl (:ebp ,(stack-frame-offset
- (new-binding-location opt-binding
- frame-map)))))))
- arg-init-done)
- code
- (make-compiled-function-postlude funobj env t))
- use-stack-frame-p))))
- ((and (new-binding-located-p req-binding frame-map)
- (not (new-binding-located-p opt-binding frame-map)))
- (multiple-value-bind (eax-code eax-stack-offset)
- (ecase (new-binding-location req-binding frame-map)
- (:eax (values nil 0))
- (1 (values '((:pushl :eax)) 1)))
- (values (append `((:call (:edi ,(global-constant-offset 'decode-args-1or2)))
- ;; (:jmp 'decode-numargs)
- entry%1op
- entry%2op
- (:pushl :ebp)
- (:movl :esp :ebp)
- (:pushl :esi))
- eax-code
- (make-compiled-stack-frame-init (- stack-frame-size eax-stack-offset))
- code
- (make-compiled-function-postlude funobj env t))
- use-stack-frame-p)))
- (t (warn "1-req-1-opt failed"))))))
- (t nil))))))
+;;;(defun make-compiled-function-body-1req-1opt (form funobj env top-level-p)
+;;; (when (and (= 1 (length (required-vars env)))
+;;; (= 1 (length (optional-vars env)))
+;;; (= 0 (length (key-vars env)))
+;;; (null (rest-var env)))
+;;; (let* ((opt-var (first (optional-vars env)))
+;;; (opt-binding (movitz-binding opt-var env nil))
+;;; (req-binding (movitz-binding (first (required-vars env)) env nil))
+;;; (default-form (optional-function-argument-init-form opt-binding)))
+;;; (compiler-values-bind (&code opt-default-code &producer opt-default-producer)
+;;; (compiler-call #'compile-form
+;;; :form default-form
+;;; :result-mode :push
+;;; :env env
+;;; :funobj funobj)
+;;; (cond
+;;; ((eq 'compile-self-evaluating opt-default-producer)
+;;; (multiple-value-bind (code stack-frame-size use-stack-frame-p frame-map)
+;;; (make-compiled-body form funobj env top-level-p nil (list opt-default-code))
+;;; (declare (ignore use-stack-frame-p))
+;;; (let ((use-stack-frame-p t))
+;;; (cond
+;;; ((and (new-binding-located-p req-binding frame-map)
+;;; (new-binding-located-p opt-binding frame-map))
+;;; (multiple-value-bind (eax-ebx-code eax-ebx-stack-offset)
+;;; (ecase (new-binding-location req-binding frame-map)
+;;; ;; might well be more cases here, but let's wait till they show up..
+;;; (:eax (values nil 0))
+;;; (1 (values '((:pushl :eax)) 1)))
+;;; ;; (warn "defc: ~S" opt-default-code)
+;;; (let ((stack-init-size (- stack-frame-size eax-ebx-stack-offset))
+;;; (installed-default-code (finalize-code opt-default-code funobj env frame-map)))
+;;; (values (append `((:call (:edi ,(global-constant-offset 'decode-args-1or2)))
+;;; entry%2op
+;;; (:pushl :ebp)
+;;; (:movl :esp :ebp)
+;;; (:pushl :esi)
+;;; start-stack-frame-setup
+;;; ,@eax-ebx-code
+;;; ,@(if (eql (1+ eax-ebx-stack-offset)
+;;; (new-binding-location opt-binding frame-map))
+;;; (append `((:pushl :ebx))
+;;; (make-compiled-stack-frame-init (1- stack-init-size)))
+;;; (append (make-compiled-stack-frame-init stack-init-size)
+;;; `((:movl :ebx (:ebp ,(stack-frame-offset
+;;; (new-binding-location opt-binding
+;;; frame-map)))))))
+;;; (:jmp 'arg-init-done)
+;;; entry%1op
+;;; (:pushl :ebp)
+;;; (:movl :esp :ebp)
+;;; (:pushl :esi)
+;;; ,@eax-ebx-code
+;;; ,@(if (eql (1+ eax-ebx-stack-offset)
+;;; (new-binding-location opt-binding frame-map))
+;;; (append installed-default-code
+;;; (make-compiled-stack-frame-init (1- stack-init-size)))
+;;; (append (make-compiled-stack-frame-init stack-init-size)
+;;; installed-default-code
+;;; `((:popl (:ebp ,(stack-frame-offset
+;;; (new-binding-location opt-binding
+;;; frame-map)))))))
+;;; arg-init-done)
+;;; code
+;;; (make-compiled-function-postlude funobj env t))
+;;; use-stack-frame-p))))
+;;; ((and (new-binding-located-p req-binding frame-map)
+;;; (not (new-binding-located-p opt-binding frame-map)))
+;;; (multiple-value-bind (eax-code eax-stack-offset)
+;;; (ecase (new-binding-location req-binding frame-map)
+;;; (:eax (values nil 0))
+;;; (1 (values '((:pushl :eax)) 1)))
+;;; (values (append `((:call (:edi ,(global-constant-offset 'decode-args-1or2)))
+;;; ;; (:jmp 'decode-numargs)
+;;; entry%1op
+;;; entry%2op
+;;; (:pushl :ebp)
+;;; (:movl :esp :ebp)
+;;; (:pushl :esi))
+;;; eax-code
+;;; (make-compiled-stack-frame-init (- stack-frame-size eax-stack-offset))
+;;; code
+;;; (make-compiled-function-postlude funobj env t))
+;;; use-stack-frame-p)))
+;;; (t (warn "1-req-1-opt failed"))))))
+;;; (t nil))))))
(defun make-compiled-stack-frame-init (stack-frame-init)
@@ -4218,14 +4215,15 @@
(when rest-var
(let* ((rest-binding (movitz-binding rest-var env))
(rest-position (function-argument-argnum rest-binding)))
+ #+ignore
(assert (or (typep rest-binding 'hidden-rest-function-argument)
- (movitz-env-get rest-var 'dynamic-extent nil env)
- (movitz-env-get rest-var 'ignore nil env))
+ (movitz-env-get rest-var 'dynamic-extent nil env))
()
"&REST variable ~S must be dynamic-extent." rest-var)
- (setq need-normalized-ecx-p t)
- (append (make-immediate-move rest-position :edx)
- `((:call (:edi ,(global-constant-offset 'restify-dynamic-extent)))
+ ;; (setq need-normalized-ecx-p t)
+ (append #+ignore (make-immediate-move rest-position :edx)
+ `(#+ignore
+ (:call (:edi ,(global-constant-offset 'restify-dynamic-extent)))
(:init-lexvar ,rest-binding
:init-with-register :eax
:init-with-type list)))))
@@ -5755,27 +5753,53 @@
(declare (ignore protect-carry)) ; nothing modifies carry anyway.
(assert (eq binding (ensure-local-binding binding funobj)))
(cond
- ((binding-lended-p binding)
- (let ((cons-position (getf (binding-lended-p binding)
- :stack-cons-location))
- (tmp-register (find-if (lambda (r)
- (and (not (member r protect-registers))
- (not (eq r init-with-register))))
- '(:edx :ecx :ebx :eax)))
- (init-register (or init-with-register :edi)))
- (when init-with-register
- (assert (not (null init-with-type))))
- (assert tmp-register () ; solve this with push eax .. pop eax if ever needed.
- "Unable to find a tmp-register for ~S." instruction)
- `((:leal (:ebp ,(1+ (stack-frame-offset (1+ cons-position))))
- ,tmp-register)
- (:movl :edi (,tmp-register 3)) ; cdr
- (:movl ,init-register (,tmp-register -1)) ; car
- (:movl ,tmp-register
- (:ebp ,(stack-frame-offset
- (new-binding-location binding frame-map)))))))
- (init-with-register
- (make-store-lexical binding init-with-register nil frame-map)))))
+ ((not (new-binding-located-p binding frame-map))
+ (unless (or (movitz-env-get (binding-name binding) 'ignore nil (binding-env binding))
+ (movitz-env-get (binding-name binding) 'ignorable nil (binding-env binding)))
+ (warn "Unused variable: ~S." (binding-name binding))))
+ (t (when (movitz-env-get (binding-name binding) 'ignore nil (binding-env binding))
+ (warn "Variable ~S used while declared ignored." (binding-name binding)))
+ (append
+ (cond
+ ((typep binding 'rest-function-argument)
+ (assert (eq :eax init-with-register))
+ (assert (or (typep binding 'hidden-rest-function-argument)
+ (movitz-env-get (binding-name binding)
+ 'dynamic-extent nil (binding-env binding)))
+ ()
+ "&REST variable ~S must be dynamic-extent." (binding-name binding))
+ (setf (need-normalized-ecx-p (find-function-env (binding-env binding)
+ funobj))
+ t)
+ (append (make-immediate-move (function-argument-argnum binding) :edx)
+ `((:call (:edi ,(global-constant-offset 'restify-dynamic-extent))))
+ #+ignore
+ (unless (or (typep binding 'hidden-rest-function-argument)
+ (movitz-env-get (binding-name binding)
+ 'dynamic-extent nil (binding-env binding)))
+ (make-compiled-funcall-by-symbol 'muerte.cl:copy-list 1 funobj)))))
+ (cond
+ ((binding-lended-p binding)
+ (let ((cons-position (getf (binding-lended-p binding)
+ :stack-cons-location))
+ (tmp-register (find-if (lambda (r)
+ (and (not (member r protect-registers))
+ (not (eq r init-with-register))))
+ '(:edx :ecx :ebx :eax)))
+ (init-register (or init-with-register :edi)))
+ (when init-with-register
+ (assert (not (null init-with-type))))
+ (assert tmp-register () ; solve this with push eax .. pop eax if ever needed.
+ "Unable to find a tmp-register for ~S." instruction)
+ `((:leal (:ebp ,(1+ (stack-frame-offset (1+ cons-position))))
+ ,tmp-register)
+ (:movl :edi (,tmp-register 3)) ; cdr
+ (:movl ,init-register (,tmp-register -1)) ; car
+ (:movl ,tmp-register
+ (:ebp ,(stack-frame-offset
+ (new-binding-location binding frame-map)))))))
+ (init-with-register
+ (make-store-lexical binding init-with-register nil frame-map))))))))
;;;;;;;;;;;;;;;;;; car