1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-05 19:31:02 -08:00

Teach byte-compiler about Aristotelian identity

* lisp/emacs-lisp/byte-opt.el (byte-optimize-equal, byte-optimize-eq):
Optimise (eq X X) -> t where X is a variable; idem for eql and equal.
* test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases):
Add test case.
This commit is contained in:
Mattias Engdegård 2023-08-07 18:14:42 +02:00
parent eeda9eff1a
commit 89bd651976
2 changed files with 21 additions and 15 deletions

View file

@ -1052,23 +1052,26 @@ See Info node `(elisp) Integer Basics'."
(and (integerp o) (<= -536870912 o 536870911))) (and (integerp o) (<= -536870912 o 536870911)))
(defun byte-optimize-equal (form) (defun byte-optimize-equal (form)
;; Replace `equal' or `eql' with `eq' if at least one arg is a (cond ((/= (length (cdr form)) 2) form) ; Arity errors reported elsewhere.
;; symbol or fixnum. ;; Anything is identical to itself.
(byte-optimize-binary-predicate ((and (eq (nth 1 form) (nth 2 form)) (symbolp (nth 1 form))) t)
(if (= (length (cdr form)) 2) ;; Replace `equal' or `eql' with `eq' if at least one arg is a
(if (or (byte-optimize--constant-symbol-p (nth 1 form)) ;; symbol or fixnum.
(byte-optimize--constant-symbol-p (nth 2 form)) ((or (byte-optimize--constant-symbol-p (nth 1 form))
(byte-optimize--fixnump (nth 1 form)) (byte-optimize--constant-symbol-p (nth 2 form))
(byte-optimize--fixnump (nth 2 form))) (byte-optimize--fixnump (nth 1 form))
(cons 'eq (cdr form)) (byte-optimize--fixnump (nth 2 form)))
form) (byte-optimize-binary-predicate (cons 'eq (cdr form))))
;; Arity errors reported elsewhere. (t (byte-optimize-binary-predicate form))))
form)))
(defun byte-optimize-eq (form) (defun byte-optimize-eq (form)
(pcase (cdr form) (cond ((/= (length (cdr form)) 2) form) ; arity error
((or `(,x nil) `(nil ,x)) `(not ,x)) ;; Anything is identical to itself.
(_ (byte-optimize-binary-predicate form)))) ((and (eq (nth 1 form) (nth 2 form)) (symbolp (nth 1 form))) t)
;; Strength-reduce comparison with `nil'.
((null (nth 1 form)) `(not ,(nth 2 form)))
((null (nth 2 form)) `(not ,(nth 1 form)))
(t (byte-optimize-binary-predicate form))))
(defun byte-optimize-member (form) (defun byte-optimize-member (form)
(cond (cond

View file

@ -785,6 +785,9 @@ inner loops respectively."
(let ((x 0)) (let ((x 0))
(list (= (setq x 1)) (list (= (setq x 1))
x)) x))
;; Aristotelian identity optimisation
(let ((x (bytecomp-test-identity 1)))
(list (eq x x) (eql x x) (equal x x)))
) )
"List of expressions for cross-testing interpreted and compiled code.") "List of expressions for cross-testing interpreted and compiled code.")