Robustify specialised IF/IF conversion introduced in 729ce57
authorPaul Khuong <pvk@pvk.ca>
Fri, 24 May 2013 17:08:55 +0000 (13:08 -0400)
committerPaul Khuong <pvk@pvk.ca>
Fri, 24 May 2013 18:49:40 +0000 (14:49 -0400)
 * When unlinking a node from its destination LVAR, always mark
   the node as potentially up for dead code elimination. IR2 can
   become really confused when converting dead code; a more
   systematic cleanup pass might provide a useful safety net.

 * The changes make a widely-used ir1-manipulation function safer,
   so this might also fix some other obscure compiler bug.

 * Reported by James Y Knight on IRC and Fila Kolodny on Launchpad
   (fixes lp#1183496).

src/compiler/ir1util.lisp

index 6c0a271..dc96f0c 100644 (file)
                       (first new-uses)
                       new-uses)))
           (setf (lvar-uses lvar) nil))
-      (setf (node-lvar node) nil)))
+      (flush-node node)))
   (values))
 ;;; Delete NODE from its LVAR uses; if LVAR has no other uses, delete
 ;;; its DEST's block, which must be unreachable.
 
   (values))
 
+;;; This function is called to unlink a node from its LVAR;
+;;; we assume that the LVAR's USE list has already been updated,
+;;; and that we only have to mark the node as up for dead code
+;;; elimination, and to clear it LVAR slot.
+(defun flush-node (node)
+  (declare (type node node))
+  (let* ((prev (node-prev node))
+         (block (ctran-block prev)))
+    (reoptimize-component (block-component block) t)
+    (setf (block-attributep (block-flags block)
+                            flush-p type-asserted type-check)
+          t))
+  (setf (node-lvar node) nil))
+
 ;;; This function is called by people who delete nodes; it provides a
 ;;; way to indicate that the value of a lvar is no longer used. We
 ;;; null out the LVAR-DEST, set FLUSH-P in the blocks containing uses
     (setf (lvar-dest lvar) nil)
     (flush-lvar-externally-checkable-type lvar)
     (do-uses (use lvar)
-      (let ((prev (node-prev use)))
-        (let ((block (ctran-block prev)))
-          (reoptimize-component (block-component block) t)
-          (setf (block-attributep (block-flags block)
-                                  flush-p type-asserted type-check)
-                t)))
-      (setf (node-lvar use) nil))
+      (flush-node use))
     (setf (lvar-uses lvar) nil))
   (values))