[movitz-cvs] CVS update: movitz/compiler.lisp

Frode Vatvedt Fjeld ffjeld at common-lisp.net
Fri Feb 13 22:05:05 UTC 2004


Update of /project/movitz/cvsroot/movitz
In directory common-lisp.net:/tmp/cvs-serv20257

Modified Files:
	compiler.lisp 
Log Message:
Added defvar *compiler-do-type-inference*. Also added code to restore
the host's *features* when doing host-side stuff.

Date: Fri Feb 13 17:05:04 2004
Author: ffjeld

Index: movitz/compiler.lisp
diff -u movitz/compiler.lisp:1.24 movitz/compiler.lisp:1.25
--- movitz/compiler.lisp:1.24	Fri Feb 13 05:40:14 2004
+++ movitz/compiler.lisp	Fri Feb 13 17:05:04 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.24 2004/02/13 10:40:14 ffjeld Exp $
+;;;; $Id: compiler.lisp,v 1.25 2004/02/13 22:05:04 ffjeld Exp $
 ;;;;                
 ;;;;------------------------------------------------------------------
 
@@ -51,6 +51,9 @@
 (defvar *compiler-compile-macro-expanders* t
   "For macros of any kind, compile the macro-expanders using the host compiler.")
 
+(defvar *compiler-do-type-inference* t
+  "Spend time and effort performing type inference and optimization.")
+
 (defvar *compiling-function-name*)
 (defvar muerte.cl:*compile-file-pathname* nil)
 
@@ -142,7 +145,8 @@
 Gensym a name whose symbol-function is set to the macro-expander, and return that symbol."
   (let ((function-name (gensym (format nil "~A-expander-~@[~A-~]" type name))))
     (if *compiler-compile-macro-expanders*
-	(compile function-name lambda-form)
+	(with-host-environment ()
+	  (compile function-name lambda-form))
       (setf (symbol-function function-name)
 	(coerce lambda-form 'function)))
     function-name))
@@ -331,113 +335,115 @@
    (multiple-value-list (type-specifier-encode nil))))
 
 (defun analyze-bindings (toplevel-funobj)
-  "Figure out usage of bindings in a toplevel funobj."
-  (let ((more-binding-references-p nil)
-	(binding-usage (make-hash-table :test 'eq)))
-    (labels ((type-is-t (type-specifier)
-	       (or (eq type-specifier t)
-		   (and (listp type-specifier)
-			(eq 'or (car type-specifier))
-			(some #'type-is-t (cdr type-specifier)))))
-	     (analyze-store (binding type)
-	       (assert (not (null type)) ()
-		 "store-lexical with empty type.")
-	       (assert (or (typep type 'binding)
-			   (eql 1 (type-specifier-num-values type))) ()
-		 "store-lexical with multiple-valued type: ~S for ~S" type binding)
-	       (let ((analysis (or (gethash binding binding-usage)
-				   (setf (gethash binding binding-usage)
-				     (make-type-analysis)))))
-		 (cond
-		  ((typep binding 'function-argument)
-		   (setf (type-analysis-encoded-type analysis)
-		     (multiple-value-list (type-specifier-encode t))))
-		  ((and (consp type) (eq 'binding-type (car type)))
-		   (let ((target-binding (binding-target (cadr type))))
-		     (cond
-		      ((eq binding target-binding))
-		      ((typep binding 'constant-object-binding)
-		       (setf (type-analysis-encoded-type analysis)
+  "Figure out usage of bindings in a toplevel funobj.
+Side-effects each binding's binding-store-type."
+  (when *compiler-do-type-inference*
+    (let ((more-binding-references-p nil)
+	  (binding-usage (make-hash-table :test 'eq)))
+      (labels ((type-is-t (type-specifier)
+		 (or (eq type-specifier t)
+		     (and (listp type-specifier)
+			  (eq 'or (car type-specifier))
+			  (some #'type-is-t (cdr type-specifier)))))
+	       (analyze-store (binding type)
+		 (assert (not (null type)) ()
+		   "store-lexical with empty type.")
+		 (assert (or (typep type 'binding)
+			     (eql 1 (type-specifier-num-values type))) ()
+		   "store-lexical with multiple-valued type: ~S for ~S" type binding)
+		 (let ((analysis (or (gethash binding binding-usage)
+				     (setf (gethash binding binding-usage)
+				       (make-type-analysis)))))
+		   (cond
+		    ((typep binding 'function-argument)
+		     (setf (type-analysis-encoded-type analysis)
+		       (multiple-value-list (type-specifier-encode t))))
+		    ((and (consp type) (eq 'binding-type (car type)))
+		     (let ((target-binding (binding-target (cadr type))))
+		       (cond
+			((eq binding target-binding))
+			((typep binding 'constant-object-binding)
+			 (setf (type-analysis-encoded-type analysis)
+			   (multiple-value-list
+			    (multiple-value-call
+				#'encoded-types-or 
+			      (values-list (type-analysis-encoded-type analysis))
+			      (member-type-encode (constant-object target-binding))))))
+			(t (pushnew target-binding (type-analysis-binding-types analysis))
+			   (setf more-binding-references-p t)))))
+		    (t (setf (type-analysis-encoded-type analysis)
 			 (multiple-value-list
 			  (multiple-value-call
 			      #'encoded-types-or 
 			    (values-list (type-analysis-encoded-type analysis))
-			    (member-type-encode (constant-object target-binding))))))
-		      (t (pushnew target-binding (type-analysis-binding-types analysis))
-			 (setf more-binding-references-p t)))))
-		  (t (setf (type-analysis-encoded-type analysis)
-		       (multiple-value-list
-			(multiple-value-call
-			    #'encoded-types-or 
-			  (values-list (type-analysis-encoded-type analysis))
-			  (type-specifier-encode type))))))))
-	     (analyze-code (code)
-	       (dolist (instruction code)
-		 (when (listp instruction)
-		   (multiple-value-bind (store-binding store-type)
-		       (find-written-binding-and-type instruction)
-		     (when store-binding
-		       (analyze-store (binding-target store-binding) store-type)))
-		   (analyze-code (instruction-sub-program instruction)))))
-	     (analyze-funobj (funobj)
-	       (loop for (nil . function-env) in (function-envs funobj)
-		   do (analyze-code (extended-code function-env)))
-	       (loop for function-binding in (sub-function-binding-usage funobj) by #'cddr
-		   do (analyze-funobj (function-binding-funobj function-binding)))
-	       funobj))
-      ;; 1. Examine each store to lexical bindings.
-      (analyze-funobj toplevel-funobj)
-      ;; 2.
-      (loop repeat 10 while more-binding-references-p
-	  doing
-	    (setf more-binding-references-p nil)
-	    (maphash (lambda (binding analysis)
-		       (dolist (target-binding (type-analysis-binding-types analysis))
-			 (let* ((target-analysis
-				 (or (gethash target-binding binding-usage)
-				     (and (typep target-binding 'function-argument)
-					  (make-type-analysis
-					   :encoded-type (multiple-value-list
-							  (type-specifier-encode t))))
-				     (error "Type-reference by ~S to unknown binding ~S"
-					    binding target-binding)))
-				(new-type (setf (type-analysis-encoded-type analysis)
-					    (multiple-value-list
-					     (multiple-value-call
-						 #'encoded-types-or 
-					       (values-list
-						(type-analysis-encoded-type analysis))
-					       (values-list
-						(type-analysis-encoded-type target-analysis)))))))
-			   (cond
-			    ((apply #'encoded-allp new-type)
-			     ;; If the type is already T, no need to look further.
-			     (setf (type-analysis-binding-types analysis) nil))
-			    ((setf (type-analysis-binding-types analysis)
-			       (remove target-binding
-				       (remove binding
-					       (union (type-analysis-binding-types analysis)
-						      (type-analysis-binding-types target-analysis)))))
-			     (setf more-binding-references-p t))))))
-		     binding-usage))
-      (when more-binding-references-p
-	(warn "Unable to remove all binding-references duding lexical type analysis."))
-      ;; 3.
-      (maphash (lambda (binding analysis)
-		 (assert (null (type-analysis-binding-types analysis)) ()
-		   "binding ~S type ~S still refers to ~S"
-		   binding
-		   (apply #'encoded-type-decode (type-analysis-encoded-type analysis))
-		   (type-analysis-binding-types analysis))
-		 (setf (binding-store-type binding)
-		   (type-analysis-encoded-type analysis))
-		 #+ignore
-		 (unless (apply #'encoded-allp (type-analysis-encoded-type analysis))
-		   (warn "Type: ~A => ~A"
-			 (binding-name binding)
-			 (apply #'encoded-type-decode (type-analysis-encoded-type analysis)))))
-	       binding-usage)
-      toplevel-funobj)))
+			    (type-specifier-encode type))))))))
+	       (analyze-code (code)
+		 (dolist (instruction code)
+		   (when (listp instruction)
+		     (multiple-value-bind (store-binding store-type)
+			 (find-written-binding-and-type instruction)
+		       (when store-binding
+			 (analyze-store (binding-target store-binding) store-type)))
+		     (analyze-code (instruction-sub-program instruction)))))
+	       (analyze-funobj (funobj)
+		 (loop for (nil . function-env) in (function-envs funobj)
+		     do (analyze-code (extended-code function-env)))
+		 (loop for function-binding in (sub-function-binding-usage funobj) by #'cddr
+		     do (analyze-funobj (function-binding-funobj function-binding)))
+		 funobj))
+	;; 1. Examine each store to lexical bindings.
+	(analyze-funobj toplevel-funobj)
+	;; 2.
+	(loop repeat 10 while more-binding-references-p
+	    doing
+	      (setf more-binding-references-p nil)
+	      (maphash (lambda (binding analysis)
+			 (dolist (target-binding (type-analysis-binding-types analysis))
+			   (let* ((target-analysis
+				   (or (gethash target-binding binding-usage)
+				       (and (typep target-binding 'function-argument)
+					    (make-type-analysis
+					     :encoded-type (multiple-value-list
+							    (type-specifier-encode t))))
+				       (error "Type-reference by ~S to unknown binding ~S"
+					      binding target-binding)))
+				  (new-type (setf (type-analysis-encoded-type analysis)
+					      (multiple-value-list
+					       (multiple-value-call
+						   #'encoded-types-or 
+						 (values-list
+						  (type-analysis-encoded-type analysis))
+						 (values-list
+						  (type-analysis-encoded-type target-analysis)))))))
+			     (cond
+			      ((apply #'encoded-allp new-type)
+			       ;; If the type is already T, no need to look further.
+			       (setf (type-analysis-binding-types analysis) nil))
+			      ((setf (type-analysis-binding-types analysis)
+				 (remove target-binding
+					 (remove binding
+						 (union (type-analysis-binding-types analysis)
+							(type-analysis-binding-types target-analysis)))))
+			       (setf more-binding-references-p t))))))
+		       binding-usage))
+	(when more-binding-references-p
+	  (warn "Unable to remove all binding-references duding lexical type analysis."))
+	;; 3.
+	(maphash (lambda (binding analysis)
+		   (assert (null (type-analysis-binding-types analysis)) ()
+		     "binding ~S type ~S still refers to ~S"
+		     binding
+		     (apply #'encoded-type-decode (type-analysis-encoded-type analysis))
+		     (type-analysis-binding-types analysis))
+		   (setf (binding-store-type binding)
+		     (type-analysis-encoded-type analysis))
+		   #+ignore
+		   (unless (apply #'encoded-allp (type-analysis-encoded-type analysis))
+		     (warn "Type: ~A => ~A"
+			   (binding-name binding)
+			   (apply #'encoded-type-decode (type-analysis-encoded-type analysis)))))
+		 binding-usage))))
+  toplevel-funobj)
 
 (defun resolve-borrowed-bindings (toplevel-funobj)
   "For <funobj>'s code, for every non-local binding used we create
@@ -1128,11 +1134,18 @@
 				   (delete-file-p nil))
   (handler-bind
       (#+sbcl (sb-ext:defconstant-uneql #'continue)
+       #+lispworks-personal-edition
+       (conditions:stack-overflow (lambda (&optional c)
+				    (declare (ignore c))
+				    (warn "Stack overflow. Skipping function ~S.~%"
+					  *compiling-function-name*)
+				    (invoke-restart 'skip-toplevel-form)))
        #+ignore ((or error warning) (lambda (c)
 			     (declare (ignore c))
 			     (format *error-output* "~&;; In file ~S:" path))))
     (unwind-protect
-	(let ((*features* (image-movitz-features *image*)))
+	(let ((*movitz-host-features* *features*)
+	      (*features* (image-movitz-features *image*)))
 	  (multiple-value-prog1
 	      (movitz-compile-file-internal path load-priority)
 	    (unless (equalp *features* (image-movitz-features *image*))
@@ -1152,45 +1165,51 @@
 						     (symbol-value '*default-load-priority*)
 						     (1+ (symbol-value '*default-load-priority*)))))
   (declare (special *default-load-priority*))
-  (with-retries-until-true (retry "Restart Movitz compilation of ~S." path)
-    (let* ((muerte.cl::*compile-file-pathname* path)
-	   (*package* (find-package :muerte))
-	   (funobj (make-instance 'movitz-funobj-pass1
-		     :name (intern (format nil "file-~A" path) :muerte)
-		     :lambda-list (movitz-read nil)))
-	   (funobj-env (make-local-movitz-environment nil funobj
-						      :type 'funobj-env
-						      :declaration-context :funobj))
-	   (function-env (make-local-movitz-environment funobj-env funobj
-							:type 'function-env
+  (with-simple-restart (continue "Skip Movitz compilation of ~S." path)
+    (with-retries-until-true (retry "Restart Movitz compilation of ~S." path)
+      (warn "Compiling ~A.." path)
+      (let* ((muerte.cl::*compile-file-pathname* path)
+	     (*package* (find-package :muerte))
+	     (funobj (make-instance 'movitz-funobj-pass1
+		       :name (intern (format nil "file-~A" path) :muerte)
+		       :lambda-list (movitz-read nil)))
+	     (funobj-env (make-local-movitz-environment nil funobj
+							:type 'funobj-env
 							:declaration-context :funobj))
-	   (file-code
-	    (with-compilation-unit ()
-	      (add-bindings-from-lambda-list () function-env)
-	      (with-open-file (stream path :direction :input)
-		(setf (funobj-env funobj) funobj-env)
-		(loop for form = (with-movitz-syntax ()
-				   (read stream nil '#0=#:eof))
-		    until (eq form '#0#)
-		    appending
-		      (with-simple-restart (skip-toplevel-form
-					    "Skip the compilation of this top-level form.")
-			(compiler-call #'compile-form
-			  :form form
-			  :funobj funobj
-			  :env function-env
-			  :top-level-p t
-			  :result-mode :ignore)))))))
-      (cond
-       ((null file-code)
-	(setf (image-load-time-funobjs *image*)
-	  (delete funobj (image-load-time-funobjs *image*) :key #'first)))
-       (t (setf (extended-code function-env) file-code
-		(need-normalized-ecx-p function-env) nil
-		(function-envs funobj) (list (cons 'muerte.cl::t function-env))
-		(funobj-env funobj) funobj-env)
-	  (make-compiled-funobj-pass2 funobj)))
-      t)))
+	     (function-env (make-local-movitz-environment funobj-env funobj
+							  :type 'function-env
+							  :declaration-context :funobj))
+	     (file-code
+	      (with-compilation-unit ()
+		(add-bindings-from-lambda-list () function-env)
+		(with-open-file (stream path :direction :input)
+		  (setf (funobj-env funobj) funobj-env)
+		  (loop for form = (with-movitz-syntax ()
+				     (read stream nil '#0=#:eof))
+		      until (eq form '#0#)
+		      appending
+			(with-simple-restart (skip-toplevel-form
+					      "Skip the compilation of top-level form~@[ ~A~]."
+					      (cond
+					       ((symbolp form) form)
+					       ((symbolp (car form)) (car form))))
+			  #+lispworks-personal-edition (hcl:mark-and-sweep 2)
+			  (compiler-call #'compile-form
+			    :form form
+			    :funobj funobj
+			    :env function-env
+			    :top-level-p t
+			    :result-mode :ignore)))))))
+	(cond
+	 ((null file-code)
+	  (setf (image-load-time-funobjs *image*)
+	    (delete funobj (image-load-time-funobjs *image*) :key #'first)))
+	 (t (setf (extended-code function-env) file-code
+		  (need-normalized-ecx-p function-env) nil
+		  (function-envs funobj) (list (cons 'muerte.cl::t function-env))
+		  (funobj-env funobj) funobj-env)
+	    (make-compiled-funobj-pass2 funobj)))
+	t))))
 
 ;;;;
 
@@ -5352,7 +5371,7 @@
 
 (define-find-read-bindings :incf-lexvar (binding delta &key protect-registers)
   (declare (ignore delta protect-registers))
-  binding)
+  nil #+ignore binding)
 
 (define-extended-code-expander :incf-lexvar (instruction funobj frame-map)
   (destructuring-bind (binding delta &key protect-registers)
@@ -5360,11 +5379,11 @@
     (check-type binding binding)
     (check-type delta integer)
     (let* ((binding (binding-target binding))
-	   (location (new-binding-location binding frame-map :default nil)))
-      (assert (= 5 (length (binding-store-type binding))) ()
-	"Weird encoded-type: ~S" (binding-store-type binding))
+	   (location (new-binding-location binding frame-map :default nil))
+	   (binding-type (binding-store-type binding)))
       (cond
-       ((and location
+       ((and binding-type
+	     location
 	     (not (binding-lended-p binding))
 	     (multiple-value-call #'encoded-subtypep
 	       (values-list (binding-store-type binding))
@@ -5374,9 +5393,10 @@
 	`((:addl ,(* delta +movitz-fixnum-factor+)
 		 (:ebp ,(stack-frame-offset location)))
 	  (:into)))
-       ((multiple-value-call #'encoded-subtypep 
-	  (values-list (binding-store-type binding))
-	  (type-specifier-encode 'integer))
+       ((and binding-type
+	     (multiple-value-call #'encoded-subtypep 
+	       (values-list (binding-store-type binding))
+	       (type-specifier-encode 'integer)))
 	(let ((register (chose-free-register protect-registers)))
 	  `(,@(make-load-lexical (ensure-local-binding binding funobj) 
 				 register funobj nil frame-map





More information about the Movitz-cvs mailing list