X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Ftypetran.lisp;h=b6c1a8ffe310c7c56d7882c645219b70d4ddeac0;hb=0e3c4b4db102bd204a30402d7e5a0de44aea57ce;hp=8733eb43f5b486b27c17818fd33b5eb641d17c37;hpb=953e2961a4e0f130d67da600d1c965d6794a8984;p=sbcl.git diff --git a/src/compiler/typetran.lisp b/src/compiler/typetran.lisp index 8733eb4..b6c1a8f 100644 --- a/src/compiler/typetran.lisp +++ b/src/compiler/typetran.lisp @@ -132,6 +132,35 @@ `(or (classoid-cell-classoid ',cell) (error "class not yet defined: ~S" name)))) +(defoptimizer (%typep-wrapper constraint-propagate-if) + ((test-value variable type) node gen) + (aver (constant-lvar-p type)) + (let ((type (lvar-value type))) + (values variable (if (ctype-p type) + type + (handler-case (careful-specifier-type type) + (t () nil)))))) + +(deftransform %typep-wrapper ((test-value variable type) * * :node node) + (aver (constant-lvar-p type)) + (if (constant-lvar-p test-value) + `',(lvar-value test-value) + (let* ((type (lvar-value type)) + (type (if (ctype-p type) + type + (handler-case (careful-specifier-type type) + (t () nil)))) + (value-type (lvar-type variable))) + (cond ((not type) + 'test-value) + ((csubtypep value-type type) + t) + ((not (types-equal-or-intersect value-type type)) + nil) + (t + (delay-ir1-transform node :constraint) + 'test-value))))) + ;;;; standard type predicates, i.e. those defined in package COMMON-LISP, ;;;; plus at least one oddball (%INSTANCEP) ;;;; @@ -514,13 +543,8 @@ ((and (eq (classoid-state class) :sealed) layout (not (classoid-subclasses class))) ;; Sealed and has no subclasses. - (let ((n-layout (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)))) - (eq ,n-layout ',layout))))) + `(and (,pred object) + (eq (,get-layout object) ',layout))) ((and (typep class 'structure-classoid) layout) ;; structure type tests; hierarchical layout depths (let ((depthoid (layout-depthoid layout)) @@ -590,11 +614,11 @@ ;;; 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. -(defun source-transform-typep (object type) +(defun %source-transform-typep (object type) (let ((ctype (careful-specifier-type type))) (or (when (not ctype) (compiler-warn "illegal type specifier for TYPEP: ~S" type) - (return-from source-transform-typep (values nil t))) + (return-from %source-transform-typep (values nil t))) (multiple-value-bind (constantp value) (type-singleton-p ctype) (and constantp `(eql ,object ',value))) @@ -614,7 +638,7 @@ `(if (member ,object ',(member-type-members ctype)) t)) (args-type (compiler-warn "illegal type specifier for TYPEP: ~S" type) - (return-from source-transform-typep (values nil t))) + (return-from %source-transform-typep (values nil t))) (t nil)) (typecase ctype (numeric-type @@ -633,6 +657,15 @@ (t nil)) `(%typep ,object ',type)))) +(defun source-transform-typep (object type) + (let ((name (gensym "OBJECT"))) + (multiple-value-bind (transform error) + (%source-transform-typep name type) + (if error + (values nil t) + (values `(let ((,name ,object)) + (%typep-wrapper ,transform ,name ',type))))))) + (define-source-transform typep (object spec &optional env) ;; KLUDGE: It looks bad to only do this on explicitly quoted forms, ;; since that would overlook other kinds of constants. But it turns