aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Corallo2020-10-27 19:40:55 +0000
committerAndrea Corallo2020-11-01 15:17:00 +0100
commit42970cceb9b15212f1a2a28a4595efc8c960f929 (patch)
treed56d387d21dc96e1a65e173c1f667161832ceca9
parent047fe3292d2f102c9aed4dc305de165b627bcddd (diff)
downloademacs-42970cceb9b15212f1a2a28a4595efc8c960f929.tar.gz
emacs-42970cceb9b15212f1a2a28a4595efc8c960f929.zip
Add new cond-rw pass to have forward propagation track cond branches
Add a new pass to rewrite conditional branches. This is introducing and placing a new LIMPLE operator 'assume' in use by fwprop to propagate conditional branch test informations on target basic blocks. * lisp/emacs-lisp/comp.el (comp-passes): Add `comp-cond-rw'. (comp-limple-assignments): Add `assume' operator. (comp-emit-assume, comp-cond-rw-target-slot, comp-cond-rw-func) (comp-cond-rw): Add new functions. (comp-fwprop-insn): Update to pattern match `assume' insns. * src/comp.c (emit_limple_insn): Add for `assume'. (syms_of_comp): Define 'Qassume' symbol.
-rw-r--r--lisp/emacs-lisp/comp.el83
-rw-r--r--src/comp.c5
2 files changed, 85 insertions, 3 deletions
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 15b8b3ab8da..9b26f6c4198 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -171,6 +171,7 @@ Can be one of: 'd-default', 'd-impure' or 'd-ephemeral'. See `comp-ctxt'.")
171 comp-fwprop 171 comp-fwprop
172 comp-call-optim 172 comp-call-optim
173 comp-ipa-pure 173 comp-ipa-pure
174 comp-cond-rw
174 comp-fwprop 175 comp-fwprop
175 comp-dead-code 176 comp-dead-code
176 comp-tco 177 comp-tco
@@ -216,7 +217,8 @@ Useful to hook into pass checkers.")
216 set-rest-args-to-local) 217 set-rest-args-to-local)
217 "Limple set operators.") 218 "Limple set operators.")
218 219
219(defconst comp-limple-assignments `(fetch-handler 220(defconst comp-limple-assignments `(assume
221 fetch-handler
220 ,@comp-limple-sets) 222 ,@comp-limple-sets)
221 "Limple operators that clobbers the first m-var argument.") 223 "Limple operators that clobbers the first m-var argument.")
222 224
@@ -1677,6 +1679,73 @@ into the C code forwarding the compilation unit."
1677 (comp-add-func-to-ctxt (comp-limplify-top-level t)))) 1679 (comp-add-func-to-ctxt (comp-limplify-top-level t))))
1678 1680
1679 1681
1682;;; conditional branches rewrite pass specific code.
1683
1684(defun comp-emit-assume (target-slot rhs bb-name kind)
1685 "Emit an assume of kind KIND for TARGET-SLOT being RHS.
1686The assume is emitted at the beginning of the block named
1687BB-NAME."
1688 (push `(assume ,(make-comp-mvar :slot target-slot) ,rhs ,kind)
1689 (comp-block-insns (gethash bb-name (comp-func-blocks comp-func))))
1690 (setf (comp-func-ssa-status comp-func) 'dirty))
1691
1692(defun comp-cond-rw-target-slot (slot-num exit-insn bb)
1693 "Search for the last assignment of SLOT-NUM in BB.
1694Keep on searching till EXIT-INSN is encountered.
1695Return the corresponding rhs slot number."
1696 (cl-flet ((targetp (x)
1697 ;; Ret t if x is an mvar and target the correct slot number.
1698 (and (comp-mvar-p x)
1699 (eql slot-num (comp-mvar-slot x)))))
1700 (cl-loop
1701 with res = nil
1702 for insn in (comp-block-insns bb)
1703 when (eq insn exit-insn)
1704 do (cl-return (and (comp-mvar-p res) (comp-mvar-slot res)))
1705 do (pcase insn
1706 (`(,(pred comp-assign-op-p) ,(pred targetp) ,rhs)
1707 (setf res rhs)))
1708 finally (cl-assert nil))))
1709
1710(defun comp-cond-rw-func ()
1711 "`comp-cond-rw' worker function for each selected function."
1712 (cl-loop
1713 for b being each hash-value of (comp-func-blocks comp-func)
1714 do (cl-loop
1715 named in-the-basic-block
1716 for insns-seq on (comp-block-insns b)
1717 do (pcase insns-seq
1718 (`((set ,(and (pred comp-mvar-p) cond)
1719 (,(pred comp-call-op-p)
1720 ,(and (or 'eq 'eql '= 'equal) test-fn) ,op1 ,op2))
1721 (comment ,_comment-str)
1722 (cond-jump ,cond ,(pred comp-mvar-p) ,bb-1 ,_bb-2))
1723 (when-let ((target-slot1 (comp-cond-rw-target-slot
1724 (comp-mvar-slot op1) (car insns-seq) b)))
1725 (comp-emit-assume target-slot1 op2 bb-1 test-fn))
1726 (when-let ((target-slot2 (comp-cond-rw-target-slot
1727 (comp-mvar-slot op2) (car insns-seq) b)))
1728 (comp-emit-assume target-slot2 op1 bb-1 test-fn))
1729 (cl-return-from in-the-basic-block))))))
1730
1731(defun comp-cond-rw (_)
1732 "Rewrite conditional branches adding appropriate 'assume' insns.
1733This is introducing and placing 'assume' insns in use by fwprop
1734to propagate conditional branch test informations on target basic
1735blocks."
1736 (maphash (lambda (_ f)
1737 (when (and (>= (comp-func-speed f) 1)
1738 ;; No point to run this on dynamic scope as
1739 ;; this pass is effecive only on local
1740 ;; variables.
1741 (comp-func-l-p f)
1742 (not (comp-func-has-non-local f)))
1743 (let ((comp-func f))
1744 (comp-cond-rw-func)
1745 (comp-log-func comp-func 3))))
1746 (comp-ctxt-funcs-h comp-ctxt)))
1747
1748
1680;;; pure-func pass specific code. 1749;;; pure-func pass specific code.
1681 1750
1682;; Simple IPA pass to infer function purity of functions not 1751;; Simple IPA pass to infer function purity of functions not
@@ -2158,6 +2227,18 @@ Forward propagate immediate involed in assignments."
2158 (comp-function-call-maybe-remove insn f args))) 2227 (comp-function-call-maybe-remove insn f args)))
2159 (_ 2228 (_
2160 (comp-mvar-propagate lval rval)))) 2229 (comp-mvar-propagate lval rval))))
2230 (`(assume ,lval ,rval ,kind)
2231 (pcase kind
2232 ('eq
2233 (comp-mvar-propagate lval rval))
2234 ((or 'eql 'equal)
2235 (if (memq (comp-mvar-type rval) '(symbol fixnum))
2236 (comp-mvar-propagate lval rval)
2237 (setf (comp-mvar-type lval) (comp-mvar-type rval))))
2238 ('=
2239 (if (eq (comp-mvar-type rval) 'fixnum)
2240 (comp-mvar-propagate lval rval)
2241 (setf (comp-mvar-type lval) 'number)))))
2161 (`(setimm ,lval ,v) 2242 (`(setimm ,lval ,v)
2162 (setf (comp-mvar-const-vld lval) t 2243 (setf (comp-mvar-const-vld lval) t
2163 (comp-mvar-constant lval) v 2244 (comp-mvar-constant lval) v
diff --git a/src/comp.c b/src/comp.c
index 0c555578f81..48e4f1c8cde 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -2131,9 +2131,9 @@ emit_limple_insn (Lisp_Object insn)
2131 n); 2131 n);
2132 emit_cond_jump (test, target2, target1); 2132 emit_cond_jump (test, target2, target1);
2133 } 2133 }
2134 else if (EQ (op, Qphi)) 2134 else if (EQ (op, Qphi) || EQ (op, Qassume))
2135 { 2135 {
2136 /* Nothing to do for phis into the backend. */ 2136 /* Nothing to do for phis or assumes in the backend. */
2137 } 2137 }
2138 else if (EQ (op, Qpush_handler)) 2138 else if (EQ (op, Qpush_handler))
2139 { 2139 {
@@ -5134,6 +5134,7 @@ native compiled one. */);
5134 DEFSYM (Qcallref, "callref"); 5134 DEFSYM (Qcallref, "callref");
5135 DEFSYM (Qdirect_call, "direct-call"); 5135 DEFSYM (Qdirect_call, "direct-call");
5136 DEFSYM (Qdirect_callref, "direct-callref"); 5136 DEFSYM (Qdirect_callref, "direct-callref");
5137 DEFSYM (Qassume, "assume");
5137 DEFSYM (Qsetimm, "setimm"); 5138 DEFSYM (Qsetimm, "setimm");
5138 DEFSYM (Qreturn, "return"); 5139 DEFSYM (Qreturn, "return");
5139 DEFSYM (Qcomp_mvar, "comp-mvar"); 5140 DEFSYM (Qcomp_mvar, "comp-mvar");