diff options
| author | Andrea Corallo | 2020-11-07 21:47:30 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-11-12 00:55:36 +0100 |
| commit | e96cd4e82c9aca01f136ccdd7a3b0fbf2db01e50 (patch) | |
| tree | 48ae8a334d7ef660bb30cd409873d503143f2aba /test | |
| parent | c3d0e2a09fd72aa9209dda3057bbb02f6a3b3df6 (diff) | |
| download | emacs-e96cd4e82c9aca01f136ccdd7a3b0fbf2db01e50.tar.gz emacs-e96cd4e82c9aca01f136ccdd7a3b0fbf2db01e50.zip | |
Add initial nativecomp typeset and range propagation support
This commit add an initial support for a better type propagation and
integer range propagation.
Each mvar can be now characterized by a set of types, a set of values
and an integral range.
* lisp/emacs-lisp/comp.el (comp-known-ret-types): Store into
typeset and remove fixnum.
(comp-known-ret-ranges, comp-type-predicates): New variables.
(comp-ctxt): Remove supertype-memoize slot and add
union-typesets-mem.
(comp-mvar): Remove const-vld, constant, type slots. Add typeset,
valset, range slots.
(comp-mvar-value-vld-p, comp-mvar-value, comp-mvar-fixnum-p)
(comp-mvar-symbol-p, comp-mvar-cons-p)
(comp-mvar-type-hint-match-p, comp-func-ret-typeset)
(comp-func-ret-range): New functions.
(make-comp-mvar, make-comp-ssa-mvar): Update logic.
(comp--typeof-types): New variable.
(comp-supertypes, comp-common-supertype): Logic update.
(comp-subtype-p, comp-union-typesets, comp-range-1+)
(comp-range-1-, comp-range-<, comp-range-union)
(comp-range-intersection): New functions.
(comp-fwprop-prologue, comp-mvar-propagate)
(comp-function-foldable-p, comp-function-call-maybe-fold)
(comp-fwprop-insn, comp-call-optim-func, comp-finalize-relocs):
Logic update.
* src/comp.c (emit_mvar_rval, emit_call_with_type_hint)
(emit_call2_with_type_hint): Logic update.
* lisp/emacs-lisp/cl-preloaded.el (cl--typeof-types): Undo the add
of fixnum and bignum as unnecessary.
* test/src/comp-tests.el
(comp-tests-mentioned-p-1, comp-tests-cond-rw-checker-val)
(comp-tests-cond-rw-checker-type, cond-rw-1, cond-rw-2)
(cond-rw-3, cond-rw-4, cond-rw-5): Update for new type interface.
(range-simple-union, range-simple-intersection): New integer range
tests.
(union-types): New union type test.
Diffstat (limited to 'test')
| -rw-r--r-- | test/src/comp-tests.el | 82 |
1 files changed, 63 insertions, 19 deletions
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el index 21c8abad038..48687d92021 100644 --- a/test/src/comp-tests.el +++ b/test/src/comp-tests.el | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | (defconst comp-test-dyn-src | 37 | (defconst comp-test-dyn-src |
| 38 | (concat comp-test-directory "comp-test-funcs-dyn.el")) | 38 | (concat comp-test-directory "comp-test-funcs-dyn.el")) |
| 39 | 39 | ||
| 40 | (when (boundp 'comp-ctxt) | 40 | (when (featurep 'nativecomp) |
| 41 | (message "Compiling tests...") | 41 | (message "Compiling tests...") |
| 42 | (load (native-compile comp-test-src)) | 42 | (load (native-compile comp-test-src)) |
| 43 | (load (native-compile comp-test-dyn-src))) | 43 | (load (native-compile comp-test-dyn-src))) |
| @@ -676,8 +676,8 @@ https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-03/msg00914.html." | |||
| 676 | (cl-loop for y in insn | 676 | (cl-loop for y in insn |
| 677 | when (cond | 677 | when (cond |
| 678 | ((consp y) (comp-tests-mentioned-p x y)) | 678 | ((consp y) (comp-tests-mentioned-p x y)) |
| 679 | ((and (comp-mvar-p y) (comp-mvar-const-vld y)) | 679 | ((and (comp-mvar-p y) (comp-mvar-value-vld-p y)) |
| 680 | (equal (comp-mvar-constant y) x)) | 680 | (equal (comp-mvar-value y) x)) |
| 681 | (t (equal x y))) | 681 | (t (equal x y))) |
| 682 | return t)) | 682 | return t)) |
| 683 | 683 | ||
| @@ -804,8 +804,8 @@ Return a list of results." | |||
| 804 | (lambda (insn) | 804 | (lambda (insn) |
| 805 | (pcase insn | 805 | (pcase insn |
| 806 | (`(return ,mvar) | 806 | (`(return ,mvar) |
| 807 | (and (comp-mvar-const-vld mvar) | 807 | (and (comp-mvar-value-vld-p mvar) |
| 808 | (= (comp-mvar-constant mvar) 123))))))))) | 808 | (eql (comp-mvar-value mvar) 123))))))))) |
| 809 | 809 | ||
| 810 | (defvar comp-tests-cond-rw-expected-type nil | 810 | (defvar comp-tests-cond-rw-expected-type nil |
| 811 | "Type to expect in `comp-tests-cond-rw-checker-type'.") | 811 | "Type to expect in `comp-tests-cond-rw-checker-type'.") |
| @@ -819,7 +819,8 @@ Return a list of results." | |||
| 819 | (lambda (insn) | 819 | (lambda (insn) |
| 820 | (pcase insn | 820 | (pcase insn |
| 821 | (`(return ,mvar) | 821 | (`(return ,mvar) |
| 822 | (eq (comp-mvar-type mvar) comp-tests-cond-rw-expected-type)))))))) | 822 | (equal (comp-mvar-typeset mvar) |
| 823 | comp-tests-cond-rw-expected-type)))))))) | ||
| 823 | 824 | ||
| 824 | (defvar comp-tests-cond-rw-0-var) | 825 | (defvar comp-tests-cond-rw-0-var) |
| 825 | (comp-deftest cond-rw-0 () | 826 | (comp-deftest cond-rw-0 () |
| @@ -839,40 +840,39 @@ Return a list of results." | |||
| 839 | (comp-deftest cond-rw-1 () | 840 | (comp-deftest cond-rw-1 () |
| 840 | "Test cond-rw pass allow us to propagate type+val under `eq' tests." | 841 | "Test cond-rw pass allow us to propagate type+val under `eq' tests." |
| 841 | (let ((lexical-binding t) | 842 | (let ((lexical-binding t) |
| 842 | (comp-tests-cond-rw-expected-type 'fixnum) | 843 | (comp-tests-cond-rw-expected-type '(integer)) |
| 843 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type) | 844 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type |
| 844 | (comp-final comp-tests-cond-rw-checker-val)))) | 845 | comp-tests-cond-rw-checker-val)))) |
| 845 | (subr-native-elisp-p (native-compile '(lambda (x) (if (eq x 123) x t)))) | 846 | (subr-native-elisp-p (native-compile '(lambda (x) (if (eq x 123) x t)))) |
| 846 | (subr-native-elisp-p (native-compile '(lambda (x) (if (eq 123 x) x t)))))) | 847 | (subr-native-elisp-p (native-compile '(lambda (x) (if (eq 123 x) x t)))))) |
| 847 | 848 | ||
| 848 | (comp-deftest cond-rw-2 () | 849 | (comp-deftest cond-rw-2 () |
| 849 | "Test cond-rw pass allow us to propagate type+val under `=' tests." | 850 | "Test cond-rw pass allow us to propagate type+val under `=' tests." |
| 850 | (let ((lexical-binding t) | 851 | (let ((lexical-binding t) |
| 851 | (comp-tests-cond-rw-expected-type 'fixnum) | 852 | (comp-tests-cond-rw-expected-type '(integer)) |
| 852 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type) | 853 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type |
| 853 | (comp-final comp-tests-cond-rw-checker-val)))) | 854 | comp-tests-cond-rw-checker-val)))) |
| 854 | (subr-native-elisp-p (native-compile '(lambda (x) (if (= x 123) x t)))))) | 855 | (subr-native-elisp-p (native-compile '(lambda (x) (if (= x 123) x t)))))) |
| 855 | 856 | ||
| 856 | (comp-deftest cond-rw-3 () | 857 | (comp-deftest cond-rw-3 () |
| 857 | "Test cond-rw pass allow us to propagate type+val under `eql' tests." | 858 | "Test cond-rw pass allow us to propagate type+val under `eql' tests." |
| 858 | (let ((lexical-binding t) | 859 | (let ((lexical-binding t) |
| 859 | (comp-tests-cond-rw-expected-type 'fixnum) | 860 | (comp-tests-cond-rw-expected-type '(integer)) |
| 860 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type) | 861 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type |
| 861 | (comp-final comp-tests-cond-rw-checker-val)))) | 862 | comp-tests-cond-rw-checker-val)))) |
| 862 | (subr-native-elisp-p (native-compile '(lambda (x) (if (eql 123 x) x t)))))) | 863 | (subr-native-elisp-p (native-compile '(lambda (x) (if (eql 123 x) x t)))))) |
| 863 | 864 | ||
| 864 | (comp-deftest cond-rw-4 () | 865 | (comp-deftest cond-rw-4 () |
| 865 | "Test cond-rw pass allow us to propagate type under `=' tests." | 866 | "Test cond-rw pass allow us to propagate type under `=' tests." |
| 866 | (let ((lexical-binding t) | 867 | (let ((lexical-binding t) |
| 867 | (comp-tests-cond-rw-expected-type 'number) | 868 | (comp-tests-cond-rw-expected-type '(number)) |
| 868 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type)))) | 869 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type)))) |
| 869 | (subr-native-elisp-p (native-compile '(lambda (x y) (if (= x y) x t)))))) | 870 | (subr-native-elisp-p (native-compile '(lambda (x y) (if (= x y) x t)))))) |
| 870 | 871 | ||
| 871 | (comp-deftest cond-rw-5 () | 872 | (comp-deftest cond-rw-5 () |
| 872 | "Test cond-rw pass allow us to propagate type under `=' tests." | 873 | "Test cond-rw pass allow us to propagate type under `=' tests." |
| 873 | (let ((lexical-binding t) | 874 | (let ((comp-tests-cond-rw-checked-function #'comp-tests-cond-rw-4-f) |
| 874 | (comp-tests-cond-rw-checked-function #'comp-tests-cond-rw-4-f) | 875 | (comp-tests-cond-rw-expected-type '(integer)) |
| 875 | (comp-tests-cond-rw-expected-type 'fixnum) | ||
| 876 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type)))) | 876 | (comp-post-pass-hooks '((comp-final comp-tests-cond-rw-checker-type)))) |
| 877 | (eval '(defun comp-tests-cond-rw-4-f (x y) | 877 | (eval '(defun comp-tests-cond-rw-4-f (x y) |
| 878 | (declare (speed 3)) | 878 | (declare (speed 3)) |
| @@ -883,4 +883,48 @@ Return a list of results." | |||
| 883 | (native-compile #'comp-tests-cond-rw-4-f) | 883 | (native-compile #'comp-tests-cond-rw-4-f) |
| 884 | (should (subr-native-elisp-p (symbol-function #'comp-tests-cond-rw-4-f))))) | 884 | (should (subr-native-elisp-p (symbol-function #'comp-tests-cond-rw-4-f))))) |
| 885 | 885 | ||
| 886 | |||
| 887 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 888 | ;; Range propagation tests. ;; | ||
| 889 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 890 | |||
| 891 | (comp-deftest range-simple-union () | ||
| 892 | (should (equal (comp-range-union '((-1 . 0)) '((3 . 4))) | ||
| 893 | '((-1 . 0) (3 . 4)))) | ||
| 894 | (should (equal (comp-range-union '((-1 . 2)) '((3 . 4))) | ||
| 895 | '((-1 . 4)))) | ||
| 896 | (should (equal (comp-range-union '((-1 . 3)) '((3 . 4))) | ||
| 897 | '((-1 . 4)))) | ||
| 898 | (should (equal (comp-range-union '((-1 . 4)) '((3 . 4))) | ||
| 899 | '((-1 . 4)))) | ||
| 900 | (should (equal (comp-range-union '((-1 . 5)) '((3 . 4))) | ||
| 901 | '((-1 . 5)))) | ||
| 902 | (should (equal (comp-range-union '((-1 . 0)) '()) | ||
| 903 | '((-1 . 0))))) | ||
| 904 | |||
| 905 | (comp-deftest range-simple-intersection () | ||
| 906 | (should (equal (comp-range-intersection '((-1 . 0)) '((3 . 4))) | ||
| 907 | '())) | ||
| 908 | (should (equal (comp-range-intersection '((-1 . 2)) '((3 . 4))) | ||
| 909 | '())) | ||
| 910 | (should (equal (comp-range-intersection '((-1 . 3)) '((3 . 4))) | ||
| 911 | '((3 . 3)))) | ||
| 912 | (should (equal (comp-range-intersection '((-1 . 4)) '((3 . 4))) | ||
| 913 | '((3 . 4)))) | ||
| 914 | (should (equal (comp-range-intersection '((-1 . 5)) '((3 . 4))) | ||
| 915 | '((3 . 4)))) | ||
| 916 | (should (equal (comp-range-intersection '((-1 . 0)) '()) | ||
| 917 | '()))) | ||
| 918 | |||
| 919 | (comp-deftest union-types () | ||
| 920 | (let ((comp-ctxt (make-comp-ctxt))) | ||
| 921 | (should (equal (comp-union-typesets '(integer) '(number)) | ||
| 922 | '(number))) | ||
| 923 | (should (equal (comp-union-typesets '(integer symbol) '(number)) | ||
| 924 | '(symbol number))) | ||
| 925 | (should (equal (comp-union-typesets '(integer symbol) '(number list)) | ||
| 926 | '(list symbol number))) | ||
| 927 | (should (equal (comp-union-typesets '(integer symbol) '()) | ||
| 928 | '(symbol integer))))) | ||
| 929 | |||
| 886 | ;;; comp-tests.el ends here | 930 | ;;; comp-tests.el ends here |