WIP on tag analysis, annotations, and utilization.
This commit is contained in:
		
							parent
							
								
									d73dfd1287
								
							
						
					
					
						commit
						579b823f44
					
				|  | @ -24,7 +24,8 @@ EXTRA_DIST=ikarus.boot.prebuilt ikarus.enumerations.ss \ | |||
|   psyntax.internal.ss psyntax.library-manager.ss \
 | ||||
|   unicode/unicode-char-cases.ss unicode/unicode-charinfo.ss \
 | ||||
|   ikarus.io.ss ikarus.time-and-date.ss ikarus.not-yet-implemented.ss \
 | ||||
|   ikarus.string-to-number.ss ikarus.compiler.source-optimizer.ss | ||||
|   ikarus.string-to-number.ss ikarus.compiler.source-optimizer.ss \
 | ||||
|   ikarus.compiler.tag-annotation-analysis.ss ikarus.ontology.ss | ||||
|   | ||||
| all: $(nodist_pkglib_DATA) | ||||
| 
 | ||||
|  |  | |||
|  | @ -178,7 +178,8 @@ EXTRA_DIST = ikarus.boot.prebuilt ikarus.enumerations.ss \ | |||
|   psyntax.internal.ss psyntax.library-manager.ss \
 | ||||
|   unicode/unicode-char-cases.ss unicode/unicode-charinfo.ss \
 | ||||
|   ikarus.io.ss ikarus.time-and-date.ss ikarus.not-yet-implemented.ss \
 | ||||
|   ikarus.string-to-number.ss ikarus.compiler.source-optimizer.ss | ||||
|   ikarus.string-to-number.ss ikarus.compiler.source-optimizer.ss \
 | ||||
|   ikarus.compiler.tag-annotation-analysis.ss ikarus.ontology.ss | ||||
| 
 | ||||
| revno = "$(shell sed 's/ .*//' ../.bzr/branch/last-revision 2>/dev/null)" | ||||
| CLEANFILES = $(nodist_pkglib_DATA) ikarus.config.ss | ||||
|  |  | |||
										
											Binary file not shown.
										
									
								
							|  | @ -67,6 +67,13 @@ | |||
|   (define (mkfuncall op arg*) | ||||
|     (import primops) | ||||
|     (struct-case op | ||||
|       [(known x t) | ||||
|        (struct-case x | ||||
|          [(primref name) | ||||
|           (if (primop? name) | ||||
|               (make-primcall name arg*) | ||||
|               (make-funcall op arg*))] | ||||
|          [else (make-funcall op arg*)])] | ||||
|       [(primref name) | ||||
|        (cond | ||||
|          [(primop? name) | ||||
|  | @ -74,6 +81,10 @@ | |||
|          [else (make-funcall op arg*)])] | ||||
|       [else (make-funcall op arg*)])) | ||||
|   ;;; | ||||
|   (define (A x) | ||||
|     (struct-case x | ||||
|       [(known x t) (make-known (Expr x) t)] | ||||
|       [else (Expr x)])) | ||||
|   (define (Expr x) | ||||
|     (struct-case x | ||||
|       [(constant) x] | ||||
|  | @ -91,11 +102,9 @@ | |||
|       [(forcall op arg*) | ||||
|        (make-forcall op (map Expr arg*))] | ||||
|       [(funcall rator arg*) | ||||
|        (mkfuncall (Expr rator) (map Expr arg*))] | ||||
|        (mkfuncall (A rator) (map A arg*))] | ||||
|       [(jmpcall label rator arg*) | ||||
|        (make-jmpcall label (Expr rator) (map Expr arg*))] | ||||
|       [(mvcall rator k) | ||||
|        (make-mvcall (Expr rator) (Clambda k))] | ||||
|       [else (error who "invalid expr" x)])) | ||||
|   ;;; | ||||
|   (define (ClambdaCase x) | ||||
|  | @ -142,6 +151,10 @@ | |||
|           [(closure code free* well-known?)  | ||||
|            (make-closure code (map Var free*) well-known?)])) | ||||
|       (make-fix lhs* (map handle-closure rhs*) body)) | ||||
|     (define (A x) | ||||
|       (struct-case x | ||||
|         [(known x t) (make-known (Expr x) t)] | ||||
|         [else (Expr x)])) | ||||
|     (define (Expr x) | ||||
|       (struct-case x | ||||
|         [(constant) x] | ||||
|  | @ -159,15 +172,13 @@ | |||
|          (let ([t (unique-var 'tmp)]) | ||||
|            (Expr (make-fix (list t) (list x) t)))] | ||||
|         [(primcall op arg*) | ||||
|          (make-primcall op (map Expr arg*))] | ||||
|          (make-primcall op (map A arg*))] | ||||
|         [(forcall op arg*) | ||||
|          (make-forcall op (map Expr arg*))] | ||||
|         [(funcall rator arg*) | ||||
|          (make-funcall (Expr rator) (map Expr arg*))] | ||||
|          (make-funcall (A rator) (map A arg*))] | ||||
|         [(jmpcall label rator arg*) | ||||
|          (make-jmpcall label (Expr rator) (map Expr arg*))] | ||||
|         [(mvcall rator k) | ||||
|          (make-mvcall (Expr rator) (Clambda k))] | ||||
|         [else (error who "invalid expr" x)])) | ||||
|     Expr) | ||||
|   ;;; | ||||
|  | @ -208,20 +219,28 @@ | |||
| 
 | ||||
| (define (insert-engine-checks x) | ||||
|   (define who 'insert-engine-checks) | ||||
|   (define (known-primref? x) | ||||
|     (struct-case x | ||||
|       [(known x t) (known-primref? x)] | ||||
|       [(primref)   #t] | ||||
|       [else #f])) | ||||
|   (define (A x) | ||||
|     (struct-case x | ||||
|       [(known x t) (Expr x)] | ||||
|       [else (Expr x)])) | ||||
|   (define (Expr x)  | ||||
|     (struct-case x | ||||
|       [(constant)                 #f] | ||||
|       [(var)                      #f] | ||||
|       [(primref)                  #f] | ||||
|       [(jmpcall label rator arg*) #t] | ||||
|       [(mvcall rator k)           #t]  | ||||
|       [(funcall rator arg*) | ||||
|        (if (primref? rator) (ormap Expr arg*) #t)] | ||||
|        (if (known-primref? rator) (ormap A arg*) #t)] | ||||
|       [(bind lhs* rhs* body)      (or (ormap Expr rhs*) (Expr body))] | ||||
|       [(fix lhs* rhs* body)       (Expr body)] | ||||
|       [(conditional e0 e1 e2)     (or (Expr e0) (Expr e1) (Expr e2))] | ||||
|       [(seq e0 e1)                (or (Expr e0) (Expr e1))] | ||||
|       [(primcall op arg*)         (ormap Expr arg*)] | ||||
|       [(primcall op arg*)         (ormap A arg*)] | ||||
|       [(forcall op arg*)          (ormap Expr arg*)] | ||||
|       [else (error who "invalid expr" x)])) | ||||
|   (define (Main x) | ||||
|  | @ -245,6 +264,10 @@ | |||
| 
 | ||||
| (define (insert-stack-overflow-check x) | ||||
|   (define who 'insert-stack-overflow-check) | ||||
|   (define (A x) | ||||
|     (struct-case x | ||||
|       [(known x t) (NonTail x)] | ||||
|       [else (NonTail x)])) | ||||
|   (define (NonTail x) | ||||
|     (struct-case x | ||||
|       [(constant)                 #f] | ||||
|  | @ -257,8 +280,9 @@ | |||
|       [(fix lhs* rhs* body)   (NonTail body)] | ||||
|       [(conditional e0 e1 e2) (or (NonTail e0) (NonTail e1) (NonTail e2))] | ||||
|       [(seq e0 e1)            (or (NonTail e0) (NonTail e1))] | ||||
|       [(primcall op arg*)     (ormap NonTail arg*)] | ||||
|       [(primcall op arg*)     (ormap A arg*)] | ||||
|       [(forcall op arg*)      (ormap NonTail arg*)] | ||||
|       [(known x t v) (NonTail x)] | ||||
|       [else (error who "invalid expr" x)])) | ||||
|   (define (Tail x)  | ||||
|     (struct-case x | ||||
|  | @ -295,58 +319,6 @@ | |||
|        (make-codes (map Clambda code*) (Main body))])) | ||||
|   (Program x)) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| (define (insert-dummy-type-annotations x) | ||||
|   (define who 'insert-dummy-type-annotations) | ||||
|   (define (Closure x) | ||||
|     (struct-case x | ||||
|       [(closure code free*)  | ||||
|        x] | ||||
|        ;(make-closure (Expr code) (map Var free*))] | ||||
|       [else (error who "not a closure" x)])) | ||||
|   (define (Expr x) | ||||
|     (struct-case x | ||||
|       [(constant i)  | ||||
|        (make-known x 'constant i)] | ||||
|       [(var)      x] | ||||
|       [(primref op)  | ||||
|        (make-known x 'primitive op)] | ||||
|       [(bind lhs* rhs* body) | ||||
|        (make-bind lhs* (map Expr rhs*) (Expr body))] | ||||
|       [(fix lhs* rhs* body) | ||||
|        (make-fix lhs* (map Closure rhs*) (Expr body))] | ||||
|       [(conditional e0 e1 e2) | ||||
|        (make-conditional (Expr e0) (Expr e1) (Expr e2))] | ||||
|       [(seq e0 e1) | ||||
|        (make-seq (Expr e0) (Expr e1))] | ||||
|       [(primcall op arg*)          | ||||
|        (make-primcall op (map Expr arg*))] | ||||
|       [(forcall op arg*) | ||||
|        (make-forcall op (map Expr arg*))] | ||||
|       [(funcall rator arg*) | ||||
|        (make-funcall (Expr rator) (map Expr arg*))] | ||||
|       [(jmpcall label rator arg*)  | ||||
|        (make-jmpcall label (Expr rator) (map Expr arg*))] | ||||
|       [(mvcall rator k) | ||||
|        (make-mvcall (Expr rator) (Expr k))] | ||||
|       [else (error who "invalid expr" x)])) | ||||
|   (define (ClambdaCase x) | ||||
|     (struct-case x | ||||
|       [(clambda-case info body) | ||||
|        (make-clambda-case info (Expr body))])) | ||||
|   (define (Clambda x) | ||||
|     (struct-case x | ||||
|       [(clambda label case* cp free* name) | ||||
|        (make-clambda label (map ClambdaCase case*) cp free* name)])) | ||||
|   (define (Program x) | ||||
|     (struct-case x  | ||||
|       [(codes code* body) | ||||
|        (make-codes (map Clambda code*) (Expr body))])) | ||||
|   (Program x)) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| (include "pass-specify-rep.ss") | ||||
| 
 | ||||
| (define parameter-registers '(%edi))  | ||||
|  | @ -392,6 +364,7 @@ | |||
|        (do-bind lhs* rhs* (S body k))] | ||||
|       [(seq e0 e1) | ||||
|        (make-seq (E e0) (S e1 k))] | ||||
|       [(known x) (S x k)] | ||||
|       [else | ||||
|        (cond | ||||
|          [(or (constant? x) (symbol? x)) (k x)] | ||||
|  | @ -604,6 +577,7 @@ | |||
|        (make-shortcut  | ||||
|           (V d body) | ||||
|           (V d handler))]  | ||||
|       [(known x) (V d x)] | ||||
|       [else  | ||||
|        (if (symbol? x)  | ||||
|            (make-set d x) | ||||
|  | @ -3012,7 +2986,6 @@ | |||
|          [x (eliminate-fix x)] | ||||
|          [x (insert-engine-checks x)] | ||||
|          [x (insert-stack-overflow-check x)] | ||||
|          ;[x (insert-dummy-type-annotations x)] | ||||
|          [x (specify-representation x)] | ||||
|          [x (impose-calling-convention/evaluation-order x)] | ||||
|          [x (time-it "frame" (lambda () (assign-frame-sizes x)))] | ||||
|  |  | |||
|  | @ -106,9 +106,6 @@ | |||
| 
 | ||||
|   (define cp0-effort-limit (make-parameter 50)) | ||||
|   (define cp0-size-limit (make-parameter 8)) | ||||
|   ;(define cp0-effort-limit (make-parameter 100)) | ||||
|   ;(define cp0-size-limit (make-parameter 10)) | ||||
| 
 | ||||
| 
 | ||||
|   (define primitive-info-list | ||||
|     '( | ||||
|  |  | |||
|  | @ -19,7 +19,8 @@ | |||
|           assembler-output optimize-cp | ||||
|           current-primitive-locations eval-core | ||||
|           compile-core-expr expand/optimize optimizer-output | ||||
|           cp0-effort-limit cp0-size-limit optimize-level) | ||||
|           cp0-effort-limit cp0-size-limit optimize-level  | ||||
|           perform-tag-analysis tag-analysis-output) | ||||
|   (import  | ||||
|     (rnrs hashtables) | ||||
|     (ikarus system $fx) | ||||
|  | @ -32,7 +33,8 @@ | |||
|         compile-core-expr-to-port assembler-output | ||||
|         current-primitive-locations eval-core | ||||
|         cp0-size-limit cp0-effort-limit  | ||||
|         expand/optimize optimizer-output) | ||||
|         expand/optimize optimizer-output | ||||
|         tag-analysis-output perform-tag-analysis) | ||||
|     (ikarus.fasl.write) | ||||
|     (ikarus.intel-assembler)) | ||||
| 
 | ||||
|  | @ -139,7 +141,7 @@ | |||
| (define-struct assign (lhs rhs)) | ||||
| (define-struct mvcall (producer consumer)) | ||||
| 
 | ||||
| (define-struct known (expr type value)) | ||||
| (define-struct known (expr type)) | ||||
| 
 | ||||
| (define-struct shortcut (body handler)) | ||||
| 
 | ||||
|  | @ -440,9 +442,10 @@ | |||
|   (define (E x) | ||||
|     (struct-case x | ||||
|       [(constant c) `(quote ,c)] | ||||
|       [(known x t) `(known ,(E x) ,(T:description t))] | ||||
|       [(code-loc x) `(code-loc ,x)] | ||||
|       [(var x) (string->symbol (format ":~a" x))] | ||||
|       [(prelex name) (string->symbol (format ":~a" x))] | ||||
|       [(prelex name) (string->symbol (format ":~a" name))] | ||||
|       [(primref x) x] | ||||
|       [(conditional test conseq altern)  | ||||
|        `(if ,(E test) ,(E conseq) ,(E altern))] | ||||
|  | @ -1121,6 +1124,8 @@ | |||
|       [else (error who "invalid expression" (unparse x))])) | ||||
|   (Expr x)) | ||||
| 
 | ||||
| (include "ikarus.compiler.tag-annotation-analysis.ss") | ||||
| 
 | ||||
| (define (introduce-vars x) | ||||
|   (define who 'introduce-vars) | ||||
|   (define (lookup x) | ||||
|  | @ -1134,6 +1139,10 @@ | |||
|       (set-var-global-loc! v (prelex-global-location x)) | ||||
|       (set-prelex-operand! x v) | ||||
|       v)) | ||||
|   (define (A x) | ||||
|     (struct-case x | ||||
|       [(known x t) (make-known (E x) t)] | ||||
|       [else (E x)])) | ||||
|   (define (E x) | ||||
|     (struct-case x | ||||
|       [(constant) x] | ||||
|  | @ -1163,9 +1172,9 @@ | |||
|            cls*) | ||||
|          cp free name)] | ||||
|       [(primcall rator rand*) | ||||
|        (make-primcall rator (map E rand*))] | ||||
|        (make-primcall rator (map A rand*))] | ||||
|       [(funcall rator rand*) | ||||
|        (make-funcall (E rator) (map E rand*))] | ||||
|        (make-funcall (A rator) (map A rand*))] | ||||
|       [(forcall rator rand*) (make-forcall rator (map E rand*))] | ||||
|       [(assign lhs rhs) | ||||
|        (make-assign (lookup lhs) (E rhs))] | ||||
|  | @ -1192,6 +1201,10 @@ | |||
|     (if (null? lhs*)  | ||||
|         (Expr body) | ||||
|         (make-fix lhs* (map CLambda rhs*) (Expr body)))) | ||||
|   (define (A x) | ||||
|     (struct-case x | ||||
|       [(known x t) (make-known (Expr x) t)] | ||||
|       [else (Expr x)])) | ||||
|   (define (Expr x) | ||||
|     (struct-case x | ||||
|       [(constant) x] | ||||
|  | @ -1217,12 +1230,22 @@ | |||
|       [(forcall op rand*) | ||||
|        (make-forcall op (map Expr rand*))] | ||||
|       [(funcall rator rand*) | ||||
|        (make-funcall (Expr rator) (map Expr rand*))] | ||||
|        (make-funcall (A rator) (map A rand*))] | ||||
|       [(mvcall p c) (make-mvcall (Expr p) (Expr c))] | ||||
|       [else (error who "invalid expression" (unparse x))])) | ||||
|   (Expr x)) | ||||
| 
 | ||||
| 
 | ||||
| (define (untag x) | ||||
|   (struct-case x  | ||||
|     [(known x t) (values x t)] | ||||
|     [else        (values x #f)])) | ||||
| 
 | ||||
| (define (tag x t) | ||||
|   (if t | ||||
|       (make-known x t) | ||||
|       x)) | ||||
| 
 | ||||
| (define (optimize-for-direct-jumps x) | ||||
|   (define who 'optimize-for-direct-jumps) | ||||
|   (define (init-var x) | ||||
|  | @ -1252,20 +1275,24 @@ | |||
|                  (cond | ||||
|                    [proper | ||||
|                     (if (fx= n (length fml*)) | ||||
|                         (make-jmpcall label rator rand*) | ||||
|                         (make-jmpcall label (strip rator) (map strip rand*)) | ||||
|                         (f (cdr cls*)))] | ||||
|                    [else | ||||
|                     (if (fx<= (length (cdr fml*)) n) | ||||
|                         (make-jmpcall label rator | ||||
|                         (make-jmpcall label (strip rator) | ||||
|                            (let f ([fml* (cdr fml*)] [rand* rand*]) | ||||
|                              (cond | ||||
|                                [(null? fml*)  | ||||
|                                 ;;; FIXME: construct list afterwards | ||||
|                                 (list (make-funcall (make-primref 'list) rand*))] | ||||
|                                [else | ||||
|                                 (cons (car rand*) | ||||
|                                 (cons (strip (car rand*)) | ||||
|                                       (f (cdr fml*) (cdr rand*)))]))) | ||||
|                         (f (cdr cls*)))])])]))]))) | ||||
|   (define (strip x) | ||||
|     (struct-case x | ||||
|       [(known x t) x] | ||||
|       [else x])) | ||||
|   (define (CLambda x) | ||||
|     (struct-case x | ||||
|       [(clambda g cls* cp free name)  | ||||
|  | @ -1277,6 +1304,14 @@ | |||
|                    (make-clambda-case info (Expr body))])) | ||||
|               cls*) | ||||
|          cp free name)])) | ||||
|   (define (A x) | ||||
|     (struct-case x | ||||
|       [(known x t) (make-known (Expr x) t)] | ||||
|       [else (Expr x)])) | ||||
|   (define (A- x) | ||||
|     (struct-case x | ||||
|       [(known x t) (Expr x)] | ||||
|       [else (Expr x)]))  | ||||
|   (define (Expr x) | ||||
|     (struct-case x | ||||
|       [(constant) x] | ||||
|  | @ -1296,19 +1331,18 @@ | |||
|       [(forcall op rand*) | ||||
|        (make-forcall op (map Expr rand*))] | ||||
|       [(funcall rator rand*) | ||||
|        (let ([rator (Expr rator)]) | ||||
|        (let-values ([(rator t) (untag (A rator))]) | ||||
|          (cond | ||||
|            [(and (var? rator) (bound-var rator)) => | ||||
|             (lambda (c) | ||||
|               (optimize c rator (map Expr rand*)))] | ||||
|               (optimize c rator (map A rand*)))] | ||||
|            [(and (primref? rator) | ||||
|                  (eq? (primref-name rator) '$$apply)) | ||||
|             (make-jmpcall (sl-apply-label)  | ||||
|                           (Expr (car rand*)) | ||||
|                           (map Expr (cdr rand*)))] | ||||
|             (make-jmpcall (sl-apply-label) | ||||
|                           (A- (car rand*)) | ||||
|                           (map A- (cdr rand*)))] | ||||
|            [else | ||||
|             (make-funcall rator (map Expr rand*))]))] | ||||
|       [(mvcall p c) (make-mvcall (Expr p) (Expr c))] | ||||
|             (make-funcall (tag rator t) (map A rand*))]))] | ||||
|       [else (error who "invalid expression" (unparse x))])) | ||||
|   (Expr x)) | ||||
| 
 | ||||
|  | @ -1335,6 +1369,10 @@ | |||
|              (list (make-constant loc) (car lhs*))) | ||||
|            (global-assign (cdr lhs*) body)))] | ||||
|       [else (global-assign (cdr lhs*) body)])) | ||||
|   (define (A x) | ||||
|     (struct-case x | ||||
|       [(known x t) (make-known (Expr x) t)] | ||||
|       [else (Expr x)])) | ||||
|   (define (Expr x) | ||||
|     (struct-case x | ||||
|       [(constant) x] | ||||
|  | @ -1367,11 +1405,14 @@ | |||
|       [(forcall op rand*) | ||||
|        (make-forcall op (map Expr rand*))] | ||||
|       [(funcall rator rand*) | ||||
|        (make-funcall (Expr rator) (map Expr rand*))] | ||||
|       [(mvcall p c) (make-mvcall (Expr p) (Expr c))] | ||||
|        (make-funcall (A rator) (map A rand*))] | ||||
|       [(jmpcall label rator rand*) | ||||
|        (make-jmpcall label (Expr rator) (map Expr rand*))] | ||||
|       [else (error who "invalid expression" (unparse x))])) | ||||
|   (define (AM x) | ||||
|     (struct-case x | ||||
|       [(known x t) (make-known (Main x) t)] | ||||
|       [else (Main x)])) | ||||
|   (define (Main x) | ||||
|     (struct-case x | ||||
|       [(constant) x] | ||||
|  | @ -1397,8 +1438,7 @@ | |||
|       [(forcall op rand*) | ||||
|        (make-forcall op (map Main rand*))] | ||||
|       [(funcall rator rand*) | ||||
|        (make-funcall (Main rator) (map Main rand*))] | ||||
|       [(mvcall p c) (make-mvcall (Main p) (Main c))] | ||||
|        (make-funcall (AM rator) (map AM rand*))] | ||||
|       [(jmpcall label rator rand*) | ||||
|        (make-jmpcall label (Main rator) (map Main rand*))] | ||||
|       [else (error who "invalid expression" (unparse x))])) | ||||
|  | @ -1448,6 +1488,19 @@ | |||
|               free | ||||
|               #f) | ||||
|             free))])) | ||||
|   (define (A x) | ||||
|     (struct-case x | ||||
|       [(known x t)  | ||||
|        (let-values ([(x free) (Expr x)]) | ||||
|          (values (make-known x t) free))] | ||||
|       [else (Expr x)])) | ||||
|   (define (A* x*) | ||||
|     (cond | ||||
|       [(null? x*) (values '() '())] | ||||
|       [else | ||||
|        (let-values ([(a a-free) (A (car x*))] | ||||
|                     [(d d-free) (A* (cdr x*))]) | ||||
|          (values (cons a d) (union a-free d-free)))])) | ||||
|   (define (Expr ex) | ||||
|     (struct-case ex | ||||
|       [(constant) (values ex '())] | ||||
|  | @ -1486,19 +1539,25 @@ | |||
|        (let-values ([(rand* rand*-free) (Expr* rand*)]) | ||||
|          (values (make-forcall op rand*)  rand*-free))] | ||||
|       [(funcall rator rand*) | ||||
|        (let-values ([(rator rat-free) (Expr rator)] | ||||
|                     [(rand* rand*-free) (Expr* rand*)]) | ||||
|          (values (make-funcall rator rand*)  | ||||
|        (let-values ([(rator rat-free) (A rator)] | ||||
|                     [(rand* rand*-free) (A* rand*)]) | ||||
|          (values (make-funcall rator rand*) | ||||
|                  (union rat-free rand*-free)))] | ||||
|       [(jmpcall label rator rand*) | ||||
|        (let-values ([(rator rat-free) | ||||
|                      (if (and (optimize-cp) (var? rator)) | ||||
|                          (values rator (singleton rator)) | ||||
|                          (Expr rator))] | ||||
|                     [(rand* rand*-free) (Expr* rand*)]) | ||||
|                      (if (optimize-cp) (Rator rator) (Expr rator))] | ||||
|                     [(rand* rand*-free) | ||||
|                      (A* rand*)]) | ||||
|          (values (make-jmpcall label rator rand*)  | ||||
|                  (union rat-free rand*-free)))]  | ||||
|                  (union rat-free rand*-free)))] | ||||
|       [else (error who "invalid expression" ex)])) | ||||
|   (define (Rator x) | ||||
|     (struct-case x | ||||
|       [(var) (values x (singleton x))] | ||||
|       ;[(known x t) | ||||
|       ; (let-values ([(x free) (Rator x)]) | ||||
|       ;   (values (make-known x t) free))] | ||||
|       [else (Expr x)])) | ||||
|   (let-values ([(prog free) (Expr prog)]) | ||||
|     (unless (null? free)  | ||||
|       (error 'convert-closures "free vars encountered in program" | ||||
|  | @ -1696,6 +1755,10 @@ | |||
|                 y)] | ||||
|              [else y]))] | ||||
|         [else x]))) | ||||
|   (define (A x) | ||||
|     (struct-case x | ||||
|       [(known x t) (make-known (E x) t)] | ||||
|       [else (E x)])) | ||||
|   (define (E x) | ||||
|     (struct-case x | ||||
|       [(constant) x] | ||||
|  | @ -1707,7 +1770,7 @@ | |||
|        (make-conditional (E test) (E conseq) (E altern))] | ||||
|       [(seq e0 e1)           (make-seq (E e0) (E e1))] | ||||
|       [(forcall op rand*)    (make-forcall op (map E rand*))] | ||||
|       [(funcall rator rand*) (make-funcall (E rator) (map E rand*))] | ||||
|       [(funcall rator rand*) (make-funcall (A rator) (map A rand*))] | ||||
|       [(jmpcall label rator rand*) | ||||
|        (make-jmpcall label (E rator) (map E rand*))] | ||||
|       [else (error who "invalid expression" (unparse x))])) | ||||
|  | @ -2267,6 +2330,7 @@ | |||
|      (printf "    ~s\n" x)])) | ||||
| 
 | ||||
| (define optimizer-output (make-parameter #f)) | ||||
| (define perform-tag-analysis (make-parameter #f)) | ||||
| 
 | ||||
| (define (compile-core-expr->code p) | ||||
|   (let* ([p (recordize p)] | ||||
|  | @ -2280,6 +2344,9 @@ | |||
|                (pretty-print (unparse-pretty p))) | ||||
|             #f)] | ||||
|          [p (rewrite-assignments p)] | ||||
|          [p (if (perform-tag-analysis) | ||||
|                 (introduce-tags p) | ||||
|                 p)] | ||||
|          [p (introduce-vars p)] | ||||
|          [p (sanitize-bindings p)] | ||||
|          [p (optimize-for-direct-jumps p)] | ||||
|  |  | |||
|  | @ -0,0 +1,434 @@ | |||
| ;;; Ikarus Scheme -- A compiler for R6RS Scheme. | ||||
| ;;; Copyright (C) 2006,2007,2008  Abdulaziz Ghuloum | ||||
| ;;;  | ||||
| ;;; This program is free software: you can redistribute it and/or modify | ||||
| ;;; it under the terms of the GNU General Public License version 3 as | ||||
| ;;; published by the Free Software Foundation. | ||||
| ;;;  | ||||
| ;;; This program is distributed in the hope that it will be useful, but | ||||
| ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| ;;; General Public License for more details. | ||||
| ;;;  | ||||
| ;;; You should have received a copy of the GNU General Public License | ||||
| ;;; along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ;;; THIS IS WIP | ||||
| (include "ikarus.ontology.ss") | ||||
| 
 | ||||
| (define tag-analysis-output (make-parameter #f)) | ||||
| 
 | ||||
| (define (introduce-tags x) | ||||
|   (define who 'introduce-tags) | ||||
|   #; | ||||
|   (define primitive-return-types  | ||||
|     '( | ||||
|       [length                fixnum] | ||||
|       [bytevector-length     fixnum] | ||||
|       [bytevector-u8-ref     fixnum] | ||||
|       [bytevector-s8-ref     fixnum] | ||||
|       [bytevector-u16-ref    fixnum] | ||||
|       [bytevector-s16-ref    fixnum] | ||||
|       [bytevector-u16-native-ref    fixnum] | ||||
|       [bytevector-s16-native-ref    fixnum] | ||||
|       [fixnum-width          fixnum] | ||||
|       [greatest-fixnum       fixnum] | ||||
|       [least-fixnum          fixnum] | ||||
|       [=                     boolean] | ||||
|       [<                     boolean] | ||||
|       [<=                    boolean] | ||||
|       [>                     boolean] | ||||
|       [>=                    boolean] | ||||
|       [even?                 boolean] | ||||
|       [odd?                  boolean] | ||||
|       [rational?             boolean] | ||||
|       [rational-valued?      boolean] | ||||
|       [real?                 boolean] | ||||
|       [real-valued?          boolean] | ||||
|       [bignum?               boolean] | ||||
|       [ratnum?               boolean] | ||||
|       [flonum?               boolean] | ||||
|       [fixnum?               boolean] | ||||
|       [integer?              boolean] | ||||
|       [exact?                boolean] | ||||
|       [finite?               boolean] | ||||
|       [inexact?              boolean] | ||||
|       [infinite?             boolean] | ||||
|       [positive?             boolean] | ||||
|       [negative?             boolean] | ||||
|       [nan?                  boolean] | ||||
|       [number?               boolean] | ||||
|       [compnum?              boolean] | ||||
|       [cflonum?              boolean] | ||||
|       [complex?              boolean] | ||||
|       [list?                 boolean] | ||||
|       [eq?                   boolean] | ||||
|       [eqv?                  boolean] | ||||
|       [equal?                boolean] | ||||
|       [gensym?               boolean] | ||||
|       [symbol-bound?         boolean] | ||||
|       [code?                 boolean] | ||||
|       [immediate?            boolean] | ||||
|       [pair?                 boolean] | ||||
|       [procedure?            boolean] | ||||
|       [symbol?               boolean] | ||||
|       [symbol=?              boolean] | ||||
|       [boolean?              boolean] | ||||
|       [boolean=?             boolean] | ||||
|       [vector?               boolean] | ||||
|       [bitwise-bit-set?      boolean] | ||||
|       [bytevector?           boolean] | ||||
|       [bytevector=?          boolean] | ||||
|       [enum-set=?            boolean] | ||||
|       [binary-port?          boolean] | ||||
|       [textual-port?         boolean] | ||||
|       [input-port?           boolean] | ||||
|       [output-port?          boolean] | ||||
|       [port?                 boolean] | ||||
|       [port-eof?             boolean] | ||||
|       [port-closed?          boolean] | ||||
|       [char-ready?           boolean] | ||||
|       [eof-object?           boolean] | ||||
|       [hashtable?            boolean] | ||||
|       [hashtable-mutable?    boolean] | ||||
|       [file-exists?          boolean] | ||||
|       [file-regular?         boolean] | ||||
|       [file-directory?       boolean] | ||||
|       [file-symbolic-link?   boolean] | ||||
|       [record?               boolean] | ||||
|       [record-field-mutable? boolean] | ||||
|       [record-type-generative? boolean] | ||||
|       [record-type-sealed?   boolean] | ||||
|       [record-type-descriptor boolean] | ||||
|       [free-identifier=?     boolean] | ||||
|       [bound-identifier=?    boolean] | ||||
|       [identifier?           boolean] | ||||
|       [char-lower-case?      boolean] | ||||
|       [char-upper-case?      boolean] | ||||
|       [char-title-case?      boolean] | ||||
|       [char-whitespace?      boolean] | ||||
|       [char-numeric?         boolean] | ||||
|       [char-alphabetic?      boolean] | ||||
|     )) | ||||
| 
 | ||||
|   (define number! | ||||
|     (let ([i 0]) | ||||
|       (lambda (x) | ||||
|         (set-prelex-operand! x i) | ||||
|         (set! i (+ i 1))))) | ||||
|   (define (V* x* env) | ||||
|     (cond | ||||
|       [(null? x*) (values '() env '())] | ||||
|       [else | ||||
|        (let-values ([(x env1 t) (V (car x*) env)] | ||||
|                     [(x* env2 t*) (V* (cdr x*) env)]) | ||||
|          (values (cons x x*) | ||||
|                  (and-envs env1 env2) | ||||
|                  (cons t t*)))])) | ||||
|   (define (constant-type x)  | ||||
|     (define (numeric x) | ||||
|       (define (size x t) | ||||
|         (T:and t | ||||
|           (cond | ||||
|             [(< x 0) T:negative] | ||||
|             [(> x 0) T:positive] | ||||
|             [(= x 0) T:zero] | ||||
|             [else    t]))) | ||||
|       (cond | ||||
|         [(fixnum? x) (size x T:fixnum)] | ||||
|         [(flonum? x) (size x T:flonum)] | ||||
|         [(or (bignum? x) (ratnum? x))  | ||||
|          (size x (T:and T:exact T:other-number))] | ||||
|         [else        T:number])) | ||||
|     (cond | ||||
|       [(number? x)    (numeric x)] | ||||
|       [(boolean? x)   (if x T:true T:false)] | ||||
|       [(null? x)      T:null] | ||||
|       [(char? x)      T:char] | ||||
|       [(string? x)    T:string] | ||||
|       [(vector? x)    T:vector] | ||||
|       [(pair? x)      T:pair] | ||||
|       [(eq? x (void)) T:void] | ||||
|       [else           T:object])) | ||||
|   (define (V x env) | ||||
|     (struct-case x | ||||
|       [(constant k) (values x env (constant-type k))] | ||||
|       [(prelex)     (values x env (lookup x env))] | ||||
|       [(primref op) (values x env T:procedure)] | ||||
|       [(seq e0 e1) | ||||
|        (let-values ([(e0 env t) (V e0 env)]) | ||||
|          (cond | ||||
|            [(eq? (T:object? t) 'no) | ||||
|             (values e0 env t)] | ||||
|            [else | ||||
|             (let-values ([(e1 env t) (V e1 env)]) | ||||
|               (values (make-seq e0 e1) env t))]))] | ||||
|       [(conditional e0 e1 e2) | ||||
|        (let-values ([(e0 env t) (V e0 env)]) | ||||
|          (cond | ||||
|            [(eq? (T:object? t) 'no) | ||||
|             (values e0 env t)] | ||||
|            [(eq? (T:false? t) 'yes) | ||||
|             (let-values ([(e2 env t) (V e2 env)]) | ||||
|               (values (make-seq e0 e2) env t))] | ||||
|            [(eq? (T:false? t) 'no) | ||||
|             (let-values ([(e1 env t) (V e1 env)]) | ||||
|               (values (make-seq e0 e1) env t))] | ||||
|            [else | ||||
|             (let-values ([(e1 env1 t1) (V e1 env)] | ||||
|                          [(e2 env2 t2) (V e2 env)]) | ||||
|               (values (make-conditional e0 e1 e2) | ||||
|                       (or-envs env1 env2) | ||||
|                       (T:or t1 t2)))]))] | ||||
|       [(bind lhs* rhs* body) | ||||
|        (let-values ([(rhs* env t*) (V* rhs* env)]) | ||||
|          (for-each number! lhs*) | ||||
|          (let ([env (extend-env* lhs* t* env)]) | ||||
|            (let-values ([(body env t) (V body env)]) | ||||
|              (values  | ||||
|                (make-bind lhs* rhs* body) | ||||
|                env t))))] | ||||
|       [(fix lhs* rhs* body) | ||||
|        (for-each number! lhs*) | ||||
|        (let-values ([(rhs* env t*) (V* rhs* env)]) | ||||
|          (let ([env (extend-env* lhs* t* env)]) | ||||
|            (let-values ([(body env t) (V body env)]) | ||||
|              (values  | ||||
|                (make-fix lhs* rhs* body) | ||||
|                env t))))] | ||||
|       [(clambda g cls* cp free name) | ||||
|        (values | ||||
|          (make-clambda g | ||||
|            (map  | ||||
|              (lambda (x) | ||||
|                (struct-case x  | ||||
|                  [(clambda-case info body) | ||||
|                   (for-each number! (case-info-args info)) | ||||
|                   (let-values ([(body env t) (V body env)]) | ||||
|                     ;;; dropped env and t | ||||
|                     (make-clambda-case info body))])) | ||||
|              cls*) | ||||
|            cp free name) | ||||
|          env | ||||
|          T:procedure)] | ||||
|       [(funcall rator rand*) | ||||
|        (let-values ([(rator rator-env rator-val) (V rator env)] | ||||
|                     [(rand* rand*-env rand*-val) (V* rand* env)]) | ||||
|          (apply-funcall rator rand* | ||||
|            rator-val rand*-val | ||||
|            rator-env rand*-env))] | ||||
|       [(forcall rator rand*) | ||||
|        (let-values ([(rand* rand*-env rand*-val) (V* rand* env)]) | ||||
|          (values (make-forcall rator rand*) | ||||
|                  rand*-env | ||||
|                  T:object))] | ||||
|       [else (error who "invalid expression" (unparse x))])) | ||||
|   (define (annotate x t) | ||||
|     (cond | ||||
|       [(T=? t T:object) x] | ||||
|       [else (make-known x t)])) | ||||
|   (define (apply-funcall rator rand* rator-val rand*-val rator-env rand*-env) | ||||
|     (let ([env (and-envs rator-env rand*-env)] | ||||
|           [rand* (map annotate rand* rand*-val)]) | ||||
|       (struct-case rator | ||||
|         [(primref op)  | ||||
|          (apply-primcall op rand* env)] | ||||
|         [else | ||||
|          (values (make-funcall (annotate rator rator-val) rand*) | ||||
|                  env | ||||
|                  T:object)]))) | ||||
|   (define (apply-primcall op rand* env) | ||||
|     (define (return t) | ||||
|       (values (make-funcall (make-primref op) rand*) env t)) | ||||
|     (define (inject ret-t . rand-t*) | ||||
|       (define (extend* x* t* env) | ||||
|         (define (extend x t env) | ||||
|           (struct-case x | ||||
|             [(known expr t0) | ||||
|              (extend expr (T:and t t0) env)] | ||||
|             [(prelex) | ||||
|              (extend-env x t env)] | ||||
|             [else env])) | ||||
|         (cond | ||||
|           [(null? x*) env] | ||||
|           [else (extend (car x*) (car t*) | ||||
|                   (extend* (cdr x*) (cdr t*) env))])) | ||||
|       (cond | ||||
|         [(= (length rand-t*) (length rand*)) | ||||
|          (values (make-funcall (make-primref op) rand*) | ||||
|                  (extend* rand* rand-t* env) | ||||
|                  ret-t)] | ||||
|         [else | ||||
|          (error 'apply-primcall "invalid extesion" op rand*)])) | ||||
|     (define (inject* ret-t arg-t) | ||||
|       (define (extend* x* env) | ||||
|         (define (extend x t env) | ||||
|           (struct-case x | ||||
|             [(known expr t0) | ||||
|              (extend expr (T:and t t0) env)] | ||||
|             [(prelex) | ||||
|              (extend-env x t env)] | ||||
|             [else env])) | ||||
|         (cond | ||||
|           [(null? x*) env] | ||||
|           [else (extend (car x*) arg-t | ||||
|                   (extend* (cdr x*) env))])) | ||||
|       (values (make-funcall (make-primref op) rand*) | ||||
|               (extend* rand* env) | ||||
|               ret-t)) | ||||
|     (case op | ||||
|       [(cons)         | ||||
|        (return T:pair)] | ||||
|       [(car cdr | ||||
|         caar cadr cdar cddr | ||||
|         caaar caadr cadar caddr cdaar cdadr cddar cdddr | ||||
|         caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr | ||||
|         cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr) | ||||
|        (inject T:object T:pair)] | ||||
|       [(set-car! set-cdr!) | ||||
|        (inject T:void T:pair T:object)] | ||||
|       [(vector make-vector list->vector) | ||||
|        (return T:vector)] | ||||
|       [(string make-string list->string) | ||||
|        (return T:string)] | ||||
|       [(string-length) | ||||
|        (inject T:fixnum T:string)] | ||||
|       [(vector-length) | ||||
|        (inject T:fixnum T:vector)] | ||||
|       [(string-ref) | ||||
|        (inject T:char T:string T:fixnum)] | ||||
|       [(string-set!) | ||||
|        (inject T:void T:string T:fixnum T:char)] | ||||
|       [(vector-ref) | ||||
|        (inject T:object T:vector T:fixnum)] | ||||
|       [(vector-set!) | ||||
|        (inject T:void T:vector T:fixnum T:object)] | ||||
|       [(integer->char) | ||||
|        (inject T:char T:fixnum)] | ||||
|       [(char->integer) | ||||
|        (inject T:fixnum T:char)] | ||||
|       [(fx+         fx-         fx*         fxadd1      fxsub1 | ||||
|         fxquotient  fxremainder fxmodulo    fxsll       fxsra | ||||
|         fxand       fxdiv       fxdiv0      fxif        fxior | ||||
|         fxlength    fxmax       fxmin       fxmod       fxmod0 | ||||
|         fxnot       fxxor       fxlogand    fxlogor     fxlognot | ||||
|         fxlogxor    fxlogand    fxlogand    fxlogand    fxlogand | ||||
|         fxlogand    fxlogand) | ||||
|        (inject* T:fixnum T:fixnum)] | ||||
|       [(fx= fx< fx<= fx> fx>= fx=? fx<? fx<=? fx>? fx>=? | ||||
|         fxeven? fxodd? fxnegative? fxpositive? fxzero? | ||||
|         fxbit-set?) | ||||
|        (inject* T:boolean T:fixnum)] | ||||
|       [(fl=? fl<? fl<=? fl>? fl>=? | ||||
|         fleven? flodd? flzero? flpositive? flnegative? | ||||
|         flfinite? flinfinite? flinteger? flnan?) | ||||
|        (inject* T:boolean T:flonum)] | ||||
|       [(char=? char<? char<=? char>? char>=?  | ||||
|         char-ci=? char-ci<? char-ci<=? char-ci>? char-ci>=?) | ||||
|        (inject* T:boolean T:char)] | ||||
|       [(string=? string<? string<=? string>? string>=? | ||||
|         string-ci=? string-ci<? string-ci<=? string-ci>? | ||||
|         string-ci>=?) | ||||
|        (inject* T:boolean T:string)] | ||||
|       [(make-parameter  | ||||
|         record-constructor   | ||||
|         record-accessor      | ||||
|         record-constructor   | ||||
|         record-predicate     | ||||
|         condition-accessor   | ||||
|         condition-predicate  | ||||
|         enum-set-constructor | ||||
|         enum-set-indexer     | ||||
|         make-guardian) | ||||
|        (return T:procedure)] | ||||
|       [else | ||||
|        (return T:object)])) | ||||
|        | ||||
|   | ||||
| 
 | ||||
|   ;;; | ||||
|   (define (extend-env* x* v* env) | ||||
|     (cond | ||||
|       [(null? x*) env] | ||||
|       [else  | ||||
|        (extend-env* (cdr x*) (cdr v*) | ||||
|          (extend-env (car x*) (car v*) env))])) | ||||
|   (define (extend-env x t env) | ||||
|     (cond | ||||
|       [(T=? t T:object) env] | ||||
|       [else | ||||
|        (let ([x (prelex-operand x)]) | ||||
|          (let f ([env env]) | ||||
|            (cond | ||||
|              [(or (null? env) (< x (caar env))) | ||||
|               (cons (cons x t) env)] | ||||
|              [else | ||||
|               (cons (car env) (f (cdr env)))])))])) | ||||
|   (define (or-envs env1 env2) | ||||
|     (define (cons-env x v env) | ||||
|       (cond | ||||
|         [(T=? v T:object) env] | ||||
|         [else (cons (cons x v) env)])) | ||||
|     (define (merge-envs1 a1 env1 env2) | ||||
|       (if (pair? env2) | ||||
|           (merge-envs2 a1 env1 (car env2) (cdr env2)) | ||||
|           empty-env)) | ||||
|     (define (merge-envs2 a1 env1 a2 env2) | ||||
|       (let ([x1 (car a1)] [x2 (car a2)]) | ||||
|         (if (eq? x1 x2) | ||||
|             (cons-env x1 (T:or (cdr a1) (cdr a2)) | ||||
|               (merge-envs env1 env2)) | ||||
|             (if (< x2 x1) | ||||
|                 (merge-envs1 a1 env1 env2) | ||||
|                 (merge-envs1 a2 env2 env1))))) | ||||
|     (define (merge-envs env1 env2) | ||||
|       (if (eq? env1 env2) | ||||
|           env1 | ||||
|           (if (pair? env1) | ||||
|               (if (pair? env2)  | ||||
|                   (merge-envs2 (car env1) (cdr env1) (car env2) (cdr env2)) | ||||
|                   empty-env) | ||||
|               empty-env))) | ||||
|     (merge-envs env1 env2)) | ||||
|   (define (and-envs env1 env2) | ||||
|     (define (cons-env x v env) | ||||
|       (cond | ||||
|         [(T=? v T:object) env] | ||||
|         [else (cons (cons x v) env)])) | ||||
|     (define (merge-envs1 a1 env1 env2) | ||||
|       (if (pair? env2) | ||||
|           (merge-envs2 a1 env1 (car env2) (cdr env2)) | ||||
|           env1)) | ||||
|     (define (merge-envs2 a1 env1 a2 env2) | ||||
|       (let ([x1 (car a1)] [x2 (car a2)]) | ||||
|         (if (eq? x1 x2) | ||||
|             (cons-env x1 (T:and (cdr a1) (cdr a2)) | ||||
|               (merge-envs env1 env2)) | ||||
|             (if (< x2 x1) | ||||
|                 (cons a2 (merge-envs1 a1 env1 env2)) | ||||
|                 (cons a1 (merge-envs1 a2 env2 env1)))))) | ||||
|     (define (merge-envs env1 env2) | ||||
|       (if (eq? env1 env2) | ||||
|           env1 | ||||
|           (if (pair? env1) | ||||
|               (if (pair? env2)  | ||||
|                   (merge-envs2 (car env1) (cdr env1) (car env2) (cdr env2)) | ||||
|                   env1) | ||||
|               env2))) | ||||
|     (merge-envs env1 env2)) | ||||
|   (define empty-env '()) | ||||
|   (define (lookup x env) | ||||
|     (cond | ||||
|       [(eq? env 'bottom) #f] | ||||
|       [else | ||||
|        (let ([x (prelex-operand x)]) | ||||
|          (cond | ||||
|            [(assq x env) => cdr] | ||||
|            [else T:object]))])) | ||||
|   (let-values ([(x env t) (V x empty-env)]) | ||||
|     (when (tag-analysis-output) | ||||
|       (pretty-print (unparse x))) | ||||
|     x)) | ||||
| 
 | ||||
|  | @ -72,13 +72,6 @@ | |||
|           &i/o-encoding-rcd &no-infinities-rtd &no-infinities-rcd | ||||
|           &no-nans-rtd &no-nans-rcd | ||||
|           &interrupted-rtd &interrupted-rcd  | ||||
| 
 | ||||
| 
 | ||||
|           &i/o-would-block-rtd | ||||
|           &i/o-would-block-rcd | ||||
|           make-i/o-would-block-condition | ||||
|           i/o-would-block-condition? | ||||
|           i/o-would-block-port | ||||
|           ) | ||||
|   (import | ||||
|     (rnrs records inspection) | ||||
|  | @ -131,11 +124,6 @@ | |||
|           i/o-encoding-error? i/o-encoding-error-char | ||||
|           no-infinities-violation? make-no-infinities-violation | ||||
|           no-nans-violation? make-no-nans-violation | ||||
|            | ||||
|           &i/o-would-block | ||||
|           make-i/o-would-block-condition | ||||
|           i/o-would-block-condition? | ||||
|           i/o-would-block-port | ||||
|           )) | ||||
|    | ||||
|   (define-record-type &condition  | ||||
|  | @ -344,10 +332,6 @@ | |||
|   (define-condition-type &interrupted &serious | ||||
|     make-interrupted-condition interrupted-condition?) | ||||
| 
 | ||||
|   (define-condition-type &i/o-would-block &condition | ||||
|     make-i/o-would-block-condition i/o-would-block-condition? | ||||
|     (port i/o-would-block-port)) | ||||
| 
 | ||||
|   (define print-condition  | ||||
|     (let () | ||||
|       (define (print-simple-condition x p) | ||||
|  |  | |||
|  | @ -1309,8 +1309,6 @@ | |||
|                               (cond | ||||
|                                 [(fx>= bytes 0) bytes] | ||||
|                                 [(fx= bytes EAGAIN-error-code) | ||||
|                                  ;(raise-continuable  | ||||
|                                  ;  (make-i/o-would-block-condition port)) | ||||
|                                  (call/cc  | ||||
|                                    (lambda (k)  | ||||
|                                      (add-io-event fd k 'r) | ||||
|  | @ -1351,8 +1349,6 @@ | |||
|                               (cond | ||||
|                                 [(fx>= bytes 0) bytes] | ||||
|                                 [(fx= bytes EAGAIN-error-code) | ||||
|                                  ;(raise-continuable  | ||||
|                                  ;  (make-i/o-would-block-condition port)) | ||||
|                                  (call/cc  | ||||
|                                    (lambda (k) | ||||
|                                      (add-io-event fd k 'w) | ||||
|  |  | |||
|  | @ -0,0 +1,273 @@ | |||
| ;;; Ikarus Scheme -- A compiler for R6RS Scheme. | ||||
| ;;; Copyright (C) 2006,2007,2008  Abdulaziz Ghuloum | ||||
| ;;;  | ||||
| ;;; This program is free software: you can redistribute it and/or modify | ||||
| ;;; it under the terms of the GNU General Public License version 3 as | ||||
| ;;; published by the Free Software Foundation. | ||||
| ;;;  | ||||
| ;;; This program is distributed in the hope that it will be useful, but | ||||
| ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| ;;; General Public License for more details. | ||||
| ;;;  | ||||
| ;;; You should have received a copy of the GNU General Public License | ||||
| ;;; along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
| 
 | ||||
| (define-syntax define-ontology | ||||
|   (lambda (x) | ||||
|     (define (make-ontology main ls) | ||||
|       (define (set-cons x ls) | ||||
|         (cond | ||||
|           [(memq x ls) ls] | ||||
|           [else (cons x ls)])) | ||||
|       (define (union ls1 ls2) | ||||
|         (cond | ||||
|           [(null? ls1) ls2] | ||||
|           [else (union (cdr ls1) (set-cons (car ls1) ls2))])) | ||||
|       (define (difference ls1 ls2) | ||||
|         (cond | ||||
|           [(null? ls1) '()] | ||||
|           [(memq (car ls1) ls2) (difference (cdr ls1) ls2)] | ||||
|           [else (cons (car ls1) (difference (cdr ls1) ls2))])) | ||||
|       (define (collect-names ls) | ||||
|         (syntax-case ls () | ||||
|           [() '()] | ||||
|           [((name (of name* ...)) . rest) | ||||
|            (union (cons #'name #'(name* ...)) (collect-names #'rest))])) | ||||
|       (define (expand x all) | ||||
|         (define (lookup x ls) | ||||
|           (cond | ||||
|             [(null? ls) (values 'tag '())] | ||||
|             [else | ||||
|              (let ([a (car ls)]) | ||||
|                (cond | ||||
|                  [(eq? x (car a))  | ||||
|                   (values (cadr a) (cdr ls))] | ||||
|                  [else | ||||
|                   (let-values ([(xp ls) (lookup x (cdr ls))]) | ||||
|                     (values xp (cons a ls)))]))])) | ||||
|         (let f ([x x] [ls ls]) | ||||
|           (let-values ([(xp ls) (lookup x ls)]) | ||||
|             (cond | ||||
|               [(pair? xp) | ||||
|                (cons (car xp) (map (lambda (x) (f x ls)) (cdr xp)))] | ||||
|               [(eq? xp 'tag) x] | ||||
|               [else (error 'expand-lookup "invalid" xp)])))) | ||||
|       (define (rename alist x) | ||||
|         (cond | ||||
|           [(symbol? x) (cdr (assq x alist))] | ||||
|           [else (cons (car x) (map (lambda (x) (rename alist x)) (cdr x)))])) | ||||
|       (define (enumerate ls) | ||||
|         (let f ([i 1] [ls ls]) | ||||
|           (cond | ||||
|             [(null? ls) '()] | ||||
|             [else (cons i (f (* i 2) (cdr ls)))]))) | ||||
|       (define (unique-elements x) | ||||
|         (define (exclude m ls) | ||||
|           (cond | ||||
|             [(null? ls) '()] | ||||
|             [(zero? (bitwise-and m (car ls))) | ||||
|              (cons (car ls) (exclude m (cdr ls)))] | ||||
|             [else (exclude m (cdr ls))])) | ||||
|         (define (exclusive* m* x**) | ||||
|           (cond | ||||
|             [(null? (cdr m*)) (values (car m*) (car x**))] | ||||
|             [else | ||||
|              (let-values ([(m1 x1*) (values (car m*) (car x**))] | ||||
|                           [(m2 x2*) (exclusive* (cdr m*) (cdr x**))]) | ||||
|                (let ([x1* (exclude m2 x1*)] | ||||
|                      [x2* (exclude m1 x2*)]) | ||||
|                  (values (bitwise-ior m1 m2) (append x1* x2*))))])) | ||||
|         (define (inclusive* m* x**) | ||||
|           (cond | ||||
|             [(null? (cdr m*)) (values (car m*) (car x**))] | ||||
|             [else | ||||
|              (let-values ([(m1 x1*) (values (car m*) (car x**))] | ||||
|                           [(m2 x2*) (inclusive* (cdr m*) (cdr x**))]) | ||||
|                (values (bitwise-ior m1 m2) | ||||
|                        (remp not | ||||
|                          (apply append | ||||
|                            (map (lambda (x) | ||||
|                                   (map (lambda (y) | ||||
|                                          (if (= (bitwise-and m1 m2 x) | ||||
|                                                 (bitwise-and m1 m2 y)) | ||||
|                                              (bitwise-ior x y) | ||||
|                                              #f)) | ||||
|                                        x2*)) | ||||
|                                 x1*)))))])) | ||||
|         (define (f* ls) | ||||
|           (cond | ||||
|             [(null? ls) (values '() '())] | ||||
|             [else | ||||
|              (let-values ([(m x*) (f (car ls))] | ||||
|                           [(m* x**) (f* (cdr ls))]) | ||||
|                (values (cons m m*) (cons x* x**)))])) | ||||
|         (define (f x) | ||||
|           (cond | ||||
|             [(integer? x) (values x (list x))] | ||||
|             [else | ||||
|              (let ([tag (car x)] [ls (cdr x)]) | ||||
|                (let-values ([(m* x**) (f* ls)]) | ||||
|                  (case tag | ||||
|                    [(exclusive) (exclusive* m* x**)] | ||||
|                    [(inclusive) (inclusive* m* x**)] | ||||
|                    [else (error 'f "invalid")])))])) | ||||
|         (let-values ([(m ls) (f x)]) | ||||
|           ls)) | ||||
|       (define (expand-names alist) | ||||
|         (lambda (n) | ||||
|           (let f ([alist alist]) | ||||
|             (cond | ||||
|               [(null? alist) '()] | ||||
|               [(zero? (bitwise-and n (cdar alist))) | ||||
|                (f (cdr alist))] | ||||
|               [else  | ||||
|                (cons (caar alist) (f (cdr alist)))])))) | ||||
|       (define (extend-alist* ls alist) | ||||
|         (define (extend-alist x alist) | ||||
|           (define (lookup x) | ||||
|             (cond | ||||
|               [(assq x alist) => cdr] | ||||
|               [else (error 'lookup "cannot find" x alist)])) | ||||
|           (let ([name (car x)] [info (cadr x)]) | ||||
|             (let ([tag (car info)] [x* (map lookup (cdr info))]) | ||||
|               (case tag | ||||
|                 [(exclusive)  | ||||
|                  (cons (cons name (apply bitwise-ior x*)) alist)] | ||||
|                 [(inclusive) | ||||
|                  (assert (= (apply bitwise-ior x*) (apply bitwise-and x*))) | ||||
|                  (cons (cons name (apply bitwise-ior x*)) alist)] | ||||
|                 [else (assert #f)])))) | ||||
|         (cond | ||||
|           [(null? ls) alist] | ||||
|           [else | ||||
|            (extend-alist (car ls) | ||||
|              (extend-alist* (cdr ls) alist))])) | ||||
|       (let* ([names (difference (collect-names ls) (map car ls))] | ||||
|              [names-alist (map cons names (enumerate names))]) | ||||
|         (let* ([expanded (expand main ls)] | ||||
|                [renamed (rename names-alist expanded)]) | ||||
|           (let* ([unique* (list-sort < (unique-elements renamed))] | ||||
|                  [canonicals (map (expand-names names-alist) unique*)]) | ||||
|             (let* ([canonical-alist (map cons canonicals (enumerate canonicals))] | ||||
|                    [seed-alist | ||||
|                     (map  | ||||
|                       (lambda (x)  | ||||
|                         (let ([ls (filter (lambda (y) (memq x (car y))) canonical-alist)]) | ||||
|                           (cons x (apply bitwise-ior (map cdr ls))))) | ||||
|                       names)]) | ||||
|               (extend-alist* ls seed-alist)))))) | ||||
|     (define (property-names ls) | ||||
|       (cond | ||||
|         [(null? ls) '()] | ||||
|         [else | ||||
|          (let ([fst (car ls)] [rest (property-names (cdr ls))]) | ||||
|            (let ([name (car fst)] [info (cadr fst)]) | ||||
|              (case (car info) | ||||
|                [(exclusive) rest] | ||||
|                [(inclusive) (append (cdr info) rest)] | ||||
|                [else (assert #f)])))])) | ||||
|     (define (generate-base-cases T main ls) | ||||
|       (define (value-name x) | ||||
|         (datum->syntax T | ||||
|           (string->symbol | ||||
|             (string-append  | ||||
|               (symbol->string (syntax->datum T)) | ||||
|               ":"  | ||||
|               (symbol->string x))))) | ||||
|       (define (predicate-name x) | ||||
|         (datum->syntax T | ||||
|           (string->symbol | ||||
|             (string-append  | ||||
|               (symbol->string (syntax->datum T)) | ||||
|               ":"  | ||||
|               (symbol->string x) | ||||
|               "?")))) | ||||
|       (let ([maind (syntax->datum main)] [lsd (syntax->datum ls)]) | ||||
|         (let ([alist (make-ontology maind lsd)] | ||||
|               [pnames (property-names lsd)]) | ||||
|           (let ([alist (remp (lambda (x) (memq (car x) pnames)) alist)]) | ||||
|             (map  | ||||
|               (lambda (x) (list (value-name (car x)) | ||||
|                                 (predicate-name (car x)) | ||||
|                                 (cdr x))) | ||||
|               alist))))) | ||||
|     (syntax-case x () | ||||
|       [(_ T T:description T? T:=? T:and T:or [name cls] [name* cls*] ...) | ||||
|        (with-syntax ([((name* predname* val*) ...) | ||||
|                       (generate-base-cases #'T #'name | ||||
|                         #'([name cls] [name* cls*] ...))]) | ||||
|          #'(begin | ||||
|              (define-record-type (T make-T T?) | ||||
|                (sealed     #t) | ||||
|                (fields (immutable n T-n))) | ||||
|              (define (T:and x0 x1) | ||||
|                (make-T (bitwise-and (T-n x0) (T-n x1)))) | ||||
|              (define (T:or x0 x1) | ||||
|                (make-T (bitwise-ior (T-n x0) (T-n x1)))) | ||||
|              (define (test x v) | ||||
|                (let ([bits (bitwise-and x v)]) | ||||
|                  (cond | ||||
|                    [(= 0 (bitwise-and x v))  'no] | ||||
|                    [(= v (bitwise-ior x v)) 'yes] | ||||
|                    [else                  'maybe]))) | ||||
|              (define name* (make-T val*)) ... | ||||
|              (define (predname* x) (test (T-n x) val*)) ... | ||||
|              (define (T:description x) | ||||
|                (let* ([ls '()] | ||||
|                       [ls | ||||
|                        (case (predname* x) | ||||
|                          [(yes) (cons '(name* yes) ls)] | ||||
|                          [else  ls])] | ||||
|                       ...) | ||||
|                  ls)) | ||||
|              (define (T:=? x y) | ||||
|                (= (T-n x) (T-n y))) | ||||
|              ))]))) | ||||
| 
 | ||||
| (define-ontology T T:description T? T=? T:and T:or | ||||
|   [object        (inclusive obj-tag obj-immediacy obj-truth)] | ||||
|   [obj-immediacy (exclusive nonimmediate immediate)] | ||||
|   [immediate     (exclusive fixnum boolean null char void)] | ||||
|   [obj-truth     (exclusive false non-false)] | ||||
|   [obj-tag       (exclusive procedure string vector pair null | ||||
|                             boolean char number void other-object)] | ||||
|   [boolean       (exclusive true false)] | ||||
|   [number        (inclusive number-tag number-size number-exactness)] | ||||
|   [number-size   (exclusive negative zero positive)] | ||||
|   [number-tag    (exclusive fixnum flonum other-number)] | ||||
|   [number-exactness (exclusive exact inexact)] | ||||
|   [exact         (exclusive fixnum other-exact)] | ||||
|   [inexact       (exclusive flonum other-inexact)] | ||||
|   ) | ||||
| 
 | ||||
| #!eof | ||||
| 
 | ||||
| (define (do-test expr result expected) | ||||
|   (if (equal? result expected) | ||||
|       (printf "OK: ~s -> ~s\n" expr expected) | ||||
|       (error 'test "failed/got/expected" expr result expected))) | ||||
| 
 | ||||
| (define-syntax test | ||||
|   (syntax-rules () | ||||
|     [(_ expr expected) (do-test 'expr expr 'expected)])) | ||||
| 
 | ||||
| (test (T:object? T:object) yes) | ||||
| (test (T:object? T:true)   yes) | ||||
| (test (T:true? T:object)   maybe) | ||||
| (test (T:true? T:true)     yes) | ||||
| (test (T:true? T:false)    no) | ||||
| (test (T:true? T:null)     no) | ||||
| (test (T:non-false? T:true) yes) | ||||
| (test (T:non-false? T:null) yes) | ||||
| (test (T:non-false? T:false) no) | ||||
| (test (T:non-false? T:boolean) maybe) | ||||
| (test (T:non-false? T:object) maybe) | ||||
| (test (T:boolean? T:true) yes) | ||||
| (test (T:boolean? T:false) yes) | ||||
| (test (T:boolean? (T:or T:true T:false)) yes) | ||||
| (test (T:boolean? (T:and T:true T:false)) no) | ||||
| (test (T:object? (T:and T:true T:false)) no) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1 +1 @@ | |||
| 1526 | ||||
| 1527 | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ | |||
| (import (except (ikarus)  | ||||
|           assembler-output optimize-cp optimize-level | ||||
|           cp0-size-limit cp0-effort-limit expand/optimize | ||||
|           optimizer-output)) | ||||
|           optimizer-output tag-analysis-output perform-tag-analysis)) | ||||
| (import (ikarus.compiler)) | ||||
| (import (except (psyntax system $bootstrap) | ||||
|                 eval-core  | ||||
|  | @ -27,6 +27,7 @@ | |||
|                 compile-core-expr-to-port)) | ||||
| (import (ikarus.compiler)) ; just for fun | ||||
| (optimize-level 2) | ||||
| (perform-tag-analysis #t) | ||||
| (pretty-width 160) | ||||
| ((pretty-format 'fix) ((pretty-format 'letrec))) | ||||
| 
 | ||||
|  | @ -1414,8 +1415,6 @@ | |||
|     [&no-nans-rcd] | ||||
|     [&interrupted-rtd] | ||||
|     [&interrupted-rcd] | ||||
|     [&i/o-would-block-rtd] | ||||
|     [&i/o-would-block-rcd] | ||||
|     [tcp-connect                      i] | ||||
|     [udp-connect                      i] | ||||
|     [tcp-connect-nonblocking          i] | ||||
|  | @ -1429,15 +1428,13 @@ | |||
|     [input-socket-buffer-size         i] | ||||
|     [output-socket-buffer-size        i] | ||||
| 
 | ||||
|     ;[&i/o-would-block                 i] | ||||
|     ;[make-i/o-would-block-condition   i] | ||||
|     ;[i/o-would-block-condition?       i] | ||||
|     ;[i/o-would-block-port             i] | ||||
|     [ellipsis-map ] | ||||
|     [optimize-cp i] | ||||
|     [optimize-level i] | ||||
|     [cp0-size-limit i] | ||||
|     [cp0-effort-limit i] | ||||
|     [tag-analysis-output i] | ||||
|     [perform-tag-analysis i] | ||||
|   )) | ||||
| 
 | ||||
| (define (macro-identifier? x)  | ||||
|  |  | |||
|  | @ -39,11 +39,6 @@ | |||
|     (tag-test (prm 'mref x (K (- ptag))) smask stag) | ||||
|     (make-constant #f))) | ||||
| 
 | ||||
| (define (safe-ref x disp mask tag) | ||||
|   (seq* | ||||
|     (interrupt-unless (tag-test x mask tag)) | ||||
|     (prm 'mref x (K (- disp tag))))) | ||||
| 
 | ||||
| (define (dirty-vector-set address) | ||||
|   (define shift-bits 2) | ||||
|   (prm 'mset  | ||||
|  | @ -59,9 +54,14 @@ | |||
|      (if (or (fixnum? t) (immediate? t)) | ||||
|          (prm 'nop) | ||||
|          (dirty-vector-set addr))] | ||||
|     [(known x t) | ||||
|      (cond | ||||
|        [(eq? (T:immediate? t) 'yes) | ||||
|         (record-optimization 'smart-dirty-vec t) | ||||
|         (nop)] | ||||
|        [else (smart-dirty-vector-set addr x)])] | ||||
|     [else (dirty-vector-set addr)])) | ||||
| 
 | ||||
| 
 | ||||
| (define (slow-mem-assign v x i) | ||||
|   (with-tmp ([t (prm 'int+ x (K i))]) | ||||
|     (make-seq  | ||||
|  | @ -74,6 +74,12 @@ | |||
|      (if (or (fixnum? t) (immediate? t)) | ||||
|          (prm 'mset x (K i) (T v)) | ||||
|          (slow-mem-assign v x i))] | ||||
|     [(known expr t) | ||||
|      (cond | ||||
|        [(eq? (T:immediate? t) 'yes) | ||||
|         (record-optimization 'mem-assign v) | ||||
|         (prm 'mset x (K i) (T expr))] | ||||
|        [else (slow-mem-assign expr x i)])] | ||||
|     [else (slow-mem-assign v x i)])) | ||||
| 
 | ||||
| (define (align-code unknown-amt known-amt) | ||||
|  | @ -111,6 +117,7 @@ | |||
| (define (equable-constant? x) | ||||
|   (struct-case x  | ||||
|     [(constant xv) (equable? xv)] | ||||
|     [(known x t) (equable-constant? x)] | ||||
|     [else #f])) | ||||
| 
 | ||||
| (define-primop eqv? safe | ||||
|  | @ -151,7 +158,8 @@ | |||
|   [(E x) (nop)]) | ||||
| 
 | ||||
| (define-primop boolean? safe | ||||
|   [(P x) (tag-test (T x) bool-mask bool-tag)] | ||||
|   [(P x)  | ||||
|    (tag-test (T x) bool-mask bool-tag)] | ||||
|   [(E x) (nop)]) | ||||
| 
 | ||||
| (define-primop bwp-object? safe | ||||
|  | @ -195,6 +203,8 @@ | |||
|                   (prm '= x (T (K (car ls)))) | ||||
|                   (K #t) | ||||
|                   (f (cdr ls)))])))])] | ||||
|      [(known expr t)  | ||||
|       (cogen-pred-$memq x expr)] | ||||
|      [else (interrupt)])] | ||||
|   [(V x ls) | ||||
|    (struct-case ls | ||||
|  | @ -211,6 +221,8 @@ | |||
|                   (prm '= x (T (K (car ls)))) | ||||
|                   (T (K ls)) | ||||
|                   (f (cdr ls)))])))])] | ||||
|      [(known expr t)  | ||||
|       (cogen-value-$memq x expr)] | ||||
|      [else (interrupt)])] | ||||
|   [(E x ls) (nop)]) | ||||
| 
 | ||||
|  | @ -223,6 +235,7 @@ | |||
|       (cond | ||||
|         [(list? ls) (nop)] | ||||
|         [else (interrupt)])] | ||||
|      [(known) (error 'translate "memq")] | ||||
|      [else (interrupt)])]) | ||||
| 
 | ||||
| (define (equable? x) | ||||
|  | @ -236,6 +249,7 @@ | |||
|         [(and (list? lsv) (andmap equable? lsv)) | ||||
|          (cogen-value-$memq x ls)] | ||||
|         [else (interrupt)])] | ||||
|      [(known) (error 'translate "memv")] | ||||
|      [else (interrupt)])] | ||||
|   [(P x ls)  | ||||
|    (struct-case ls | ||||
|  | @ -244,6 +258,7 @@ | |||
|         [(and (list? lsv) (andmap equable? lsv)) | ||||
|          (cogen-pred-$memq x ls)] | ||||
|         [else (interrupt)])] | ||||
|      [(known) (error 'translate "memv")] | ||||
|      [else (interrupt)])] | ||||
|   [(E x ls) | ||||
|    (struct-case ls | ||||
|  | @ -251,6 +266,7 @@ | |||
|       (cond | ||||
|         [(list? lsv) (nop)] | ||||
|         [else (interrupt)])] | ||||
|      [(known) (error 'translate "memv")] | ||||
|      [else (interrupt)])]) | ||||
| 
 | ||||
| /section) | ||||
|  | @ -258,7 +274,8 @@ | |||
| (section ;;; pairs  | ||||
| 
 | ||||
| (define-primop pair? safe | ||||
|   [(P x) (tag-test (T x) pair-mask pair-tag)] | ||||
|   [(P x) | ||||
|    (tag-test (T x) pair-mask pair-tag)] | ||||
|   [(E x) (nop)]) | ||||
| 
 | ||||
| (define-primop cons safe | ||||
|  | @ -290,29 +307,41 @@ | |||
|      (prm 'mset x (K (- disp-cdr pair-tag)) (T v)) | ||||
|      (smart-dirty-vector-set x v))]) | ||||
| 
 | ||||
| (define (assert-pair x) | ||||
|   (struct-case x | ||||
|     [(known x t) | ||||
|      (case (T:pair? t) | ||||
|        [(yes) (record-optimization 'assert-pair x) (nop)] | ||||
|        [(no)  (interrupt)] | ||||
|        [else  (assert-pair x)])] | ||||
|     [else | ||||
|      (interrupt-unless (tag-test x pair-mask pair-tag))])) | ||||
| 
 | ||||
| (define-primop car safe | ||||
|   [(V x) | ||||
|    (safe-ref (T x) disp-car pair-mask pair-tag)] | ||||
|   [(E x) | ||||
|    (interrupt-unless (tag-test (T x) pair-mask pair-tag))]) | ||||
|    (with-tmp ([x (T x)]) | ||||
|      (assert-pair x) | ||||
|      (prm 'mref x (K (- disp-car pair-tag))))] | ||||
|   [(E x) (assert-pair (T x))]) | ||||
| 
 | ||||
| (define-primop cdr safe | ||||
|   [(V x) | ||||
|    (safe-ref (T x) disp-cdr pair-mask pair-tag)] | ||||
|   [(E x) | ||||
|    (interrupt-unless (tag-test (T x) pair-mask pair-tag))]) | ||||
|    (with-tmp ([x (T x)]) | ||||
|      (assert-pair x) | ||||
|      (prm 'mref x (K (- disp-cdr pair-tag))))] | ||||
|   [(E x) (assert-pair (T x))]) | ||||
| 
 | ||||
| (define-primop set-car! safe | ||||
|   [(E x v) | ||||
|    (with-tmp ([x (T x)]) | ||||
|      (interrupt-unless (tag-test x pair-mask pair-tag)) | ||||
|      (assert-pair x) | ||||
|      (prm 'mset x (K (- disp-car pair-tag)) (T v)) | ||||
|      (smart-dirty-vector-set x v))]) | ||||
| 
 | ||||
| (define-primop set-cdr! safe | ||||
|   [(E x v) | ||||
|    (with-tmp ([x (T x)]) | ||||
|      (interrupt-unless (tag-test x pair-mask pair-tag)) | ||||
|      (assert-pair x) | ||||
|      (prm 'mset x (K (- disp-cdr pair-tag)) (T v)) | ||||
|      (smart-dirty-vector-set x v))]) | ||||
| 
 | ||||
|  | @ -322,7 +351,7 @@ | |||
|     [(null? ls) (T val)] | ||||
|     [else  | ||||
|      (with-tmp ([x (expand-cxr val (cdr ls))])  | ||||
|        (interrupt-unless (tag-test x pair-mask pair-tag)) | ||||
|        (assert-pair x) | ||||
|        (prm 'mref x  | ||||
|           (case (car ls)  | ||||
|             [(a)  (K (- disp-car pair-tag))] | ||||
|  | @ -408,25 +437,60 @@ | |||
| (section ;;; vectors | ||||
|   (section ;;; helpers | ||||
|     (define (vector-range-check x idx) | ||||
|       (define (check-fx i) | ||||
|         (seq* | ||||
|            (interrupt-unless (tag-test (T x) vector-mask vector-tag)) | ||||
|            (with-tmp ([len (cogen-value-$vector-length x)]) | ||||
|              (interrupt-unless (prm 'u< (K (* i wordsize)) len)) | ||||
|              (interrupt-unless-fixnum len)))) | ||||
|       (define (check-? idx) | ||||
|         (seq* | ||||
|           (interrupt-unless (tag-test (T x) vector-mask vector-tag)) | ||||
|       (define (check-non-vector x idx) | ||||
|         (define (check-fx idx) | ||||
|           (seq* | ||||
|              (interrupt-unless (tag-test (T x) vector-mask vector-tag)) | ||||
|              (with-tmp ([len (cogen-value-$vector-length x)]) | ||||
|                (interrupt-unless (prm 'u< (T idx) len)) | ||||
|                (interrupt-unless-fixnum len)))) | ||||
|         (define (check-? idx) | ||||
|           (seq* | ||||
|             (interrupt-unless (tag-test (T x) vector-mask vector-tag)) | ||||
|             (with-tmp ([len (cogen-value-$vector-length x)]) | ||||
|               (interrupt-unless (prm 'u< (T idx) len)) | ||||
|               (with-tmp ([t (prm 'logor len (T idx))]) | ||||
|                 (interrupt-unless-fixnum t))))) | ||||
|         (struct-case idx | ||||
|           [(constant i) | ||||
|            (if (and (fixnum? i) (fx>= i 0))  | ||||
|                (check-fx idx) | ||||
|                (check-? idx))] | ||||
|           [(known idx idx-t) | ||||
|            (case (T:fixnum? idx-t) | ||||
|              [(yes) (check-fx idx)] | ||||
|              [(maybe) (vector-range-check x idx)] | ||||
|              [else | ||||
|               (printf "vector check with mismatch index tag ~s" idx-t) | ||||
|               (vector-range-check x idx)])] | ||||
|           [else (check-? idx)])) | ||||
|       (define (check-vector x idx) | ||||
|         (define (check-fx idx) | ||||
|           (with-tmp ([len (cogen-value-$vector-length x)]) | ||||
|             (interrupt-unless (prm 'u< (T idx) len)) | ||||
|             (with-tmp ([t (prm 'logor len (T idx))]) | ||||
|               (interrupt-unless-fixnum t))))) | ||||
|       (struct-case idx | ||||
|         [(constant i) | ||||
|          (if (and (fixnum? i) (fx>= i 0))  | ||||
|              (check-fx i) | ||||
|              (check-? idx))] | ||||
|         [else (check-? idx)])) | ||||
|             (interrupt-unless (prm 'u< (T idx) len)))) | ||||
|         (define (check-? idx) | ||||
|           (seq* | ||||
|             (interrupt-unless-fixnum (T idx))  | ||||
|             (with-tmp ([len (cogen-value-$vector-length x)]) | ||||
|               (interrupt-unless (prm 'u< (T idx) len))))) | ||||
|         (struct-case idx | ||||
|           [(constant i) | ||||
|            (if (and (fixnum? i) (fx>= i 0))  | ||||
|                (check-fx idx) | ||||
|                (check-? idx))] | ||||
|           [(known idx idx-t) | ||||
|            (case (T:fixnum? idx-t) | ||||
|              [(yes) (check-fx idx)] | ||||
|              [(no)  (interrupt)] | ||||
|              [else  (check-vector x idx)])] | ||||
|           [else (check-? idx)]))  | ||||
|       (struct-case x | ||||
|         [(known x t) | ||||
|          (case (T:vector? t) | ||||
|            [(yes) (record-optimization 'check-vector x) (check-vector x idx)] | ||||
|            [(no) (interrupt)] | ||||
|            [else (check-non-vector x idx)])] | ||||
|         [else (check-non-vector x idx)])) | ||||
|     /section) | ||||
| 
 | ||||
| (define-primop vector? unsafe | ||||
|  | @ -437,30 +501,31 @@ | |||
|   [(V len) | ||||
|    (struct-case len | ||||
|      [(constant i) | ||||
|       (unless (fixnum? i) (interrupt)) | ||||
|       (with-tmp ([v (prm 'alloc | ||||
|                         (K (align (+ (* i wordsize) disp-vector-data))) | ||||
|                         (K vector-tag))]) | ||||
|           (prm 'mset v  | ||||
|                (K (- disp-vector-length vector-tag)) | ||||
|                (K (* i fx-scale))) | ||||
|           v)] | ||||
|       (if (fixnum? i) | ||||
|           (interrupt) | ||||
|           (with-tmp ([v (prm 'alloc | ||||
|                             (K (align (+ (* i wordsize) disp-vector-data))) | ||||
|                             (K vector-tag))]) | ||||
|               (prm 'mset v  | ||||
|                    (K (- disp-vector-length vector-tag)) | ||||
|                    (K (* i fx-scale))) | ||||
|               v))] | ||||
|      [(known expr t) | ||||
|       (cogen-value-$make-vector expr)] | ||||
|      [else | ||||
|       (with-tmp ([alen (align-code (T len) disp-vector-data)]) | ||||
|         (with-tmp ([v (prm 'alloc alen (K vector-tag))]) | ||||
|             (prm 'mset v (K (- disp-vector-length vector-tag)) (T len)) | ||||
|             v))])] | ||||
|           (prm 'mset v (K (- disp-vector-length vector-tag)) (T len)) | ||||
|           v))])] | ||||
|   [(P len) (K #t)] | ||||
|   [(E len) (nop)]) | ||||
| 
 | ||||
| (define-primop make-vector safe | ||||
|   [(V len)  | ||||
|    (with-tmp ([x (make-forcall "ikrt_make_vector1" (list (T len)))])  | ||||
|    (with-tmp ([x (make-forcall "ikrt_make_vector1" (list (T len)))]) | ||||
|       (interrupt-when (prm '= x (K 0))) | ||||
|       x)]) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| (define-primop $vector-ref unsafe | ||||
|   [(V x i) | ||||
|    (or  | ||||
|  | @ -470,6 +535,8 @@ | |||
|              (fx>= i 0) | ||||
|              (prm 'mref (T x)  | ||||
|                   (K (+ (* i wordsize) (- disp-vector-data vector-tag)))))] | ||||
|        [(known i t) | ||||
|         (cogen-value-$vector-ref x i)] | ||||
|        [else #f]) | ||||
|      (prm 'mref (T x)  | ||||
|         (prm 'int+ (T i) (K (- disp-vector-data vector-tag)))))] | ||||
|  | @ -482,16 +549,30 @@ | |||
| 
 | ||||
| (define-primop vector-length safe | ||||
|   [(V x) | ||||
|    (seq* | ||||
|      (interrupt-unless (tag-test (T x) vector-mask vector-tag)) | ||||
|      (with-tmp ([t (cogen-value-$vector-length x)]) | ||||
|        (interrupt-unless-fixnum t) | ||||
|        t))] | ||||
|    (struct-case x | ||||
|      [(known x t) | ||||
|       (case (T:vector? t) | ||||
|         [(yes) (record-optimization 'vector-length x) (cogen-value-$vector-length x)] | ||||
|         [(no)  (interrupt)] | ||||
|         [else  (cogen-value-vector-length x)])] | ||||
|      [else | ||||
|       (seq* | ||||
|         (interrupt-unless (tag-test (T x) vector-mask vector-tag)) | ||||
|         (with-tmp ([t (cogen-value-$vector-length x)]) | ||||
|           (interrupt-unless-fixnum t) | ||||
|           t))])] | ||||
|   [(E x) | ||||
|    (seq* | ||||
|      (interrupt-unless (tag-test (T x) vector-mask vector-tag)) | ||||
|      (with-tmp ([t (cogen-value-$vector-length x)]) | ||||
|        (interrupt-unless-fixnum t)))] | ||||
|    (struct-case x | ||||
|      [(known x t) | ||||
|       (case (T:vector? t) | ||||
|         [(yes) (record-optimization 'vector-length x) (nop)] | ||||
|         [(no)  (interrupt)] | ||||
|         [else  (cogen-effect-vector-length x)])] | ||||
|      [else | ||||
|       (seq* | ||||
|         (interrupt-unless (tag-test (T x) vector-mask vector-tag)) | ||||
|         (with-tmp ([t (cogen-value-$vector-length x)]) | ||||
|           (interrupt-unless-fixnum t)))])] | ||||
|   [(P x)  | ||||
|    (seq* (cogen-effect-vector-length x) (K #t))]) | ||||
| 
 | ||||
|  | @ -512,6 +593,8 @@ | |||
|       (mem-assign v (T x)  | ||||
|          (+ (* i wordsize) | ||||
|             (- disp-vector-data vector-tag)))] | ||||
|      [(known i t) | ||||
|       (cogen-effect-$vector-set! x i v)] | ||||
|      [else | ||||
|       (mem-assign v  | ||||
|          (prm 'int+ (T x) (T i)) | ||||
|  | @ -558,6 +641,7 @@ | |||
|       (prm 'mref (T x) | ||||
|          (K (+ (- disp-closure-data closure-tag) | ||||
|                (* i wordsize))))] | ||||
|      [(known) (error 'translate "$cpref")] | ||||
|      [else (interrupt)])]) | ||||
| 
 | ||||
| /section) | ||||
|  | @ -635,6 +719,7 @@ | |||
|             (interrupt-when (cogen-pred-$unbound-object? v)) | ||||
|             v) | ||||
|           (interrupt))] | ||||
|      [(known) (error 'translate "top-level-value")] | ||||
|      [else | ||||
|       (with-tmp ([x (T x)]) | ||||
|         (interrupt-unless (cogen-pred-symbol? x)) | ||||
|  | @ -648,6 +733,7 @@ | |||
|           (with-tmp ([v (cogen-value-$symbol-value x)]) | ||||
|             (interrupt-when (cogen-pred-$unbound-object? v))) | ||||
|           (interrupt))] | ||||
|      [(known) (error 'translate "top-level-value")] | ||||
|      [else | ||||
|       (with-tmp ([x (T x)]) | ||||
|         (interrupt-unless (cogen-pred-symbol? x)) | ||||
|  | @ -659,7 +745,6 @@ | |||
|   [(E x v) | ||||
|    (with-tmp ([x (T x)] [v (T v)]) | ||||
|      (prm 'mset x (K (- disp-symbol-record-proc symbol-ptag)) v) | ||||
|      ;(prm 'mset x (K (- disp-symbol-error-function symbol-tag)) v) | ||||
|      (dirty-vector-set x))]) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -737,11 +822,13 @@ | |||
|     [(constant a) | ||||
|      (unless (fixnum? a) (interrupt)) | ||||
|      (prm 'int* (T b) (K a))] | ||||
|     [(known a t) (cogen-value-$fx* a b)] | ||||
|     [else | ||||
|      (struct-case b | ||||
|        [(constant b) | ||||
|         (unless (fixnum? b) (interrupt)) | ||||
|         (prm 'int* (T a) (K b))] | ||||
|        [(known b t) (cogen-value-$fx* a b)] | ||||
|        [else | ||||
|         (prm 'int* (T a) (prm 'sra (T b) (K fx-shift)))])])] | ||||
|   [(P x y) (K #t)] | ||||
|  | @ -778,6 +865,7 @@ | |||
|      [(constant i)  | ||||
|       (unless (fixnum? i) (interrupt)) | ||||
|       (prm 'sll (T x) (K i))] | ||||
|      [(known i t) (cogen-value-$fxsll x i)] | ||||
|      [else  | ||||
|       (prm 'sll (T x) (prm 'sra (T i) (K fx-shift)))])] | ||||
|   [(P x i) (K #t)] | ||||
|  | @ -791,6 +879,7 @@ | |||
|       (prm 'logand  | ||||
|            (prm 'sra (T x) (K (if (> i 31) 31 i))) | ||||
|            (K (* -1 fx-scale)))] | ||||
|      [(known i t) (cogen-value-$fxsra x i)] | ||||
|      [else  | ||||
|       (with-tmp ([i (prm 'sra (T i) (K fx-shift))]) | ||||
|         (with-tmp ([i (make-conditional | ||||
|  | @ -880,6 +969,7 @@ | |||
|              (K (+ i (- disp-bignum-data record-tag)))) | ||||
|            (K 255)) | ||||
|         (K fx-shift))] | ||||
|      [(known i t) (cogen-value-$bignum-byte-ref s i)] | ||||
|      [else | ||||
|       (prm 'sll | ||||
|         (prm 'srl ;;; FIXME: bref | ||||
|  | @ -950,6 +1040,7 @@ | |||
|              (K (+ (- 7 i) (- disp-flonum-data record-tag)))) | ||||
|            (K 255)) | ||||
|         (K fx-shift))] | ||||
|      [(known) (error 'translate "$flonum-u8-ref")] | ||||
|      [else (interrupt)])] | ||||
|   [(P s i) (K #t)] | ||||
|   [(E s i) (nop)]) | ||||
|  | @ -971,6 +1062,7 @@ | |||
|       (prm 'bset/h (T x) | ||||
|          (K (+ (- 7 i) (- disp-flonum-data vector-tag))) | ||||
|             (prm 'sll (T v) (K (- 8 fx-shift))))] | ||||
|      [(known) (error 'translate "$flonum-set!")] | ||||
|      [else (interrupt)])]) | ||||
| 
 | ||||
| (define-primop $fixnum->flonum unsafe | ||||
|  | @ -992,6 +1084,13 @@ | |||
|         (if (flonum? v)  | ||||
|             (check-flonums (cdr ls) code) | ||||
|             (interrupt))] | ||||
|        [(known x t) | ||||
|         (case (T:flonum? t) | ||||
|           [(yes) | ||||
|            (record-optimization 'check-flonum x) | ||||
|            (check-flonums (cdr ls) code)] | ||||
|           [(no) (interrupt)] | ||||
|           [else (check-flonums (cons x (cdr ls)) code)])] | ||||
|        [else | ||||
|         (check-flonums (cdr ls)  | ||||
|           (with-tmp ([x (T (car ls))]) | ||||
|  | @ -1188,116 +1287,107 @@ | |||
| 
 | ||||
| (section ;;; generic arithmetic | ||||
| 
 | ||||
| (define (non-fixnum? x) | ||||
|   (struct-case x | ||||
|     [(constant i) (not (fixnum? i))] | ||||
|     [else #f])) | ||||
| 
 | ||||
| (define (or* a a*) | ||||
|   (cond | ||||
|     [(null? a*) a] | ||||
|     [(constant? (car a*)) (or* a (cdr a*))] | ||||
|     [else (or* (prm 'logor a (T (car a*))) (cdr a*))])) | ||||
| 
 | ||||
| (define (assert-fixnums a a*) | ||||
|   (cond | ||||
|     [(constant? a)  | ||||
|      (if (null? a*)  | ||||
|          (nop) | ||||
|          (assert-fixnums (car a*) (cdr a*)))] | ||||
|     [else | ||||
|      (interrupt-unless  | ||||
|        (tag-test (or* (T a) a*) fx-mask fx-tag))])) | ||||
|   (define (or* a a*) | ||||
|     (cond | ||||
|       [(null? a*) a] | ||||
|       [else (or* (prm 'logor a (T (car a*))) (cdr a*))])) | ||||
|   (define (known-fixnum? x) | ||||
|     (struct-case x | ||||
|       [(constant i) (fixnum? i)] | ||||
|       [(known x t)  | ||||
|        (case (T:fixnum? t) | ||||
|          [(yes) (record-optimization 'assert-fixnum x) #t] | ||||
|          [else  #f])] | ||||
|       [else #f])) | ||||
|   (define (known-non-fixnum? x) | ||||
|     (struct-case x | ||||
|       [(constant i) (not (fixnum? i))] | ||||
|       [(known x t) (eq? (T:fixnum? t) 'no)] | ||||
|       [else #f])) | ||||
|   (let-values ([(fx* others) (partition known-fixnum? (cons a a*))]) | ||||
|     (let-values ([(nfx* others) (partition known-non-fixnum?  others)]) | ||||
|       (cond | ||||
|         [(not (null? nfx*)) (interrupt)] | ||||
|         [(null? others)     (nop)] | ||||
|         [else | ||||
|          (interrupt-unless  | ||||
|            (tag-test (or* (T (car others)) (cdr others)) fx-mask fx-tag))])))) | ||||
| 
 | ||||
| (define (fixnum-fold-p op a a*) | ||||
|   (cond | ||||
|     [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)] | ||||
|     [else | ||||
|      (seq* | ||||
|        (assert-fixnums a a*) | ||||
|        (let f ([a a] [a* a*]) | ||||
|          (cond | ||||
|            [(null? a*) (K #t)] | ||||
|            [else | ||||
|             (let ([b (car a*)]) | ||||
|               (make-conditional | ||||
|                 (prm op (T a) (T b)) | ||||
|                 (f b (cdr a*)) | ||||
|                 (K #f)))])))])) | ||||
| 
 | ||||
| (define (fixnum-fold-e a a*) | ||||
|   (cond | ||||
|     [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)] | ||||
|     [else (assert-fixnums a a*)])) | ||||
|   (seq* | ||||
|     (assert-fixnums a a*) | ||||
|     (let f ([a a] [a* a*]) | ||||
|       (cond | ||||
|         [(null? a*) (K #t)] | ||||
|         [else | ||||
|          (let ([b (car a*)]) | ||||
|            (make-conditional | ||||
|              (prm op (T a) (T b)) | ||||
|              (f b (cdr a*)) | ||||
|              (K #f)))])))) | ||||
| 
 | ||||
| (define-primop = safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (fixnum-fold-p '= a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (fixnum-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-fixnums a a*)]) | ||||
| 
 | ||||
| (define-primop < safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (fixnum-fold-p '< a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (fixnum-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-fixnums a a*)]) | ||||
| 
 | ||||
| (define-primop <= safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (fixnum-fold-p '<= a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (fixnum-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-fixnums a a*)]) | ||||
| 
 | ||||
| (define-primop > safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (fixnum-fold-p '> a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (fixnum-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-fixnums a a*)]) | ||||
| 
 | ||||
| (define-primop >= safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (fixnum-fold-p '>= a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (fixnum-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-fixnums a a*)]) | ||||
| 
 | ||||
| (define-primop - safe | ||||
|   [(V a)  | ||||
|    (cond | ||||
|      [(non-fixnum? a) (interrupt)] | ||||
|      [else | ||||
|       (interrupt) | ||||
|       (seq* | ||||
|         (assert-fixnums a '()) | ||||
|         (prm 'int-/overflow (K 0) (T a)))])] | ||||
|    (interrupt) | ||||
|    (seq* | ||||
|      (assert-fixnums a '()) | ||||
|      (prm 'int-/overflow (K 0) (T a)))] | ||||
|   [(V a . a*) | ||||
|    (cond | ||||
|      [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)] | ||||
|      [else | ||||
|       (interrupt) | ||||
|       (seq* | ||||
|         (assert-fixnums a a*) | ||||
|         (let f ([a (T a)] [a* a*]) | ||||
|           (cond | ||||
|             [(null? a*) a] | ||||
|             [else | ||||
|              (f (prm 'int-/overflow a (T (car a*))) (cdr a*))])))])] | ||||
|    (interrupt) | ||||
|    (seq* | ||||
|      (assert-fixnums a a*) | ||||
|      (let f ([a (T a)] [a* a*]) | ||||
|        (cond | ||||
|          [(null? a*) a] | ||||
|          [else | ||||
|           (f (prm 'int-/overflow a (T (car a*))) (cdr a*))])))] | ||||
|   [(P a . a*) (seq* (assert-fixnums a a*) (K #t))] | ||||
|   [(E a . a*) (assert-fixnums a a*)]) | ||||
| 
 | ||||
| (define-primop + safe | ||||
|   [(V) (K 0)] | ||||
|   [(V a . a*) | ||||
|    (cond | ||||
|      [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)] | ||||
|      [else | ||||
|       (interrupt) | ||||
|       (seq* | ||||
|         (assert-fixnums a a*) | ||||
|         (let f ([a (T a)] [a* a*]) | ||||
|           (cond | ||||
|             [(null? a*) a] | ||||
|             [else | ||||
|              (f (prm 'int+/overflow a (T (car a*))) (cdr a*))])))])] | ||||
|    (interrupt) | ||||
|    (seq* | ||||
|      (assert-fixnums a a*) | ||||
|      (let f ([a (T a)] [a* a*]) | ||||
|        (cond | ||||
|          [(null? a*) a] | ||||
|          [else | ||||
|           (f (prm 'int+/overflow a (T (car a*))) (cdr a*))])))] | ||||
|   [(P) (K #t)] | ||||
|   [(P a . a*) (seq* (assert-fixnums a a*) (K #t))] | ||||
|   [(E) (nop)] | ||||
|  | @ -1314,27 +1404,34 @@ | |||
|   [(V x) (cogen-value-+ x (K -1))]) | ||||
| 
 | ||||
| 
 | ||||
| (define (cogen-binary-* a b) | ||||
|   (define (cogen-*-non-constants a b) | ||||
|     (interrupt) | ||||
|     (with-tmp ([a (T a)] [b (T b)]) | ||||
|       (assert-fixnum a) | ||||
|       (assert-fixnum b) | ||||
|       (prm 'int*/overflow a  | ||||
|         (prm 'sra b (K fx-shift))))) | ||||
|   (define (cogen-*-constant a b) | ||||
|     (struct-case a | ||||
|       [(constant ak) | ||||
|        (if (fx? ak) | ||||
|            (begin | ||||
|              (interrupt) | ||||
|              (with-tmp ([b (T b)]) | ||||
|                 (assert-fixnum b) | ||||
|                 (prm 'int*/overflow a b))) | ||||
|            (interrupt))] | ||||
|       [(known x t) (cogen-*-constant x b)] | ||||
|       [else #f])) | ||||
|   (or (cogen-*-constant a b) | ||||
|       (cogen-*-constant b a) | ||||
|       (cogen-*-non-constants a b))) | ||||
| 
 | ||||
| 
 | ||||
| (define-primop * safe | ||||
|   [(V) (K (fxsll 1 fx-shift))] | ||||
|   [(V a b)  | ||||
|    (struct-case a | ||||
|      [(constant ak)  | ||||
|       (cond | ||||
|         [(fx? ak) | ||||
|          (with-tmp ([b (T b)]) | ||||
|            (assert-fixnum b) | ||||
|            (prm 'int*/overflow b a))] | ||||
|         [else (interrupt)])] | ||||
|      [else  | ||||
|       (struct-case b | ||||
|         [(constant bk) | ||||
|          (cond | ||||
|            [(fx? bk)  | ||||
|             (with-tmp ([a (T a)]) | ||||
|               (assert-fixnum a) | ||||
|               (prm 'int*/overflow a b))] | ||||
|            [else (interrupt)])] | ||||
|         [else (interrupt)])])] | ||||
|   [(V a b) (cogen-binary-* a b)] | ||||
|   [(P) (K #t)] | ||||
|   [(P a . a*) (seq* (assert-fixnums a a*) (K #t))] | ||||
|   [(E) (nop)] | ||||
|  | @ -1343,17 +1440,14 @@ | |||
| (define-primop bitwise-and safe | ||||
|   [(V) (K (fxsll -1 fx-shift))] | ||||
|   [(V a . a*) | ||||
|    (cond | ||||
|      [(or (non-fixnum? a) (ormap non-fixnum? a*)) (interrupt)] | ||||
|      [else | ||||
|       (interrupt) | ||||
|       (seq* | ||||
|         (assert-fixnums a a*) | ||||
|         (let f ([a (T a)] [a* a*]) | ||||
|           (cond | ||||
|             [(null? a*) a] | ||||
|             [else | ||||
|              (f (prm 'logand a (T (car a*))) (cdr a*))])))])] | ||||
|    (interrupt) | ||||
|    (seq* | ||||
|      (assert-fixnums a a*) | ||||
|      (let f ([a (T a)] [a* a*]) | ||||
|        (cond | ||||
|          [(null? a*) a] | ||||
|          [else | ||||
|           (f (prm 'logand a (T (car a*))) (cdr a*))])))] | ||||
|   [(P) (K #t)] | ||||
|   [(P a . a*) (seq* (assert-fixnums a a*) (K #t))] | ||||
|   [(E) (nop)] | ||||
|  | @ -1367,37 +1461,14 @@ | |||
|   [(V x y) (cogen-value-- x y)]) | ||||
| 
 | ||||
| (define-primop fx* safe | ||||
|   [(V a b)  | ||||
|    (struct-case a | ||||
|      [(constant ak)  | ||||
|       (cond | ||||
|         [(fx? ak) | ||||
|          (with-tmp ([b (T b)]) | ||||
|            (assert-fixnum b) | ||||
|            (prm 'int*/overflow b a))] | ||||
|         [else (interrupt)])] | ||||
|      [else  | ||||
|       (struct-case b | ||||
|         [(constant bk) | ||||
|          (cond | ||||
|            [(fx? bk)  | ||||
|             (with-tmp ([a (T a)]) | ||||
|               (assert-fixnum a) | ||||
|               (prm 'int*/overflow a b))] | ||||
|            [else (interrupt)])] | ||||
|         [else  | ||||
|          (with-tmp ([a (T a)] [b (T b)]) | ||||
|            (assert-fixnum a) | ||||
|            (assert-fixnum b) | ||||
|            (prm 'int*/overflow  | ||||
|              (prm 'sra a (K fx-shift)) b))])])]) | ||||
|   [(V a b) (cogen-binary-* a b)]) | ||||
| 
 | ||||
| (define-primop zero? safe | ||||
|   [(P x) | ||||
|    (seq* | ||||
|      (interrupt-unless (cogen-pred-fixnum? x)) | ||||
|      (assert-fixnum x) | ||||
|      (cogen-pred-$fxzero? x))] | ||||
|   [(E x) (interrupt-unless (cogen-pred-fixnum? x))]) | ||||
|   [(E x) (assert-fixnum x)]) | ||||
| 
 | ||||
| 
 | ||||
| (define-primop fxarithmetic-shift-left safe | ||||
|  | @ -1444,7 +1515,6 @@ | |||
|       [else #f]))) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| (define-primop div safe | ||||
|   [(V x n)  | ||||
|    (struct-case n  | ||||
|  | @ -1459,6 +1529,7 @@ | |||
|                (K fx-shift))))] | ||||
|         [else | ||||
|          (interrupt)])] | ||||
|      [(known) (error 'translate "div")] | ||||
|      [else (interrupt)])]) | ||||
| 
 | ||||
| (define-primop quotient safe | ||||
|  | @ -1479,6 +1550,7 @@ | |||
|                (prm 'sra (T x) (K 1)) | ||||
|                (K (fxsll -1 fx-shift))))) | ||||
|          (interrupt))] | ||||
|     [(known expr t) (cogen-value-quotient x expr)] | ||||
|     [else (interrupt)])]) | ||||
| 
 | ||||
| /section) | ||||
|  | @ -1507,6 +1579,8 @@ | |||
|                          (K vector-tag))]) | ||||
|         (prm 'mset t (K (- disp-struct-rtd vector-tag)) (T rtd)) | ||||
|         t)] | ||||
|      [(known expr t) | ||||
|       (cogen-value-$make-struct rtd expr)] | ||||
|      [else | ||||
|       (with-tmp ([ln (align-code len disp-struct-data)]) | ||||
|         (with-tmp ([t (prm 'alloc ln (K vector-tag))]) | ||||
|  | @ -1594,71 +1668,74 @@ | |||
|   [(P x) (K #t)] | ||||
|   [(E x) (nop)]) | ||||
| 
 | ||||
| (define (non-char? x) | ||||
|   (struct-case x | ||||
|     [(constant i) (not (char? i))] | ||||
|     [else #f])) | ||||
| 
 | ||||
| (define (assert-chars a a*) | ||||
|   (cond | ||||
|     [(constant? a)  | ||||
|      (if (null? a*)  | ||||
|          (nop) | ||||
|          (assert-chars (car a*) (cdr a*)))] | ||||
|     [else | ||||
|      (interrupt-unless  | ||||
|        (tag-test (or* (T a) a*) char-mask char-tag))])) | ||||
|   (define (or* a a*) | ||||
|     (cond | ||||
|       [(null? a*) a] | ||||
|       [else (or* (prm 'logor a (T (car a*))) (cdr a*))])) | ||||
|   (define (known-char? x) | ||||
|     (struct-case x | ||||
|       [(constant i) (char? i)] | ||||
|       [(known x t) (eq? (T:char? t) 'yes)] | ||||
|       [else #f])) | ||||
|   (define (known-non-char? x) | ||||
|     (struct-case x | ||||
|       [(constant i) (not (char? i))] | ||||
|       [(known x t) (eq? (T:char? t) 'no)] | ||||
|       [else #f])) | ||||
|   (let-values ([(fx* others) (partition known-char? (cons a a*))]) | ||||
|     (let-values ([(nfx* others) (partition known-non-char?  others)]) | ||||
|       (cond | ||||
|         [(not (null? nfx*)) (interrupt)] | ||||
|         [(null? others)     (nop)] | ||||
|         [else | ||||
|          (interrupt-unless  | ||||
|            (tag-test (or* (T (car others)) (cdr others)) char-mask char-tag))])))) | ||||
| 
 | ||||
| (define (char-fold-p op a a*) | ||||
|   (cond | ||||
|     [(or (non-char? a) (ormap non-char? a*)) (interrupt)] | ||||
|     [else | ||||
|      (seq* | ||||
|        (assert-chars a a*) | ||||
|        (let f ([a a] [a* a*]) | ||||
|          (cond | ||||
|            [(null? a*) (K #t)] | ||||
|            [else | ||||
|             (let ([b (car a*)]) | ||||
|               (make-conditional | ||||
|                 (prm op (T a) (T b)) | ||||
|                 (f b (cdr a*)) | ||||
|                 (K #f)))])))])) | ||||
|   (seq* | ||||
|     (assert-chars a a*) | ||||
|     (let f ([a a] [a* a*]) | ||||
|       (cond | ||||
|         [(null? a*) (K #t)] | ||||
|         [else | ||||
|          (let ([b (car a*)]) | ||||
|            (make-conditional | ||||
|              (prm op (T a) (T b)) | ||||
|              (f b (cdr a*)) | ||||
|              (K #f)))])))) | ||||
| 
 | ||||
| (define (char-fold-e a a*) | ||||
|   (cond | ||||
|     [(or (non-char? a) (ormap non-char? a*)) (interrupt)] | ||||
|     [else (assert-chars a a*)])) | ||||
| 
 | ||||
| (define-primop char=? safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (char-fold-p '= a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (char-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-chars a a*)]) | ||||
| 
 | ||||
| (define-primop char<? safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (char-fold-p '< a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (char-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-chars a a*)]) | ||||
| 
 | ||||
| (define-primop char<=? safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (char-fold-p '<= a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (char-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-chars a a*)]) | ||||
| 
 | ||||
| (define-primop char>? safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (char-fold-p '> a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (char-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-chars a a*)]) | ||||
| 
 | ||||
| (define-primop char>=? safe | ||||
|   [(P) (interrupt)] | ||||
|   [(P a . a*) (char-fold-p '>= a a*)] | ||||
|   [(E) (interrupt)] | ||||
|   [(E a . a*) (char-fold-e a a*)]) | ||||
|   [(E a . a*) (assert-chars a a*)]) | ||||
| 
 | ||||
| /section) | ||||
| 
 | ||||
|  | @ -1683,6 +1760,8 @@ | |||
|              (K (+ n (- disp-bytevector-data bytevector-tag))) | ||||
|              (K 0)) | ||||
|          s)] | ||||
|      [(known expr t) | ||||
|       (cogen-value-$make-bytevector expr)] | ||||
|      [else | ||||
|       (with-tmp ([s (prm 'alloc  | ||||
|                       (align-code  | ||||
|  | @ -1937,6 +2016,8 @@ | |||
|              (K (- disp-string-length string-tag)) | ||||
|              (K (* n fx-scale))) | ||||
|          s)] | ||||
|      [(known expr)  | ||||
|       (cogen-value-$make-string expr)] | ||||
|      [else | ||||
|       (with-tmp ([s (prm 'alloc  | ||||
|                       (align-code (T n) disp-string-data) | ||||
|  | @ -1973,15 +2054,27 @@ | |||
|   [(P s i) (K #t)] | ||||
|   [(E s i) (nop)]) | ||||
| 
 | ||||
| (define (assert-fixnum x) | ||||
|   (struct-case x | ||||
|     [(constant i)  | ||||
|      (if (fixnum? i) (nop) (interrupt))] | ||||
|     [else (interrupt-unless (cogen-pred-fixnum? x))])) | ||||
| (define assert-fixnum  | ||||
|   (case-lambda  | ||||
|     [(x) | ||||
|      (struct-case x | ||||
|        [(constant i)  | ||||
|         (if (fixnum? i) (nop) (interrupt))] | ||||
|        [(known expr t) | ||||
|         (case (T:fixnum? t) | ||||
|           [(yes) (nop)] | ||||
|           [(no)  (interrupt)] | ||||
|           [else  (assert-fixnum expr)])] | ||||
|        [else (interrupt-unless (cogen-pred-fixnum? x))])])) | ||||
| 
 | ||||
| (define (assert-string x) | ||||
|   (struct-case x | ||||
|     [(constant s) (if (string? s) (nop) (interrupt))] | ||||
|     [(known expr t) | ||||
|      (case (T:string? t) | ||||
|        [(yes) (record-optimization 'assert-string x) (nop)] | ||||
|        [(no)  (interrupt)] | ||||
|        [else  (assert-string expr)])] | ||||
|     [else (interrupt-unless (cogen-pred-string? x))])) | ||||
| 
 | ||||
| (define-primop string-ref safe | ||||
|  | @ -2003,7 +2096,6 @@ | |||
|      (assert-string s) | ||||
|      (interrupt-unless (prm 'u< (T i) (cogen-value-$string-length s))))]) | ||||
| 
 | ||||
| 
 | ||||
| (define-primop $string-set! unsafe | ||||
|   [(E x i c) | ||||
|    (struct-case i | ||||
|  |  | |||
|  | @ -44,7 +44,6 @@ | |||
|   ) | ||||
| 
 | ||||
| (module (specify-representation) | ||||
|   ;(import object-representation) | ||||
|   (import primops) | ||||
|   (define-struct PH | ||||
|     (interruptable? p-handler p-handled? v-handler v-handled? e-handler e-handled?)) | ||||
|  | @ -108,6 +107,14 @@ | |||
|                      (prm '!= (make-no-interrupt-call x args) (K bool-f)) | ||||
|                      (make-shortcut body h)))] | ||||
|              [else (error 'with-interrupt-handler "invalid context" ctxt)])))])) | ||||
|   (define (copy-tag orig new) | ||||
|     (struct-case orig | ||||
|       [(known _ t) (make-known new t)] | ||||
|       [else new])) | ||||
|   (define (remove-tag x) | ||||
|     (struct-case x | ||||
|       [(known expr t) expr] | ||||
|       [else x])) | ||||
|   (define-syntax with-tmp | ||||
|     (lambda (x) | ||||
|       (syntax-case x () | ||||
|  | @ -116,7 +123,7 @@ | |||
|            #'(let ([lhs* rhs*] ...) | ||||
|                (let ([n* (unique-var 'lhs*)] ...) | ||||
|                  (make-bind (list n* ...) (list lhs* ...) | ||||
|                     (let ([lhs* n*] ...) | ||||
|                     (let ([lhs* (copy-tag lhs* n*)] ...) | ||||
|                       (seq* b b* ...))))))]))) | ||||
|   ;;; if ctxt is V: | ||||
|   ;;;   if cogen-value, then V | ||||
|  | @ -140,11 +147,17 @@ | |||
|          (let-values ([(lhs* rhs* arg*) (S* (cdr ls))]) | ||||
|            (let ([a (car ls)]) | ||||
|              (struct-case a | ||||
|                [(known expr type v) | ||||
|                 (let ([tmp (unique-var 'tmp)]) | ||||
|                   (values (cons tmp lhs*) | ||||
|                           (cons (V expr) rhs*) | ||||
|                           (cons (make-known tmp type v) arg*)))] | ||||
|                [(known expr type) | ||||
|                 (struct-case expr | ||||
|                   [(constant i) | ||||
|                    ;;; erase known tag | ||||
|                    (values lhs* rhs* (cons expr arg*))] | ||||
|                   [else | ||||
|                    ;(printf "known ~s ~s\n" type expr) | ||||
|                    (let ([tmp (unique-var 'tmp)]) | ||||
|                      (values (cons tmp lhs*) | ||||
|                              (cons (V expr) rhs*) | ||||
|                              (cons (make-known tmp type) arg*)))])] | ||||
|                [(constant i) | ||||
|                 (values lhs* rhs* (cons a arg*))] | ||||
|                [else | ||||
|  | @ -353,7 +366,7 @@ | |||
| 
 | ||||
|   (define (V x) ;;; erase known values | ||||
|     (struct-case x  | ||||
|       [(known x type value) | ||||
|       [(known x t) | ||||
|        (unknown-V x)] | ||||
|       [else (unknown-V x)])) | ||||
| 
 | ||||
|  | @ -439,43 +452,59 @@ | |||
|       [else (error 'cogen-E "invalid effect expr" x)])) | ||||
| 
 | ||||
|   (define (Function x) | ||||
|     (define (nonproc x) | ||||
|       (with-tmp ([x (V x)]) | ||||
|         (make-shortcut | ||||
|           (make-seq | ||||
|             (make-conditional | ||||
|               (tag-test x closure-mask closure-tag) | ||||
|               (prm 'nop) | ||||
|               (prm 'interrupt)) | ||||
|             x) | ||||
|           (V (make-funcall (make-primref 'error) | ||||
|                (list (K 'apply) (K "not a procedure") x)))))) | ||||
|     (struct-case x | ||||
|        [(primcall op args) | ||||
|     (define (Function x check?) | ||||
|       (define (nonproc x check?) | ||||
|         (cond | ||||
|           [(and (eq? op 'top-level-value) | ||||
|                 (= (length args) 1) | ||||
|                 (struct-case (car args) | ||||
|                   [(constant t)  | ||||
|                    (and (symbol? t) t)] | ||||
|                   [else #f])) => | ||||
|            (lambda (sym) | ||||
|              (record-symbol-call! sym) | ||||
|              (reset-symbol-proc! sym) | ||||
|              (prm 'mref (T (K sym)) | ||||
|                   (K (- disp-symbol-record-proc symbol-ptag))))] | ||||
|           [else (nonproc x)])] | ||||
|        [(primref op) (V x)] | ||||
|        [else (nonproc x)])) | ||||
|           [check? | ||||
|            (with-tmp ([x (V x)]) | ||||
|              (make-shortcut | ||||
|                (make-seq | ||||
|                  (make-conditional | ||||
|                    (tag-test x closure-mask closure-tag) | ||||
|                    (prm 'nop) | ||||
|                    (prm 'interrupt)) | ||||
|                  x) | ||||
|                (V (make-funcall (make-primref 'error) | ||||
|                     (list (K 'apply) (K "not a procedure") x)))))] | ||||
|           [else | ||||
|            (V x)])) | ||||
|       (struct-case x | ||||
|          [(primcall op args) | ||||
|           (cond | ||||
|             [(and (eq? op 'top-level-value) | ||||
|                   (= (length args) 1) | ||||
|                   (let f ([x (car args)]) | ||||
|                     (struct-case x | ||||
|                       [(constant x)  | ||||
|                        (and (symbol? x) x)] | ||||
|                       [(known x t) (f x)] | ||||
|                       [else #f]))) => | ||||
|              (lambda (sym) | ||||
|                (reset-symbol-proc! sym) | ||||
|                (prm 'mref (T (K sym)) | ||||
|                     (K (- disp-symbol-record-proc symbol-ptag))))] | ||||
|             [else (nonproc x check?)])] | ||||
|          [(primref op) (V x)] | ||||
|          [(known x t v) | ||||
|           (cond | ||||
|             [(eq? (T:procedure? t) 'yes) | ||||
|              ;(record-optimization 'procedure x) | ||||
|              (Function x #f)] | ||||
|             [else (Function x check?)])] | ||||
|          [else (nonproc x check?)])) | ||||
|     (Function x #t)) | ||||
| 
 | ||||
| 
 | ||||
|   (define encountered-symbol-calls '()) | ||||
|   (define (record-symbol-call! x) | ||||
|      | ||||
|     (unless (memq x encountered-symbol-calls) | ||||
|       (set! encountered-symbol-calls  | ||||
|         (cons x encountered-symbol-calls)))) | ||||
| 
 | ||||
|   (define record-optimization^ | ||||
|     (let ([h (make-eq-hashtable)]) | ||||
|       (lambda (what expr) | ||||
|         (let ([n (hashtable-ref h what 0)]) | ||||
|           (hashtable-set! h what (+ n 1)) | ||||
|           (printf "optimize ~a[~s]: ~s\n" what n (unparse expr)))))) | ||||
|   (define-syntax record-optimization | ||||
|     (syntax-rules () | ||||
|       [(_ what expr) (void)])) | ||||
| 
 | ||||
|   ;;;======================================================================== | ||||
|   ;;; | ||||
|  | @ -491,7 +520,8 @@ | |||
|     (struct-case x | ||||
|       [(var) x] | ||||
|       [(constant i) (constant-rep x)] | ||||
|       [(known expr type val) (T expr)] | ||||
|       [(known expr type) | ||||
|        (make-known (T expr) type)] | ||||
|       [else (error 'cogen-T "invalid" (unparse x))])) | ||||
| 
 | ||||
|   (define (ClambdaCase x) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Abdulaziz Ghuloum
						Abdulaziz Ghuloum