Changeset 14726


Ignore:
Timestamp:
Apr 22, 2011, 9:26:45 PM (9 years ago)
Author:
gb
Message:

Acode optimizers for 2-arg +,-,*,/. Generalize acode constant-folding.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/compiler/nx2.lisp

    r14696 r14726  
    279279         seg vreg xfer forms))
    280280
    281 (defun acode-constant-fold-integer-binop (seg vreg xfer x y function)
    282   (let* ((const-x (acode-integer-form-p x))
    283          (const-y (acode-integer-form-p y))
    284          (result (and const-x const-y (ignore-errors (funcall function const-x const-y)))))
    285     (when result
    286       (backend-use-operator (if (nx1-target-fixnump result)
    287                               (%nx1-operator fixnum)
    288                               (%nx1-operator immediate))
    289                             seg
    290                             vreg
    291                             xfer
    292                             result)
    293       t)))
     281(defun backend-apply-acode (acode seg vreg xfer)
     282  (apply (svref (backend-p2-dispatch *target-backend*)
     283                (%ilogand (acode-operator acode) operator-id-mask))
     284         seg vreg xfer (acode-operands acode)))
     285
     286
     287
     288(defun acode-constant-fold-binop (seg vreg xfer x y function)
     289  (multiple-value-bind (x-p const-x) (acode-constant-p x)
     290    (when x-p
     291      (multiple-value-bind (y-p const-y) (acode-constant-p y)
     292        (when y-p
     293          (let* ((result (ignore-errors (funcall function const-x const-y))))
     294            (when result
     295              (backend-use-operator (if (nx1-target-fixnump result)
     296                                      (%nx1-operator fixnum)
     297                                      (%nx1-operator immediate))
     298                                    seg
     299                                    vreg
     300                                    xfer
     301                                    result)
     302              t)))))))
    294303
    295304;;; Return non-nil iff we can do something better than a subprim call
     
    393402(defun acode-optimize-logand2 (seg vreg xfer num1 num2 trust-decls &optional (result-type 'integer))
    394403  (declare (ignore result-type))        ;see below
    395   (or (acode-constant-fold-integer-binop seg vreg xfer num1 num2 'logand)
     404  (or (acode-constant-fold-binop seg vreg xfer num1 num2 'logand)
    396405      (let* ((unsigned-natural-type *nx-target-natural-type*)
    397406             (target-fixnum-type *nx-target-fixnum-type*))
     
    436445(defun acode-optimize-logior2 (seg vreg xfer num1 num2 trust-decls &optional (result-type 'integer))
    437446  (declare (ignorable result-type))
    438   (or (acode-constant-fold-integer-binop seg vreg xfer num1 num2 'logior)
     447  (or (acode-constant-fold-binop seg vreg xfer num1 num2 'logior)
    439448      (let* ((unsigned-natural-type *nx-target-natural-type*)
    440449             (target-fixnum-type *nx-target-fixnum-type*))
     
    475484(defun acode-optimize-logxor2 (seg vreg xfer num1 num2 trust-decls &optional (result-type 'integer))
    476485  (declare (ignorable result-type))
    477   (or (acode-constant-fold-integer-binop seg vreg xfer num1 num2 'logxor)
     486  (or (acode-constant-fold-binop seg vreg xfer num1 num2 'logxor)
    478487      (let* ((unsigned-natural-type *nx-target-natural-type*)
    479488             (target-fixnum-type *nx-target-fixnum-type*))
     
    511520               t)
    512521              (t nil)))))
     522
     523
     524
     525(defun acode-optimize-add2 (seg vreg xfer num1 num2 trust-decls &optional (result-type 'number))
     526  (declare (ignorable result-type))
     527  (or (acode-constant-fold-binop seg vreg xfer num1 num2 '+)
     528      (multiple-value-bind (num1 num2)
     529          (nx-binop-numeric-contagion num1 num2 trust-decls)
     530        (if (and (acode-form-typep num1 'double-float trust-decls)
     531                 (acode-form-typep num2 'double-float trust-decls))
     532          (progn
     533            (backend-use-operator (%nx1-operator %double-float+-2)
     534                                  seg
     535                                  vreg
     536                                  xfer
     537                                  num1
     538                                  num2)
     539            t)
     540          (if (and (acode-form-typep num1 'single-float trust-decls)
     541                   (acode-form-typep num2 'single-float trust-decls))
     542            (progn
     543              (backend-use-operator (%nx1-operator %short-float+-2)
     544                                    seg
     545                                    vreg
     546                                    xfer
     547                                    num1
     548                                    num2)
     549              t)
     550            (if (and (acode-form-typep num1 *nx-target-fixnum-type* trust-decls)
     551                     (acode-form-typep num2 *nx-target-fixnum-type* trust-decls))
     552              (progn
     553                (backend-use-operator (%nx1-operator %i+)
     554                                      seg
     555                                      vreg
     556                                      xfer
     557                                      num1
     558                                      num2
     559                                      t)
     560                t)))))))
     561
     562(defun acode-optimize-sub2 (seg vreg xfer num1 num2 trust-decls &optional (result-type 'number))
     563  (declare (ignorable result-type))
     564  (or (acode-constant-fold-binop seg vreg xfer num1 num2 '-)
     565      (multiple-value-bind (num1 num2)
     566          (nx-binop-numeric-contagion num1 num2 trust-decls)
     567        (if (and (acode-form-typep num1 'double-float trust-decls)
     568                 (acode-form-typep num2 'double-float trust-decls))
     569          (progn
     570            (backend-use-operator (%nx1-operator %double-float--2)
     571                                  seg
     572                                  vreg
     573                                  xfer
     574                                  num1
     575                                  num2)
     576            t)
     577          (if (and (acode-form-typep num1 'single-float trust-decls)
     578                   (acode-form-typep num2 'single-float trust-decls))
     579            (progn
     580              (backend-use-operator (%nx1-operator %short-float--2)
     581                                    seg
     582                                    vreg
     583                                    xfer
     584                                    num1
     585                                    num2)
     586              t)
     587            (if (and (acode-form-typep num1 *nx-target-fixnum-type* trust-decls)
     588                     (acode-form-typep num2 *nx-target-fixnum-type* trust-decls))
     589              (progn
     590                (backend-use-operator (%nx1-operator %i-)
     591                                      seg
     592                                      vreg
     593                                      xfer
     594                                      num1
     595                                      num2
     596                                      t)
     597                t)))))))
     598       
     599
     600       
     601(defun acode-optimize-mul2 (seg vreg xfer num1 num2 trust-decls &optional (result-type 'number))
     602  (declare (ignorable result-type))
     603  (or (acode-constant-fold-binop seg vreg xfer num1 num2 '*)
     604      (let* ((f1 (acode-fixnum-form-p num1)))
     605        (when f1
     606          (cond ((and (eql f1 1)
     607                      (acode-form-typep num2 'number trust-decls))
     608                 (backend-apply-acode num2 seg vreg xfer)
     609                 t)
     610                ((and (eql (logcount f1) 1)
     611                      (acode-form-typep num2 *nx-target-fixnum-type* trust-decls))
     612                 (backend-use-operator (%nx1-operator ash)
     613                                       seg
     614                                       vreg
     615                                       xfer
     616                                       num2
     617                                       (make-acode (%nx1-operator fixnum)
     618                                                   (1- (integer-length f1))))
     619                 t))))
     620      (let* ((f2 (acode-fixnum-form-p num2)))
     621        (when f2
     622          (cond ((and (eql f2 1)
     623                      (acode-form-typep num1 'number trust-decls))
     624                 (backend-apply-acode num1 seg vreg xfer)
     625                 t)
     626                ((and (eql (logcount f2) 1) (acode-form-typep num1 *nx-target-fixnum-type* trust-decls))
     627                 (backend-use-operator (%nx1-operator ash)
     628                                       seg
     629                                       vreg
     630                                       xfer
     631                                       num1
     632                                       (make-acode (%nx1-operator fixnum)
     633                                                   (1- (integer-length f2))))
     634                 t))))
     635      (multiple-value-bind (form1 form2)
     636          (nx-binop-numeric-contagion num1 num2 trust-decls)
     637        (if (and (acode-form-typep form1 'double-float trust-decls)
     638                 (acode-form-typep form2 'double-float trust-decls))
     639          (progn
     640            (backend-use-operator (%nx1-operator %double-float*-2)
     641                                  seg
     642                                  vreg
     643                                  xfer
     644                                  form1
     645                                  form2)
     646            t)
     647          (if (and (acode-form-typep form1 'single-float trust-decls)
     648                   (acode-form-typep form2 'single-float trust-decls))
     649            (progn
     650              (backend-use-operator (%nx1-operator %short-float*-2)
     651                                    seg
     652                                    vreg
     653                                    xfer
     654                                    form1
     655                                    form2)
     656              t))))))
     657
     658(defun acode-optimize-div2 (seg vreg xfer num1 num2 trust-decls &optional (result-type 'number))
     659  (declare (ignorable result-type))
     660  (or (acode-constant-fold-binop seg vreg xfer num1 num2 '/)
     661      (multiple-value-bind (num1 num2)
     662          (nx-binop-numeric-contagion num1 num2 trust-decls)
     663        (if (and (acode-form-typep num1 'double-float trust-decls)
     664                 (acode-form-typep num2 'double-float trust-decls))
     665          (progn
     666            (backend-use-operator (%nx1-operator %double-float/-2)
     667                                  seg
     668                                  vreg
     669                                  xfer
     670                                  num1
     671                                  num2)
     672            t)
     673          (if (and (acode-form-typep num1 'single-float trust-decls)
     674                   (acode-form-typep num2 'single-float trust-decls))
     675            (progn
     676              (backend-use-operator (%nx1-operator %short-float/-2)
     677                                    seg
     678                                    vreg
     679                                    xfer
     680                                    num1
     681                                    num2)
     682              t)
     683            (let* ((f2 (acode-fixnum-form-p num2))
     684                   (unwrapped (acode-unwrapped-form num1))
     685                   (f1 nil)
     686                   (f1/f2 nil))
     687              (if (and f2
     688                       (not (zerop f2))
     689                       (acode-p unwrapped)
     690                       (or (eq (acode-operator unwrapped) (%nx1-operator mul2))
     691                           (eq (acode-operator unwrapped) (%nx1-operator %i*)))
     692                       (setq f1 (acode-fixnum-form-p (cadr unwrapped)))
     693                       (typep (setq f1/f2 (/ f1 f2)) 'fixnum))
     694                (progn
     695                  (backend-use-operator (%nx1-operator mul2)
     696                                        seg
     697                                        vreg
     698                                        xfer
     699                                        (make-acode (%nx1-operator fixnum) f1/f2)
     700                                        (caddr unwrapped))
     701                  t))))))))
    513702                 
    514703               
Note: See TracChangeset for help on using the changeset viewer.