diff options
author | Mattias Engdegård <mattiase@acm.org> | 2021-07-30 13:44:07 +0200 |
---|---|---|
committer | Mattias Engdegård <mattiase@acm.org> | 2021-09-11 17:17:33 +0200 |
commit | 020a408edabcbaa3722af6fc5bb8b5fe6add6af0 (patch) | |
tree | 9175f95b1379875b9dd418b0941e79731fb33d8a /test/lisp/emacs-lisp | |
parent | 376a31b0cdf64f4264904e2a9d49216959a35bd2 (diff) | |
download | emacs-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.el | 44 |
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.") |