ir-normalize computes block ordering
authorDavid Vázquez <davazp@gmail.com>
Fri, 17 May 2013 08:48:46 +0000 (09:48 +0100)
committerDavid Vázquez <davazp@gmail.com>
Fri, 17 May 2013 08:48:46 +0000 (09:48 +0100)
experimental/compiler.lisp

index e1f5a48..441fea5 100644 (file)
   name
   entry
   exit
-  functions)
+  functions
+  blocks)
 
 ;;; The current component. We accumulate the results of the IR
 ;;; conversion in this component.
        (let ((*cursor* (cursor :block ,block)))
          ,@body))))
 
-;;; Return the list of blocks in COMPONENT, conveniently sorted.
-(defun component-blocks (component)
-  (let ((seen nil)
-        (output nil))
-    (labels ((compute-rdfo-from (block)
+;;; Call function for each block in component in post-order.
+(defun map-postorder-blocks (function component)
+  (let ((seen nil))
+    (labels ((compute-from (block)
                (unless (or (component-exit-p block) (find block seen))
                  (push block seen)
                  (dolist (successor (block-succ block))
                    (unless (component-exit-p block)
-                     (compute-rdfo-from successor)))
-                 (push block output))))
-      (compute-rdfo-from (unlist (block-succ (component-entry component))))
-      output)))
+                     (compute-from successor)))
+                 (funcall function block))))
+      (compute-from (unlist (block-succ (component-entry component))))
+      nil)))
 
 ;;; Iterate across different blocks in COMPONENT.
 (defmacro do-blocks ((block component &optional result) &body body)
-  `(dolist (,block (component-blocks ,component) ,result)
+  `(dolist (,block (or (component-blocks ,component)
+                       (error "Component is not normalized."))
+             ,result)
      ,@body))
 
 (defmacro do-blocks-backward ((block component &optional result) &body body)
-  `(dolist (,block (reverse (component-blocks ,component)) ,result)
+  `(dolist (,block (or (reverse (component-blocks ,component))
+                       (error "component is not normalized."))
+             ,result)
      ,@body))
 
 ;;; A few consistency checks in the IR useful for catching bugs.
 ;;;; conversion as well as insert new IR code during optimizations.
 ;;;;
 ;;;; The function `ir-normalize' will coalesce basic blocks in a
-;;;; component to generate proper maximal basic blocks.
+;;;; component to generate proper maximal basic blocks, as well as
+;;;; compute reverse depth first ordering on the blocks.
 
 ;;; A alist of IR translator functions.
 (defvar *ir-translator* nil)
           (setf (block-pred next) (substitute block succ (block-pred next))))
         t))))
 
+;;; Normalize a component. This function must be called after a batch
+;;; of modifications to the flowgraph of the component to make sure it
+;;; is a valid input for the possible optimizations and the backend.
 (defun ir-normalize (&optional (component *component*))
-  (do-blocks-backward (block component)
-    (maybe-coalesce-block block)
-    (when (empty-block-p block)
-      (delete-empty-block block))))
+  (flet ((clean-and-coallesce (block)
+           (maybe-coalesce-block block)
+           (when (empty-block-p block)
+             (delete-empty-block block)))
+         (add-to-list (block)
+           (push block (component-blocks *component*))))
+    (map-postorder-blocks #'clean-and-coallesce component)
+    (map-postorder-blocks #'add-to-list component)))
 
 
 ;;; IR Debugging