summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStas Boukarev <stassats@gmail.com>2024-09-23 00:07:47 +0300
committerStas Boukarev <stassats@gmail.com>2024-09-29 23:11:51 +0300
commit0dc73d653d13c7f511905b669ba551973aed4664 (patch)
tree76d790c61567d74060cd8034150131c832fa4ba8
parentb44db82a75ed33f684cc8afd9417dcf98abf39d5 (diff)
Inline simple FIND on lists.
It's more compact than calling a function.
-rw-r--r--src/compiler/seqtran.lisp41
-rw-r--r--tests/seq.pure.lisp5
2 files changed, 29 insertions, 17 deletions
diff --git a/src/compiler/seqtran.lisp b/src/compiler/seqtran.lisp
index 49466f7ad..fc192c0f7 100644
--- a/src/compiler/seqtran.lisp
+++ b/src/compiler/seqtran.lisp
@@ -2703,20 +2703,35 @@
(deftransform %find-position ((item sequence from-end start end key test)
(t list t t t t t)
*
- :policy (> speed space))
+ :node node)
"expand inline"
- '(%find-position-if (let ((test-fun (%coerce-callable-to-fun test)))
- ;; The order of arguments for asymmetric tests
- ;; (e.g. #'<, as opposed to order-independent
- ;; tests like #'=) is specified in the spec
- ;; section 17.2.1 -- the O/Zi stuff there.
- (lambda (i)
- (funcall test-fun item i)))
- sequence
- from-end
- start
- end
- (%coerce-callable-to-fun key)))
+ (if (or (policy node (> speed space))
+ ;; Is it small anyway?
+ (and (or (not key)
+ (lvar-fun-is key '(identity)))
+ (and (constant-lvar-p start)
+ (eql (lvar-value start) 0))
+ (and (constant-lvar-p end)
+ (null (lvar-value end)))
+ (and (constant-lvar-p from-end)
+ (null (lvar-value from-end)))
+ (policy node (< safety 2))
+ (lvar-fun-is test '(eq))))
+ `(locally (declare (optimize (space 0)
+ (speed ,(max 1 (policy node speed)))))
+ (%find-position-if (let ((test-fun (%coerce-callable-to-fun test)))
+ ;; The order of arguments for asymmetric tests
+ ;; (e.g. #'<, as opposed to order-independent
+ ;; tests like #'=) is specified in the spec
+ ;; section 17.2.1 -- the O/Zi stuff there.
+ (lambda (i)
+ (funcall test-fun item i)))
+ sequence
+ from-end
+ start
+ end
+ (%coerce-callable-to-fun key)))
+ (give-up-ir1-transform)))
;;; The inline expansions for the VECTOR case are saved as macros so
;;; that we can share them between the DEFTRANSFORMs and the default
diff --git a/tests/seq.pure.lisp b/tests/seq.pure.lisp
index 6b9769dca..8d7407049 100644
--- a/tests/seq.pure.lisp
+++ b/tests/seq.pure.lisp
@@ -238,10 +238,7 @@
(0 (= speed 0))
(t t)))
(extra-safe (&key speed safety &allow-other-keys)
- (case safety
- (0 (= speed 0))
- (1 (< speed 2))
- (t t)))
+ (>= safety 2))
(test (type expr &key (filter #'safe))
(checked-compile-and-assert
(:optimize `(:compilation-speed nil :space nil :filter ,filter)