emacs-diffs
[Top][All Lists]
Advanced

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

feature/native-comp bddd7a2 3/4: Do not emit assumptions referencing clo


From: Andrea Corallo
Subject: feature/native-comp bddd7a2 3/4: Do not emit assumptions referencing clobbered mvars (bug#46670)
Date: Tue, 23 Feb 2021 18:24:55 -0500 (EST)

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

    Do not emit assumptions referencing clobbered mvars (bug#46670)
    
        * lisp/emacs-lisp/comp.el (comp-func): Add `vframe-size' slot.
        (comp-new-frame): Add `vsize' parameter.
        (comp-limplify-top-level, comp-limplify-function): Update for new
        `comp-new-frame'.
        (comp-maybe-add-vmvar): New function.
        (comp-add-cond-cstrs): Logic update to emit assumptions not
        referencing clobbered variables.
        (comp-place-phis, comp-ssa, comp-ssa-rename-insn)
        (comp-ssa-rename): Update rename logic to rename also negative
        slots.
        (comp-fwprop-insn): Update to handle `(assume mvar mvar)' form.
        * test/src/comp-tests.el (46670-1): Add testcase.
        * test/src/comp-test-funcs.el (comp-test-46670-1-f)
        (comp-test-46670-2-f): New functions.
---
 lisp/emacs-lisp/comp.el     | 102 ++++++++++++++++++++++++++++----------------
 test/src/comp-test-funcs.el |   7 +++
 test/src/comp-tests.el      |   6 +++
 3 files changed, 78 insertions(+), 37 deletions(-)

diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index b6451d5..f18f8e3 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -809,6 +809,7 @@ non local exit (ends with an `unreachable' insn)."))
 Once in SSA form this *must* be set to 'dirty' every time the topology of the
 CFG is mutated by a pass.")
   (frame-size nil :type integer)
+  (vframe-size 0 :type integer)
   (blocks (make-hash-table :test #'eq) :type hash-table
           :documentation "Basic block symbol -> basic block.")
   (lap-block (make-hash-table :test #'equal) :type hash-table
@@ -1468,11 +1469,11 @@ STACK-OFF is the index of the first slot frame 
involved."
       (setf (comp-mvar-typeset mvar) (list type)))
     mvar))
 
-(defun comp-new-frame (size &optional ssa)
+(defun comp-new-frame (size vsize &optional ssa)
   "Return a clean frame of meta variables of size SIZE.
 If SSA non-nil populate it of m-var in ssa form."
-  (cl-loop with v = (make-comp-vec)
-           for i below size
+  (cl-loop with v = (make-comp-vec :beg (- vsize) :end size)
+           for i from (- vsize) below size
            for mvar = (if ssa
                           (make-comp-ssa-mvar :slot i)
                         (make-comp-mvar :slot i))
@@ -2116,7 +2117,7 @@ into the C code forwarding the compilation unit."
          (comp-func func)
          (comp-pass (make-comp-limplify
                      :curr-block (make--comp-block-lap -1 0 'top-level)
-                     :frame (comp-new-frame 1))))
+                     :frame (comp-new-frame 1 0))))
     (comp-make-curr-block 'entry (comp-sp))
     (comp-emit-annotation (if for-late-load
                               "Late top level"
@@ -2177,7 +2178,7 @@ into the C code forwarding the compilation unit."
   (let* ((frame-size (comp-func-frame-size func))
          (comp-func func)
          (comp-pass (make-comp-limplify
-                     :frame (comp-new-frame frame-size))))
+                     :frame (comp-new-frame frame-size 0))))
     (comp-fill-label-h)
     ;; Prologue
     (comp-make-curr-block 'entry (comp-sp))
@@ -2322,6 +2323,18 @@ The assume is emitted at the beginning of the block BB."
       (_ (cl-assert nil)))
     (setf (comp-func-ssa-status comp-func) 'dirty)))
 
+(defun comp-maybe-add-vmvar (op cmp-res insns-seq)
+  "If CMP-RES is clobbering OP emit a new constrained MVAR and return it.
+Return OP otherwise."
+  (if-let ((match (eql (comp-mvar-slot op) (comp-mvar-slot cmp-res)))
+           (new-mvar (make-comp-mvar
+                      :slot
+                      (- (cl-incf (comp-func-vframe-size comp-func))))))
+      (progn
+        (push `(assume ,new-mvar ,op) (cdr insns-seq))
+        new-mvar)
+    op))
+
 (defun comp-add-new-block-between (bb-symbol bb-a bb-b)
   "Create a new basic-block named BB-SYMBOL and add it between BB-A and BB-B."
   (cl-loop
@@ -2427,6 +2440,7 @@ TARGET-BB-SYM is the symbol name of the target block."
    do
    (cl-loop
     named in-the-basic-block
+    with prev-insns-seq
     for insns-seq on (comp-block-insns b)
     do
     (pcase insns-seq
@@ -2452,10 +2466,14 @@ TARGET-BB-SYM is the symbol name of the target block."
         (let ((block-target (comp-add-cond-cstrs-target-block b 
branch-target)))
           (setf (car branch-target-cell) (comp-block-name block-target))
           (when (comp-mvar-used-p target-mvar1)
-            (comp-emit-assume kind target-mvar1 op2 block-target negated))
+            (comp-emit-assume kind target-mvar1
+                              (comp-maybe-add-vmvar op2 cmp-res prev-insns-seq)
+                              block-target negated))
           (when (comp-mvar-used-p target-mvar2)
             (comp-emit-assume (comp-reverse-cmp-fun kind)
-                              target-mvar2 op1 block-target negated)))
+                              target-mvar2
+                              (comp-maybe-add-vmvar op1 cmp-res prev-insns-seq)
+                              block-target negated)))
         finally (cl-return-from in-the-basic-block)))
       (`((set ,(and (pred comp-mvar-p) cmp-res)
               (,(pred comp-call-op-p)
@@ -2493,7 +2511,8 @@ TARGET-BB-SYM is the symbol name of the target block."
         (let ((block-target (comp-add-cond-cstrs-target-block b 
branch-target)))
           (setf (car branch-target-cell) (comp-block-name block-target))
           (comp-emit-assume 'and target-mvar cstr block-target negated))
-        finally (cl-return-from in-the-basic-block)))))))
+        finally (cl-return-from in-the-basic-block))))
+    (setf prev-insns-seq insns-seq))))
 
 (defsubst comp-insert-insn (insn insn-cell)
   "Insert INSN as second insn of INSN-CELL."
@@ -2816,7 +2835,8 @@ blocks."
                                (eq op 'fetch-handler))
                         return t)))
 
-    (cl-loop for i from 0 below (comp-func-frame-size comp-func) ; FIXME
+    (cl-loop for i from (- (comp-func-vframe-size comp-func))
+                   below (comp-func-frame-size comp-func)
              ;; List of blocks with a definition of mvar i
              for defs-v = (cl-loop with blocks = (comp-func-blocks comp-func)
                                    for b being each hash-value of blocks
@@ -2854,40 +2874,44 @@ PRE-LAMBDA and POST-LAMBDA are called in pre or 
post-order if non-nil."
 
 (cl-defstruct (comp-ssa (:copier nil))
   "Support structure used while SSA renaming."
-  (frame (comp-new-frame (comp-func-frame-size comp-func) t) :type comp-vec
+  (frame (comp-new-frame (comp-func-frame-size comp-func)
+                         (comp-func-vframe-size comp-func) t)
+         :type comp-vec
          :documentation "`comp-vec' of m-vars."))
 
 (defun comp-ssa-rename-insn (insn frame)
-  (dotimes (slot-n (comp-func-frame-size comp-func))
-    (cl-flet ((targetp (x)
-                ;; Ret t if x is an mvar and target the correct slot number.
-                (and (comp-mvar-p x)
-                     (eql slot-n (comp-mvar-slot x))))
-              (new-lvalue ()
-                ;; If is an assignment make a new mvar and put it as l-value.
-                (let ((mvar (make-comp-ssa-mvar :slot slot-n)))
-                  (setf (comp-vec-aref frame slot-n) mvar
-                        (cadr insn) mvar))))
-      (pcase insn
-        (`(,(pred comp-assign-op-p) ,(pred targetp) . ,_)
-         (let ((mvar (comp-vec-aref frame slot-n)))
-           (setf (cddr insn) (cl-nsubst-if mvar #'targetp (cddr insn))))
-         (new-lvalue))
-        (`(fetch-handler . ,_)
-         ;; Clobber all no matter what!
-         (setf (comp-vec-aref frame slot-n) (make-comp-ssa-mvar :slot slot-n)))
-        (`(phi ,n)
-         (when (equal n slot-n)
-           (new-lvalue)))
-        (_
-         (let ((mvar (comp-vec-aref frame slot-n)))
-           (setcdr insn (cl-nsubst-if mvar #'targetp (cdr insn)))))))))
+  (cl-loop
+   for slot-n from (- (comp-func-vframe-size comp-func))
+              below (comp-func-frame-size comp-func)
+   do
+   (cl-flet ((targetp (x)
+               ;; Ret t if x is an mvar and target the correct slot number.
+               (and (comp-mvar-p x)
+                    (eql slot-n (comp-mvar-slot x))))
+             (new-lvalue ()
+               ;; If is an assignment make a new mvar and put it as l-value.
+               (let ((mvar (make-comp-ssa-mvar :slot slot-n)))
+                 (setf (comp-vec-aref frame slot-n) mvar
+                       (cadr insn) mvar))))
+     (pcase insn
+       (`(,(pred comp-assign-op-p) ,(pred targetp) . ,_)
+        (let ((mvar (comp-vec-aref frame slot-n)))
+          (setf (cddr insn) (cl-nsubst-if mvar #'targetp (cddr insn))))
+        (new-lvalue))
+       (`(fetch-handler . ,_)
+        ;; Clobber all no matter what!
+        (setf (comp-vec-aref frame slot-n) (make-comp-ssa-mvar :slot slot-n)))
+       (`(phi ,n)
+        (when (equal n slot-n)
+          (new-lvalue)))
+       (_
+        (let ((mvar (comp-vec-aref frame slot-n)))
+          (setcdr insn (cl-nsubst-if mvar #'targetp (cdr insn)))))))))
 
 (defun comp-ssa-rename ()
   "Entry point to rename into SSA within the current function."
   (comp-log "Renaming\n" 2)
-  (let ((frame-size (comp-func-frame-size comp-func))
-        (visited (make-hash-table)))
+  (let ((visited (make-hash-table)))
     (cl-labels ((ssa-rename-rec (bb in-frame)
                   (unless (gethash bb visited)
                     (puthash bb t visited)
@@ -2903,7 +2927,9 @@ PRE-LAMBDA and POST-LAMBDA are called in pre or 
post-order if non-nil."
                        do (ssa-rename-rec child (comp-vec-copy in-frame)))))))
 
       (ssa-rename-rec (gethash 'entry (comp-func-blocks comp-func))
-                      (comp-new-frame frame-size t)))))
+                      (comp-new-frame (comp-func-frame-size comp-func)
+                                      (comp-func-vframe-size comp-func)
+                                      t)))))
 
 (defun comp-finalize-phis ()
   "Fixup r-values into phis in all basic blocks."
@@ -3094,6 +3120,8 @@ Fold the call in case."
           (comp-fwprop-call insn lval f args)))
        (_
         (comp-mvar-propagate lval rval))))
+    (`(assume ,lval ,(and (pred comp-mvar-p) rval))
+     (comp-mvar-propagate lval rval))
     (`(assume ,lval (,kind . ,operands))
      (cl-case kind
        (and
diff --git a/test/src/comp-test-funcs.el b/test/src/comp-test-funcs.el
index 694d9d4..5bae743 100644
--- a/test/src/comp-test-funcs.el
+++ b/test/src/comp-test-funcs.el
@@ -478,6 +478,13 @@
              (eq family 'unspecified))
       family)))
 
+(defun comp-test-46670-1-f (x)
+  "foo")
+
+(defun comp-test-46670-2-f (s)
+  (and (equal (comp-test-46670-1-f (length s)) s)
+       s))
+
 
 ;;;;;;;;;;;;;;;;;;;;
 ;; Tromey's tests ;;
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
index f7b5a6b..fa84ffb 100644
--- a/test/src/comp-tests.el
+++ b/test/src/comp-tests.el
@@ -497,6 +497,12 @@ 
https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-03/msg00914.html.";
   (load (native-compile (concat comp-test-directory "comp-test-45603.el")))
   (should (fboundp #'comp-test-45603--file-local-name)))
 
+(comp-deftest 46670-1 ()
+  "<https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-02/msg01413.html>"
+  (should (string= (comp-test-46670-2-f "foo") "foo"))
+  (should (equal (subr-type (symbol-function #'comp-test-46670-2-f))
+                 '(function (t) (or null sequence)))))
+
 
 ;;;;;;;;;;;;;;;;;;;;;
 ;; Tromey's tests. ;;



reply via email to

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