Changeset 15411


Ignore:
Timestamp:
Jun 11, 2012, 5:12:21 PM (7 years ago)
Author:
gb
Message:

The time/space tradeoffs between emitting a function return sequence and
branching to such a sequence are different on x86 than on other platforms.
(A 5-byte conditional branch or jmp can be larger than the return sequence;
how large the return sequence is depends on how many NVRs are restored and
on how they're restored.

Use x862-fold-popj to better approximate the costs involved in these tradeoffs.

We try to handle the fixnum-operands cases of some arithmetic and
logical operations inline; if the operations can be done tail-recursively,
try to do so.

Location:
trunk/source/compiler/X86
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/compiler/X86/X8632/x8632-vinsns.lisp

    r15347 r15411  
    12601260  (jmp lab))
    12611261
     1262(define-x8632-vinsn return-or-fix-overflow (()
     1263                                            ())
     1264  (jo :fix)
     1265  (:byte #xf3) (ret)
     1266  :fix
     1267  (jmp (:@ .SPfix-overflow)))
    12621268
    12631269(define-x8632-vinsn add-constant (((dest :imm))
  • trunk/source/compiler/X86/X8664/x8664-vinsns.lisp

    r15347 r15411  
    13911391   (movq (:%q x8664::arg_z) (:%q val)))
    13921392  (jmp lab))
     1393
     1394(define-x8664-vinsn return-or-fix-overflow (()
     1395                                            ())
     1396  (jo :fix)
     1397  (:byte #xf3) (ret)
     1398  :fix
     1399  (jmp (:@ .SPfix-overflow)))
    13931400
    13941401(define-x8664-vinsn add-constant (((dest :imm))
  • trunk/source/compiler/X86/x862.lisp

    r15380 r15411  
    57495749         (label nil)
    57505750         (vstack nil)
    5751          (foldp (not *x862-open-code-inline*)))
     5751         (foldp (x862-fold-popj)))
    57525752    (if (%izerop mask) (setq mask nil))
    57535753    (with-x86-local-vinsn-macros (seg)
     
    60836083       (eq 0 *x862-undo-count*)))
    60846084
    6085 (defun x862-mv-p (cd)
     6085;;; on x86, branching to a shared exit point can sometimes be
     6086;;; larger than simply exiting, but it's hard to know that in
     6087;;; advance.  If the exit point involves restoring nvrs, then
     6088;;; it's likely that branching will be smaller.
     6089(defun x862-fold-popj ()
     6090  (unless *x862-open-code-inline* ;  never fold if speed>space
     6091    *x862-register-restore-ea*))  ;  fold if we'll need to restore nvrs.
     6092 
     6093
     6094(defun x862-mv-p (cd)
    60866095  (or (eq cd $backend-return) (x862-mvpass-p cd)))
    60876096
     
    77537762                 (falselabel (backend-get-next-label))
    77547763                 (need-else (unless false-is-goto (or (not (nx-null false)) (x862-for-value-p vreg))))
    7755                  (both-single-valued (and (not *x862-open-code-inline*)
     7764                 (both-single-valued (and (x862-fold-popj)
    77567765                                          (eq xfer $backend-return)
    77577766                                          (x862-for-value-p vreg)
     
    79277936
    79287937(defun x862-inline-sub2 (seg vreg xfer form1 form2)
    7929   (let* ((v2 (acode-fixnum-form-p form2)))
     7938  (let* ((v2 (acode-fixnum-form-p form2))
     7939         (tailp (and (x862-tailcallok xfer) (not (x862-fold-popj)))))
    79307940    (if (and v2 (not (eql v2 most-negative-fixnum)))
    79317941      (x862-inline-add2 seg vreg xfer form1 (make-acode (%nx1-operator fixnum) (- v2)))
    79327942      (with-x86-local-vinsn-macros (seg vreg xfer)
    79337943        (x862-two-targeted-reg-forms seg form1 ($ *x862-arg-y*) form2 ($ *x862-arg-z*))
     7944        (when tailp
     7945        (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* t)
     7946        (! restore-full-lisp-context))
    79347947    (let* ((out-of-line (backend-get-next-label))
    79357948           (done (backend-get-next-label)))
     
    79417954            (! branch-unless-both-args-fixnums ($ *x862-arg-y*) ($ *x862-arg-z*) (aref *backend-labels* out-of-line))))
    79427955        (! fixnum-sub2 ($ *x862-arg-z*) ($ *x862-arg-y*) ($ *x862-arg-z*))
    7943         (x862-check-fixnum-overflow seg ($ *x862-arg-z*) done)
     7956        (if tailp
     7957          (! return-or-fix-overflow)
     7958          (x862-check-fixnum-overflow seg ($ *x862-arg-z*) done))
    79447959        (@ out-of-line)
     7960        (if tailp
     7961          (! jump-subprim (subprim-name->offset '.SPbuiltin-minus))
     7962          (progn
    79457963        (! call-subprim-2 ($ *x862-arg-z*) (subprim-name->offset '.SPbuiltin-minus) ($ *x862-arg-y*) ($ *x862-arg-z*))
    79467964        (@ done)
    7947         (x862-copy-register seg target ($ *x862-arg-z*)))
    7948       (^))))))
     7965        (x862-copy-register seg target ($ *x862-arg-z*)))))
     7966      (unless tailp
     7967        (^)))))))
    79497968
    79507969(defun x862-inline-add2 (seg vreg xfer form1 form2)
     
    79577976                        form2
    79587977                        (if fix2
    7959                           form1))))
     7978                          form1)))
     7979           (tailp (and (x862-tailcallok xfer) (not (x862-fold-popj)))))
    79607980      (if otherform
    79617981        (x862-one-targeted-reg-form seg otherform ($ *x862-arg-z*))
    79627982        (x862-two-targeted-reg-forms seg form1 ($ *x862-arg-y*) form2 ($ *x862-arg-z*)))
     7983      (when tailp
     7984        (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* t)
     7985        (! restore-full-lisp-context))
    79637986      (let* ((out-of-line (backend-get-next-label))
    79647987             (done (backend-get-next-label)))
     
    79757998            (! add-constant ($ *x862-arg-z*) (ash (or fix1 fix2) *x862-target-fixnum-shift*))
    79767999            (! fixnum-add2 ($ *x862-arg-z*) ($ *x862-arg-y*)))
    7977           (x862-check-fixnum-overflow seg ($ *x862-arg-z*) done)
     8000          (if tailp
     8001            (! return-or-fix-overflow)
     8002            (x862-check-fixnum-overflow seg ($ *x862-arg-z*) done))
    79788003          (@ out-of-line)
    79798004          (if otherform
    79808005            (x862-lri seg ($ *x862-arg-y*) (ash (or fix1 fix2) *x862-target-fixnum-shift*)))
    7981           (! call-subprim-2 ($ *x862-arg-z*) (subprim-name->offset '.SPbuiltin-plus) ($ *x862-arg-y*) ($ *x862-arg-z*))
    7982           (@ done)
    7983           (x862-copy-register seg target ($ *x862-arg-z*)))
    7984         (^)))))
     8006          (if tailp
     8007            (! jump-subprim (subprim-name->offset '.SPbuiltin-plus))
     8008            (progn
     8009              (! call-subprim-2 ($ *x862-arg-z*) (subprim-name->offset '.SPbuiltin-plus) ($ *x862-arg-y*) ($ *x862-arg-z*))
     8010              (@ done)
     8011              (x862-copy-register seg target ($ *x862-arg-z*)))))
     8012        (unless tailp
     8013          (^))))))
    79858014           
    79868015(defx862 x862-add2 add2 (seg vreg xfer form1 form2)
     
    80188047               (fiximm (if fixval (<= (integer-length fixval)
    80198048                                      (- 31 *x862-target-fixnum-shift*))))
    8020                (otherform (when fiximm (if fix1 form2 form1))))
     8049               (otherform (when fiximm (if fix1 form2 form1)))
     8050               (tailp (and (x862-tailcallok xfer) (not (x862-fold-popj)))))
    80218051          (let* ((out-of-line (backend-get-next-label))
    80228052                 (done (backend-get-next-label)))
     
    80258055                (x862-one-targeted-reg-form seg otherform ($ *x862-arg-z*))
    80268056                (x862-two-targeted-reg-forms seg form1 ($ *x862-arg-y*) form2 ($ *x862-arg-z*)))
     8057              (when tailp
     8058                (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* t)
     8059                (! restore-full-lisp-context))
    80278060              (if otherform
    80288061                (unless (acode-fixnum-form-p otherform)
     
    80368069                (! %logior-c ($ *x862-arg-z*) ($ *x862-arg-z*) (ash fixval *x862-target-fixnum-shift*))
    80378070                (! %logior2 ($ *x862-arg-z*) ($ *x862-arg-z*) ($ *x862-arg-y*)))
    8038               (-> done)
     8071              (if tailp
     8072                (! jump-return-pc)
     8073                (-> done))
    80398074              (@ out-of-line)
    80408075              (if otherform
    80418076                (x862-lri seg ($ *x862-arg-y*) (ash fixval *x862-target-fixnum-shift*)))
    8042               (! call-subprim-2 ($ *x862-arg-z*) (subprim-name->offset '.SPbuiltin-logior) ($ *x862-arg-y*) ($ *x862-arg-z*))
    8043               (@ done)
    8044               (x862-copy-register seg target ($ *x862-arg-z*)))
    8045             (^)))))))
     8077              (if tailp
     8078                (! jump-subprim (subprim-name->offset '.SPbuiltin-logior))
     8079                (progn
     8080                  (! call-subprim-2 ($ *x862-arg-z*) (subprim-name->offset '.SPbuiltin-logior) ($ *x862-arg-y*) ($ *x862-arg-z*))
     8081                  (@ done)
     8082                  (x862-copy-register seg target ($ *x862-arg-z*)))))
     8083            (unless tailp
     8084              (^))))))))
    80468085
    80478086(defx862 x862-logior2 logior2 (seg vreg xfer form1 form2)
     
    80658104               (fiximm (if fixval (<= (integer-length fixval)
    80668105                                      (- 31 *x862-target-fixnum-shift*))))
    8067                (otherform (when fiximm (if fix1 form2 form1))))
     8106               (otherform (when fiximm (if fix1 form2 form1)))
     8107               (tailp (and (x862-tailcallok xfer) (not (x862-fold-popj)))))
    80688108          (let* ((out-of-line (backend-get-next-label))
    80698109                 (done (backend-get-next-label)))
     
    80728112                (x862-one-targeted-reg-form seg otherform ($ *x862-arg-z*))
    80738113                (x862-two-targeted-reg-forms seg form1 ($ *x862-arg-y*) form2 ($ *x862-arg-z*)))
     8114              (when tailp
     8115                (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* t)
     8116                (! restore-full-lisp-context))
    80748117              (if otherform
    80758118                (unless (acode-fixnum-form-p otherform)
     
    80838126                (! %logand-c ($ *x862-arg-z*) ($ *x862-arg-z*) (ash fixval *x862-target-fixnum-shift*))
    80848127                (! %logand2 ($ *x862-arg-z*) ($ *x862-arg-z*) ($ *x862-arg-y*)))
    8085               (-> done)
     8128              (if tailp
     8129                (! jump-return-pc)
     8130                (-> done))
    80868131              (@ out-of-line)
    80878132              (if otherform
    80888133                (x862-lri seg ($ *x862-arg-y*) (ash fixval *x862-target-fixnum-shift*)))
    8089               (! call-subprim-2 ($ *x862-arg-z*) (subprim-name->offset '.SPbuiltin-logand) ($ *x862-arg-y*) ($ *x862-arg-z*))
    8090               (@ done)
    8091               (x862-copy-register seg target ($ *x862-arg-z*)))
    8092             (^)))))))
     8134              (if tailp
     8135                (! jump-subprim (subprim-name->offset '.SPbuiltin-logand))
     8136                (progn
     8137                  (! call-subprim-2 ($ *x862-arg-z*) (subprim-name->offset '.SPbuiltin-logand) ($ *x862-arg-y*) ($ *x862-arg-z*))
     8138                  (@ done)
     8139                  (x862-copy-register seg target ($ *x862-arg-z*)))))
     8140              (^)))))))
    80938141
    80948142(defx862 x862-logand2 logand2 (seg vreg xfer form1 form2)
Note: See TracChangeset for help on using the changeset viewer.