summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/bytecomp.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/bytecomp.el')
-rw-r--r--lisp/emacs-lisp/bytecomp.el29
1 files changed, 21 insertions, 8 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 25513bd0248..efe86404fcf 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -197,6 +197,7 @@ adds `c' to it; otherwise adds `.elc'."
;; that doesn't define this function, so this seems to be a reasonable
;; thing to do.
(autoload 'byte-decompile-bytecode "byte-opt")
+(autoload 'byte-optimize-lapcode-tail-recursion "byte-opt")
(defcustom byte-compile-verbose
(and (not noninteractive) (> baud-rate search-slow-speed))
@@ -1000,6 +1001,8 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'."
(defvar byte-compile-current-file nil)
(defvar byte-compile-current-group nil)
(defvar byte-compile-current-buffer nil)
+(defvar byte-compile-current-defun nil)
+(defvar byte-compile-current-arglist nil)
;; Log something that isn't a warning.
(defmacro byte-compile-log (format-string &rest args)
@@ -2538,7 +2541,9 @@ not to take responsibility for the actual compilation of the code."
;; Tell the caller that we didn't compile it yet.
nil)
- (let* ((code (byte-compile-lambda (cons arglist body) t)))
+ (let* ((byte-compile-current-defun name)
+ (byte-compile-current-arglist arglist)
+ (code (byte-compile-lambda (cons arglist body) t)))
(if this-one
;; A definition in b-c-initial-m-e should always take precedence
;; during compilation, so don't let it be redefined. (Bug#8647)
@@ -2668,11 +2673,13 @@ If FORM is a lambda or a macro, byte-compile it as a function."
(setq fun (byte-compile--reify-function fun)))
;; Expand macros.
(setq fun (byte-compile-preprocess fun))
- (setq fun (byte-compile-top-level fun nil 'eval))
- (if macro (push 'macro fun))
- (if (symbolp form)
- (fset form fun)
- fun)))))))
+ (let ((byte-compile-current-defun (and (symbolp form) form))
+ (byte-compile-current-arglist (nth 1 (cadr fun))))
+ (setq fun (byte-compile-top-level fun nil 'eval))
+ (if macro (push 'macro fun))
+ (if (symbolp form)
+ (fset form fun)
+ fun))))))))
(defun byte-compile-sexp (sexp)
"Compile and return SEXP."
@@ -2923,9 +2930,15 @@ for symbols generated by the byte compiler itself."
(caar tmp))))))
(byte-compile-out 'byte-return 0)
(setq byte-compile-output (nreverse byte-compile-output))
- (if (memq byte-optimize '(t byte))
+ (when (memq byte-optimize '(t byte))
+ (setq byte-compile-output
+ (byte-optimize-lapcode byte-compile-output))
+ ;; Do tail recursion optimization after `byte-optimize-lapcode',
+ ;; since the lapcode now contains more than a single `byte-return',
+ ;; allowing us to optimize multiple tail recursive calls
+ (when byte-compile-current-defun
(setq byte-compile-output
- (byte-optimize-lapcode byte-compile-output)))
+ (byte-optimize-lapcode-tail-recursion byte-compile-output))))
;; Decompile trivial functions:
;; only constants and variables, or a single funcall except in lambdas.