summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
authorMattias EngdegÄrd <mattiase@acm.org>2022-06-26 18:46:13 +0200
committerMattias EngdegÄrd <mattiase@acm.org>2022-06-26 20:43:28 +0200
commitf2a5d48e89bc5611c9cc9aeb978faacee32de6c8 (patch)
tree32d6d31fd8570bfaf2c491f0c47db88ae4f1077d /lisp/emacs-lisp
parentd3893d7e8e20b392e531f00981191138e26d8bff (diff)
downloademacs-f2a5d48e89bc5611c9cc9aeb978faacee32de6c8.tar.gz
emacs-f2a5d48e89bc5611c9cc9aeb978faacee32de6c8.tar.bz2
emacs-f2a5d48e89bc5611c9cc9aeb978faacee32de6c8.zip
Optimise away functions in for-effect context
* lisp/emacs-lisp/byte-opt.el (byte-optimize-form-code-walker): Turn functions into nil when compiled for-effect since they have no side-effects on their own. This may enable further improvements such as the elimination of variable bindings. `unwind-protect` forms can be treated as plain function call at this point. In particular, their unwind function argument should be not optimised for effect since it's a function.
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/byte-opt.el34
1 files changed, 17 insertions, 17 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 1a50c5a43af..a8741c53bbf 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -406,7 +406,7 @@ for speeding up processing.")
(`(function . ,_)
;; This forms is compiled as constant or by breaking out
;; all the subexpressions and compiling them separately.
- form)
+ (and (not for-effect) form))
(`(condition-case ,var ,exp . ,clauses)
`(,fn ,var ;Not evaluated.
@@ -422,15 +422,13 @@ for speeding up processing.")
(byte-optimize-body (cdr clause) for-effect))))
clauses)))
- (`(unwind-protect ,exp :fun-body ,f)
- ;; The unwinding part of an unwind-protect is compiled (and thus
- ;; optimized) as a top-level form, but run the optimizer for it here
- ;; anyway for lexical variable usage and substitution. But the
- ;; protected part has the same for-effect status as the
- ;; unwind-protect itself. (The unwinding part is always for effect,
- ;; but that isn't handled properly yet.)
- (let ((bodyform (byte-optimize-form exp for-effect)))
- `(,fn ,bodyform :fun-body ,(byte-optimize-form f nil))))
+ ;; `unwind-protect' is a special form which here takes the shape
+ ;; (unwind-protect EXPR :fun-body UNWIND-FUN).
+ ;; We can treat it as if it were a plain function at this point,
+ ;; although there are specific optimisations possible.
+ ;; In particular, the return value of UNWIND-FUN is never used
+ ;; so its body should really be compiled for-effect, but we
+ ;; don't do that right now.
(`(catch ,tag . ,exps)
`(,fn ,(byte-optimize-form tag nil)
@@ -438,13 +436,15 @@ for speeding up processing.")
;; Needed as long as we run byte-optimize-form after cconv.
(`(internal-make-closure . ,_)
- ;; Look up free vars and mark them to be kept, so that they
- ;; won't be optimised away.
- (dolist (var (caddr form))
- (let ((lexvar (assq var byte-optimize--lexvars)))
- (when lexvar
- (setcar (cdr lexvar) t))))
- form)
+ (and (not for-effect)
+ (progn
+ ;; Look up free vars and mark them to be kept, so that they
+ ;; won't be optimised away.
+ (dolist (var (caddr form))
+ (let ((lexvar (assq var byte-optimize--lexvars)))
+ (when lexvar
+ (setcar (cdr lexvar) t))))
+ form)))
(`((lambda . ,_) . ,_)
(let ((newform (macroexp--unfold-lambda form)))