diff options
author | Vibhav Pant <vibhavp@gmail.com> | 2017-02-24 20:50:51 +0530 |
---|---|---|
committer | Vibhav Pant <vibhavp@gmail.com> | 2017-02-24 20:50:51 +0530 |
commit | ca611bda9cd462aa6d92cdaad1db9783afb27e8e (patch) | |
tree | 8cb39b139a6dca4ac349a3cd16e3026c19d4abfd /lisp/emacs-lisp/bytecomp.el | |
parent | 91932fff1ded8ed3b4d39dd06891f26960153b9e (diff) | |
download | emacs-feature/byte-tail-recursion.tar.gz |
Optimize tail recursive calls while byte compiling.feature/byte-tail-recursion
* lisp/emacs-lisp/byte-opt.el (byte-optimize-stack-adjustment)
(byte-optimize-conv-return-goto), (byte-optimize-copy-ops),
(byte-optimize-called-function), (byte-optimize-lapcode-tail-recursion):
New functions.
* lisp/emacs-lisp/bytecomp.el: Add variables b-c-current-{defun,
arglist}.
(byte-compile-file-form-defmumble), (byte-compile): Set them.
(byte-compile-out-toplevel): Use byte-optimize-lapcode-tail-recursion.
Diffstat (limited to 'lisp/emacs-lisp/bytecomp.el')
-rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 29 |
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. |