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