Initial revision
authorChris Hanson <org/chris-hanson/cph>
Wed, 26 Apr 1989 05:11:29 +0000 (05:11 +0000)
committerChris Hanson <org/chris-hanson/cph>
Wed, 26 Apr 1989 05:11:29 +0000 (05:11 +0000)
v7/src/compiler/base/constr.scm [new file with mode: 0644]
v7/src/compiler/rtlopt/rinvex.scm [new file with mode: 0644]

diff --git a/v7/src/compiler/base/constr.scm b/v7/src/compiler/base/constr.scm
new file mode 100644 (file)
index 0000000..3482853
--- /dev/null
@@ -0,0 +1,273 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/base/constr.scm,v 1.1 1989/04/26 05:11:06 cph Rel $
+
+Copyright (c) 1989 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+\f
+;;; Procedures for managing a set of ordering constraints
+
+(define-structure (constraint
+                  (conc-name constraint/)
+                  (constructor
+                   &make-constraint (element)))
+  (element false read-only true)
+  (graph-head false)
+  (afters '())
+  (generation)
+  (closed? true))
+
+(define-structure (constraint-graph
+                  (conc-name constraint-graph/)
+                  (constructor make-constraint-graph ()))
+  (entry-nodes '())
+  (closed? true))
+
+(define (make-constraint element #!optional graph-head afters)
+  (let ((constraint (&make-constraint element)))
+    (if (and (not (default-object? graph-head))
+            (constraint-graph? graph-head))
+       (begin
+         (set-constraint/graph-head! constraint graph-head)
+         (set-constraint-graph/entry-nodes!
+          graph-head
+          (cons constraint (constraint-graph/entry-nodes graph-head)))))
+    (if (not (default-object? afters))
+       (for-each
+        (lambda (after) (constraint-add! constraint after))
+        afters))
+    constraint))
+
+(define (find-constraint element graph-head)
+
+  (define (loop children)
+    (if (pair? children)
+       (or (search (car children))
+           (loop (cdr children)))
+       false))
+
+  (define (search constraint)
+    (if (eqv? element (constraint/element constraint))
+       constraint
+       (loop (constraint/afters constraint))))
+  
+  (loop (constraint-graph/entry-nodes graph-head)))
+
+(define (find-or-make-constraint element graph-head
+                                #!optional afters)
+  (or (find-constraint element graph-head)
+      (if (default-object? afters)
+         (make-constraint element graph-head)
+         (make-constraint element graph-head afters))))
+          
+\f
+(define (constraint-add! before after)
+  (if (eq? (constraint/element before) (constraint/element after))
+      (error "A node cannot be constrained to come after itself" after))
+  (set-constraint/afters! before (cons after (constraint/afters before)))
+  (let ((c-graph (constraint/graph-head after)))
+    (if c-graph
+       (set-constraint-graph/entry-nodes! 
+        c-graph
+        (delq! after (constraint-graph/entry-nodes c-graph)))))
+  (set-constraint/closed?! before false)
+  (if (constraint/graph-head before)
+      (set-constraint-graph/closed?!
+       (constraint/graph-head before)
+       false)))
+
+(define (add-constraint-element! before-element after-element
+                                graph-head)
+  (find-or-make-constraint
+   before-element
+   graph-head
+   (list after-element)))
+
+(define (add-constraint-set! befores afters graph-head)
+  (let ((after-constraints
+        (map (lambda (after)
+               (find-or-make-constraint after graph-head))
+             afters)))
+    (for-each
+     (lambda (before)
+       (find-or-make-constraint before graph-head after-constraints))
+     befores)))
+\f
+(define (close-constraint-graph! c-graph)
+  (with-new-constraint-marks
+   (lambda ()
+     (for-each close-constraint-node!
+              (constraint-graph/entry-nodes c-graph))))
+  (set-constraint-graph/closed?! c-graph true))
+
+(define (close-constraint-node! node)
+  (with-new-constraint-marks
+   (lambda ()
+     (&close-constraint-node! node))))
+
+(define (&close-constraint-node! node)
+  (transitively-close-dag!
+   node
+   constraint/afters
+   (lambda (before afters)
+     (set-constraint/afters!
+      before
+      (append
+       (constraint/afters before)
+       (if (memq node afters)
+          (error
+           "Illegal cycle in constraint graph involving node:"
+           node)
+          afters))))
+   constraint-marked?
+   (lambda (node)
+     (constraint-mark! node)
+     (set-constraint/closed?! node true))))
+
+(define (transitively-close-dag! node select update! marked? mark!)
+  (let transitively-close*! ((node node))
+    (let ((elements (select node)))
+      (if (or (null? elements) (marked? node))
+         elements
+         (begin
+           (mark! node)
+           (update! node (safe-mapcan transitively-close*! elements))
+           (select node))))))
+
+(define-integrable (safe-mapcan procedure list)
+  (mapcan (lambda (item) (list-copy (procedure item))) list))
+\f
+(define (order-per-constraints elements constraint-graph)
+  (order-per-constraints/extracted
+   elements
+   constraint-graph
+   identity-procedure))
+
+(define (order-per-constraints/extracted things
+                                        constraint-graph
+                                        element-extractor)
+;;; This orders a set of things according to the constraints where the
+;;; things are not elements of the constraint-graph nodes but elements
+;;; can be extracted from the things by element-extractor
+  (let loop ((linearized-constraints
+             (reverse-postorder
+              (constraint-graph/entry-nodes constraint-graph)
+              constraint/afters
+              with-new-constraint-marks
+              constraint-mark!
+              constraint-marked?))
+            (things things)
+            (result '()))
+    (if (and (pair? linearized-constraints)
+            (pair? things))
+       (let ((match (list-search-positive
+                        things
+                      (lambda (thing)
+                        (eqv?
+                         (constraint/element
+                          (car linearized-constraints))
+                         (element-extractor thing))))))
+         (loop (cdr linearized-constraints)
+               (delv match things)
+               (if (and match
+                        (not (memv match result)))
+                   (cons match result)
+                   result)))
+       (reverse! result))))
+
+(define (legal-ordering-per-constraints? element-ordering constraint-graph)
+  (let loop ((ordering element-ordering)
+            (nodes (constraint-graph/entry-nodes constraint-graph)))
+
+    (define (depth-first-search? node)
+      (if (or (null? node) (constraint-marked? node))
+         false
+         (begin
+           (constraint-mark! node)
+           (if (eq? (constraint/element node) (car ordering))
+               (loop (cdr ordering) (constraint/afters node))
+               (multiple-search? (constraint/afters node))))))
+
+    (define (multiple-search? nodes)
+      (if (null? nodes)
+         false
+         (or (depth-first-search? (car nodes))
+             (multiple-search? (cdr nodes)))))
+
+    (if (null? ordering)
+       true
+       (with-new-constraint-marks
+        (lambda ()
+          (multiple-search? nodes))))))
+\f
+(define (reverse-postorder entry-nodes get-children
+                          with-new-node-marks node-mark!
+                          node-marked?)
+
+  (define result)
+  
+  (define (loop node)
+    (node-mark! node)
+    (for-each next (get-children node))
+    (set! result (cons node result)))
+
+  (define (next node)
+    (and node
+        (not (node-marked? node))
+        (loop node)))
+    
+  (define (doit node)
+    (set! result '())
+    (loop node)
+    (reverse! result))
+
+  (with-new-node-marks
+   (lambda ()
+     (mapcan doit entry-nodes))))
+
+(define *constraint-generation*)
+
+(define (with-new-constraint-marks thunk)
+  (fluid-let ((*constraint-generation* (make-constraint-generation)))
+    (thunk)))
+
+(define make-constraint-generation
+  (let ((constraint-generation 0))
+    (named-lambda (make-constraint/generation)
+      (let ((value constraint-generation))
+       (set! constraint-generation (1+ constraint-generation))
+       value))))
+
+(define (constraint-marked? constraint)
+  (eq? (constraint/generation constraint) *constraint-generation*))
+
+(define (constraint-mark! constraint)
+  (set-constraint/generation! constraint *constraint-generation*))
+
diff --git a/v7/src/compiler/rtlopt/rinvex.scm b/v7/src/compiler/rtlopt/rinvex.scm
new file mode 100644 (file)
index 0000000..cc84edf
--- /dev/null
@@ -0,0 +1,299 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/rtlopt/rinvex.scm,v 1.1 1989/04/26 05:11:29 cph Rel $
+
+Copyright (c) 1989 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; RTL Invertible Expression Elimination
+
+(declare (usual-integrations))
+\f
+(define *initial-queue*)
+(define *branch-queue*)
+(define *register-values*)
+
+(define (invertible-expression-elimination rgraphs)
+  (with-new-node-marks (lambda () (for-each walk-rgraph rgraphs))))
+
+(define (walk-rgraph rgraph)
+  (fluid-let ((*current-rgraph* rgraph)
+             (*initial-queue* (make-queue))
+             (*branch-queue* '())
+             (*register-values*
+              (make-vector (rgraph-n-registers rgraph) false)))
+    (for-each (lambda (edge)
+               (enqueue!/unsafe *initial-queue* (edge-right-node edge)))
+             (rgraph-initial-edges rgraph))
+    (continue-walk)))
+
+(define (continue-walk)
+  (cond ((not (null? *branch-queue*))
+        (let ((entry (car *branch-queue*)))
+          (set! *branch-queue* (cdr *branch-queue*))
+          (set! *register-values* (car entry))
+          (walk-bblock (cdr entry))))
+       ((not (queue-empty? *initial-queue*))
+        (vector-fill! *register-values* false)
+        (walk-bblock (dequeue!/unsafe *initial-queue*)))))
+
+(define (walk-bblock bblock)
+  (let loop ((rinst (bblock-instructions bblock)))
+    (let ((rtl (rinst-rtl rinst)))
+      ((lookup-method (rtl:expression-type rtl)) rtl))
+    (if (rinst-next rinst)
+       (loop (rinst-next rinst))))
+  (node-mark! bblock)
+  (if (sblock? bblock)
+      (let ((next (snode-next bblock)))
+       (if (walk-next? next)
+           (walk-next next)
+           (continue-walk)))
+      (let ((consequent (pnode-consequent bblock))
+           (alternative (pnode-alternative bblock)))
+       (if (walk-next? consequent)
+           (if (walk-next? alternative)
+               (if (node-previous>1? consequent)
+                   (begin
+                     (enqueue!/unsafe *initial-queue* consequent)
+                     (walk-next alternative))
+                   (begin
+                     (if (node-previous>1? alternative)
+                         (enqueue!/unsafe *initial-queue* alternative)
+                         (set! *branch-queue*
+                               (cons (cons (vector-copy *register-values*)
+                                           alternative)
+                                     *branch-queue*)))
+                     (walk-bblock consequent)))
+               (walk-next consequent))
+           (if (walk-next? alternative)
+               (walk-next alternative)
+               (continue-walk))))))
+
+(define-integrable (walk-next? bblock)
+  (and bblock (not (node-marked? bblock))))
+
+(define-integrable (walk-next bblock)
+  (if (node-previous>1? bblock) (vector-fill! *register-values* false))
+  (walk-bblock bblock))
+
+(define-integrable (register-value register)
+  (vector-ref *register-values* register))
+
+(define-integrable (set-register-value! register value)
+  (vector-set! *register-values* register value)
+  unspecific)
+\f
+(define (expression-update! get-expression set-expression! object)
+  (set-expression!
+   object
+   (let loop ((expression (get-expression object)))
+     (if (rtl:register? expression)
+        expression
+        (optimize-expression (rtl:map-subexpressions expression loop))))))
+
+(define (optimize-expression expression)
+  (let ((type (rtl:expression-type expression))
+       (fold-unary
+        (lambda (type)
+          (let ((subexpression
+                 (canonicalize-subexpression (cadr expression))))
+            (if (eq? type (rtl:expression-type subexpression))
+                (cadr subexpression)
+                expression)))))
+    (let loop ((unary-inversions unary-inversions))
+      (cond ((null? unary-inversions)
+            expression)
+           ((eq? type (caar unary-inversions))
+            (fold-unary (cdar unary-inversions)))
+           ((eq? type (cdar unary-inversions))
+            (fold-unary (caar unary-inversions)))
+           (else
+            (loop (cdr unary-inversions)))))))
+
+(define unary-inversions
+  '((OBJECT->FIXNUM . FIXNUM->OBJECT)
+    (OBJECT->UNSIGNED-FIXNUM . FIXNUM->OBJECT)
+    (ADDRESS->FIXNUM . FIXNUM->ADDRESS)))
+
+(define (canonicalize-subexpression expression)
+  (or (and (rtl:pseudo-register-expression? expression)
+          (register-value (rtl:register-number expression)))
+      expression))
+
+(define (define-method type method)
+  (let ((entry (assq type methods)))
+    (if entry
+       (set-cdr! entry method)
+       (set! methods (cons (cons type method) methods))))
+  type)
+
+(define (lookup-method type)
+  (if (eq? type 'ASSIGN)
+      walk/assign
+      (let ((entry (assq type methods)))
+       (if (not entry)
+           (error "Missing method" type))
+       (cdr entry))))
+
+(define methods
+  '())
+
+(define (walk/assign statement)
+  (expression-update! rtl:assign-expression
+                     rtl:set-assign-expression!
+                     statement)
+  (let ((address (rtl:assign-address statement)))
+    (if (rtl:pseudo-register-expression? address)
+       (set-register-value! (rtl:register-number address)
+                            (rtl:assign-expression statement)))))
+
+(define-method 'INVOCATION:SPECIAL-PRIMITIVE
+  (lambda (statement)
+    statement
+    (for-each-pseudo-register
+     (lambda (register)
+       (set-register-value! register false)))))
+\f
+(for-each (lambda (type)
+           (define-method type (lambda (statement) statement unspecific)))
+         '(CLOSURE-HEADER
+           CONTINUATION-ENTRY
+           CONTINUATION-HEADER
+           IC-PROCEDURE-HEADER
+           INVOCATION:APPLY
+           INVOCATION:COMPUTED-JUMP
+           INVOCATION:COMPUTED-LEXPR
+           INVOCATION:JUMP
+           INVOCATION:LEXPR
+           INVOCATION:PRIMITIVE
+           INVOCATION:UUO-LINK
+           OPEN-PROCEDURE-HEADER
+           OVERFLOW-TEST
+           POP-RETURN
+           PROCEDURE-HEADER))
+
+(define (define-one-arg-method type get set)
+  (define-method type
+    (lambda (statement)
+      (expression-update! get set statement))))
+
+(define-one-arg-method 'FIXNUM-PRED-1-ARG
+  rtl:fixnum-pred-1-arg-operand
+  rtl:set-fixnum-pred-1-arg-operand!)
+
+(define-one-arg-method 'TRUE-TEST
+  rtl:true-test-expression
+  rtl:set-true-test-expression!)
+
+(define-one-arg-method 'TYPE-TEST
+  rtl:type-test-expression
+  rtl:set-type-test-expression!)
+
+(define-one-arg-method 'UNASSIGNED-TEST
+  rtl:type-test-expression
+  rtl:set-unassigned-test-expression!)
+
+(define-one-arg-method 'INVOCATION:CACHE-REFERENCE
+  rtl:invocation:cache-reference-name
+  rtl:set-invocation:cache-reference-name!)
+
+(define-one-arg-method 'INVOCATION:LOOKUP
+  rtl:invocation:lookup-environment
+  rtl:set-invocation:lookup-environment!)
+
+(define-one-arg-method 'INVOCATION-PREFIX:MOVE-FRAME-UP
+  rtl:invocation-prefix:move-frame-up-locative
+  rtl:set-invocation-prefix:move-frame-up-locative!)
+
+(define-one-arg-method 'INTERPRETER-CALL:ACCESS
+  rtl:interpreter-call:access-environment
+  rtl:set-interpreter-call:access-environment!)
+
+(define-one-arg-method 'INTERPRETER-CALL:CACHE-REFERENCE
+  rtl:interpreter-call:cache-reference-name
+  rtl:set-interpreter-call:cache-reference-name!)
+
+(define-one-arg-method 'INTERPRETER-CALL:CACHE-UNASSIGNED?
+  rtl:interpreter-call:cache-unassigned?-name
+  rtl:set-interpreter-call:cache-unassigned?-name!)
+
+(define-one-arg-method 'INTERPRETER-CALL:LOOKUP
+  rtl:interpreter-call:lookup-environment
+  rtl:set-interpreter-call:lookup-environment!)
+
+(define-one-arg-method 'INTERPRETER-CALL:UNASSIGNED?
+  rtl:interpreter-call:unassigned?-environment
+  rtl:set-interpreter-call:unassigned?-environment!)
+
+(define-one-arg-method 'INTERPRETER-CALL:UNBOUND?
+  rtl:interpreter-call:unbound?-environment
+  rtl:set-interpreter-call:unbound?-environment!)
+\f
+(define (define-two-arg-method type get-1 set-1 get-2 set-2)
+  (define-method type
+    (lambda (statement)
+      (expression-update! get-1 set-1 statement)
+      (expression-update! get-2 set-2 statement))))
+
+(define-two-arg-method 'EQ-TEST
+  rtl:eq-test-expression-1
+  rtl:set-eq-test-expression-1!
+  rtl:eq-test-expression-2
+  rtl:set-eq-test-expression-2!)
+
+(define-two-arg-method 'FIXNUM-PRED-2-ARGS
+  rtl:fixnum-pred-2-args-operand-1
+  rtl:set-fixnum-pred-2-args-operand-1!
+  rtl:fixnum-pred-2-args-operand-2
+  rtl:set-fixnum-pred-2-args-operand-2!)
+(define-two-arg-method 'INVOCATION-PREFIX:DYNAMIC-LINK
+  rtl:invocation-prefix:dynamic-link-locative
+  rtl:set-invocation-prefix:dynamic-link-locative!
+  rtl:invocation-prefix:dynamic-link-register
+  rtl:set-invocation-prefix:dynamic-link-register!)
+
+(define-two-arg-method 'INTERPRETER-CALL:CACHE-ASSIGNMENT
+  rtl:interpreter-call:cache-assignment-name
+  rtl:set-interpreter-call:cache-assignment-name!
+  rtl:interpreter-call:cache-assignment-value
+  rtl:set-interpreter-call:cache-assignment-value!)
+
+(define-two-arg-method 'INTERPRETER-CALL:DEFINE
+  rtl:interpreter-call:define-environment
+  rtl:set-interpreter-call:define-environment!
+  rtl:interpreter-call:define-value
+  rtl:set-interpreter-call:define-value!)
+
+(define-two-arg-method 'INTERPRETER-CALL:SET!
+  rtl:interpreter-call:set!-environment
+  rtl:set-interpreter-call:set!-environment!
+  rtl:interpreter-call:set!-value
+  rtl:set-interpreter-call:set!-value!)
\ No newline at end of file