Fix broken IR graph flow with merge iblocks

This commit is contained in:
John Lorentzson 2025-07-03 15:58:56 +02:00
parent 235ca8c07e
commit 7171398c07
3 changed files with 27 additions and 11 deletions

View file

@ -74,7 +74,7 @@
(then-iblock (make-instance 'iblock :name "then"))
(else-iblock (make-instance 'iblock :name "else"))
(continuation (if else-exists-p
(make-instance 'iblock :name "merge")
(make-instance 'iblock-merge :name "merge")
else-iblock)))
(build-insert-end (make-instance
'ir-if

View file

@ -40,19 +40,33 @@
;;; Compilation setup
(defun fix-iblock-flow (iblock)
(let ((reached '()))
(defun fix-iblock-flow (start-iblock)
(let ((reached '())
(last nil)
(deferred '()))
(labels
((fix (iblock prev)
((fix-deferred ()
(unless (null deferred)
(loop :for after :in (nreverse (pop deferred))
:do (fix after last))))
(fix (iblock prev)
(unless (member iblock reached)
(push iblock reached)
(setf (next iblock)
(first (successors iblock))
(prev iblock) prev)
(loop :for prev := iblock :then s
:for s :in (successors iblock)
:do (fix s prev)))))
(fix iblock nil))))
(unless (null prev)
(setf (next prev) iblock))
(setf (prev iblock) prev
last iblock)
(fix-deferred)
(push '() deferred)
(loop :for s :in (successors iblock)
:if (typep s 'iblock-merge)
:do (pushnew s (car deferred))
:else
:do (fix s last))
(when (null prev)
(loop :until (null deferred)
:do (fix-deferred))))))
(fix start-iblock nil))))
(defmacro with-compilation-setup ((iblock builder &key add-return-p) &body body)
`(let ((,iblock (make-instance 'iblock :name "toplevel" :program (make-instance 'ir-program)))

View file

@ -12,6 +12,8 @@
(%prev :accessor prev :type (or null iblock) :initform nil)
(%name :accessor name :initarg :name :initform nil)))
(defclass iblock-merge (iblock) ())
(defmethod find-variable (reference (search-from ir-program))
(multiple-value-bind (var existsp)
(gethash reference (variables search-from))