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

Frode Vatvedt Fjeld ffjeld at common-lisp.net
Sat Aug 20 20:30:46 UTC 2005


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

Modified Files:
	compiler.lisp 
Log Message:
Re-worked several aspects of binding/environments: assignment,
type-inference, etc.

Date: Sat Aug 20 22:30:44 2005
Author: ffjeld

Index: movitz/compiler.lisp
diff -u movitz/compiler.lisp:1.149 movitz/compiler.lisp:1.150
--- movitz/compiler.lisp:1.149	Mon Aug 15 23:44:23 2005
+++ movitz/compiler.lisp	Sat Aug 20 22:30:40 2005
@@ -8,7 +8,7 @@
 ;;;; Created at:    Wed Oct 25 12:30:49 2000
 ;;;; Distribution:  See the accompanying file COPYING.
 ;;;;                
-;;;; $Id: compiler.lisp,v 1.149 2005/08/15 21:44:23 ffjeld Exp $
+;;;; $Id: compiler.lisp,v 1.150 2005/08/20 20:30:40 ffjeld Exp $
 ;;;;                
 ;;;;------------------------------------------------------------------
 
@@ -473,7 +473,7 @@
 		 (assert (or (typep type 'binding)
 			     (eql 1 (type-specifier-num-values type))) ()
 		   "store-lexical with multiple-valued type: ~S for ~S" type binding)
-		 ;; (warn "store ~S type ~S, thunk ~S" binding type thunk)
+		 #+ignore (warn "store ~S type ~S, thunk ~S" binding type thunk)
 		 (let ((analysis (or (gethash binding binding-usage)
 				     (setf (gethash binding binding-usage)
 				       (make-type-analysis-with-declaration binding)))))
@@ -492,14 +492,14 @@
 			    (values-list (type-analysis-encoded-type analysis))
 			    (type-specifier-encode type))))))))
 	       (analyze-code (code)
+		 #+ignore (print-code 'analyze code)
 		 (dolist (instruction code)
 		   (when (listp instruction)
 		     (multiple-value-bind (store-binding store-type thunk thunk-args)
 			 (find-written-binding-and-type instruction)
 		       (when store-binding
-			 #+ignore
-			 (warn "store: ~S binding ~S type ~S thunk ~S"
-			       instruction store-binding store-type thunk)
+			 #+ignore (warn "store: ~S binding ~S type ~S thunk ~S"
+					instruction store-binding store-type thunk)
 			 (analyze-store store-binding store-type thunk thunk-args)))
 		     (analyze-code (instruction-sub-program instruction)))))
 	       (analyze-funobj (funobj)
@@ -617,6 +617,8 @@
 		 ;; Binding is local to this funobj
 		 (typecase binding
 		   (forwarding-binding
+		    (process-binding funobj (forwarding-binding-target binding) usages)
+		    #+ignore
 		    (setf (forwarding-binding-target binding)
 		      (process-binding funobj (forwarding-binding-target binding) usages)))
 		   (function-binding
@@ -2377,7 +2379,14 @@
     :accessor binding-env)
    (declarations
     :initarg :declarations
-    :accessor binding-declarations)))
+    :accessor binding-declarations)
+   (extent-env
+    :accessor binding-extent-env
+    :initform nil)))
+
+(defmethod (setf binding-env) :after (env (binding binding))
+  (unless (binding-extent-env binding)
+    (setf (binding-extent-env binding) env)))
 
 (defmethod print-object ((object binding) stream)
   (print-unreadable-object (object stream :type t :identity t)
@@ -2387,12 +2396,13 @@
 		   (binding-name object))
 	      (when (and (binding-target object)
 			 (not (eq object (binding-target object))))
-		(binding-name (binding-target object)))
+		(binding-name (forwarding-binding-target object)))
 	      (when (and #+ignore (slot-exists-p object 'store-type)
 			 #+ignore (slot-boundp object 'store-type)
 			 (binding-store-type object))
-		(apply #'encoded-type-decode
-		       (binding-store-type object)))))))
+		(or (apply #'encoded-type-decode
+			   (binding-store-type object))
+		    'empty))))))
 
 (defclass constant-object-binding (binding)
   ((object
@@ -2653,11 +2663,11 @@
 	      '((:int 100))
 	      :test #'equalp)))
   
-(defun sub-environment-p (env1 env2)
-  (cond
-   ((eq env1 env2) t)
-   ((null env1) nil)
-   (t (sub-environment-p (movitz-environment-uplink env1) env2))))
+#+ignore (defun sub-environment-p (env1 env2)
+	   (cond
+	    ((eq env1 env2) t)
+	    ((null env1) nil)
+	    (t (sub-environment-p (movitz-environment-uplink env1) env2))))
 
 (defun find-code-constants-and-jumpers (code &key include-programs)
   "Return code's constants (a plist of constants and their usage-counts) and jumper-sets."
@@ -3006,7 +3016,7 @@
    sub-environments found in CODE. A frame-map which is an assoc from
    bindings to stack-frame locations."
   ;; Then assign them to locations in the stack-frame.
-  ;; (warn "assigning code:~%~{~&    ~A~}" code)
+  #+ignore (warn "assigning code:~%~{~&    ~A~}" code)
   (check-type function-env function-env)
   (assert (= initial-stack-frame-position
 	     (1+ (frame-map-size frame-map))))
@@ -3022,10 +3032,42 @@
 	     (error "SEFEW: ~S" function-env))
 	    ;; The floor of this env is the roof of its extent-uplink.
 	    (t (assign-env-bindings (movitz-environment-extent-uplink env)))))
+	 ;; PROMOTE FORW-BINDINGS TO UPPER ENV!!
 	 (assign-env-bindings (env)
 	   (or (getf env-roof-map env nil)
 	       (let* ((stack-frame-position (env-floor env))
 		      (bindings-to-locate
+		       (loop for binding being the hash-keys of var-counts
+			   when (eq env (binding-extent-env binding))
+			   unless (let ((variable (binding-name binding)))
+				    (cond
+				     ((not (typep binding 'lexical-binding)))
+				     ((typep binding 'lambda-binding))
+				     ((typep binding 'constant-object-binding))
+				     ((typep binding 'forwarding-binding)
+				      ;; Immediately "assign" to target.
+				      (when (plusp (or (car (gethash binding var-counts)) 0))
+					(setf (new-binding-location binding frame-map)
+					  (forwarding-binding-target binding)))
+				      t)
+				     ((typep binding 'borrowed-binding))
+				     ((typep binding 'funobj-binding))
+				     ((and (typep binding 'fixed-required-function-argument)
+					   (plusp (or (car (gethash binding var-counts)) 0)))
+				      (prog1 nil ; may need lending-cons
+					(setf (new-binding-location binding frame-map)
+					  `(:argument-stack ,(function-argument-argnum binding)))))
+				     ((unless (or (movitz-env-get variable 'ignore nil
+								  (binding-env binding) nil)
+						  (movitz-env-get variable 'ignorable nil
+								  (binding-env binding) nil)
+						  (typep binding 'hidden-rest-function-argument)
+						  (third (gethash binding var-counts)))
+					(warn "Unused variable: ~S"
+					      (binding-name binding))))
+				     ((not (plusp (or (car (gethash binding var-counts)) 0))))))
+			   collect binding)
+		       #+ignore
 		       (loop for (variable . binding) in (movitz-environment-bindings env)
 			   unless (cond
 				   ((not (typep binding 'lexical-binding)))
@@ -3087,6 +3129,22 @@
 							     (cdr init-pc))
 						15)
 					    count)))))))))
+		 #+ignore (labels ((dox (env upper)
+				     (if (or (not env)
+					     (not (sub-env-p env function-env)))
+					 0
+				       (let ((level (dox (funcall upper env) upper)))
+					 (format t "~%~v{ ~}~S" level t env)
+					 (+ level 4)))))
+			    (warn "At ~S binding ~S:~{ ~S~}: Extent: ~A~%Bind: ~A" 
+				  stack-frame-position
+				  env bindings-to-locate
+				  (with-output-to-string (*standard-output*)
+				    (dox env #'movitz-environment-extent-uplink))
+				  (with-output-to-string (*standard-output*)
+				    (when bindings-to-locate
+				      (dox (binding-env (first bindings-to-locate))
+					   #'movitz-environment-uplink)))))
 		 ;; First, make several passes while trying to locate bindings
 		 ;; into registers.
 		 (loop repeat 100 with try-again = t and did-assign = t
@@ -3181,6 +3239,8 @@
 			(setf (new-binding-location binding frame-map)
 			  `(:argument-stack ,(function-argument-argnum binding))))
 		       (located-binding
+			#+ignore (warn "Assigning ~S at ~S"
+				       binding stack-frame-position)
 			(setf (new-binding-location binding frame-map)
 			  (post-incf stack-frame-position))))))
 		 (setf (getf env-roof-map env)
@@ -3190,7 +3250,7 @@
 		   ;; do (warn "bind: ~S: ~S" binding (eq function-env (find-function-env env funobj)))
 	  when (sub-env-p env function-env)
 	  do (assign-env-bindings (binding-env binding)))
-      ;; (warn "Frame-map:~{ ~A~}"  frame-map)
+      #+ignore (warn "Frame-map:~{ ~A~}"  frame-map)
       frame-map)))
 
 
@@ -3269,7 +3329,7 @@
   "Resolve a binding in terms of forwarding."
   (etypecase binding
     (forwarding-binding
-     (forwarding-binding-target binding))
+     (binding-target (forwarding-binding-target binding)))
     (binding
      binding)))
 
@@ -3460,8 +3520,8 @@
 ;;;			    :untagged-fixnum-ecx))
 		    ((and binding-type
 			  (type-specifier-singleton decoded-type))
-		     (warn "Immloadlex: ~S"
-			   (type-specifier-singleton decoded-type))
+		     #+ignore (warn "Immloadlex: ~S"
+				    (type-specifier-singleton decoded-type))
 		     (make-immediate-move (movitz-immediate-value
 					   (car (type-specifier-singleton decoded-type)))
 					  :ecx))
@@ -3571,6 +3631,7 @@
 	(located-binding
 	 (let ((binding-type (binding-store-type binding))
 	       (binding-location (new-binding-location binding frame-map)))
+	   #+ignore (warn "~S type: ~S" binding binding-type)
 	   (cond
 	    ((and (binding-lended-p binding)
 		  (not shared-reference-p))
@@ -5349,13 +5410,32 @@
 	  :result-mode :eax
 	  :forward form-info)))))
   
-(define-compiler compile-form-unprotected (&all all &form form &result-mode result-mode)
+(define-compiler compile-form-unprotected (&all downstream &form form &result-mode result-mode
+						&extent extent)
   "3.1.2.1 Form Evaluation. May not honor RESULT-MODE.
 That is, RESULT-MODE is taken to be a suggestion, not an imperative."
-  (typecase form
-    (symbol (compiler-call #'compile-symbol :forward all))
-    (cons   (compiler-call #'compile-cons :forward all))
-    (t      (compiler-call #'compile-self-evaluating :forward all))))
+  (compiler-values-bind (&all upstream)
+      (typecase form
+	(symbol (compiler-call #'compile-symbol :forward downstream))
+	(cons   (compiler-call #'compile-cons :forward downstream))
+	(t      (compiler-call #'compile-self-evaluating :forward downstream)))
+    (when (typep (upstream :final-form) 'lexical-binding)
+      (labels ((fix-extent (binding)
+		 (cond
+		  ((sub-env-p extent (binding-extent-env binding))
+		   #+ignore (warn "Binding ~S OK in ~S wrt. ~S."
+				  binding
+				  (binding-extent-env binding)
+				  (downstream :env)))
+		  (t #+ignore (break "Binding ~S escapes from ~S to ~S"
+				     binding (binding-extent-env binding)
+				     extent)
+		      (setf (binding-extent-env binding) extent)))
+		 (when (typep binding 'forwarding-binding)
+		   (fix-extent (forwarding-binding-target binding)))))
+	(when extent
+	  (fix-extent (upstream :final-form)))))
+    (compiler-values (upstream))))
 
 (defun lambda-form-p (form)
   (and (listp form)
@@ -6092,17 +6172,20 @@
       (:jne ',push-values-loop)
       ,push-values-done)))
 
+(defun stack-add (x y)
+  (if (and (integerp x) (integerp y))
+      (+ x y)
+    t))
+
+(define-modify-macro stack-incf (&optional (delta 1)) stack-add)
+
 (defun stack-delta (inner-env outer-env)
   "Calculate the amount of stack-space used (in 32-bit stack slots) at the time
 of <inner-env> since <outer-env>,
 the number of intervening dynamic-slots (special bindings, unwind-protects, and catch-tags),
 and a list of any intervening unwind-protect environment-slots."
   (labels 
-      ((stack-distance-add (x y)
-	 (if (and (integerp x) (integerp y))
-	     (+ x y)
-	   t))
-       (find-stack-delta (env stack-distance num-dynamic-slots unwind-protects)
+      ((find-stack-delta (env stack-distance num-dynamic-slots unwind-protects)
 	 #+ignore (warn "find-stack-delta: ~S dist ~S, slots ~S" env
 			(stack-used env) (num-dynamic-slots env))
 	 (cond
@@ -6116,8 +6199,8 @@
 	  ((null env)
 	   (values nil 0 nil))
 	  (t (find-stack-delta (movitz-environment-uplink env)
-			       (stack-distance-add stack-distance (stack-used env))
-			       (stack-distance-add num-dynamic-slots (num-dynamic-slots env))
+			       (stack-add stack-distance (stack-used env))
+			       (stack-add num-dynamic-slots (num-dynamic-slots env))
 			       (if (typep env 'unwind-protect-env)
 				   (cons env unwind-protects)
 				 unwind-protects))))))
@@ -6334,6 +6417,8 @@
        ((not (typep init-with-register 'binding))
 	(assert init-with-type)
 	(values binding init-with-type)	)
+       ((and init-with-type (not (bindingp init-with-type)))
+	(values binding init-with-type))
        (t (values binding t
 		  (lambda (x) x)
 		  (list init-with-register)))))
@@ -6701,12 +6786,18 @@
 	(warn "Add for lend0: ~S" destination))
       (let ((loc0 (new-binding-location (binding-target term0) frame-map :default nil))
 	    (loc1 (new-binding-location (binding-target term1) frame-map :default nil)))
-;;;	(warn "add: ~A" instruction)
+	#+ignore
+	(warn "add: ~A for ~A" instruction result-type)
 	#+ignore
 	(warn "add for: ~S is ~A, from ~A/~A and ~A/~A."
 	      destination result-type
 	      term0 loc0
 	      term1 loc1)
+	#+ignore
+	(when (eql loc0 loc1)
+	  (warn "add for:~%~A/~A in ~S~&~A/~A in ~S."
+		term0 loc0 (binding-extent-env (binding-target term0))
+		term1 loc1 (binding-extent-env (binding-target term1))))
 	(cond
 	 ((type-specifier-singleton result-type)
 	  ;; (break "constant add: ~S" instruction)
@@ -6744,7 +6835,7 @@
 	 ((and (movitz-subtypep type0 'fixnum)
 	       (movitz-subtypep type1 'fixnum)
 	       (movitz-subtypep result-type 'fixnum))
-	  ;; (warn "ADDX: ~S" instruction)
+	  #+ignore (warn "ADDX: ~S" instruction)
 	  (cond
 	   ((and (type-specifier-singleton type0)
 		 (eq loc1 destination-location))
@@ -6752,10 +6843,14 @@
 	     ((member destination-location '(:eax :ebx :ecx :edx))
 	      `((:addl ,(movitz-immediate-value (car (type-specifier-singleton type0)))
 		       ,destination)))
-	     (t (assert (integerp loc1))
-		(break "check that this is correct..")
-		`((:addl ,(movitz-immediate-value (car (type-specifier-singleton type0)))
-			 (:ebp ,(stack-frame-offset loc1)))))))
+	     ((integerp loc1)
+	      ;; (break "check that this is correct..")
+	      `((:addl ,(movitz-immediate-value (car (type-specifier-singleton type0)))
+		       (:ebp ,(stack-frame-offset loc1)))))
+	     ((eq :argument-stack (operator loc1))
+	      `((:addl ,(movitz-immediate-value (car (type-specifier-singleton type0)))
+		       (:ebp ,(argument-stack-offset (binding-target term1))))))
+	     (t (error "Don't know how to add this for loc1 ~S" loc1))))
 	   ((and (type-specifier-singleton type0)
 		 (eq term1 destination)
 		 (integerp destination-location))
@@ -6768,41 +6863,44 @@
 	    (append `((:addl ,(movitz-immediate-value (car (type-specifier-singleton type0)))
 			     ,loc1))
 		    (make-store-lexical destination loc1 nil funobj frame-map)))
-	   (t #+ignore (warn "ADD: ~A/~S = ~A/~S + ~A/~S,~%~A ~A"
-			     destination-location
-			     destination
-			     loc0 term0
-			     loc1 term1
-			     (type-specifier-singleton type0)
-			     (eq loc1 destination))
+	   ((and (integerp loc0) (integerp loc1)
+		 (member destination-location '(:eax :ebx :ecx :edx)))
+	    (append `((:movl (:ebp ,(stack-frame-offset loc0)) ,destination-location)
+		      (:addl (:ebp ,(stack-frame-offset loc1)) ,destination-location))))
+	   (t (warn "ADD: ~A/~S = ~A/~S + ~A/~S"
+		    destination-location
+		    destination
+		    loc0 term0
+		    loc1 term1)
+	      #+ignore (warn "map: ~A" frame-map)
 ;;; 	    (warn "ADDI: ~S" instruction)
-	    (append (cond
-		     ((type-specifier-singleton type0)
-		      (append (make-load-lexical term1 :eax funobj nil frame-map)
-			      (make-load-constant (car (type-specifier-singleton type0))
-						  :ebx funobj frame-map)))
-		     ((type-specifier-singleton type1)
-		      (append (make-load-lexical term0 :eax funobj nil frame-map)
-			      (make-load-constant (car (type-specifier-singleton type1))
-						  :ebx funobj frame-map)))
-		     ((and (eq :eax loc0) (eq :ebx loc1))
-		      nil)
-		     ((and (eq :ebx loc0) (eq :eax loc1))
-		      nil)		; terms order isn't important
-		     ((eq :eax loc1)
-		      (append
-		       (make-load-lexical term0 :ebx funobj nil frame-map)))
-		     (t (append
-			 (make-load-lexical term0 :eax funobj nil frame-map)
-			 (make-load-lexical term1 :ebx funobj nil frame-map))))
-		    `((:movl (:edi ,(global-constant-offset '+)) :esi))
-		    (make-compiled-funcall-by-esi 2)
-		    (etypecase destination
-		      (symbol
-		       (unless (eq destination :eax)
-			 `((:movl :eax ,destination))))
-		      (binding
-		       (make-store-lexical destination :eax nil funobj frame-map)))))))
+	      (append (cond
+		       ((type-specifier-singleton type0)
+			(append (make-load-lexical term1 :eax funobj nil frame-map)
+				(make-load-constant (car (type-specifier-singleton type0))
+						    :ebx funobj frame-map)))
+		       ((type-specifier-singleton type1)
+			(append (make-load-lexical term0 :eax funobj nil frame-map)
+				(make-load-constant (car (type-specifier-singleton type1))
+						    :ebx funobj frame-map)))
+		       ((and (eq :eax loc0) (eq :ebx loc1))
+			nil)
+		       ((and (eq :ebx loc0) (eq :eax loc1))
+			nil)		; terms order isn't important
+		       ((eq :eax loc1)
+			(append
+			 (make-load-lexical term0 :ebx funobj nil frame-map)))
+		       (t (append
+			   (make-load-lexical term0 :eax funobj nil frame-map)
+			   (make-load-lexical term1 :ebx funobj nil frame-map))))
+		      `((:movl (:edi ,(global-constant-offset '+)) :esi))
+		      (make-compiled-funcall-by-esi 2)
+		      (etypecase destination
+			(symbol
+			 (unless (eq destination :eax)
+			   `((:movl :eax ,destination))))
+			(binding
+			 (make-store-lexical destination :eax nil funobj frame-map)))))))
 	 (t (append (cond
 		     ((type-specifier-singleton type0)
 		      (append (make-load-lexical term1 :eax funobj nil frame-map)
@@ -6848,12 +6946,13 @@
 	(rotatef x y)
 	(rotatef x-type y-type)
 	(rotatef x-singleton y-singleton))
-      (let (;; (x-loc (new-binding-location (binding-target x) frame-map :default nil))
+      (let (#+ignore (x-loc (new-binding-location (binding-target x) frame-map :default nil))
 	    (y-loc (new-binding-location (binding-target y) frame-map :default nil)))
 	#+ignore
-	(warn "eql ~S/~S ~S/~S"
-	      x x-loc
-	      y y-loc)
+	(warn "eql ~S/~S xx~Xxx ~S/~S: ~S"
+	      x x-loc (binding-target y)
+	      y y-loc
+	      instruction)
 	(flet ((make-branch ()
 		 (ecase (operator return-mode)
 		   (:boolean-branch-on-false




More information about the Movitz-cvs mailing list