summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/comp.el
diff options
context:
space:
mode:
authorAndrea Corallo <akrl@sdf.org>2020-02-16 12:19:10 +0100
committerAndrea Corallo <akrl@sdf.org>2020-02-16 18:11:43 +0100
commit8c108ce607693f9fb5bfa6ca30da66faad777512 (patch)
tree5f6d9dfa2f3e38e9b218462b92d467dd03c28e73 /lisp/emacs-lisp/comp.el
parent5bd485340fea0788035241860aad0804ebeeb388 (diff)
downloademacs-8c108ce607693f9fb5bfa6ca30da66faad777512.tar.gz
emacs-8c108ce607693f9fb5bfa6ca30da66faad777512.tar.bz2
emacs-8c108ce607693f9fb5bfa6ca30da66faad777512.zip
Add a simple pass for self TCO
Diffstat (limited to 'lisp/emacs-lisp/comp.el')
-rw-r--r--lisp/emacs-lisp/comp.el43
1 files changed, 43 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 7ba319204d1..67fc8f39f8c 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -106,6 +106,7 @@ Can be used by code that wants to expand differently in this case.")
comp-call-optim
comp-propagate-2
comp-dead-code
+ comp-tco
comp-final)
"Passes to be executed in order.")
@@ -1889,6 +1890,48 @@ These are substituted with a normal 'set' op."
(comp-ctxt-funcs-h comp-ctxt))))
+;;; Tail Call Optimization pass specific code.
+
+(defun comp-form-tco-call-seq (args)
+ "Generate a tco sequence for ARGS."
+ `(,@(cl-loop for arg in args
+ for i from 0
+ collect `(set ,(make-comp-mvar :slot i) ,arg))
+ (jump bb_0)))
+
+(defun comp-tco-func ()
+ "Try to pattern match and perform TCO within the current function."
+ (cl-loop
+ for b being each hash-value of (comp-func-blocks comp-func)
+ do (cl-loop
+ named in-the-basic-block
+ for insns-seq on (comp-block-insns b)
+ do (pcase insns-seq
+ (`((set ,l-val (direct-call ,func . ,args))
+ (comment ,_comment)
+ (return ,ret-val))
+ (when (and (eq func (comp-func-name comp-func))
+ (eq l-val ret-val))
+ (let ((tco-seq (comp-form-tco-call-seq args)))
+ (setf (car insns-seq) (car tco-seq)
+ (cdr insns-seq) (cdr tco-seq))
+ (cl-return-from in-the-basic-block))))))))
+
+(defun comp-tco (_)
+ "Simple peephole pass performing self TCO."
+ (when (>= comp-speed 3)
+ (maphash (lambda (_ f)
+ (let ((comp-func f))
+ (unless (comp-func-has-non-local comp-func)
+ (comp-tco-func)
+ (comp-log-func comp-func 3))))
+ (comp-ctxt-funcs-h comp-ctxt))))
+
+;; NOTE: After TCO runs edges, phis etc are not updated. In case some
+;; other pass that make use of them after here is added `comp-ssa'
+;; should be re-run.
+
+
;;; Final pass specific code.
(defun comp-compile-ctxt-to-file (name)