⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vm-tran.lisp

📁 开源跨平台Lisp编译器
💻 LISP
📖 第 1 页 / 共 3 页
字号:
;;;; implementation-dependent transforms;;;; This software is part of the SBCL system. See the README file for;;;; more information.;;;;;;;; This software is derived from the CMU CL system, which was;;;; written at Carnegie Mellon University and released into the;;;; public domain. The software is in the public domain and is;;;; provided with absolutely no warranty. See the COPYING and CREDITS;;;; files for more information.(in-package "SB!C");;; We need to define these predicates, since the TYPEP source;;; transform picks whichever predicate was defined last when there;;; are multiple predicates for equivalent types.(define-source-transform short-float-p (x) `(single-float-p ,x))#!-long-float(define-source-transform long-float-p (x) `(double-float-p ,x))(define-source-transform compiled-function-p (x)  #!-sb-eval  `(functionp ,x)  #!+sb-eval  (once-only ((x x))    `(and (functionp ,x)          (not (sb!eval:interpreted-function-p ,x)))))(define-source-transform char-int (x)  `(char-code ,x))(deftransform abs ((x) (rational))  '(if (< x 0) (- x) x));;; We don't want to clutter the bignum code.#!+(or x86 x86-64)(define-source-transform sb!bignum:%bignum-ref (bignum index)  ;; KLUDGE: We use TRULY-THE here because even though the bignum code  ;; is (currently) compiled with (SAFETY 0), the compiler insists on  ;; inserting CAST nodes to ensure that INDEX is of the correct type.  ;; These CAST nodes do not generate any type checks, but they do  ;; interfere with the operation of FOLD-INDEX-ADDRESSING, below.  ;; This scenario is a problem for the more user-visible case of  ;; folding as well.  --njf, 2006-12-01  `(sb!bignum:%bignum-ref-with-offset ,bignum                                      (truly-the bignum-index ,index) 0))#!+(or x86 x86-64)(defun fold-index-addressing (fun-name element-size lowtag data-offset                              index offset &optional setter-p)  (multiple-value-bind (func index-args) (extract-fun-args index '(+ -) 2)    (destructuring-bind (x constant) index-args      (declare (ignorable x))      (unless (constant-lvar-p constant)        (give-up-ir1-transform))      (let ((value (lvar-value constant)))        (unless (and (integerp value)                     (sb!vm::foldable-constant-offset-p                      element-size lowtag data-offset                      (funcall func value (lvar-value offset))))          (give-up-ir1-transform "constant is too large for inlining"))        (splice-fun-args index func 2)        `(lambda (thing index off1 off2 ,@(when setter-p                                            '(value)))           (,fun-name thing index (,func off2 off1) ,@(when setter-p                                                        '(value))))))))#!+(or x86 x86-64)(deftransform sb!bignum:%bignum-ref-with-offset    ((bignum index offset) * * :node node)  (fold-index-addressing 'sb!bignum:%bignum-ref-with-offset                         sb!vm:n-word-bits sb!vm:other-pointer-lowtag                         sb!vm:bignum-digits-offset                         index offset))#!+x86(progn(define-source-transform sb!kernel:%vector-raw-bits (thing index)  `(sb!kernel:%raw-bits-with-offset ,thing ,index 2))(define-source-transform sb!kernel:%raw-bits (thing index)  `(sb!kernel:%raw-bits-with-offset ,thing ,index 0))(define-source-transform sb!kernel:%set-vector-raw-bits (thing index value)  `(sb!kernel:%set-raw-bits-with-offset ,thing ,index 2 ,value))(define-source-transform sb!kernel:%set-raw-bits (thing index value)  `(sb!kernel:%set-raw-bits-with-offset ,thing ,index 0 ,value))(deftransform sb!kernel:%raw-bits-with-offset ((thing index offset) * * :node node)  (fold-index-addressing 'sb!kernel:%raw-bits-with-offset                         sb!vm:n-word-bits sb!vm:other-pointer-lowtag                         0 index offset))(deftransform sb!kernel:%set-raw-bits-with-offset ((thing index offset value) * *)  (fold-index-addressing 'sb!kernel:%set-raw-bits-with-offset                         sb!vm:n-word-bits sb!vm:other-pointer-lowtag                         0 index offset t))) ; PROGN;;; The layout is stored in slot 0.(define-source-transform %instance-layout (x)  `(truly-the layout (%instance-ref ,x 0)))(define-source-transform %set-instance-layout (x val)  `(%instance-set ,x 0 (the layout ,val)))(define-source-transform %funcallable-instance-layout (x)  `(truly-the layout (%funcallable-instance-info ,x 0)))(define-source-transform %set-funcallable-instance-layout (x val)  `(setf (%funcallable-instance-info ,x 0) (the layout ,val)));;;; character support;;; In our implementation there are really only BASE-CHARs.#+nil(define-source-transform characterp (obj)  `(base-char-p ,obj));;;; simplifying HAIRY-DATA-VECTOR-REF and HAIRY-DATA-VECTOR-SET(deftransform hairy-data-vector-ref ((string index) (simple-string t))  (let ((ctype (lvar-type string)))    (if (array-type-p ctype)        ;; the other transform will kick in, so that's OK        (give-up-ir1-transform)        `(etypecase string          ((simple-array character (*))           (data-vector-ref string index))          #!+sb-unicode          ((simple-array base-char (*))           (data-vector-ref string index))          ((simple-array nil (*))           (data-vector-ref string index))))))(deftransform hairy-data-vector-ref ((array index) (array t) *)  "avoid runtime dispatch on array element type"  (let ((element-ctype (extract-upgraded-element-type array))        (declared-element-ctype (extract-declared-element-type array)))    (declare (type ctype element-ctype))    (when (eq *wild-type* element-ctype)      (give-up-ir1-transform       "Upgraded element type of array is not known at compile time."))    ;; (The expansion here is basically a degenerate case of    ;; WITH-ARRAY-DATA. Since WITH-ARRAY-DATA is implemented as a    ;; macro, and macros aren't expanded in transform output, we have    ;; to hand-expand it ourselves.)    (let* ((element-type-specifier (type-specifier element-ctype)))      `(multiple-value-bind (array index)           (%data-vector-and-index array index)         (declare (type (simple-array ,element-type-specifier 1) array))         ,(let ((bare-form '(data-vector-ref array index)))            (if (type= element-ctype declared-element-ctype)                bare-form                `(the ,(type-specifier declared-element-ctype)                      ,bare-form)))))));;; Transform multi-dimensional array to one dimensional data vector;;; access.(deftransform data-vector-ref ((array index) (simple-array t))  (let ((array-type (lvar-type array)))    (unless (array-type-p array-type)      (give-up-ir1-transform))    (let ((dims (array-type-dimensions array-type)))      (when (or (atom dims) (= (length dims) 1))        (give-up-ir1-transform))      (let ((el-type (array-type-specialized-element-type array-type))            (total-size (if (member '* dims)                            '*                            (reduce #'* dims))))        `(data-vector-ref (truly-the (simple-array ,(type-specifier el-type)                                                   (,total-size))                                     (%array-data-vector array))                          index)))));;; Transform data vector access to a form that opens up optimization;;; opportunities. On platforms that support DATA-VECTOR-REF-WITH-OFFSET;;; DATA-VECTOR-REF is not supported at all.#!+(or x86 x86-64)(define-source-transform data-vector-ref (array index)  `(data-vector-ref-with-offset ,array ,index 0))#!+(or x86 x86-64)(deftransform data-vector-ref-with-offset ((array index offset))  (let ((array-type (lvar-type array)))    (when (or (not (array-type-p array-type))              (eql (array-type-specialized-element-type array-type)                   *wild-type*))      (give-up-ir1-transform))    ;; It shouldn't be possible to get here with anything but a non-complex    ;; vector.    (aver (not (array-type-complexp array-type)))    (let* ((element-type (type-specifier (array-type-specialized-element-type array-type)))           (saetp (find-saetp element-type)))      (when (< (sb!vm:saetp-n-bits saetp) sb!vm:n-byte-bits)        (give-up-ir1-transform))      (fold-index-addressing 'data-vector-ref-with-offset                             (sb!vm:saetp-n-bits saetp)                             sb!vm:other-pointer-lowtag                             sb!vm:vector-data-offset                             index offset))))(deftransform hairy-data-vector-set ((string index new-value)                                     (simple-string t t))  (let ((ctype (lvar-type string)))    (if (array-type-p ctype)        ;; the other transform will kick in, so that's OK        (give-up-ir1-transform)        `(etypecase string          ((simple-array character (*))           (data-vector-set string index new-value))          #!+sb-unicode          ((simple-array base-char (*))           (data-vector-set string index new-value))          ((simple-array nil (*))           (data-vector-set string index new-value))))))(deftransform hairy-data-vector-set ((array index new-value)                                     (array t t)                                     *)  "avoid runtime dispatch on array element type"  (let ((element-ctype (extract-upgraded-element-type array))        (declared-element-ctype (extract-declared-element-type array)))    (declare (type ctype element-ctype))    (when (eq *wild-type* element-ctype)      (give-up-ir1-transform       "Upgraded element type of array is not known at compile time."))    (let ((element-type-specifier (type-specifier element-ctype)))      `(multiple-value-bind (array index)           (%data-vector-and-index array index)         (declare (type (simple-array ,element-type-specifier 1) array)                  (type ,element-type-specifier new-value))         ,(if (type= element-ctype declared-element-ctype)              '(data-vector-set array index new-value)              `(truly-the ,(type-specifier declared-element-ctype)                 (data-vector-set array index                  (the ,(type-specifier declared-element-ctype)                       new-value))))))));;; Transform multi-dimensional array to one dimensional data vector;;; access.(deftransform data-vector-set ((array index new-value)                               (simple-array t t))  (let ((array-type (lvar-type array)))    (unless (array-type-p array-type)      (give-up-ir1-transform))    (let ((dims (array-type-dimensions array-type)))      (when (or (atom dims) (= (length dims) 1))        (give-up-ir1-transform))      (let ((el-type (array-type-specialized-element-type array-type))            (total-size (if (member '* dims)                            '*                            (reduce #'* dims))))        `(data-vector-set (truly-the (simple-array ,(type-specifier el-type)                                                   (,total-size))                                     (%array-data-vector array))                          index                          new-value)))))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -