;;; Delete any nodes in BLOCK whose value is unused and which have no
;;; side effects. We can delete sets of lexical variables when the set
;;; variable has no references.
-(defun flush-dead-code (block)
+(defun flush-dead-code (block &aux victim)
(declare (type cblock block))
(setf (block-flush-p block) nil)
(do-nodes-backwards (node lvar block :restart-p t)
(unless lvar
(typecase node
(ref
+ (setf victim node)
(delete-ref node)
(unlink-node node))
(combination
(when (flushable-combination-p node)
+ (setf victim node)
(flush-combination node)))
(mv-combination
(when (eq (basic-combination-kind node) :local)
(when (or (leaf-refs var)
(lambda-var-sets var))
(return nil)))
+ (setf victim node)
(flush-dest (first (basic-combination-args node)))
(delete-let fun)))))
(exit
(let ((value (exit-value node)))
(when value
+ (setf victim node)
(flush-dest value)
(setf (exit-value node) nil))))
(cset
(let ((var (set-var node)))
(when (and (lambda-var-p var)
(null (leaf-refs var)))
+ (setf victim node)
(flush-dest (set-value node))
(setf (basic-var-sets var)
(delq node (basic-var-sets var)))
(unlink-node node))))
(cast
(unless (cast-type-check node)
+ (setf victim node)
(flush-dest (cast-value node))
(unlink-node node))))))
- (values))
+ victim)
\f
;;;; local call return type propagation
(return))
(incf loop-count)))
+ (when *check-consistency*
+ (do-blocks-backwards (block component)
+ (awhen (flush-dead-code block)
+ (let ((*compiler-error-context* it))
+ (compiler-warn "dead code detected at the end of ~S"
+ 'ir1-phases)))))
+
(ir1-finalize component)
(values))