master: Don't delete blocks during constraint propagation
stassats via Sbcl-commits <[email protected]> Sat, 25 Jul 2026 15:42:28 +0000
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via 4331687bb8ce33d48c084e990a497e1a1ba79830 (commit)
from e45c5c70b571e9dcb1e784c810bd071407f9e89d (commit)
- Log -----------------------------------------------------------------
commit 4331687bb8ce33d48c084e990a497e1a1ba79830
Author: Stas Boukarev <[email protected]>
Date: Sat Jul 25 18:38:16 2026 +0300
Don't delete blocks during constraint propagation
When deleting SETs.
Fixes lp#2161789
---
src/compiler/constraint.lisp | 30 +++++++++++++++++-------------
src/compiler/ir1util.lisp | 5 +++++
tests/constraint.pure.lisp | 14 ++++++++++++++
3 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/src/compiler/constraint.lisp b/src/compiler/constraint.lisp
index 6c67fe3d9..3526e3fff 100644
--- a/src/compiler/constraint.lisp
+++ b/src/compiler/constraint.lisp
@@ -53,6 +53,7 @@
(declaim (type (and (vector t) (not simple-array)) *constraint-universe*))
(defvar *constraint-universe*)
(defvar *blocks-to-terminate*)
+(defvar *sets-to-delete*)
(defvar *constraint-blocks*)
(defvar *constraint-blocks-p*)
@@ -1335,18 +1336,19 @@
(let ((var (set-var set)))
(when (and (lambda-var-p var)
(lambda-var-eq-constraints var))
- (let* ((value (set-value set))
- (ref (principal-lvar-use value)))
- (when (and (ref-p ref)
- (eq (ref-leaf ref) var))
- (let ((constraint (gethash (node-lvar ref)
- (lambda-var-eq-constraints var))))
- (when (and constraint
- (conset-member constraint in))
- (setf (lambda-var-sets var)
- (delq1 set (lambda-var-sets var)))
- (delete-filter set (node-lvar set) value)
- t)))))))
+ (or (member set *sets-to-delete*)
+ (let* ((value (set-value set))
+ (ref (principal-lvar-use value)))
+ (when (and (ref-p ref)
+ (eq (ref-leaf ref) var))
+ (let ((constraint (gethash (node-lvar ref)
+ (lambda-var-eq-constraints var))))
+ (when (and constraint
+ (conset-member constraint in))
+ ;; Don't delete here because it might lead to block
+ ;; deletion and disturb the computed constraints
+ (push set *sets-to-delete*)
+ t))))))))
;;;; Flow analysis
@@ -1778,6 +1780,7 @@
(setf (if-consequent-constraints last) nil))))
(let (*blocks-to-terminate*
+ *sets-to-delete*
*constraint-blocks-p*)
(dolist (block (find-and-propagate-constraints component))
(unless (block-delete-p block)
@@ -1787,5 +1790,6 @@
(memq :constraints *compile-trace-targets*))
(print-constraints component))
(loop for node in *blocks-to-terminate*
- do (maybe-terminate-block node nil)))
+ do (maybe-terminate-block node nil))
+ (mapc #'delete-set *sets-to-delete*))
(values))
diff --git a/src/compiler/ir1util.lisp b/src/compiler/ir1util.lisp
index 1d161de7f..a2d7d4d55 100644
--- a/src/compiler/ir1util.lisp
+++ b/src/compiler/ir1util.lisp
@@ -4262,3 +4262,8 @@ is :ANY, the function name is not checked."
(loop for d in x
always (or (typep d 'index)
(eq d '*)))))
+(defun delete-set (set)
+ (let ((var (set-var set)))
+ (setf (lambda-var-sets var)
+ (delq1 set (lambda-var-sets var)))
+ (delete-filter set (node-lvar set) (set-value set))))
diff --git a/tests/constraint.pure.lisp b/tests/constraint.pure.lisp
index 1c32942ff..20fb320f1 100644
--- a/tests/constraint.pure.lisp
+++ b/tests/constraint.pure.lisp
@@ -2165,6 +2165,7 @@
(loop
(let ((new (+ v 1)))
(setf v new)))))))
+
(with-test (:name :join-equality-constraints-loop)
(checked-compile
`(lambda (data n d j)
@@ -2190,3 +2191,16 @@
(go g826)))
(do ((index22 0 d)) ((or j index22)))))))
+
+(with-test (:name :delete-redundant-set-delay)
+ (checked-compile-and-assert
+ ()
+ `(lambda (a)
+ (let ((b 0))
+ (let ((c b))
+ (if (eql a 0)
+ (setf b c))
+ a)))
+ ((0) 0)
+ ((1) 1)
+ ((2) 2)))
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL