summaryrefslogtreecommitdiff
path: root/test/lisp/emacs-lisp
diff options
context:
space:
mode:
authorMattias Engdegård <mattiase@acm.org>2021-07-30 13:44:07 +0200
committerMattias Engdegård <mattiase@acm.org>2021-09-11 17:17:33 +0200
commit020a408edabcbaa3722af6fc5bb8b5fe6add6af0 (patch)
tree9175f95b1379875b9dd418b0941e79731fb33d8a /test/lisp/emacs-lisp
parent376a31b0cdf64f4264904e2a9d49216959a35bd2 (diff)
downloademacs-020a408edabcbaa3722af6fc5bb8b5fe6add6af0.tar.gz
emacs-020a408edabcbaa3722af6fc5bb8b5fe6add6af0.tar.bz2
emacs-020a408edabcbaa3722af6fc5bb8b5fe6add6af0.zip
Propagate aliased lexical variables in byte compiler
Replace uses of a variable aliasing another variable with that aliased variable, to allow for variable removal when possible. This also enables opportunities for other optimisations. Example: (let ((y x)) (f y)) => (f x) The optimisation is only performed if both aliased and aliasing variables are lexically bound. Shadowing bindings are α-renamed when necessary for correctness. Example: (let* ((b a) (a EXPR)) (f a b)) => (let* ((a{new} EXPR)) (f a{new} a)) * lisp/emacs-lisp/byte-opt.el (byte-optimize--aliased-vars): New. (byte-optimize-form-code-walker): Cancel aliasing upon mutation. (byte-optimize--rename-var-body, byte-optimize--rename-var): New. (byte-optimize-let-form): Add the optimisation. * test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--test-cases): Add relevant test cases.
Diffstat (limited to 'test/lisp/emacs-lisp')
-rw-r--r--test/lisp/emacs-lisp/bytecomp-tests.el44
1 files changed, 44 insertions, 0 deletions
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index ac96494cab1..2832dd02469 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -551,6 +551,50 @@
(let ((n 0))
(list (mapcar (lambda (x) (assoc (setq n (1+ n)) nil)) '(a "nil"))
n))
+
+ ;; Exercise variable-aliasing optimisations.
+ (let ((a (list 1)))
+ (let ((b a))
+ (let ((a (list 2)))
+ (list a b))))
+
+ (let ((a (list 1)))
+ (let ((a (list 2))
+ (b a))
+ (list a b)))
+
+ (let* ((a (list 1))
+ (b a)
+ (a (list 2)))
+ (condition-case a
+ (list a b)
+ (error (list 'error a b))))
+
+ (let* ((a (list 1))
+ (b a)
+ (a (list 2)))
+ (condition-case a
+ (/ 0)
+ (error (list 'error a b))))
+
+ (let* ((a (list 1))
+ (b a)
+ (a (list 2))
+ (f (list (lambda (x) (list x a)))))
+ (funcall (car f) 3))
+
+ (let* ((a (list 1))
+ (b a)
+ (f (list (lambda (x) (setq a x)))))
+ (funcall (car f) 3)
+ (list a b))
+
+ (let* ((a (list 1))
+ (b a)
+ (a (list 2))
+ (f (list (lambda (x) (setq a x)))))
+ (funcall (car f) 3)
+ (list a b))
)
"List of expressions for cross-testing interpreted and compiled code.")