master: Remove some type declarations
snuglas via Sbcl-commits <[email protected]> Sat, 04 Jul 2026 20:56:58 +0000
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via a89ff67e7782826374d94c374a80b5510534ecca (commit)
from 74f07eb8f486b1628ba821ed1b9ca2f98f63f20f (commit)
- Log -----------------------------------------------------------------
commit a89ff67e7782826374d94c374a80b5510534ecca
Author: Douglas Katzman <[email protected]>
Date: Sat Jul 4 19:43:59 2026 +0000
Remove some type declarations
This generates better code because in FIND-OR-CREATE-CONSTRAINT the declaration
on Y is redundant with type tests in FIND-CONSTRAINT, and in FIND-CONSTRAINT it
is redundant with the ETYPECASE.
---
src/compiler/constraint.lisp | 40 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)
diff --git a/src/compiler/constraint.lisp b/src/compiler/constraint.lisp
index acc180c40..f02144087 100644
--- a/src/compiler/constraint.lisp
+++ b/src/compiler/constraint.lisp
@@ -167,6 +167,22 @@
(defun conset-difference (conset1 conset2)
(sset-difference conset1 conset2) (values)))
+;;; Consets are still some of the worst-performing things in the compiler.
+;;; Profiling a particularly slow-compiling file shows the top 10 functions below:
+;;; Self Total Cumul
+;;; Nr Count % Count % Count % Calls Function
+;;; ------------------------------------------------------------------------
+;;; 1 985 20.7 985 20.7 985 20.7 - SB-C::CONSET-ADJOIN
+;;; 2 939 19.7 939 19.7 1924 40.4 - SB-KERNEL:%ADJOIN-EQ
+;;; 3 621 13.0 621 13.0 2545 53.5 - SB-IMPL::GETHASH/EQ-HASH/COMMON
+;;; 4 476 10.0 1112 23.4 3021 63.5 - SB-C::FIND-CONSTRAINT
+;;; 5 231 4.9 2465 51.8 3252 68.3 - (FLET SB-C::BODY-FUN :IN SB-C::INHERIT-CONSTRAINTS)
+;;; 6 189 4.0 1570 33.0 3441 72.3 - SB-C::JOIN-TYPE-CONSTRAINTS
+;;; 7 177 3.7 403 8.5 3618 76.0 - SB-C::TYPE-FROM-CONSTRAINTS
+;;; 8 173 3.6 1278 26.8 3791 79.6 - SB-C::FIND-OR-CREATE-CONSTRAINT
+;;; 9 66 1.4 210 4.4 3857 81.0 - (FLET SB-C::BODY-FUN :IN SB-C::TYPE-FROM-CONSTRAINTS)
+;;; 10 58 1.2 123 2.6 3915 82.2 - SB-KERNEL::%TYPE-INTERSECTION
+
(locally
;; This is performance critical for the compiler, and benefits
;; from the following declarations. Probably you'll want to
@@ -338,12 +354,30 @@
(defconsetop conset-intersection bit-and)
(defconsetop conset-difference bit-andc2)))
+;;; [the remark about types not being hash-consed is actually obsolete]
;;; Constraints are hash-consed. Unfortunately, types aren't, so we have
;;; to over-approximate and then linear search through the potential hits.
;;; LVARs can only be found in EQL (not-p = NIL) constraints, while constant
;;; and lambda-vars can only be found in EQL constraints.
+;;;
+;;; *Not* checking the type of Y on entry to FIND-CONSTRAINT is a performance improvement.
+;;; On one hand, this is no different from EXPLICIT-CHECK in a defknown of a function that
+;;; dispatches internally, but on the other it would be nicer if the compiler could figure
+;;; out that it's doing a ton of duplicated work in first asserting Y's type and then doing
+;;; an ETYPECASE on it which covers everything (and omits VECTOR-LENGTH-CONSTRAINT).
+;;; So it will correctly fail on bad inputs. But also, the asm code for the check for the
+;;; type CONSTRAINT-Y is particularly lousy for some reason, namely:
+;;; (disassemble '(lambda (y) (the constraint-y y))) => about 25 instructions (100 bytes)
+;;; versus the types individually:
+;;; (disassemble '(lambda (y) (the ctype y))) => hierarchical test, about 5 instructions
+;;; (disassemble '(lambda (y) (the lvar y))) => layout EQ test, about 5 instructions
+;;; (disassemble '(lambda (y) (the (or constant lambda-var) y))) => similarly quick
+;;;
+;;; Unfortunately, given the complete set of types to check for CONSTRAINT-Y, the compiler
+;;; chooses to use an MPH-based lookup which only makes sense in theory - in practice it's
+;;; both redundant and worse. This function's asm code got 15% smaller by omitting the decl.
(defun find-constraint (kind x y not-p)
- (declare (type lambda-var x) (type constraint-y y) (type boolean not-p))
+ (declare (type lambda-var x) #|(type constraint-y y)|# (type boolean not-p))
(etypecase y
(ctype
(awhen (lambda-var-ctype-constraints x)
@@ -417,9 +451,11 @@
;;; guaranteeing that all equivalent constraints are EQ. This
;;; shouldn't be called on LAMBDA-VARs with no CONSTRAINTS set.
(defun find-or-create-constraint (kind x y not-p)
- (declare (type lambda-var x) (type constraint-y y) (type boolean not-p))
+ ;; See FIND-CONSTRAINT about why it's best not to assert the type of Y here
+ (declare (type lambda-var x) #|(type constraint-y y)|# (type boolean not-p))
(or (find-constraint kind x y not-p)
(let ((new (make-constraint (length *constraint-universe*)
+ ;; MAKE-CONSTRAINT will type-check Y
kind x y not-p)))
(vector-push-extend new *constraint-universe*
(1+ (length *constraint-universe*)))
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL