~ chicken-core (chicken-5) 4650202a6e026e664c4d9ff4413f74f500b62a6e
commit 4650202a6e026e664c4d9ff4413f74f500b62a6e Author: felix <felix@call-with-current-continuation.org> AuthorDate: Wed Apr 6 04:41:03 2011 -0400 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Wed Apr 6 04:41:03 2011 -0400 slight generalization in specialization matching, types.db fixes diff --git a/scrutinizer.scm b/scrutinizer.scm index 023c5974..3d9f148c 100755 --- a/scrutinizer.scm +++ b/scrutinizer.scm @@ -88,7 +88,8 @@ (define specialization-statistics '()) (define (scrutinize node db complain specialize) - (let ((blist '())) + (let ((blist '()) + (safe-calls 0)) (define (constant-result lit) (cond ((string? lit) 'string) ((symbol? lit) 'symbol) @@ -110,13 +111,13 @@ ((char? lit) 'char) (else '*))) (define (global-result id loc) - (cond ((##sys#get id '##compiler#type) => + (cond ((variable-mark id '##compiler#type) => (lambda (a) (cond #| ((and (get db id 'assigned) ; remove assigned global from type db - (not (##sys#get id '##compiler#declared-type))) - (##sys#put! id '##compiler#type #f) + (not (variable-mark id '##compiler#declared-type))) + (mark-variable id '##compiler#type #f) '(*)) |# ((eq? a 'deprecated) @@ -143,7 +144,7 @@ (define (variable-result id e loc flow) (cond ((blist-type id flow)) ((and (get db id 'assigned) - (not (##sys#get id '##compiler#declared-type))) + (not (variable-mark id '##compiler#declared-type))) '(*)) ((assq id e) => (lambda (a) @@ -510,12 +511,12 @@ (let ((r (procedure-result-types ptype values-rest (cdr args)))) (d " result-types: ~a" r) (when specialize - ;;XXX we should check whether this is a standard- or extended bindng + ;;XXX we should check whether this is a standard- or extended binding (let ((pn (procedure-name ptype)) (op #f)) (when pn (cond ((and (fx= 1 nargs) - (##sys#get pn '##compiler#predicate)) => + (variable-mark pn '##compiler#predicate)) => (lambda (pt) (cond ((match-specialization (list pt) (cdr args)) (report @@ -537,7 +538,7 @@ node `(let ((#:tmp #(1))) '#f)) (set! op (list pt `(not ,pt))))))) - ((##sys#get pn '##compiler#specializations) => + ((variable-mark pn '##compiler#specializations) => (lambda (specs) (for-each (lambda (spec) @@ -551,7 +552,10 @@ (else (set! specialization-statistics (cons (cons op 1) - specialization-statistics)))))))) + specialization-statistics)))))) + (when (and (not op) (procedure-type? ptype)) + (set-car! (node-parameters node) #t) + (set! safe-calls (add1 safe-calls))))) r)))) (define (procedure-type? t) (or (eq? 'procedure t) @@ -696,7 +700,7 @@ r)))))))) ((set! ##core#set!) (let* ((var (first params)) - (type (##sys#get var '##compiler#type)) + (type (variable-mark var '##compiler#type)) (rt (single (sprintf "in assignment to `~a'" var) (walk (first subs) e loc var #f flow #f) @@ -713,6 +717,8 @@ #t)) (when (and b (eq? 'undefined (cdr b))) (set-cdr! b rt)) + ;;XXX we could set the ##compiler#type property here for hidden + ;; globals that are only assigned once (when b (set! blist (alist-cons (cons var (car flow)) rt blist))) '(undefined))) @@ -733,8 +739,8 @@ (iota len))) (fn (car args)) (pn (procedure-name fn)) - (enforces (and pn (##sys#get pn '##compiler#enforce-argument-types))) - (pt (and pn (##sys#get pn '##compiler#predicate)))) + (enforces (and pn (variable-mark pn '##compiler#enforce-argument-types))) + (pt (and pn (variable-mark pn '##compiler#predicate)))) (let ((r (call-result n args e loc params))) (invalidate-blist) (for-each @@ -785,6 +791,8 @@ (lambda (ss) (printf " ~a ~s~%" (cdr ss) (car ss))) specialization-statistics)) + (when (positive? safe-calls) + (debugging 'x "safe calls" safe-calls)) rn))) (define (load-type-database name #!optional (path (repository-path))) @@ -794,23 +802,28 @@ (for-each (lambda (e) (cond ((eq? 'predicate (car e)) - (##sys#put! (cadr e) '##compiler#predicate (caddr e))) + (mark-variable (cadr e) '##compiler#predicate (caddr e))) (else (let* ((name (car e)) - (old (##sys#get name '##compiler#type)) + (old (variable-mark name '##compiler#type)) (new (cadr e)) (specs (and (pair? (cddr e)) (cddr e)))) (when (and (pair? new) (eq? 'procedure! (car new))) - (##sys#put! name '##compiler#enforce-argument-types #t) + (mark-variable name '##compiler#enforce-argument-types #t) (set-car! new 'procedure)) + (cond-expand + (debugbuild + (unless (validate-type new name) + (warning "invalid type specification" name new))) + (else)) (when (and old (not (equal? old new))) (##sys#notice (sprintf "type-definition `~a' for toplevel binding `~a' conflicts with previously loaded type `~a'" name new old))) - (##sys#put! name '##compiler#type new) + (mark-variable name '##compiler#type new) (when specs - (##sys#put! name '##compiler#specializations specs)))))) + (mark-variable name '##compiler#specializations specs)))))) (read-file dbfile)))) (define (match-specialization typelist atypes) @@ -828,11 +841,19 @@ ((and) (every (cut match <> t) (cdr st))) (else (equal? st t)))) ((eq? st '*)) + ((eq? st 'list) (match '(or null pair) t)) + ((eq? st 'number) (match '(or fixnum float) t)) + ((eq? t 'list) (match st '(or null pair))) + ((eq? t 'number) (match st '(or fixnum float))) ((eq? st 'procedure) (or (eq? t 'procedure) - (and (pair? t) (eq? 'procedure (car t))))) - ;;XXX match number with fixnum and float? - (else #f))) + (and (pair? t) (eq? 'procedure (car t))))) ; doesn't match argument/result types + ((pair? t) + (case (car t) + ((or) (every (cut match st <>) (cdr t))) ; must match every option + ((and) #f) ; should not happen... + (else (equal? st t)))) + (else (equal? st t)))) (let loop ((tl typelist) (atypes atypes)) (cond ((null? tl) (null? atypes)) ((null? atypes) #f) @@ -872,16 +893,19 @@ ((symbol? llist) '(#!rest *)) ((not (pair? llist)) #f) ((eq? '#!optional (car llist)) - (cons '#!optional (validate-llist (cdr llist)))) + (let ((l1 (validate-llist (cdr llist)))) + (and l1 (cons '#!optional l1)))) ((eq? '#!rest (car llist)) (cond ((null? (cdr llist)) '(#!rest *)) ((not (pair? (cdr llist))) #f) - ((and (pair? (cddr llist)) - (eq? '#!key (caddr llist))) - `(#!rest ,(validate (cadr llist)))) - (else #f))) + (else + (let ((l1 (validate (cadr llist)))) + (and l1 `(#!rest ,l1)))))) ((eq? '#!key (car llist)) '(#!rest *)) - (else (cons (validate (car llist)) (validate-llist (cdr llist)))))) + (else + (let* ((l1 (validate (car llist))) + (l2 (validate-llist (cdr llist)))) + (and l1 l2 (cons l1 l2)))))) (define (validate t) (cond ((memq t '(* string symbol char number boolean list pair procedure vector null eof undefined port blob diff --git a/support.scm b/support.scm index 61d10df9..ab0295b7 100644 --- a/support.scm +++ b/support.scm @@ -569,7 +569,10 @@ '##core#lambda) (third params) (walk (car subs)) ) ) - ((##core#call) (map walk subs)) + ((##core#call) + (if (first params) + `(##core#app ,@(map walk subs)) + (map walk subs))) ((##core#callunit) (cons* '##core#callunit (car params) (map walk subs))) ((##core#undefined) (list class)) ((##core#bind) diff --git a/types.db b/types.db index e92875f1..d73a3c04 100644 --- a/types.db +++ b/types.db @@ -48,16 +48,15 @@ (eq? (procedure eq? (* *) boolean)) (eqv? (procedure eqv? (* *) boolean) - (((and (not number) (not float)) *) (eq? #(1) #(2))) - ((* (and (not number) (not float))) (eq? #(1) #(2)))) + (((not float) *) (eq? #(1) #(2))) + ((* (not float)) (eq? #(1) #(2)))) (equal? (procedure equal? (* *) boolean) (((or fixnum symbol char eof null undefined) *) (eq? #(1) #(2))) ((* (or fixnum symbol char eof null undefined) (eq? #(1) #(2))))) -(pair? (procedure pair? (*) boolean) - ((pair) (let ((#:tmp #(1))) '#t)) - (((and (not pair) (not list))) (let ((#:tmp #(1))) '#f))) +(pair? (procedure pair? (*) boolean)) +(predicate pair? pair) (cons (procedure cons (* *) pair)) @@ -96,19 +95,17 @@ (set-car! (procedure! set-car! (pair *) undefined) ((pair *) (##sys#setslot #(1) '0 #(2)))) (set-cdr! (procedure! set-cdr! (pair *) undefined) ((pair *) (##sys#setslot #(1) '1 #(2)))) -(null? (procedure null? (*) boolean) - ((null) (let ((#:tmp #(1))) '#t)) - (((and (not list) (not null))) (let ((#:tmp #(1))) '#f))) - -(list? (procedure list? (*) boolean) - (((or null pair list)) (let ((#:tmp #(1))) '#t)) - (((not (or null pair list))) (let ((#:tmp #(1))) '#f))) +(null? (procedure null? (*) boolean)) +(predicate null? null) + +(list? (procedure list? (*) boolean)) +(predicate list? list) (list (procedure list (#!rest) list)) (length (procedure! length (list) fixnum) ((list) (##core#inline "C_u_i_length" #(1)))) (list-tail (procedure! list-tail (list fixnum) *)) (list-ref (procedure! list-ref (list fixnum) *)) -(append (procedure append (list #!rest) list)) +(append (procedure append (list #!rest) *)) (reverse (procedure! reverse (list) list)) (memq (procedure memq (* list) *) ((* list) (##core#inline "C_u_i_memq" #(1) #(2)))) (memv (procedure memv (* list) *)) @@ -124,28 +121,24 @@ (symbol->string (procedure! symbol->string (symbol) string)) (string->symbol (procedure! string->symbol (string) symbol)) -(number? (procedure number? (*) boolean) - (((or fixnum float number)) (let ((#:tmp #(1))) '#t)) - (((not (or fixnum float number)) (let ((#:tmp #(1))) '#f)))) +(number? (procedure number? (*) boolean)) +(predicate number? number) (integer? (procedure integer? (*) boolean) ((fixnum) (let ((#:tmp #(1))) '#t)) ((float) (##core#inline "C_u_i_fpintegerp" #(1)))) -(exact? (procedure exact? (*) boolean) - ((fixnum) (let ((#:tmp #(1))) '#t)) - ((float) (let ((#:tmp #(1))) '#f))) +(exact? (procedure exact? (*) boolean)) +(predicate exact? fixnum) -(real? (procedure real? (*) boolean) - (((or fixnum float number)) (let ((#:tmp #(1))) '#t))) +(real? (procedure real? (*) boolean)) +(predicate real? number) -(complex? (procedure complex? (*) boolean) - (((or fixnum float number)) (let ((#:tmp #(1))) '#t)) - (((not (or fixnum float number))) (let ((#:tmp #(1))) '#f))) +(complex? (procedure complex? (*) boolean)) +(predicate complex? number) -(inexact? (procedure inexact? (*) boolean) - ((fixnum) (let ((#:tmp #(1))) '#f)) - ((float) (let ((#:tmp #(1))) '#t))) +(inexact? (procedure inexact? (*) boolean)) +(predicate inexact? float) (rational? (procedure rational? (*) boolean) ((fixnum) (let ((#:tmp #(1))) '#t))) @@ -975,7 +968,7 @@ (irregex-flags (procedure! irregex-flags ((struct regexp)) *) (((struct regexp)) (##sys#slot #(1) '5))) -(irregex-fold (procedure! irregex-fold (* (procedure (fixnum (struct regexp-match)) *) * string #!optional (procedure! (fixnum *) *) fixnum fixnum) *)) +(irregex-fold (procedure! irregex-fold (* (procedure (fixnum (struct regexp-match)) *) * string #!optional (procedure (fixnum *) *) fixnum fixnum) *)) (irregex-fold/chunked (procedure! irregex-fold/chunked (* (procedure (fixnum (struct regexp-match)) *) * procedure * #!optional (procedure (fixnum *) *) fixnum fixnum) *)) (irregex-lengths (procedure! irregex-lengths ((struct regexp)) *) @@ -1790,7 +1783,7 @@ (blob->f64vector/shared (procedure! blob->f64vector/shared (blob) (struct f64vector))) (blob->s16vector (procedure! blob->s16vector (blob) (struct s16vector))) (blob->s16vector/shared (procedure! blob->s16vector/shared (blob) (struct s16vector))) -(blob->s32vector (procedure! blob->s32vector (blob) (strucrt s32vector))) +(blob->s32vector (procedure! blob->s32vector (blob) (struct s32vector))) (blob->s32vector/shared (procedure! blob->s32vector/shared (blob) (struct s32vector))) (blob->s8vector (procedure! blob->s8vector (blob) (struct u8vector))) (blob->s8vector/shared (procedure! blob->s8vector/shared (blob) (struct u8vector)))Trap