(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.
(values))
;;; Replace all uses of OLD with uses of NEW, where NEW has an
-;;; arbitary number of uses.
-(defun substitute-lvar-uses (new old)
+;;; arbitary number of uses. NEW is supposed to be "later" than OLD.
+(defun substitute-lvar-uses (new old propagate-dx)
(declare (type lvar old)
- (type (or lvar null) new))
-
- (cond (new (do-uses (node old)
- (%delete-lvar-use node)
- (add-lvar-use node new))
- (reoptimize-lvar new))
+ (type (or lvar null) new)
+ (type boolean propagate-dx))
+
+ (cond (new
+ (do-uses (node old)
+ (%delete-lvar-use node)
+ (add-lvar-use node new))
+ (reoptimize-lvar new)
+ (awhen (and propagate-dx (lvar-dynamic-extent old))
+ (setf (lvar-dynamic-extent old) nil)
+ (unless (lvar-dynamic-extent new)
+ (setf (lvar-dynamic-extent new) it)
+ (setf (cleanup-info it) (substitute new old (cleanup-info it)))))
+ (when (lvar-dynamic-extent new)
+ (do-uses (node new)
+ (node-ends-block node))))
(t (flush-dest old)))
+
(values))
\f
;;;; block starting/creation
(when (and (basic-combination-p use)
(eq (basic-combination-kind use) :local))
(merges use))))
+ (substitute-lvar-uses lvar value
+ (and lvar (eq (lvar-uses lvar) node)))
(%delete-lvar-use node)
- (substitute-lvar-uses lvar value)
(prog1
(unlink-node node)
(dolist (merge (merges))
(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)))
\f
;;;; miscellaneous shorthand functions
(defun node-dest (node)
(awhen (node-lvar node) (lvar-dest it)))
+#!-sb-fluid (declaim (inline node-stack-allocate-p))
+(defun node-stack-allocate-p (node)
+ (awhen (node-lvar node)
+ (lvar-dynamic-extent it)))
+
(declaim (inline block-to-be-deleted-p))
(defun block-to-be-deleted-p (block)
(or (block-delete-p block)
(defun ctran-home-lambda (ctran)
(ctran-home-lambda-or-null ctran))
+(declaim (inline cast-single-value-p))
+(defun cast-single-value-p (cast)
+ (not (values-type-p (cast-asserted-type cast))))
+
#!-sb-fluid (declaim (inline lvar-single-value-p))
(defun lvar-single-value-p (lvar)
(or (not lvar)
(cast
(locally
(declare (notinline lvar-single-value-p))
- (and (not (values-type-p (cast-asserted-type dest)))
+ (and (cast-single-value-p dest)
(lvar-single-value-p (node-lvar dest)))))
(t
t)))))
type-restrictions
(lambda (lexenv-lambda default))
(cleanup (lexenv-cleanup default))
+ (handled-conditions (lexenv-handled-conditions default))
+ (disabled-package-locks
+ (lexenv-disabled-package-locks default))
(policy (lexenv-policy default)))
(macrolet ((frob (var slot)
`(let ((old (,slot default)))
(frob blocks lexenv-blocks)
(frob tags lexenv-tags)
(frob type-restrictions lexenv-type-restrictions)
- lambda cleanup policy)))
+ lambda cleanup handled-conditions
+ disabled-package-locks policy)))
;;; Makes a LEXENV, suitable for using in a MACROLET introduced
;;; macroexpander
(lexenv-type-restrictions lexenv) ; XXX
nil
nil
+ (lexenv-handled-conditions lexenv)
+ (lexenv-disabled-package-locks lexenv)
(lexenv-policy lexenv))))
\f
;;;; flow/DFO/component hackery
(frob if-alternative)
(when (eq (if-consequent last)
(if-alternative last))
- (setf (component-reoptimize (block-component block)) t)))))
+ (reoptimize-component (block-component block) :maybe)))))
(t
(unless (memq new (block-succ block))
(link-blocks block new)))))
;;; end. The tricky thing is a special cleanup block; all its nodes
;;; have the same cleanup info, corresponding to the start, so the
;;; same approach returns safe result.
-(defun map-block-nlxes (fun block)
+(defun map-block-nlxes (fun block &optional dx-cleanup-fun)
(loop for cleanup = (block-end-cleanup block)
then (node-enclosing-cleanup (cleanup-mess-up cleanup))
while cleanup
((: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))
(let* ((arg-lvar (first (basic-combination-args mess-up)))
(nlx-info (constant-value (ref-leaf (lvar-use arg-lvar)))))
- (funcall fun nlx-info)))))))
+ (funcall fun nlx-info)))
+ ((:dynamic-extent)
+ (when dx-cleanup-fun
+ (funcall dx-cleanup-fun cleanup)))))))
;;; Set the FLAG for all the blocks in COMPONENT to NIL, except for
;;; the head and tail which are set to T.
(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))))))
(do-uses (use lvar)
(let ((prev (node-prev use)))
(let ((block (ctran-block prev)))
- (setf (component-reoptimize (block-component block)) t)
+ (reoptimize-component (block-component block) t)
(setf (block-attributep (block-flags block)
flush-p type-asserted type-check)
t)))
(unless (policy *compiler-error-context* (= inhibit-warnings 3))
;; ANSI section "3.2.5 Exceptional Situations in the Compiler"
;; requires this to be no more than a STYLE-WARNING.
+ #-sb-xc-host
(compiler-style-warn "The variable ~S is defined but never used."
- (leaf-debug-name var)))
+ (leaf-debug-name var))
+ ;; There's no reason to accept this kind of equivocation
+ ;; when compiling our own code, though.
+ #+sb-xc-host
+ (warn "The variable ~S is defined but never used."
+ (leaf-debug-name var)))
(setf (leaf-ever-used var) t)))) ; to avoid repeated warnings? -- WHN
(values))
(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
(defun find-nlx-info (exit)
(declare (type exit exit))
(let* ((entry (exit-entry exit))
- (entry-cleanup (entry-cleanup entry)))
+ (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))))
\f
;;;; functional hackery
;; arbitrarily huge blocks of code. -- WHN)
(let ((*compiler-error-context* node))
(compiler-notify "*INLINE-EXPANSION-LIMIT* (~W) was exceeded, ~
- probably trying to~% ~
- inline a recursive function."
+ probably trying to~% ~
+ inline a recursive function."
*inline-expansion-limit*))
nil)
(t t))))
(do-uses (node lvar)
(setf (node-reoptimize node) t)
(setf (block-reoptimize (node-block node)) t)
- (setf (component-reoptimize (node-component node)) t)))))))
+ (reoptimize-component (node-component node) :maybe)))))))