emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/native-comp 7d07a71 3/4: Add sum/subtraction integer range propa


From: Andrea Corallo
Subject: feature/native-comp 7d07a71 3/4: Add sum/subtraction integer range propagation support
Date: Sun, 27 Dec 2020 15:53:39 -0500 (EST)

branch: feature/native-comp
commit 7d07a718416d6c24df0719483279c4278dce4acb
Author: Andrea Corallo <akrl@sdf.org>
Commit: Andrea Corallo <akrl@sdf.org>

    Add sum/subtraction integer range propagation support
    
        * lisp/emacs-lisp/comp-cstr.el (comp-range-+, comp-range--): New
        functions.
        (comp-cstr-set-range-for-arithm): New macro.
        (comp-cstr-add-2, comp-cstr-sub-2, comp-cstr-add, comp-cstr-sub):
        New function.
        * lisp/emacs-lisp/comp.el (comp-fwprop-call): Wire-up + - integer
        range propagation.
---
 lisp/emacs-lisp/comp-cstr.el | 63 ++++++++++++++++++++++++++++++
 lisp/emacs-lisp/comp.el      |  5 ++-
 test/src/comp-tests.el       | 91 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 157 insertions(+), 2 deletions(-)

diff --git a/lisp/emacs-lisp/comp-cstr.el b/lisp/emacs-lisp/comp-cstr.el
index d41501e..28cffcf 100644
--- a/lisp/emacs-lisp/comp-cstr.el
+++ b/lisp/emacs-lisp/comp-cstr.el
@@ -280,6 +280,22 @@ Return them as multiple value."
       x
     (1- x)))
 
+(defsubst comp-range-+ (x y)
+  (pcase (cons x y)
+    ((or '(+ . -) '(- . +)) '??)
+    ((or `(- . ,_) `(,_ . -)) '-)
+    ((or `(+ . ,_) `(,_ . +)) '+)
+    (_ (+ x y))))
+
+(defsubst comp-range-- (x y)
+  (pcase (cons x y)
+    ((or '(+ . +) '(- . -)) '??)
+    ('(+ . -) '+)
+    ('(- . +) '-)
+    ((or `(+ . ,_) `(,_ . -)) '+)
+    ((or `(- . ,_) `(,_ . +)) '-)
+    (_ (- x y))))
+
 (defsubst comp-range-< (x y)
   (cond
    ((eq x '+) nil)
@@ -389,6 +405,39 @@ Return them as multiple value."
             (range dst) (range old-dst)
             (neg dst) (neg old-dst)))))
 
+(defmacro comp-cstr-set-range-for-arithm (dst src1 src2 &rest range-body)
+  ;; Prevent some code duplication for `comp-cstr-add-2'
+  ;; `comp-cstr-sub-2'.
+  (declare (debug (range-body))
+           (indent defun))
+  `(with-comp-cstr-accessors
+     (when-let ((r1 (range ,src1))
+                (r2 (range ,src2)))
+       (let* ((l1 (comp-cstr-smallest-in-range r1))
+              (l2 (comp-cstr-smallest-in-range r2))
+              (h1 (comp-cstr-greatest-in-range r1))
+              (h2 (comp-cstr-greatest-in-range r2)))
+         (setf (typeset ,dst) (when (cl-some (lambda (x)
+                                               (comp-subtype-p 'float x))
+                                             (append (typeset src1)
+                                                     (typeset src2)))
+                                '(float))
+               (range ,dst) ,@range-body)))))
+
+(defun comp-cstr-add-2 (dst src1 src2)
+  "Sum SRC1 and SRC2 into DST."
+  (comp-cstr-set-range-for-arithm dst src1 src2
+    `((,(comp-range-+ l1 l2) . ,(comp-range-+ h1 h2)))))
+
+(defun comp-cstr-sub-2 (dst src1 src2)
+  "Subtract SRC1 and SRC2 into DST."
+  (comp-cstr-set-range-for-arithm dst src1 src2
+    (let ((l (comp-range-- l1 h2))
+          (h (comp-range-- h1 l2)))
+      (if (or (eq l '??) (eq h '??))
+          '((- . +))
+        `((,l . ,h))))))
+
 
 ;;; Union specific code.
 
@@ -742,6 +791,20 @@ SRC can be either a comp-cstr or an integer."
                `((- . ,low))))))
       (comp-cstr-set-cmp-range dst old-dst ext-range))))
 
+(defun comp-cstr-add (dst srcs)
+  "Sum SRCS into DST."
+  (comp-cstr-add-2 dst (cl-first srcs) (cl-second srcs))
+  (cl-loop
+   for src in (nthcdr 2 srcs)
+   do (comp-cstr-add-2 dst dst src)))
+
+(defun comp-cstr-sub (dst srcs)
+  "Subtract SRCS into DST."
+  (comp-cstr-sub-2 dst (cl-first srcs) (cl-second srcs))
+  (cl-loop
+   for src in (nthcdr 2 srcs)
+   do (comp-cstr-sub-2 dst dst src)))
+
 (defun comp-cstr-union-no-range (dst &rest srcs)
   "Combine SRCS by union set operation setting the result in DST.
 Do not propagate the range component.
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 936e47f..336ed39 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -2648,7 +2648,10 @@ Fold the call in case."
         (setf (comp-mvar-range lval) (comp-cstr-range cstr)
               (comp-mvar-valset lval) (comp-cstr-valset cstr)
               (comp-mvar-typeset lval) (comp-cstr-typeset cstr)
-              (comp-mvar-neg lval) (comp-cstr-neg cstr))))))
+              (comp-mvar-neg lval) (comp-cstr-neg cstr))))
+    (cl-case f
+      (+ (comp-cstr-add lval args))
+      (- (comp-cstr-sub lval args)))))
 
 (defun comp-fwprop-insn (insn)
   "Propagate within INSN."
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
index 446c306..154229e 100644
--- a/test/src/comp-tests.el
+++ b/test/src/comp-tests.el
@@ -1036,7 +1036,96 @@ Return a list of results."
       ((defun comp-tests-ret-type-spec-f (x)
               (when (> x 1.0)
                 x))
-       (or null marker number))))
+       (or null marker number))
+
+      ;; 36
+      ;; SBCL: (OR (RATIONAL (5)) (SINGLE-FLOAT 5.0)
+      ;;           (DOUBLE-FLOAT 5.0d0) NULL) !?
+      ((defun comp-tests-ret-type-spec-f (x y)
+         (when (and (> x 3)
+                    (> y 2))
+           (+ x y)))
+       (or null float (integer 7 *)))
+
+      ;; 37
+      ;; SBCL: (OR REAL NULL)
+      ((defun comp-tests-ret-type-spec-f (x y)
+         (when (and (<= x 3)
+                    (<= y 2))
+           (+ x y)))
+       (or null float (integer * 5)))
+
+      ;; 38 SBCL gives: (OR (RATIONAL (2) (10)) (SINGLE-FLOAT 2.0 10.0)
+      ;;                    (DOUBLE-FLOAT 2.0d0 10.0d0) NULL)!?
+      ((defun comp-tests-ret-type-spec-f (x y)
+         (when (and (< 1 x 5)
+                   (< 1 y 5))
+           (+ x y)))
+       (or null float (integer 4 8)))
+
+      ;; 37
+      ;; SBCL gives: (OR REAL NULL)
+      ((defun comp-tests-ret-type-spec-f (x y)
+                   (when (and (<= 1 x 10)
+                              (<= 2 y 3))
+                     (+ x y)))
+       (or null float (integer 3 13)))
+
+      ;; 38
+      ;; SBCL: (OR REAL NULL)
+      ((defun comp-tests-ret-type-spec-f (x y)
+                   (when (and (<= 1 x 10)
+                              (<= 2 y 3))
+                     (- x y)))
+       (or null float (integer -2 8)))
+
+      ;; 39
+      ((defun comp-tests-ret-type-spec-f (x y)
+         (when (and (<= 1 x)
+                    (<= 2 y 3))
+           (- x y)))
+       (or null float (integer -2 *)))
+
+      ;; 40
+      ((defun comp-tests-ret-type-spec-f (x y)
+         (when (and (<= 1 x 10)
+                    (<= 2 y))
+           (- x y)))
+       (or null float (integer * 8)))
+
+      ;; 41
+      ((defun comp-tests-ret-type-spec-f (x y)
+                   (when (and (<= x 10)
+                              (<= 2 y))
+                     (- x y)))
+       (or null float (integer * 8)))
+
+      ;; 42
+      ((defun comp-tests-ret-type-spec-f (x y)
+          (when (and (<= x 10)
+                     (<= y 3))
+            (- x y)))
+       (or null float integer))
+
+      ;; 43
+      ((defun comp-tests-ret-type-spec-f (x y)
+          (when (and (<= 2 x)
+                     (<= 3 y))
+            (- x y)))
+       (or null float integer))
+
+      ;; 44
+      ;; SBCL: (OR (RATIONAL (6) (30)) (SINGLE-FLOAT 6.0 30.0)
+      ;;           (DOUBLE-FLOAT 6.0d0 30.0d0) NULL)
+      ((defun comp-tests-ret-type-spec-f (x y z i j k)
+         (when (and (< 1 x 5)
+                   (< 1 y 5)
+                   (< 1 z 5)
+                   (< 1 i 5)
+                   (< 1 j 5)
+                   (< 1 k 5))
+           (+ x y z i j k)))
+       (or null float (integer 12 24)))))
 
   (defun comp-tests-define-type-spec-test (number x)
     `(comp-deftest ,(intern (format "ret-type-spec-%d" number)) ()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]