diff --git a/scheme/Makefile.am b/scheme/Makefile.am
index 0d7e57b..2f13c65 100644
--- a/scheme/Makefile.am
+++ b/scheme/Makefile.am
@@ -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)
diff --git a/scheme/Makefile.in b/scheme/Makefile.in
index 8e74c84..32bdea9 100644
--- a/scheme/Makefile.in
+++ b/scheme/Makefile.in
@@ -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
diff --git a/scheme/ikarus.boot.prebuilt b/scheme/ikarus.boot.prebuilt
index a2f3ecf..cdc4609 100644
Binary files a/scheme/ikarus.boot.prebuilt and b/scheme/ikarus.boot.prebuilt differ
diff --git a/scheme/ikarus.compiler.altcogen.ss b/scheme/ikarus.compiler.altcogen.ss
index d8e12cf..d531a83 100644
--- a/scheme/ikarus.compiler.altcogen.ss
+++ b/scheme/ikarus.compiler.altcogen.ss
@@ -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)))]
diff --git a/scheme/ikarus.compiler.source-optimizer.ss b/scheme/ikarus.compiler.source-optimizer.ss
index 77e4232..cf2907f 100644
--- a/scheme/ikarus.compiler.source-optimizer.ss
+++ b/scheme/ikarus.compiler.source-optimizer.ss
@@ -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
'(
diff --git a/scheme/ikarus.compiler.ss b/scheme/ikarus.compiler.ss
index f79b699..3f3da35 100644
--- a/scheme/ikarus.compiler.ss
+++ b/scheme/ikarus.compiler.ss
@@ -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)]
diff --git a/scheme/ikarus.compiler.tag-annotation-analysis.ss b/scheme/ikarus.compiler.tag-annotation-analysis.ss
new file mode 100644
index 0000000..b1154f4
--- /dev/null
+++ b/scheme/ikarus.compiler.tag-annotation-analysis.ss
@@ -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 .
+
+
+
+;;; 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))
+
diff --git a/scheme/ikarus.conditions.ss b/scheme/ikarus.conditions.ss
index ba1ccf2..674cffa 100644
--- a/scheme/ikarus.conditions.ss
+++ b/scheme/ikarus.conditions.ss
@@ -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)
diff --git a/scheme/ikarus.io.ss b/scheme/ikarus.io.ss
index 05e8ffe..8243b5e 100644
--- a/scheme/ikarus.io.ss
+++ b/scheme/ikarus.io.ss
@@ -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)
diff --git a/scheme/ikarus.ontology.ss b/scheme/ikarus.ontology.ss
new file mode 100755
index 0000000..513604f
--- /dev/null
+++ b/scheme/ikarus.ontology.ss
@@ -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 .
+
+(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)
+
+
+
diff --git a/scheme/last-revision b/scheme/last-revision
index 4aea099..c16dfe7 100644
--- a/scheme/last-revision
+++ b/scheme/last-revision
@@ -1 +1 @@
-1526
+1527
diff --git a/scheme/makefile.ss b/scheme/makefile.ss
index c3ae0f4..6ef7bbc 100755
--- a/scheme/makefile.ss
+++ b/scheme/makefile.ss
@@ -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)
diff --git a/scheme/pass-specify-rep-primops.ss b/scheme/pass-specify-rep-primops.ss
index d67335c..b5efeb9 100644
--- a/scheme/pass-specify-rep-primops.ss
+++ b/scheme/pass-specify-rep-primops.ss
@@ -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
diff --git a/scheme/pass-specify-rep.ss b/scheme/pass-specify-rep.ss
index 1599b86..a1bb299 100644
--- a/scheme/pass-specify-rep.ss
+++ b/scheme/pass-specify-rep.ss
@@ -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)