Another check in check-ir-consistency
authorDavid Vázquez <davazp@gmail.com>
Fri, 17 May 2013 15:33:22 +0000 (16:33 +0100)
committerDavid Vázquez <davazp@gmail.com>
Fri, 17 May 2013 15:33:22 +0000 (16:33 +0100)
experimental/compiler.lisp

index 441fea5..9a8824f 100644 (file)
         (unless (find block (block-pred succ))
           (error "The block `~S' does not belong to the predecessors list of the its successor `~S'"
                  (block-id block)
-                 (block-id succ))))
+                 (block-id succ)))
+        (unless (find succ (component-blocks component))
+          (error "Block `~S' is reachable but it is not in the component `~S'" succ component)))
       (dolist (pred (block-pred block))
         (unless (find block (block-succ pred))
           (error "The block `~S' does not belong to the successors' list of its predecessor `~S'"
                  (block-id block)
-                 (block-id pred)))))))
+                 (block-id pred)))
+        (unless (find pred (component-blocks component))
+          (error "Block `~S' is reachable but it is not in the component `~S'" pred component))))))
 
 
 ;;; Blocks are `basic block`. Basic blocks are organized as a control
 (defstruct (basic-block
              (:conc-name "BLOCK-")
              (:constructor make-block)
-             (:predicate block-p))
+             (:predicate block-p)
+             (:print-object generic-printer))
   (id (generate-id 'basic-block))
   ;; List of successors and predecessors of this basic block.
   succ pred
   ;; The sentinel nodes of the sequence.
   entry exit
   ;; The component where this block belongs
-  (component *component*))
+  (component *component*)
+  (dominators%))
 
 ;;; Sentinel nodes in the control flow graph of basic blocks.
 (defstruct (component-entry (:include basic-block)))
          (add-to-list (block)
            (push block (component-blocks *component*))))
     (map-postorder-blocks #'clean-and-coallesce component)
-    (map-postorder-blocks #'add-to-list component)))
+    (map-postorder-blocks #'add-to-list component)
+    (check-ir-consistency)))
 
 
 ;;; IR Debugging
   (when (singlep (block-succ block))
     (format t "GO ~a~%~%" (format-block-name (unlist (block-succ block))))))
 
-(defun print-component (component &optional (stream *standard-output*))
+(defun /print (component &optional (stream *standard-output*))
   (format t ";;; COMPONENT ~a (~a) ~%~%" (component-name component) (component-id component))
   (let ((*standard-output* stream))
     (do-blocks (block component)
   (format t ";;; END COMPONENT ~a ~%~%" (component-name component))
   (let ((*standard-output* stream))
     (dolist (func (component-functions component))
-      (print-component (functional-component func)))))
+      (/print (functional-component func)))))
 
 ;;; Translate FORM into IR and print a textual repreresentation of the
 ;;; component.
     (with-component-compilation ('toplevel)
       (ir-convert form (make-lvar :id "out"))
       (when normalize (ir-normalize))
-      (check-ir-consistency)
-      (print-component *component*))))
+      (/print *component*)
+      *component*)))
 
 (defmacro /ir (form)
   `(convert-toplevel-and-print ',form))
 
 
+
+;;;; Dominators
+
+(defun compute-dominators (component)
+  ;; Initialize the dominators of the entry to the component to be
+  ;; empty and the power set of the set of blocks for proper basic
+  ;; blocks in the component.
+  (let ((n (length (component-blocks component))))
+    ;; The component entry special block has not predecessors in the
+    ;; set of (proper) basic blocks.
+    (setf (block-dominators% (component-entry component))
+          (make-array n :element-type 'bit :initial-element 0))
+    (do-blocks (block component)
+      (setf (block-dominators% block) (make-array n :element-type 'bit :initial-element 1))))
+  ;; Iterate across the blocks in the component removing non domintors
+  ;; until it reaches a fixed point.tpn
+  (do ((i 0 0)
+       (changes t))
+      ((not changes))
+    (setf changes nil)
+    (do-blocks (block component)
+      (format t "Processing ~a~%" (format-block-name block))
+      (let ((new (reduce #'bit-and (mapcar #'block-dominators% (block-pred block)))))
+        (setf (aref new i) 1)
+        (setf changes (or changes (not (equal new (block-dominators% block)))))
+        (setf (block-dominators% block) new)
+        (incf i)))))
+
+
+
 ;;;; Primitives
 ;;;;
 ;;;; Primitive functions are a set of functions provided by the