1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-09 07:40:39 -08:00

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.
This commit is contained in:
Mattias Engdegård 2021-07-30 13:44:07 +02:00
parent 376a31b0cd
commit 020a408eda
2 changed files with 184 additions and 17 deletions

View file

@ -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.")