emacs-diffs
[Top][All Lists]
Advanced

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

feature/native-comp 34ed9d2 2/3: * Introduce latches


From: Andrea Corallo
Subject: feature/native-comp 34ed9d2 2/3: * Introduce latches
Date: Sat, 13 Jun 2020 10:48:07 -0400 (EDT)

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

    * Introduce latches
    
    Define a new kind of basic block 'latch' to close over loops.  Its
    purpose is for now to emit calls to `comp-maybe-gc-or-quit' but in
    future will be usefull for the loop optimizer to exploit unboxes.
    
        * lisp/emacs-lisp/comp.el (comp-block): New base class.
        (comp-block-lap): New class for LAP derived basic blocks.
        (comp-latch): New class.
        (comp-bb-maybe-add, comp-make-curr-block, comp-emit-handler)
        (comp-emit-switch, comp-emit-switch, comp-limplify-top-level)
        (comp-addr-to-bb-name, comp-limplify-block)
        (comp-limplify-function): Update logic for new bb objects
        arrangment.
        (comp-latch-make-fill): New function.
        (comp-emit-uncond-jump, comp-emit-cond-jump): Update to emit
        latches.
        (comp-new-block-sym): Add a postfix paramenter.
---
 lisp/emacs-lisp/comp.el | 112 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 76 insertions(+), 36 deletions(-)

diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 2cde99e..5027d1d 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -279,16 +279,9 @@ To be used when ncall-conv is nil."))
         :documentation "t if rest argument is present."))
 
 (cl-defstruct (comp-block (:copier nil)
-                          (:constructor make--comp-block
-                                        (addr sp name))) ; Positional
-  "A basic block."
+                          (:constructor nil))
+  "A base class for basic blocks."
   (name nil :type symbol)
-  ;; These two slots are used during limplification.
-  (sp nil :type number
-      :documentation "When non nil indicates the sp value while entering
-into it.")
-  (addr nil :type number
-        :documentation "Start block LAP address.")
   (insns () :type list
          :documentation "List of instructions.")
   (closed nil :type boolean
@@ -309,6 +302,22 @@ into it.")
              :documentation "This is a copy of the frame when leaving the 
block.
 Is in use to help the SSA rename pass."))
 
+(cl-defstruct (comp-block-lap (:copier nil)
+                              (:include comp-block)
+                              (:constructor make--comp-block-lap
+                                            (addr sp name))) ; Positional
+  "A basic block created from lap."
+  ;; These two slots are used during limplification.
+  (sp nil :type number
+      :documentation "When non nil indicates the sp value while entering
+into it.")
+  (addr nil :type number
+        :documentation "Start block LAP address."))
+
+(cl-defstruct (comp-latch (:copier nil)
+                          (:include comp-block))
+  "A basic block for a latch loop.")
+
 (cl-defstruct (comp-edge (:copier nil) (:constructor make--comp-edge))
   "An edge connecting two basic blocks."
   (src nil :type comp-block)
@@ -751,20 +760,22 @@ Restore the original value afterwards."
 (defun comp-bb-maybe-add (lap-addr &optional sp)
   "If necessary create a pending basic block for LAP-ADDR with stack depth SP.
 The basic block is returned regardless it was already declared or not."
-  (let ((bb (or (cl-loop  ; See if the block was already liplified.
+  (let ((bb (or (cl-loop  ; See if the block was already limplified.
                  for bb being the hash-value in (comp-func-blocks comp-func)
-                 when (equal (comp-block-addr bb) lap-addr)
+                 when (and (comp-block-lap-p bb)
+                           (equal (comp-block-lap-addr bb) lap-addr))
                    return bb)
                 (cl-find-if (lambda (bb) ; Look within the pendings blocks.
-                              (= (comp-block-addr bb) lap-addr))
+                              (and (comp-block-lap-p bb)
+                                   (= (comp-block-lap-addr bb) lap-addr)))
                             (comp-limplify-pending-blocks comp-pass)))))
     (if bb
         (progn
-          (unless (or (null sp) (= sp (comp-block-sp bb)))
+          (unless (or (null sp) (= sp (comp-block-lap-sp bb)))
             (signal 'native-ice (list "incoherent stack pointers"
-                                      sp (comp-block-sp bb))))
+                                      sp (comp-block-lap-sp bb))))
           bb)
-      (car (push (make--comp-block lap-addr sp (comp-new-block-sym))
+      (car (push (make--comp-block-lap lap-addr sp (comp-new-block-sym))
                  (comp-limplify-pending-blocks comp-pass))))))
 
 (defsubst comp-call (func &rest args)
@@ -832,21 +843,44 @@ If DST-N is specified use it otherwise assume it to be 
the current slot."
 ENTRY-SP is the sp value when entering.
 The block is added to the current function.
 The block is returned."
-  (let ((bb (make--comp-block addr entry-sp block-name)))
+  (let ((bb (make--comp-block-lap addr entry-sp block-name)))
     (setf (comp-limplify-curr-block comp-pass) bb
           (comp-limplify-pc comp-pass) addr
-          (comp-limplify-sp comp-pass) (comp-block-sp bb))
+          (comp-limplify-sp comp-pass) (when (comp-block-lap-p bb)
+                                         (comp-block-lap-sp bb)))
     (puthash (comp-block-name bb) bb (comp-func-blocks comp-func))
     bb))
 
+(defun comp-latch-make-fill (target)
+  "Create a latch pointing to TARGET and fill it.
+Return the created latch"
+  (let ((latch (make-comp-latch :name (comp-new-block-sym "latch")))
+        (curr-bb (comp-limplify-curr-block comp-pass)))
+    ;; See `comp-make-curr-block'.
+    (setf (comp-limplify-curr-block comp-pass) latch)
+    (when (< comp-speed 3)
+      ;; At speed 3 the programmer is responsible to manually
+      ;; place `comp-maybe-gc-or-quit'.
+      (comp-emit '(call comp-maybe-gc-or-quit)))
+    ;; See `comp-emit-uncond-jump'.
+    (comp-emit `(jump ,(comp-block-name target)))
+    (comp-mark-curr-bb-closed)
+    (puthash (comp-block-name latch) latch (comp-func-blocks comp-func))
+    (setf (comp-limplify-curr-block comp-pass) curr-bb)
+    latch))
+
 (defun comp-emit-uncond-jump (lap-label)
   "Emit an unconditional branch to LAP-LABEL."
   (cl-destructuring-bind (label-num . stack-depth) lap-label
     (when stack-depth
       (cl-assert (= (1- stack-depth) (comp-sp))))
-    (let ((target (comp-bb-maybe-add (comp-label-to-addr label-num)
-                                     (comp-sp))))
-      (comp-emit `(jump ,(comp-block-name target)))
+    (let* ((target-addr (comp-label-to-addr label-num))
+           (target (comp-bb-maybe-add target-addr
+                                      (comp-sp)))
+           (latch (when (< target-addr (comp-limplify-pc comp-pass))
+                    (comp-latch-make-fill target)))
+           (eff-target-name (comp-block-name (or latch target))))
+      (comp-emit `(jump ,eff-target-name))
       (comp-mark-curr-bb-closed))))
 
 (defun comp-emit-cond-jump (a b target-offset lap-label negated)
@@ -859,13 +893,16 @@ Return value is the fall through block name."
     (let* ((bb (comp-block-name (comp-bb-maybe-add (1+ (comp-limplify-pc 
comp-pass))
                                                    (comp-sp)))) ; Fall through 
block.
            (target-sp (+ target-offset (comp-sp)))
-           (target (comp-block-name (comp-bb-maybe-add (comp-label-to-addr 
label-num)
-                                                       target-sp))))
+           (target-addr (comp-label-to-addr label-num))
+           (target (comp-bb-maybe-add target-addr target-sp))
+           (latch (when (< target-addr (comp-limplify-pc comp-pass))
+                    (comp-latch-make-fill target)))
+           (eff-target-name (comp-block-name (or latch target))))
       (when label-sp
         (cl-assert (= (1- label-sp) (+ target-offset (comp-sp)))))
       (comp-emit (if negated
-                    (list 'cond-jump a b target bb)
-                  (list 'cond-jump a b bb target)))
+                    (list 'cond-jump a b eff-target-name bb)
+                  (list 'cond-jump a b bb eff-target-name)))
       (comp-mark-curr-bb-closed)
       bb)))
 
@@ -878,7 +915,7 @@ Return value is the fall through block name."
                                           (comp-sp)))
            (handler-bb (comp-bb-maybe-add (comp-label-to-addr label-num)
                                           (1+ (comp-sp))))
-           (pop-bb (make--comp-block nil (comp-sp) (comp-new-block-sym))))
+           (pop-bb (make--comp-block-lap nil (comp-sp) (comp-new-block-sym))))
       (comp-emit (list 'push-handler
                        handler-type
                        (comp-slot+1)
@@ -904,9 +941,11 @@ Return value is the fall through block name."
                                                (comp-slot)
                                                (comp-slot+1))))))
 
-(defun comp-new-block-sym ()
-  "Return a unique symbol naming the next new basic block."
-  (intern (format "bb_%s" (funcall (comp-func-block-cnt-gen comp-func)))))
+(defun comp-new-block-sym (&optional postfix)
+  "Return a unique symbol postfixing POSTFIX naming the next new basic block."
+  (intern (format (if postfix "bb_%s_%s" "bb_%s")
+                  (funcall (comp-func-block-cnt-gen comp-func))
+                  postfix)))
 
 (defun comp-fill-label-h ()
   "Fill label-to-addr hash table for the current function."
@@ -948,9 +987,9 @@ Return value is the fall through block name."
         for ff-bb = (if last
                         (comp-bb-maybe-add (1+ (comp-limplify-pc comp-pass))
                                            (comp-sp))
-                      (make--comp-block nil
-                                        (comp-sp)
-                                        (comp-new-block-sym)))
+                      (make--comp-block-lap nil
+                                            (comp-sp)
+                                            (comp-new-block-sym)))
         for ff-bb-name = (comp-block-name ff-bb)
         if (eq test-func 'eq)
           do (comp-emit (list 'cond-jump var m-test ff-bb-name target-name))
@@ -1375,7 +1414,7 @@ into the C code forwarding the compilation unit."
                                :frame-size 1))
          (comp-func func)
          (comp-pass (make-comp-limplify
-                     :curr-block (make--comp-block -1 0 'top-level)
+                     :curr-block (make--comp-block-lap -1 0 'top-level)
                      :frame (comp-new-frame 1))))
     (comp-make-curr-block 'entry (comp-sp))
     (comp-emit-annotation (if for-late-load
@@ -1396,7 +1435,7 @@ into the C code forwarding the compilation unit."
   "Search for a block starting at ADDR into pending or limplified blocks."
   ;; FIXME Actually we could have another hash for this.
   (cl-flet ((pred (bb)
-              (equal (comp-block-addr bb) addr)))
+              (equal (comp-block-lap-addr bb) addr)))
     (if-let ((pending (cl-find-if #'pred
                                   (comp-limplify-pending-blocks comp-pass))))
         (comp-block-name pending)
@@ -1407,8 +1446,8 @@ into the C code forwarding the compilation unit."
 (defun comp-limplify-block (bb)
   "Limplify basic-block BB and add it to the current function."
   (setf (comp-limplify-curr-block comp-pass) bb
-        (comp-limplify-sp comp-pass) (comp-block-sp bb)
-        (comp-limplify-pc comp-pass) (comp-block-addr bb))
+        (comp-limplify-sp comp-pass) (comp-block-lap-sp bb)
+        (comp-limplify-pc comp-pass) (comp-block-lap-addr bb))
   (puthash (comp-block-name bb) bb (comp-func-blocks comp-func))
   (cl-loop
    for inst-cell on (nthcdr (comp-limplify-pc comp-pass)
@@ -1459,7 +1498,8 @@ into the C code forwarding the compilation unit."
     ;; Sanity check against block duplication.
     (cl-loop with addr-h = (make-hash-table)
              for bb being the hash-value in (comp-func-blocks func)
-             for addr = (comp-block-addr bb)
+             for addr = (when (comp-block-lap-p bb)
+                          (comp-block-lap-addr bb))
              when addr
                do (cl-assert (null (gethash addr addr-h)))
                   (puthash addr t addr-h))



reply via email to

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