aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/emacs-lisp/comp.el80
-rw-r--r--test/src/comp-tests.el4
2 files changed, 73 insertions, 11 deletions
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index e8db2383c41..6f1ef26ac78 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -1868,7 +1868,19 @@ into the C code forwarding the compilation unit."
1868 (comp-add-func-to-ctxt (comp-limplify-top-level t)))) 1868 (comp-add-func-to-ctxt (comp-limplify-top-level t))))
1869 1869
1870 1870
1871;;; conditional branches rewrite pass specific code. 1871;;; add-cstrs pass specific code.
1872
1873;; This pass is responsible for adding constraints, these are
1874;; generated from:
1875;;
1876;; - Conditional branches: each branch taken or non taken can be used
1877;; in the CFG to infer infomations on the tested variables.
1878;;
1879;; - Function calls: function calls to function assumed to be not
1880;; redefinable can be used to add constrains on the function
1881;; arguments. Ex: if we execute successfully (= x y) we know that
1882;; afterwards both x and y must satisfy the (or number marker)
1883;; type specifier.
1872 1884
1873(defun comp-emit-assume (target rhs bb negated) 1885(defun comp-emit-assume (target rhs bb negated)
1874 "Emit an assume for mvar TARGET being RHS. 1886 "Emit an assume for mvar TARGET being RHS.
@@ -1907,10 +1919,10 @@ The assume is emitted at the beginning of the block BB."
1907 (cl-return (puthash bb-symbol new-bb (comp-func-blocks comp-func))) 1919 (cl-return (puthash bb-symbol new-bb (comp-func-blocks comp-func)))
1908 finally (cl-assert nil))) 1920 finally (cl-assert nil)))
1909 1921
1910(defun comp-add-cond-cstrs-target-mvar (mvar exit-insn bb) 1922;; Cheap substitute to a copy propagation pass...
1911 "Given MVAR search in BB what we'll use as assume target. 1923(defun comp-cond-cstrs-target-mvar (mvar exit-insn bb)
1912Keep on searching till EXIT-INSN is encountered. 1924 "Given MVAR search in BB the original mvar MVAR got assigned from.
1913Return the corresponding rhs mvar." 1925Keep on searching till EXIT-INSN is encountered."
1914 (cl-flet ((targetp (x) 1926 (cl-flet ((targetp (x)
1915 ;; Ret t if x is an mvar and target the correct slot number. 1927 ;; Ret t if x is an mvar and target the correct slot number.
1916 (and (comp-mvar-p x) 1928 (and (comp-mvar-p x)
@@ -1955,10 +1967,8 @@ TARGET-BB-SYM is the symbol name of the target block."
1955 (comment ,_comment-str) 1967 (comment ,_comment-str)
1956 (cond-jump ,cond ,(pred comp-mvar-p) . ,blocks)) 1968 (cond-jump ,cond ,(pred comp-mvar-p) . ,blocks))
1957 (cl-loop 1969 (cl-loop
1958 with target-mvar1 = (comp-add-cond-cstrs-target-mvar op1 (car insns-seq) 1970 with target-mvar1 = (comp-cond-cstrs-target-mvar op1 (car insns-seq) b)
1959 b) 1971 with target-mvar2 = (comp-cond-cstrs-target-mvar op2 (car insns-seq) b)
1960 with target-mvar2 = (comp-add-cond-cstrs-target-mvar op2 (car insns-seq)
1961 b)
1962 for branch-target-cell on blocks 1972 for branch-target-cell on blocks
1963 for branch-target = (car branch-target-cell) 1973 for branch-target = (car branch-target-cell)
1964 for assume-target = (comp-add-cond-cstrs-target-block b branch-target) 1974 for assume-target = (comp-add-cond-cstrs-target-block b branch-target)
@@ -1970,6 +1980,57 @@ TARGET-BB-SYM is the symbol name of the target block."
1970 do (comp-emit-assume target-mvar2 op1 assume-target negated) 1980 do (comp-emit-assume target-mvar2 op1 assume-target negated)
1971 finally (cl-return-from in-the-basic-block))))))) 1981 finally (cl-return-from in-the-basic-block)))))))
1972 1982
1983(defun comp-emit-call-cstr (mvar call-cell cstr)
1984 "Emit a constraint CSTR for MVAR after CALL-CELL."
1985 (let ((next-cell (cdr call-cell))
1986 (new-cell `((assume ,(make-comp-mvar :slot (comp-mvar-slot mvar))
1987 (and ,mvar ,cstr)))))
1988 (setf (cdr call-cell) new-cell
1989 (cdr new-cell) next-cell
1990 (comp-func-ssa-status comp-func) 'dirty)))
1991
1992(defun comp-lambda-list-gen (lambda-list)
1993 "Return a generator to iterate over LAMBDA-LIST."
1994 (lambda ()
1995 (cl-case (car lambda-list)
1996 (&optional
1997 (setf lambda-list (cdr lambda-list))
1998 (prog1
1999 (car lambda-list)
2000 (setf lambda-list (cdr lambda-list))))
2001 (&rest
2002 (cadr lambda-list))
2003 (t
2004 (prog1
2005 (car lambda-list)
2006 (setf lambda-list (cdr lambda-list)))))))
2007
2008(defun comp-add-call-cstr ()
2009 "Add args assumptions for each function of which the type specifier is known."
2010 (cl-loop
2011 for bb being each hash-value of (comp-func-blocks comp-func)
2012 do
2013 (comp-loop-insn-in-block bb
2014 (when-let ((match
2015 (pcase insn
2016 (`(set ,lhs (,(pred comp-call-op-p) ,f . ,args))
2017 (when-let ((cstr-f (gethash f comp-known-func-cstr-h)))
2018 (cl-values cstr-f lhs args)))
2019 (`(,(pred comp-call-op-p) ,f . ,args)
2020 (when-let ((cstr-f (gethash f comp-known-func-cstr-h)))
2021 (cl-values cstr-f nil args))))))
2022 (cl-multiple-value-bind (cstr-f lhs args) match
2023 (cl-loop
2024 for arg in args
2025 for gen = (comp-lambda-list-gen (comp-cstr-f-args cstr-f))
2026 for cstr = (funcall gen)
2027 for target = (comp-cond-cstrs-target-mvar arg insn bb)
2028 when (and target
2029 (or (null lhs)
2030 (not (eql (comp-mvar-slot lhs)
2031 (comp-mvar-slot target)))))
2032 do (comp-emit-call-cstr target insn-cell cstr)))))))
2033
1973(defun comp-add-cstrs (_) 2034(defun comp-add-cstrs (_)
1974 "Rewrite conditional branches adding appropriate 'assume' insns. 2035 "Rewrite conditional branches adding appropriate 'assume' insns.
1975This is introducing and placing 'assume' insns in use by fwprop 2036This is introducing and placing 'assume' insns in use by fwprop
@@ -1984,6 +2045,7 @@ blocks."
1984 (not (comp-func-has-non-local f))) 2045 (not (comp-func-has-non-local f)))
1985 (let ((comp-func f)) 2046 (let ((comp-func f))
1986 (comp-add-cond-cstrs) 2047 (comp-add-cond-cstrs)
2048 (comp-add-call-cstr)
1987 (comp-log-func comp-func 3)))) 2049 (comp-log-func comp-func 3))))
1988 (comp-ctxt-funcs-h comp-ctxt))) 2050 (comp-ctxt-funcs-h comp-ctxt)))
1989 2051
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
index 4ea8dbbadb3..a3e887bde95 100644
--- a/test/src/comp-tests.el
+++ b/test/src/comp-tests.el
@@ -872,14 +872,14 @@ Return a list of results."
872 (if (= x 3) 872 (if (= x 3)
873 'foo 873 'foo
874 x)) 874 x))
875 (or (member foo) (integer * 2) (integer 4 *))) 875 (or (member foo) marker number))
876 876
877 ;; 13 877 ;; 13
878 ((defun comp-tests-ret-type-spec-8-4-f (x y) 878 ((defun comp-tests-ret-type-spec-8-4-f (x y)
879 (if (= x y) 879 (if (= x y)
880 x 880 x
881 'foo)) 881 'foo))
882 t) 882 (or (member foo) marker number))
883 883
884 ;; 14 884 ;; 14
885 ((defun comp-tests-ret-type-spec-9-1-f (x) 885 ((defun comp-tests-ret-type-spec-9-1-f (x)