aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorMattias EngdegÄrd2019-05-22 12:36:03 +0200
committerMattias EngdegÄrd2019-06-19 11:20:59 +0200
commit14a81524c27ab54850e0fda736e4ee0c92e447b5 (patch)
tree07dae25c695381ab4dc7c5fe70543276b90ace82 /lisp
parentb8c74742c0238fe15b1cdc9a7f6ee021d038368f (diff)
downloademacs-14a81524c27ab54850e0fda736e4ee0c92e447b5.tar.gz
emacs-14a81524c27ab54850e0fda736e4ee0c92e447b5.zip
Compile cond with heterogeneous tests into switch (bug#36139)
Allow any mixture of `eq', `eql' and `equal', `memq', `memql' and `member' in a switch-like `cond' to be compiled into a single switch. * lisp/emacs-lisp/bytecomp.el (byte-compile--common-test): New. (byte-compile-cond-jump-table-info): Use most specific common test. * test/lisp/emacs-lisp/bytecomp-tests.el (byte-opt-testsuite-arith-data): Add test cases for multi-value clause cond forms.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/emacs-lisp/bytecomp.el29
1 files changed, 17 insertions, 12 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index ab04c1bf439..3a23543f6a7 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -4132,6 +4132,12 @@ that suppresses all warnings during execution of BODY."
4132 4132
4133(defconst byte-compile--default-val (cons nil nil) "A unique object.") 4133(defconst byte-compile--default-val (cons nil nil) "A unique object.")
4134 4134
4135(defun byte-compile--common-test (test-1 test-2)
4136 "Most specific common test of `eq', `eql' and `equal'"
4137 (cond ((or (eq test-1 'equal) (eq test-2 'equal)) 'equal)
4138 ((or (eq test-1 'eql) (eq test-2 'eql)) 'eql)
4139 (t 'eq)))
4140
4135(defun byte-compile-cond-jump-table-info (clauses) 4141(defun byte-compile-cond-jump-table-info (clauses)
4136 "If CLAUSES is a `cond' form where: 4142 "If CLAUSES is a `cond' form where:
4137The condition for each clause is of the form (TEST VAR VALUE). 4143The condition for each clause is of the form (TEST VAR VALUE).
@@ -4143,7 +4149,8 @@ Return a list of the form ((TEST . VAR) ((VALUES BODY) ...))"
4143 (let ((cases '()) 4149 (let ((cases '())
4144 (ok t) 4150 (ok t)
4145 (all-keys nil) 4151 (all-keys nil)
4146 prev-var prev-test) 4152 (prev-test 'eq)
4153 prev-var)
4147 (and (catch 'break 4154 (and (catch 'break
4148 (dolist (clause (cdr clauses) ok) 4155 (dolist (clause (cdr clauses) ok)
4149 (let* ((condition (car clause)) 4156 (let* ((condition (car clause))
@@ -4152,15 +4159,13 @@ Return a list of the form ((TEST . VAR) ((VALUES BODY) ...))"
4152 (byte-compile-cond-vars (cadr condition) (cl-caddr condition)))) 4159 (byte-compile-cond-vars (cadr condition) (cl-caddr condition))))
4153 (obj1 (car-safe vars)) 4160 (obj1 (car-safe vars))
4154 (obj2 (cdr-safe vars)) 4161 (obj2 (cdr-safe vars))
4155 (body (cdr-safe clause)) 4162 (body (cdr-safe clause)))
4156 equality)
4157 (unless prev-var 4163 (unless prev-var
4158 (setq prev-var obj1)) 4164 (setq prev-var obj1))
4159 (cond 4165 (cond
4160 ((and obj1 (memq test '(eq eql equal)) 4166 ((and obj1 (memq test '(eq eql equal))
4161 (eq obj1 prev-var) 4167 (eq obj1 prev-var))
4162 (or (not prev-test) (eq test prev-test))) 4168 (setq prev-test (byte-compile--common-test prev-test test))
4163 (setq prev-test test)
4164 ;; Discard values already tested for. 4169 ;; Discard values already tested for.
4165 (unless (member obj2 all-keys) 4170 (unless (member obj2 all-keys)
4166 (push obj2 all-keys) 4171 (push obj2 all-keys)
@@ -4171,12 +4176,12 @@ Return a list of the form ((TEST . VAR) ((VALUES BODY) ...))"
4171 (listp obj2) 4176 (listp obj2)
4172 ;; Require a non-empty body, since the member function 4177 ;; Require a non-empty body, since the member function
4173 ;; value depends on the switch argument. 4178 ;; value depends on the switch argument.
4174 body 4179 body)
4175 (setq equality (cdr (assq test '((memq . eq) 4180 (setq prev-test
4176 (memql . eql) 4181 (byte-compile--common-test
4177 (member . equal))))) 4182 prev-test (cdr (assq test '((memq . eq)
4178 (or (not prev-test) (eq equality prev-test))) 4183 (memql . eql)
4179 (setq prev-test equality) 4184 (member . equal))))))
4180 (let ((vals nil)) 4185 (let ((vals nil))
4181 ;; Discard values already tested for. 4186 ;; Discard values already tested for.
4182 (dolist (elem obj2) 4187 (dolist (elem obj2)