X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Ftypetran.lisp;h=3117ce28b2a7c64d6687f9749c1593fef85e5180;hb=8a19c6876412b8ad1cf729297c2a373d63a0d0ec;hp=8e860f4ebbb9edcc9c1dd179e56b448906ab558b;hpb=204f2fa9771ad9e55718dc76205afec7d11b3011;p=sbcl.git diff --git a/src/compiler/typetran.lisp b/src/compiler/typetran.lisp index 8e860f4..3117ce2 100644 --- a/src/compiler/typetran.lisp +++ b/src/compiler/typetran.lisp @@ -12,9 +12,6 @@ ;;;; provided with absolutely no warranty. See the COPYING and CREDITS ;;;; files for more information. -;;; FIXME: Many of the functions in this file could probably be -;;; byte-compiled, since they're one-pass, cons-heavy code. - (in-package "SB!C") ;;;; type predicate translation @@ -80,7 +77,8 @@ ;;; Flush %TYPEP tests whose result is known at compile time. (deftransform %typep ((object type)) - (unless (constant-continuation-p type) (give-up-ir1-transform)) + (unless (constant-continuation-p type) + (give-up-ir1-transform)) (ir1-transform-type-predicate object (specifier-type (continuation-value type)))) @@ -89,7 +87,7 @@ ;;; whether the single argument is known to (not) be of the ;;; appropriate type, expanding to T or NIL as appropriate. (deftransform fold-type-predicate ((object) * * :node node :defun-only t) - (let ((ctype (gethash (leaf-name + (let ((ctype (gethash (leaf-source-name (ref-leaf (continuation-use (basic-combination-fun node)))) @@ -99,8 +97,7 @@ ;;; If FIND-CLASS is called on a constant class, locate the CLASS-CELL ;;; at load time. -(deftransform find-class ((name) ((constant-argument symbol)) * - :when :both) +(deftransform find-class ((name) ((constant-arg symbol)) *) (let* ((name (continuation-value name)) (cell (find-class-cell name))) `(or (class-cell-class ',cell) @@ -147,7 +144,7 @@ ;;;; ;;;; See also VM dependent transforms. -(def-source-transform atom (x) +(define-source-transform atom (x) `(not (consp ,x))) ;;;; TYPEP source transform @@ -273,8 +270,8 @@ (satisfies `(if (funcall #',(second spec) ,object) t nil)) ((not and) (once-only ((n-obj object)) - `(,(first spec) ,@(mapcar #'(lambda (x) - `(typep ,n-obj ',x)) + `(,(first spec) ,@(mapcar (lambda (x) + `(typep ,n-obj ',x)) (rest spec)))))))))) ;;; Do source transformation for TYPEP of a known union type. If a @@ -361,7 +358,7 @@ (res `(= (array-dimension ,obj ,i) ,dim))))) (res))))) -;;; If we can find a type predicate that tests for the type w/o +;;; If we can find a type predicate that tests for the type without ;;; dimensions, then use that predicate and test for dimensions. ;;; Otherwise, just do %TYPEP. (defun source-transform-array-typep (obj type) @@ -387,17 +384,7 @@ ;;; then we also check whether the layout for the object is invalid ;;; and signal an error if so. Otherwise, look up the indirect ;;; class-cell and call CLASS-CELL-TYPEP at runtime. -;;; -;;; KLUDGE: The :WHEN :BOTH option here is probably a suboptimal -;;; solution to the problem of %INSTANCE-TYPEP forms in byte compiled -;;; code; it'd probably be better just to have %INSTANCE-TYPEP forms -;;; never be generated in byte compiled code, or maybe to have a DEFUN -;;; %INSTANCE-TYPEP somewhere to handle them if they are. But it's not -;;; terribly important because mostly, %INSTANCE-TYPEP forms *aren't* -;;; generated in byte compiled code. (As of sbcl-0.6.5, they could -;;; sometimes be generated when byte compiling inline functions, but -;;; it's quite uncommon.) -- WHN 20000523 -(deftransform %instance-typep ((object spec) (* *) * :node node :when :both) +(deftransform %instance-typep ((object spec) (* *) * :node node) (aver (constant-continuation-p spec)) (let* ((spec (continuation-value spec)) (class (specifier-type spec)) @@ -459,6 +446,24 @@ (eq (svref (layout-inherits ,n-layout) ,depthoid) ',layout)))))))) + ((and layout (>= (layout-depthoid layout) 0)) + ;; hierarchical layout depths for other things (e.g. + ;; CONDITIONs) + (let ((depthoid (layout-depthoid layout)) + (n-layout (gensym)) + (n-inherits (gensym))) + `(and (,pred object) + (let ((,n-layout (,get-layout object))) + ,@(when (policy *lexenv* (>= safety speed)) + `((when (layout-invalid ,n-layout) + (%layout-invalid-error object ',layout)))) + (if (eq ,n-layout ',layout) + t + (let ((,n-inherits (layout-inherits ,n-layout))) + (declare (optimize (safety 0))) + (and (> (length ,n-inherits) ,depthoid) + (eq (svref ,n-inherits ,depthoid) + ',layout)))))))) (t (/noshow "default case -- ,PRED and CLASS-CELL-TYPEP") `(and (,pred object) @@ -478,11 +483,8 @@ ;;; If the type is TYPE= to a type that has a predicate, then expand ;;; to that predicate. Otherwise, we dispatch off of the type's type. ;;; These transformations can increase space, but it is hard to tell -;;; when, so we ignore policy and always do them. When byte-compiling, -;;; we only do transforms that have potential for control -;;; simplification. Instance type tests are converted to -;;; %INSTANCE-TYPEP to allow type propagation. -(def-source-transform typep (object spec) +;;; when, so we ignore policy and always do them. +(define-source-transform typep (object spec) ;; KLUDGE: It looks bad to only do this on explicitly quoted forms, ;; since that would overlook other kinds of constants. But it turns ;; out that the DEFTRANSFORM for TYPEP detects any constant @@ -504,74 +506,42 @@ (member-type `(member ,object ',(member-type-members type))) (args-type - (compiler-warning "illegal type specifier for TYPEP: ~S" - (cadr spec)) + (compiler-warn "illegal type specifier for TYPEP: ~S" + (cadr spec)) `(%typep ,object ,spec)) (t nil)) - (and (not (byte-compiling)) - (typecase type - (numeric-type - (source-transform-numeric-typep object type)) - (sb!xc:class - `(%instance-typep ,object ,spec)) - (array-type - (source-transform-array-typep object type)) - (cons-type - (source-transform-cons-typep object type)) - (t nil))) + (typecase type + (numeric-type + (source-transform-numeric-typep object type)) + (sb!xc:class + `(%instance-typep ,object ,spec)) + (array-type + (source-transform-array-typep object type)) + (cons-type + (source-transform-cons-typep object type)) + (t nil)) `(%typep ,object ,spec))) (values nil t))) ;;;; coercion -;;; old working version -(deftransform coerce ((x type) (* *) * :when :both) +(deftransform coerce ((x type) (* *) *) (unless (constant-continuation-p type) (give-up-ir1-transform)) (let ((tspec (specifier-type (continuation-value type)))) (if (csubtypep (continuation-type x) tspec) 'x + ;; Note: The THE here makes sure that specifiers like + ;; (SINGLE-FLOAT 0.0 1.0) can raise a TYPE-ERROR. `(the ,(continuation-value type) - ,(cond ((csubtypep tspec (specifier-type 'double-float)) - '(%double-float x)) - ;; FIXME: If LONG-FLOAT is to be supported, we - ;; need to pick it off here before falling through - ;; to %SINGLE-FLOAT. - ((csubtypep tspec (specifier-type 'float)) - '(%single-float x)) - (t - (give-up-ir1-transform))))))) + ,(cond + ((csubtypep tspec (specifier-type 'double-float)) + '(%double-float x)) + ;; FIXME: #!+long-float (t ,(error "LONG-FLOAT case needed")) + ((csubtypep tspec (specifier-type 'float)) + '(%single-float x)) + ((csubtypep tspec (specifier-type 'simple-vector)) + '(coerce-to-simple-vector x)) + (t + (give-up-ir1-transform))))))) -;;; KLUDGE: new broken version -- 20000504 -;;; FIXME: should be fixed or deleted -#+nil -(deftransform coerce ((x type) (* *) * :when :both) - (unless (constant-continuation-p type) - (give-up-ir1-transform)) - (let ((tspec (specifier-type (continuation-value type)))) - (if (csubtypep (continuation-type x) tspec) - 'x - `(if #+nil (typep x type) #-nil nil - x - (the ,(continuation-value type) - ,(cond ((csubtypep tspec (specifier-type 'double-float)) - '(%double-float x)) - ;; FIXME: If LONG-FLOAT is to be supported, - ;; we need to pick it off here before falling - ;; through to %SINGLE-FLOAT. - ((csubtypep tspec (specifier-type 'float)) - '(%single-float x)) - #+nil - ((csubtypep tspec (specifier-type 'list)) - '(coerce-to-list x)) - #+nil - ((csubtypep tspec (specifier-type 'string)) - '(coerce-to-simple-string x)) - #+nil - ((csubtypep tspec (specifier-type 'bit-vector)) - '(coerce-to-bit-vector x)) - #+nil - ((csubtypep tspec (specifier-type 'vector)) - '(coerce-to-vector x type)) - (t - (give-up-ir1-transform))))))))