1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-28 08:11:05 -08:00

Constant-propagate variables bound outside loops

Previously, variables bound outside `while` loops were not substituted
inside even in the absense of mutation.  Add the necessary mutation
checking inside loops to allow propagation of values and aliased
variables.

* lisp/emacs-lisp/byte-opt.el
(byte-optimize--inhibit-outside-loop-constprop): New variable.
(byte-optimize-form-code-walker): First traverse each loop without
substitution to discover mutation, then without restrictions.
* test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-test-loop): New.
(bytecomp-tests--test-cases): Add test cases.
This commit is contained in:
Mattias Engdegård 2021-09-22 11:03:30 +02:00
parent 32de11d8de
commit 8d0ee5e7a9
2 changed files with 71 additions and 18 deletions

View file

@ -41,6 +41,24 @@
"Identity, but hidden from some optimisations."
x)
(defmacro bytecomp-test-loop (outer1 outer2 inner1 inner2)
"Exercise constant propagation inside `while' loops.
OUTER1, OUTER2, INNER1 and INNER2 are forms placed in the outer and
inner loops respectively."
`(let ((x 1) (i 3) (res nil))
(while (> i 0)
(let ((y 2) (j 2))
(setq res (cons (list 'outer x y) res))
(while (> j 0)
(setq res (cons (list 'inner x y) res))
,inner1
,inner2
(setq j (1- j)))
,outer1
,outer2)
(setq i (1- i)))
res))
(defconst bytecomp-tests--test-cases
'(
;; some functional tests
@ -454,6 +472,25 @@
(setq x 10))))
4)
;; Loop constprop: set the inner and outer variables in the inner
;; and outer loops, all combinations.
(bytecomp-test-loop nil nil nil nil )
(bytecomp-test-loop nil nil nil (setq x 6))
(bytecomp-test-loop nil nil (setq x 5) nil )
(bytecomp-test-loop nil nil (setq x 5) (setq x 6))
(bytecomp-test-loop nil (setq x 4) nil nil )
(bytecomp-test-loop nil (setq x 4) nil (setq x 6))
(bytecomp-test-loop nil (setq x 4) (setq x 5) nil )
(bytecomp-test-loop nil (setq x 4) (setq x 5) (setq x 6))
(bytecomp-test-loop (setq x 3) nil nil nil )
(bytecomp-test-loop (setq x 3) nil nil (setq x 6))
(bytecomp-test-loop (setq x 3) nil (setq x 5) nil )
(bytecomp-test-loop (setq x 3) nil (setq x 5) (setq x 6))
(bytecomp-test-loop (setq x 3) (setq x 4) nil nil )
(bytecomp-test-loop (setq x 3) (setq x 4) nil (setq x 6))
(bytecomp-test-loop (setq x 3) (setq x 4) (setq x 5) nil )
(bytecomp-test-loop (setq x 3) (setq x 4) (setq x 5) (setq x 6))
;; No error, no success handler.
(condition-case x
(list 42)