summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/byte-opt.el
diff options
context:
space:
mode:
authorMattias EngdegÄrd <mattiase@acm.org>2023-02-08 13:45:57 +0100
committerMattias EngdegÄrd <mattiase@acm.org>2023-02-08 13:45:57 +0100
commit680bc20553ebf01375ab7957b6f0be066335fd6e (patch)
treee51b40f968a9f6bcd259bda40573cea0d5cc2c91 /lisp/emacs-lisp/byte-opt.el
parentf3fce3a71c7571be19a451403b46fa667bfa3c16 (diff)
downloademacs-680bc20553ebf01375ab7957b6f0be066335fd6e.tar.gz
Flatten nested `concat` calls
* lisp/emacs-lisp/byte-opt.el (byte-optimize-concat): Flatten nested forms; concat is associative. This reduces the number of calls and may coalesce adjacent constant strings.
Diffstat (limited to 'lisp/emacs-lisp/byte-opt.el')
-rw-r--r--lisp/emacs-lisp/byte-opt.el34
1 files changed, 22 insertions, 12 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index b7e21db688f..3eef8f385b5 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -1132,21 +1132,31 @@ See Info node `(elisp) Integer Basics'."
form))
(defun byte-optimize-concat (form)
- "Merge adjacent constant arguments to `concat'."
+ "Merge adjacent constant arguments to `concat' and flatten nested forms."
(let ((args (cdr form))
(newargs nil))
(while args
- (let ((strings nil)
- val)
- (while (and args (macroexp-const-p (car args))
- (progn
- (setq val (byteopt--eval-const (car args)))
- (and (or (stringp val)
- (and (or (listp val) (vectorp val))
- (not (memq nil
- (mapcar #'characterp val))))))))
- (push val strings)
- (setq args (cdr args)))
+ (let ((strings nil))
+ (while
+ (and args
+ (let ((arg (car args)))
+ (pcase arg
+ ;; Merge consecutive constant arguments.
+ ((pred macroexp-const-p)
+ (let ((val (byteopt--eval-const arg)))
+ (and (or (stringp val)
+ (and (or (listp val) (vectorp val))
+ (not (memq nil
+ (mapcar #'characterp val)))))
+ (progn
+ (push val strings)
+ (setq args (cdr args))
+ t))))
+ ;; Flatten nested `concat' form.
+ (`(concat . ,nested-args)
+ (setq args (append nested-args (cdr args)))
+ t)))))
+
(when strings
(let ((s (apply #'concat (nreverse strings))))
(when (not (zerop (length s)))