X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fir1util.lisp;h=0efb8ae5ded073ef524d345de7f79ce9a05cc66a;hb=731d5dd65a7b94b5d49d1663d9b60c3a406ce38c;hp=5126c043554de1ead5109089d0007dde47ce1740;hpb=ea12c1295d511ba5242f3ce64c44e1e445f72cc8;p=sbcl.git diff --git a/src/compiler/ir1util.lisp b/src/compiler/ir1util.lisp index 5126c04..0efb8ae 100644 --- a/src/compiler/ir1util.lisp +++ b/src/compiler/ir1util.lisp @@ -63,10 +63,13 @@ (list uses)))) (defun principal-lvar-use (lvar) - (let ((use (lvar-uses lvar))) - (if (cast-p use) - (principal-lvar-use (cast-value use)) - use))) + (labels ((plu (lvar) + (declare (type lvar lvar)) + (let ((use (lvar-uses lvar))) + (if (cast-p use) + (plu (cast-value use)) + use)))) + (plu lvar))) ;;; Update lvar use information so that NODE is no longer a use of its ;;; LVAR. @@ -325,6 +328,26 @@ (merge-tail-sets merge))))) (t (flush-dest value) (unlink-node node)))) + +;;; Make a CAST and insert it into IR1 before node NEXT. +(defun insert-cast-before (next lvar type policy) + (declare (type node next) (type lvar lvar) (type ctype type)) + (with-ir1-environment-from-node next + (let* ((ctran (node-prev next)) + (cast (make-cast lvar type policy)) + (internal-ctran (make-ctran))) + (setf (ctran-next ctran) cast + (node-prev cast) ctran) + (use-ctran cast internal-ctran) + (link-node-to-previous-ctran next internal-ctran) + (setf (lvar-dest lvar) cast) + (reoptimize-lvar lvar) + (when (return-p next) + (node-ends-block cast)) + (setf (block-attributep (block-flags (node-block cast)) + type-check type-asserted) + t) + cast))) ;;;; miscellaneous shorthand functions @@ -720,7 +743,7 @@ ((:block :tagbody) (aver (entry-p mess-up)) (loop for exit in (entry-exits mess-up) - for nlx-info = (find-nlx-info exit) + for nlx-info = (exit-nlx-info exit) do (funcall fun nlx-info))) ((:catch :unwind-protect) (aver (combination-p mess-up)) @@ -984,6 +1007,9 @@ (when (optional-dispatch-more-entry leaf) (frob (optional-dispatch-more-entry leaf))) (let ((main (optional-dispatch-main-entry leaf))) + (when entry + (setf (functional-entry-fun entry) main) + (setf (functional-entry-fun main) entry)) (when (eq (functional-kind main) :optional) (frob main)))))) @@ -1330,15 +1356,21 @@ (setf (node-prev node) nil) t))))))) +;;; Return true if CTRAN has been deleted, false if it is still a valid +;;; part of IR1. +(defun ctran-deleted-p (ctran) + (declare (type ctran ctran)) + (let ((block (ctran-block ctran))) + (or (not (block-component block)) + (block-delete-p block)))) + ;;; Return true if NODE has been deleted, false if it is still a valid ;;; part of IR1. (defun node-deleted (node) (declare (type node node)) (let ((prev (node-prev node))) - (not (and prev - (let ((block (ctran-block prev))) - (and (block-component block) - (not (block-delete-p block)))))))) + (or (not prev) + (ctran-deleted-p prev)))) ;;; Delete all the blocks and functions in COMPONENT. We scan first ;;; marking the blocks as DELETE-P to prevent weird stuff from being @@ -1502,10 +1534,17 @@ ;;; exits to CONT in that entry, then return it, otherwise return NIL. (defun find-nlx-info (exit) (declare (type exit exit)) - (let ((entry (exit-entry exit))) + (let* ((entry (exit-entry exit)) + (cleanup (entry-cleanup entry)) + (block (first (block-succ (node-block exit))))) (dolist (nlx (physenv-nlx-info (node-physenv entry)) nil) - (when (eq (nlx-info-exit nlx) exit) + (when (and (eq (nlx-info-block nlx) block) + (eq (nlx-info-cleanup nlx) cleanup)) (return nlx))))) + +(defun nlx-info-lvar (nlx) + (declare (type nlx-info nlx)) + (node-lvar (block-last (nlx-info-target nlx)))) ;;;; functional hackery