370.3
svn: r6545
This commit is contained in:
parent
a6c36a3739
commit
63ce7b93fb
|
@ -27,7 +27,7 @@
|
|||
stop-after
|
||||
(rename *in-indexed in-indexed)
|
||||
|
||||
sequence-generator
|
||||
sequence-generate
|
||||
|
||||
define-sequence-syntax
|
||||
make-do-sequence
|
||||
|
@ -520,9 +520,9 @@
|
|||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; runnign sequences outside of a loop:
|
||||
|
||||
(define (sequence-generator g)
|
||||
(define (sequence-generate g)
|
||||
(unless (sequence? g)
|
||||
(raise-type-error 'sequence-generator "sequence" g))
|
||||
(raise-type-error 'sequence-generate "sequence" g))
|
||||
(let-values ([(pos->val pos-next init pos-cont? pre-cont? post-cont?)
|
||||
(make-sequence #f g)])
|
||||
(let ([pos init])
|
||||
|
|
|
@ -2015,9 +2015,18 @@
|
|||
h1))])
|
||||
|
||||
(let ([check-tables-equal
|
||||
(lambda (mode t1 t2)
|
||||
(lambda (mode t1 t2 flag)
|
||||
(test #t equal? t1 t2)
|
||||
(test (equal-hash-code t1) equal-hash-code t2)
|
||||
(test (equal-hash-code t1) equal-hash-code t2)
|
||||
(test #t equal? t1 (hash-table-copy t1))
|
||||
(let ([again (apply make-hash-table 'equal flag)])
|
||||
(let loop ([i (hash-table-iterate-first t1)])
|
||||
(when i
|
||||
(hash-table-put! again
|
||||
(hash-table-iterate-key t1 i)
|
||||
(hash-table-iterate-value t1 i))
|
||||
(loop (hash-table-iterate-next t1 i))))
|
||||
(test #t equal? t1 again))
|
||||
(let ([meta-ht (make-hash-table 'equal)])
|
||||
(hash-table-put! meta-ht t1 mode)
|
||||
(test mode hash-table-get meta-ht t2 (lambda () #f)))
|
||||
|
@ -2025,10 +2034,12 @@
|
|||
|
||||
(check-tables-equal 'the-norm-table
|
||||
(check-hash-tables null #f)
|
||||
(check-hash-tables null #t))
|
||||
(check-hash-tables null #t)
|
||||
null)
|
||||
(check-tables-equal 'the-weak-table
|
||||
(check-hash-tables (list 'weak) #f)
|
||||
(check-hash-tables (list 'weak) #t)))
|
||||
(check-hash-tables (list 'weak) #t)
|
||||
(list 'weak)))
|
||||
|
||||
(save))) ; prevents gcing of the ht-registered values
|
||||
|
||||
|
@ -2104,6 +2115,21 @@
|
|||
(test 2 hash-table-get (hash-table-copy #hasheq((1 . 2))) 1)
|
||||
(test (void) hash-table-put! (hash-table-copy #hasheq((1 . 2))) 3 4)
|
||||
|
||||
(test #f hash-table-iterate-first (make-hash-table))
|
||||
(test #f hash-table-iterate-first (make-hash-table 'weak))
|
||||
(err/rt-test (hash-table-iterate-next (make-hash-table) 0))
|
||||
(err/rt-test (hash-table-iterate-next (make-hash-table 'weak) 0))
|
||||
|
||||
(let ([check-all-bad
|
||||
(lambda (op)
|
||||
(err/rt-test (op #f 0))
|
||||
(err/rt-test (op (make-hash-table) -1))
|
||||
(err/rt-test (op (make-hash-table) (- (expt 2 100))))
|
||||
(err/rt-test (op (make-hash-table) 1.0)))])
|
||||
(check-all-bad hash-table-iterate-next)
|
||||
(check-all-bad hash-table-iterate-key)
|
||||
(check-all-bad hash-table-iterate-value))
|
||||
|
||||
(arity-test make-hash-table 0 2)
|
||||
(arity-test make-immutable-hash-table 1 2)
|
||||
(arity-test hash-table-count 1 1)
|
||||
|
|
|
@ -434,6 +434,59 @@
|
|||
'(let ([x (random)])
|
||||
x))
|
||||
|
||||
(test-comp '(let-values ([(x y) (values 1 2)])
|
||||
(+ x y))
|
||||
3)
|
||||
|
||||
(test-comp '(letrec ([x 3]
|
||||
[f (lambda (y) x)])
|
||||
f)
|
||||
'(letrec ([f (lambda (y) 3)])
|
||||
f))
|
||||
|
||||
(test-comp '(letrec ([x 3]
|
||||
[f (lambda (y) x)])
|
||||
(f 10))
|
||||
3)
|
||||
|
||||
(test-comp '(letrec ([f (lambda (y) (f y))])
|
||||
3)
|
||||
3)
|
||||
|
||||
(test-comp '(letrec ([len (lambda (l)
|
||||
(if (null? l)
|
||||
0
|
||||
(len (cdr l))))])
|
||||
(len null))
|
||||
0)
|
||||
|
||||
(test-comp '(letrec ([foo (lambda ()
|
||||
(set! foo 10))])
|
||||
0)
|
||||
0)
|
||||
|
||||
(test-comp '(letrec ([foo (lambda () 12)]
|
||||
[goo (lambda () foo)])
|
||||
goo)
|
||||
'(let* ([foo (lambda () 12)]
|
||||
[goo (lambda () foo)])
|
||||
goo))
|
||||
|
||||
(test-comp '(let* ([foo (lambda () 12)]
|
||||
[goo (lambda () foo)])
|
||||
11)
|
||||
11)
|
||||
|
||||
(test-comp '(letrec ([foo (lambda () 12)]
|
||||
[goo (lambda () foo)])
|
||||
11)
|
||||
11)
|
||||
|
||||
(test-comp '(letrec ([goo (lambda () foo)]
|
||||
[foo (lambda () goo)])
|
||||
15)
|
||||
15)
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Check bytecode verification of lifted functions
|
||||
|
||||
|
|
|
@ -872,17 +872,21 @@
|
|||
(break-enabled #f))
|
||||
(init ;; init function gets to decide whether to do the normal body:
|
||||
(lambda ()
|
||||
(printf "here ~s\n" (procedure? capture-pre))
|
||||
(dynamic-wind
|
||||
(lambda ()
|
||||
(printf "here3 ~s\n" (procedure? capture-pre))
|
||||
(capture-pre
|
||||
reset
|
||||
(lambda ()
|
||||
(printf "here4\n")
|
||||
(set! did-pre1 #t)
|
||||
(semaphore-post p)
|
||||
(pre-thunk)
|
||||
(pre-semaphore-wait s)
|
||||
(set! did-pre2 #t))))
|
||||
(lambda ()
|
||||
(printf "here2\n")
|
||||
(capture-act
|
||||
reset
|
||||
(lambda ()
|
||||
|
@ -930,6 +934,7 @@
|
|||
;; create fresh semaphores
|
||||
(set! s (make-semaphore))
|
||||
(set! p (make-semaphore))
|
||||
(printf "mk ~s\n" mk-t*)
|
||||
;; create the thread
|
||||
(let ([t (mk-t* break-off?
|
||||
pre-thunk act-thunk post-thunk
|
||||
|
@ -1016,6 +1021,9 @@
|
|||
(body))])
|
||||
;; Grab a continuation for the dyn-wind's pre/act/post
|
||||
(go (lambda args
|
||||
(printf "here???\n")
|
||||
(printf "??? ~s\n" k+reset)
|
||||
(printf "??? ~s\n" capture)
|
||||
(apply mk-t
|
||||
(lambda (f) (f))
|
||||
(if (eq? which 'pre) capture no-capture)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
Version 370.2
|
||||
Added hash-table-iterate-{first,next,key,value}
|
||||
|
||||
Version 370.2
|
||||
Added make-sibling-inspector
|
||||
Added graph? argument to read[-syntax]/recursive
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "schpriv.h"
|
||||
#include "schminc.h"
|
||||
#include "schmach.h"
|
||||
#include "schexpobs.h"
|
||||
|
||||
#if defined(UNIX_LIMIT_STACK) || defined(UNIX_LIMIT_FDSET_SIZE)
|
||||
|
@ -2650,6 +2651,8 @@ Optimize_Info *scheme_optimize_info_create()
|
|||
return info;
|
||||
}
|
||||
|
||||
static void register_transitive_use(Optimize_Info *info, int pos, int j);
|
||||
|
||||
static void register_stat_dist(Optimize_Info *info, int i, int j)
|
||||
{
|
||||
if (!info->stat_dists) {
|
||||
|
@ -2681,16 +2684,81 @@ static void register_stat_dist(Optimize_Info *info, int i, int j)
|
|||
info->sd_depths[i] = j + 1;
|
||||
}
|
||||
|
||||
if (info->transitive_use && info->transitive_use[i]) {
|
||||
/* We're using a procedure that we weren't sure would be used.
|
||||
Transitively mark everything that the procedure uses --- unless
|
||||
a transitive accumulation is in effect, in which case we
|
||||
don't for this one now, leaving it to be triggered when
|
||||
the one we're accumulating is triggered. */
|
||||
if (!info->transitive_use_pos) {
|
||||
mzshort *map = info->transitive_use[i];
|
||||
int len = info->transitive_use_len[i];
|
||||
int k;
|
||||
|
||||
info->transitive_use[i] = NULL;
|
||||
|
||||
for (k = 0; k < len; k++) {
|
||||
register_transitive_use(info, map[k], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info->stat_dists[i][j] = 1;
|
||||
}
|
||||
|
||||
static Scheme_Object *transitive_k(void)
|
||||
{
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
Optimize_Info *info = (Optimize_Info *)p->ku.k.p1;
|
||||
|
||||
p->ku.k.p1 = NULL;
|
||||
|
||||
register_transitive_use(info, p->ku.k.i1, p->ku.k.i2);
|
||||
|
||||
return scheme_false;
|
||||
}
|
||||
|
||||
static void register_transitive_use(Optimize_Info *info, int pos, int j)
|
||||
{
|
||||
#ifdef DO_STACK_CHECK
|
||||
# include "mzstkchk.h"
|
||||
{
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
|
||||
p->ku.k.p1 = (void *)info;
|
||||
p->ku.k.i1 = pos;
|
||||
p->ku.k.i2 = j;
|
||||
|
||||
scheme_handle_stack_overflow(transitive_k);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (info) {
|
||||
if (info->flags & SCHEME_LAMBDA_FRAME)
|
||||
j++;
|
||||
if (pos < info->new_frame)
|
||||
break;
|
||||
pos -= info->new_frame;
|
||||
info = info->next;
|
||||
}
|
||||
|
||||
if (info->sd_depths[pos] <= j) {
|
||||
scheme_signal_error("bad transitive position depth: %d vs. %d",
|
||||
info->sd_depths[pos], j);
|
||||
}
|
||||
|
||||
register_stat_dist(info, pos, j);
|
||||
}
|
||||
|
||||
void scheme_env_make_closure_map(Optimize_Info *info, mzshort *_size, mzshort **_map)
|
||||
{
|
||||
/* A closure map lists the captured variables for a closure; the
|
||||
indices are resolved two new indicies in the second phase of
|
||||
compilation. */
|
||||
Optimize_Info *frame;
|
||||
int i, j, pos = 0, lpos = 0;
|
||||
int i, j, pos = 0, lpos = 0, tu;
|
||||
mzshort *map, size;
|
||||
|
||||
/* Count vars used by this closure (skip args): */
|
||||
|
@ -2715,6 +2783,13 @@ void scheme_env_make_closure_map(Optimize_Info *info, mzshort *_size, mzshort **
|
|||
map = MALLOC_N_ATOMIC(mzshort, size);
|
||||
*_map = map;
|
||||
|
||||
if (info->next && info->next->transitive_use_pos) {
|
||||
info->next->transitive_use[info->next->transitive_use_pos - 1] = map;
|
||||
info->next->transitive_use_len[info->next->transitive_use_pos - 1] = size;
|
||||
tu = 1;
|
||||
} else
|
||||
tu = 0;
|
||||
|
||||
/* Build map, unmarking locals and marking deeper in parent frame */
|
||||
j = 1; pos = 0;
|
||||
for (frame = info->next; frame; frame = frame->next) {
|
||||
|
@ -2727,7 +2802,8 @@ void scheme_env_make_closure_map(Optimize_Info *info, mzshort *_size, mzshort **
|
|||
if (frame->stat_dists[i][j]) {
|
||||
map[pos++] = lpos;
|
||||
frame->stat_dists[i][j] = 0; /* This closure's done with these vars... */
|
||||
frame->stat_dists[i][j - 1] = 1; /* ... but ensure previous keeps */
|
||||
if (!tu)
|
||||
frame->stat_dists[i][j - 1] = 1; /* ... but ensure previous keeps */
|
||||
}
|
||||
}
|
||||
lpos++;
|
||||
|
@ -2829,6 +2905,34 @@ int scheme_optimize_is_used(Optimize_Info *info, int pos)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int scheme_optimize_any_uses(Optimize_Info *info, int start_pos, int end_pos)
|
||||
{
|
||||
int j, i;
|
||||
|
||||
if (info->stat_dists) {
|
||||
for (i = start_pos; i < end_pos; i++) {
|
||||
for (j = info->sd_depths[i]; j--; ) {
|
||||
if (info->stat_dists[i][j])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (info->transitive_use) {
|
||||
for (i = info->new_frame; i--; ) {
|
||||
if (info->transitive_use[i]) {
|
||||
for (j = info->transitive_use_len[i]; j--; ) {
|
||||
if ((info->transitive_use[i][j] >= start_pos)
|
||||
&& (info->transitive_use[i][j] < end_pos))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Scheme_Object *do_optimize_info_lookup(Optimize_Info *info, int pos, int j, int *closure_offset)
|
||||
{
|
||||
Scheme_Object *p, *n;
|
||||
|
|
|
@ -94,6 +94,10 @@ static Scheme_Object *hash_table_get(int argc, Scheme_Object *argv[]);
|
|||
static Scheme_Object *hash_table_remove(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *hash_table_map(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *hash_table_for_each(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *hash_table_iterate_start(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *hash_table_iterate_next(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *hash_table_iterate_value(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *hash_table_iterate_key(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *eq_hash_code(int argc, Scheme_Object *argv[]);
|
||||
static Scheme_Object *equal_hash_code(int argc, Scheme_Object *argv[]);
|
||||
|
||||
|
@ -465,6 +469,27 @@ scheme_init_list (Scheme_Env *env)
|
|||
2, 2),
|
||||
env);
|
||||
|
||||
scheme_add_global_constant("hash-table-iterate-first",
|
||||
scheme_make_noncm_prim(hash_table_iterate_start,
|
||||
"hash-table-iterate-first",
|
||||
1, 1),
|
||||
env);
|
||||
scheme_add_global_constant("hash-table-iterate-next",
|
||||
scheme_make_noncm_prim(hash_table_iterate_next,
|
||||
"hash-table-iterate-next",
|
||||
2, 2),
|
||||
env);
|
||||
scheme_add_global_constant("hash-table-iterate-value",
|
||||
scheme_make_noncm_prim(hash_table_iterate_value,
|
||||
"hash-table-iterate-value",
|
||||
2, 2),
|
||||
env);
|
||||
scheme_add_global_constant("hash-table-iterate-key",
|
||||
scheme_make_noncm_prim(hash_table_iterate_key,
|
||||
"hash-table-iterate-key",
|
||||
2, 2),
|
||||
env);
|
||||
|
||||
scheme_add_global_constant("eq-hash-code",
|
||||
scheme_make_noncm_prim(eq_hash_code,
|
||||
"eq-hash-code",
|
||||
|
@ -1701,6 +1726,167 @@ static Scheme_Object *hash_table_for_each(int argc, Scheme_Object *argv[])
|
|||
return do_map_hash_table(argc, argv, "hash-table-for-each", 0);
|
||||
}
|
||||
|
||||
static Scheme_Object *hash_table_next(const char *name, int start, int argc, Scheme_Object *argv[])
|
||||
{
|
||||
if (SCHEME_HASHTP(argv[0])) {
|
||||
Scheme_Hash_Table *hash;
|
||||
int i, sz;
|
||||
|
||||
hash = (Scheme_Hash_Table *)argv[0];
|
||||
|
||||
sz = hash->size;
|
||||
if (start >= 0) {
|
||||
if ((start >= sz) || !hash->vals[start])
|
||||
return NULL;
|
||||
}
|
||||
for (i = start + 1; i < sz; i++) {
|
||||
if (hash->vals[i])
|
||||
return scheme_make_integer(i);
|
||||
}
|
||||
|
||||
return scheme_false;
|
||||
} else if (SCHEME_BUCKTP(argv[0])) {
|
||||
Scheme_Bucket_Table *hash;
|
||||
Scheme_Bucket *bucket;
|
||||
int i, sz;
|
||||
|
||||
hash = (Scheme_Bucket_Table *)argv[0];
|
||||
|
||||
sz = hash->size;
|
||||
|
||||
if (start >= 0) {
|
||||
bucket = ((start < sz) ? hash->buckets[start] : NULL);
|
||||
if (!bucket || !bucket->val || !bucket->key)
|
||||
return NULL;
|
||||
}
|
||||
for (i = start + 1; i < sz; i++) {
|
||||
bucket = hash->buckets[i];
|
||||
if (bucket && bucket->val && bucket->key) {
|
||||
return scheme_make_integer(i);
|
||||
}
|
||||
}
|
||||
|
||||
return scheme_false;
|
||||
} else {
|
||||
scheme_wrong_type(name, "hash table", 0, argc, argv);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static Scheme_Object *hash_table_iterate_start(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return hash_table_next("hash-table-iterate-first", -1, argc, argv);
|
||||
}
|
||||
|
||||
static Scheme_Object *hash_table_iterate_next(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
Scheme_Object *p = argv[1], *v;
|
||||
int pos;
|
||||
|
||||
if (SCHEME_INTP(p)) {
|
||||
pos = SCHEME_INT_VAL(p);
|
||||
if (pos < 0)
|
||||
pos = 0x7FFFFFFE;
|
||||
} else {
|
||||
pos = 0x7FFFFFFE;
|
||||
}
|
||||
|
||||
v = hash_table_next("hash-table-iterate-next", pos, argc, argv);
|
||||
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
if (SCHEME_INTP(p)) {
|
||||
if (SCHEME_INT_VAL(p) >= 0)
|
||||
p = NULL;
|
||||
} else if (SCHEME_BIGNUMP(p)) {
|
||||
if (SCHEME_BIGPOS(p))
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
if (p)
|
||||
scheme_wrong_type("hash-table-iterate-next", "exact non-negative integer", 1, argc, argv);
|
||||
|
||||
scheme_arg_mismatch("hash-table-iterate-next", "no element at index: ", argv[1]);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Scheme_Object *hash_table_index(const char *name, int argc, Scheme_Object *argv[], int get_val)
|
||||
{
|
||||
Scheme_Object *p = argv[1];
|
||||
int pos, sz;
|
||||
|
||||
if (SCHEME_INTP(p)) {
|
||||
pos = SCHEME_INT_VAL(p);
|
||||
if (pos < 0)
|
||||
pos = 0x7FFFFFFF;
|
||||
} else {
|
||||
pos = 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
if (SCHEME_HASHTP(argv[0])) {
|
||||
Scheme_Hash_Table *hash;
|
||||
|
||||
hash = (Scheme_Hash_Table *)argv[0];
|
||||
|
||||
sz = hash->size;
|
||||
if (pos < sz) {
|
||||
if (hash->vals[pos]) {
|
||||
if (get_val)
|
||||
return hash->vals[pos];
|
||||
else
|
||||
return hash->keys[pos];
|
||||
}
|
||||
}
|
||||
} else if (SCHEME_BUCKTP(argv[0])) {
|
||||
Scheme_Bucket_Table *hash;
|
||||
int sz;
|
||||
Scheme_Bucket *bucket;
|
||||
|
||||
hash = (Scheme_Bucket_Table *)argv[0];
|
||||
|
||||
sz = hash->size;
|
||||
if (pos < sz) {
|
||||
bucket = hash->buckets[pos];
|
||||
if (bucket && bucket->val && bucket->key) {
|
||||
if (get_val)
|
||||
return (Scheme_Object *)bucket->val;
|
||||
else {
|
||||
if (hash->weak)
|
||||
return (Scheme_Object *)HT_EXTRACT_WEAK(bucket->key);
|
||||
else
|
||||
return (Scheme_Object *)bucket->key;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
scheme_wrong_type(name, "hash table", 0, argc, argv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((SCHEME_INTP(p)
|
||||
&& (SCHEME_INT_VAL(p) >= 0))
|
||||
|| (SCHEME_BIGNUMP(p)
|
||||
&& SCHEME_BIGPOS(p))) {
|
||||
scheme_arg_mismatch(name, "no element at index: ", p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scheme_wrong_type(name, "exact non-negative integer", 1, argc, argv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Scheme_Object *hash_table_iterate_value(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return hash_table_index("hash-table-iterate-value", argc, argv, 1);
|
||||
}
|
||||
|
||||
static Scheme_Object *hash_table_iterate_key(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
return hash_table_index("hash-table-iterate-key", argc, argv, 0);
|
||||
}
|
||||
|
||||
static Scheme_Object *eq_hash_code(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
long v;
|
||||
|
|
|
@ -2688,6 +2688,8 @@ static int mark_optimize_info_MARK(void *p) {
|
|||
gcMARK(i->use);
|
||||
gcMARK(i->consts);
|
||||
gcMARK(i->top_level_consts);
|
||||
gcMARK(i->transitive_use);
|
||||
gcMARK(i->transitive_use_len);
|
||||
|
||||
return
|
||||
gcBYTES_TO_WORDS(sizeof(Optimize_Info));
|
||||
|
@ -2702,6 +2704,8 @@ static int mark_optimize_info_FIXUP(void *p) {
|
|||
gcFIXUP(i->use);
|
||||
gcFIXUP(i->consts);
|
||||
gcFIXUP(i->top_level_consts);
|
||||
gcFIXUP(i->transitive_use);
|
||||
gcFIXUP(i->transitive_use_len);
|
||||
|
||||
return
|
||||
gcBYTES_TO_WORDS(sizeof(Optimize_Info));
|
||||
|
|
|
@ -1075,6 +1075,8 @@ mark_optimize_info {
|
|||
gcMARK(i->use);
|
||||
gcMARK(i->consts);
|
||||
gcMARK(i->top_level_consts);
|
||||
gcMARK(i->transitive_use);
|
||||
gcMARK(i->transitive_use_len);
|
||||
|
||||
size:
|
||||
gcBYTES_TO_WORDS(sizeof(Optimize_Info));
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#define USE_COMPILED_STARTUP 1
|
||||
|
||||
#define EXPECTED_PRIM_COUNT 898
|
||||
#define EXPECTED_PRIM_COUNT 902
|
||||
|
||||
#ifdef MZSCHEME_SOMETHING_OMITTED
|
||||
# undef USE_COMPILED_STARTUP
|
||||
|
|
|
@ -1744,6 +1744,10 @@ typedef struct Optimize_Info
|
|||
int *sd_depths;
|
||||
int used_toplevel;
|
||||
char *use;
|
||||
|
||||
int transitive_use_pos; /* set to pos + 1 when optimizing a letrec-bound procedure */
|
||||
mzshort **transitive_use;
|
||||
int *transitive_use_len;
|
||||
} Optimize_Info;
|
||||
|
||||
typedef struct Scheme_Object *(*Scheme_Syntax_Optimizer)(Scheme_Object *data, Optimize_Info *info);
|
||||
|
@ -1991,6 +1995,7 @@ void scheme_optimize_info_used_top(Optimize_Info *info);
|
|||
void scheme_optimize_mutated(Optimize_Info *info, int pos);
|
||||
Scheme_Object *scheme_optimize_reverse(Optimize_Info *info, int pos, int unless_mutated);
|
||||
int scheme_optimize_is_used(Optimize_Info *info, int pos);
|
||||
int scheme_optimize_any_uses(Optimize_Info *info, int start_pos, int end_pos);
|
||||
|
||||
Scheme_Object *scheme_optimize_clone(int dup_ok, Scheme_Object *obj, Optimize_Info *info, int delta, int closure_depth);
|
||||
Scheme_Object *scheme_optimize_shift(Scheme_Object *obj, int delta, int after_depth);
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
|
||||
#define MZSCHEME_VERSION_MAJOR 370
|
||||
#define MZSCHEME_VERSION_MINOR 2
|
||||
#define MZSCHEME_VERSION_MINOR 3
|
||||
|
||||
#define MZSCHEME_VERSION "370.2" _MZ_SPECIAL_TAG
|
||||
#define MZSCHEME_VERSION "370.3" _MZ_SPECIAL_TAG
|
||||
|
|
|
@ -2559,6 +2559,42 @@ int scheme_compiled_propagate_ok(Scheme_Object *value, Optimize_Info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int is_values_apply(Scheme_Object *e)
|
||||
{
|
||||
if (SAME_TYPE(SCHEME_TYPE(e), scheme_application_type)) {
|
||||
Scheme_App_Rec *app = (Scheme_App_Rec *)e;
|
||||
return SAME_OBJ(scheme_values_func, app->args[0]);
|
||||
} else if (SAME_TYPE(SCHEME_TYPE(e), scheme_application2_type)) {
|
||||
Scheme_App2_Rec *app = (Scheme_App2_Rec *)e;
|
||||
return SAME_OBJ(scheme_values_func, app->rator);
|
||||
} else if (SAME_TYPE(SCHEME_TYPE(e), scheme_application3_type)) {
|
||||
Scheme_App3_Rec *app = (Scheme_App3_Rec *)e;
|
||||
return SAME_OBJ(scheme_values_func, app->rator);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unpack_values_application(Scheme_Object *e, Scheme_Compiled_Let_Value *naya)
|
||||
{
|
||||
if (SAME_TYPE(SCHEME_TYPE(e), scheme_application_type)) {
|
||||
Scheme_App_Rec *app = (Scheme_App_Rec *)e;
|
||||
int i;
|
||||
for (i = 0; i < app->num_args; i++) {
|
||||
naya->value = app->args[i + 1];
|
||||
naya = (Scheme_Compiled_Let_Value *)naya->body;
|
||||
}
|
||||
} else if (SAME_TYPE(SCHEME_TYPE(e), scheme_application2_type)) {
|
||||
Scheme_App2_Rec *app = (Scheme_App2_Rec *)e;
|
||||
naya->value = app->rand;
|
||||
} else if (SAME_TYPE(SCHEME_TYPE(e), scheme_application3_type)) {
|
||||
Scheme_App3_Rec *app = (Scheme_App3_Rec *)e;
|
||||
naya->value = app->rand1;
|
||||
naya = (Scheme_Compiled_Let_Value *)naya->body;
|
||||
naya->value = app->rand2;
|
||||
}
|
||||
}
|
||||
|
||||
static Scheme_Object *make_clones(Scheme_Compiled_Let_Value *retry_start,
|
||||
Scheme_Compiled_Let_Value *pre_body,
|
||||
Optimize_Info *body_info)
|
||||
|
@ -2597,6 +2633,7 @@ static int set_code_flags(Scheme_Compiled_Let_Value *retry_start,
|
|||
Scheme_Compiled_Let_Value *clv;
|
||||
Scheme_Object *value, *first;
|
||||
int flags = CLOS_SINGLE_RESULT | CLOS_PRESERVES_MARKS;
|
||||
Scheme_Closure_Data *data;
|
||||
|
||||
/* The first in a clone pair is the one that is consulted for
|
||||
references. The second one is the clone, and its the one whose
|
||||
|
@ -2606,16 +2643,21 @@ static int set_code_flags(Scheme_Compiled_Let_Value *retry_start,
|
|||
clv = retry_start;
|
||||
while (clones) {
|
||||
value = retry_start->value;
|
||||
first = SCHEME_CAR(clones);
|
||||
if (SAME_OBJ(value, SCHEME_CAR(first))) {
|
||||
Scheme_Closure_Data *data;
|
||||
data = (Scheme_Closure_Data *)SCHEME_CDR(first);
|
||||
|
||||
if (SAME_TYPE(scheme_compiled_unclosed_procedure_type, SCHEME_TYPE(value))) {
|
||||
data = (Scheme_Closure_Data *)value;
|
||||
flags = (flags & SCHEME_CLOSURE_DATA_FLAGS(data));
|
||||
|
||||
first = SCHEME_CAR(clones);
|
||||
|
||||
data = (Scheme_Closure_Data *)SCHEME_CDR(first);
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data) & mask_flags);
|
||||
data = (Scheme_Closure_Data *)SCHEME_CAR(first);
|
||||
SCHEME_CLOSURE_DATA_FLAGS(data) = set_flags | (SCHEME_CLOSURE_DATA_FLAGS(data) & mask_flags);
|
||||
|
||||
clones = SCHEME_CDR(clones);
|
||||
}
|
||||
|
||||
if (clv == pre_body)
|
||||
break;
|
||||
clv = (Scheme_Compiled_Let_Value *)clv->body;
|
||||
|
@ -2629,9 +2671,9 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
{
|
||||
Optimize_Info *body_info, *rhs_info;
|
||||
Scheme_Let_Header *head = (Scheme_Let_Header *)form;
|
||||
Scheme_Compiled_Let_Value *clv, *pre_body, *retry_start;
|
||||
Scheme_Compiled_Let_Value *clv, *pre_body, *retry_start, *prev_body;
|
||||
Scheme_Object *body, *value;
|
||||
int i, j, pos, is_rec, all_simple = 1;
|
||||
int i, j, pos, is_rec, not_simply_let_star = 0;
|
||||
int size_before_opt, did_set_value;
|
||||
|
||||
/* Special case: (let ([x E]) x) where E is lambda, case-lambda, or
|
||||
|
@ -2671,8 +2713,6 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
rhs_info = body_info;
|
||||
|
||||
is_rec = (SCHEME_LET_FLAGS(head) & SCHEME_LET_RECURSIVE);
|
||||
if (is_rec)
|
||||
all_simple = 0;
|
||||
|
||||
body = head->body;
|
||||
pos = 0;
|
||||
|
@ -2681,13 +2721,13 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
for (j = pre_body->count; j--; ) {
|
||||
if (pre_body->flags[j] & SCHEME_WAS_SET_BANGED) {
|
||||
scheme_optimize_mutated(body_info, pos + j);
|
||||
all_simple = 0;
|
||||
}
|
||||
}
|
||||
pos += pre_body->count;
|
||||
body = pre_body->body;
|
||||
}
|
||||
|
||||
prev_body = NULL;
|
||||
body = head->body;
|
||||
pre_body = NULL;
|
||||
retry_start = NULL;
|
||||
|
@ -2696,21 +2736,75 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
for (i = head->num_clauses; i--; ) {
|
||||
pre_body = (Scheme_Compiled_Let_Value *)body;
|
||||
|
||||
if (!retry_start)
|
||||
retry_start = pre_body;
|
||||
|
||||
size_before_opt = body_info->size;
|
||||
|
||||
value = scheme_optimize_expr(pre_body->value, rhs_info);
|
||||
|
||||
if ((pre_body->count == 1)
|
||||
&& SAME_TYPE(scheme_compiled_unclosed_procedure_type, SCHEME_TYPE(pre_body->value))
|
||||
&& !scheme_optimize_is_used(body_info, pos)) {
|
||||
if (!body_info->transitive_use) {
|
||||
mzshort **tu;
|
||||
int *tu_len;
|
||||
tu = (mzshort **)scheme_malloc(sizeof(mzshort *) * head->count);
|
||||
tu_len = (int *)scheme_malloc_atomic(sizeof(int) * head->count);
|
||||
memset(tu_len, 0, sizeof(int) * head->count);
|
||||
body_info->transitive_use = tu;
|
||||
body_info->transitive_use_len = tu_len;
|
||||
}
|
||||
body_info->transitive_use_pos = pos + 1;
|
||||
}
|
||||
|
||||
value = scheme_optimize_expr(pre_body->value, rhs_info);
|
||||
pre_body->value = value;
|
||||
|
||||
body_info->transitive_use_pos = 0;
|
||||
|
||||
if (is_rec && !not_simply_let_star) {
|
||||
/* Keep track of whether we can simplify to let*: */
|
||||
if (scheme_optimize_any_uses(rhs_info, pos, head->count))
|
||||
not_simply_let_star = 1;
|
||||
}
|
||||
|
||||
/* Change (let-values ([(id ...) (values e ...)]) body)
|
||||
to (let-values ([id e] ...) body) for simple e. */
|
||||
if ((pre_body->count != 1)
|
||||
&& is_values_apply(value)
|
||||
&& scheme_omittable_expr(value, pre_body->count)) {
|
||||
Scheme_Compiled_Let_Value *naya;
|
||||
Scheme_Object *rest = pre_body->body;
|
||||
int *new_flags;
|
||||
int cnt = pre_body->count;
|
||||
|
||||
while (cnt--) {
|
||||
naya = MALLOC_ONE_TAGGED(Scheme_Compiled_Let_Value);
|
||||
naya->so.type = scheme_compiled_let_value_type;
|
||||
naya->body = rest;
|
||||
naya->count = 1;
|
||||
naya->position = pre_body->position + cnt;
|
||||
new_flags = (int *)scheme_malloc_atomic(sizeof(int));
|
||||
new_flags[0] = pre_body->flags[cnt];
|
||||
naya->flags = new_flags;
|
||||
rest = (Scheme_Object *)naya;
|
||||
}
|
||||
|
||||
naya = (Scheme_Compiled_Let_Value *)rest;
|
||||
unpack_values_application(value, naya);
|
||||
if (prev_body)
|
||||
prev_body->body = (Scheme_Object *)naya;
|
||||
else
|
||||
head->body = (Scheme_Object *)naya;
|
||||
head->num_clauses += (pre_body->count - 1);
|
||||
i += (pre_body->count - 1);
|
||||
pre_body = naya;
|
||||
body = (Scheme_Object *)naya;
|
||||
value = pre_body->value;
|
||||
}
|
||||
|
||||
if ((pre_body->count == 1)
|
||||
&& !(pre_body->flags[0] & SCHEME_WAS_SET_BANGED)) {
|
||||
|
||||
if (SAME_TYPE(SCHEME_TYPE(value), scheme_local_type)) {
|
||||
/* Don't optimize reference to a local binding
|
||||
that's not available yet, or that mutable. */
|
||||
that's not available yet, or that's mutable. */
|
||||
int vpos;
|
||||
vpos = SCHEME_LOCAL_POS(value);
|
||||
if ((vpos < head->count) && (vpos >= pos))
|
||||
|
@ -2729,6 +2823,9 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
}
|
||||
}
|
||||
|
||||
if (!retry_start)
|
||||
retry_start = pre_body;
|
||||
|
||||
/* Re-optimize to inline letrec bindings? */
|
||||
if (is_rec
|
||||
&& !body_info->letrec_not_twice
|
||||
|
@ -2761,6 +2858,13 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
Scheme_Object *self_value;
|
||||
int sz;
|
||||
|
||||
if ((clv->count == 1)
|
||||
&& body_info->transitive_use
|
||||
&& !scheme_optimize_is_used(body_info, clv->position)) {
|
||||
body_info->transitive_use[clv->position] = NULL;
|
||||
body_info->transitive_use_pos = clv->position + 1;
|
||||
}
|
||||
|
||||
cl = SCHEME_CDR(cl);
|
||||
self_value = SCHEME_CDR(cl_first);
|
||||
|
||||
|
@ -2779,6 +2883,12 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
body_info->letrec_not_twice = 0;
|
||||
|
||||
clv->value = value;
|
||||
|
||||
if (!(clv->flags[0] & SCHEME_WAS_SET_BANGED)) {
|
||||
scheme_optimize_propagate(body_info, clv->position, value);
|
||||
}
|
||||
|
||||
body_info->transitive_use_pos = 0;
|
||||
}
|
||||
if (clv == pre_body)
|
||||
break;
|
||||
|
@ -2796,6 +2906,7 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
}
|
||||
|
||||
pos += pre_body->count;
|
||||
prev_body = pre_body;
|
||||
body = pre_body->body;
|
||||
info->size += 1;
|
||||
}
|
||||
|
@ -2812,37 +2923,41 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline)
|
|||
info->preserves_marks = body_info->preserves_marks;
|
||||
|
||||
/* Clear used flags where possible */
|
||||
if (all_simple) {
|
||||
body = head->body;
|
||||
pos = 0;
|
||||
for (i = head->num_clauses; i--; ) {
|
||||
int used = 0, j;
|
||||
pre_body = (Scheme_Compiled_Let_Value *)body;
|
||||
for (j = pre_body->count; j--; ) {
|
||||
if (scheme_optimize_is_used(body_info, pos+j)) {
|
||||
used = 1;
|
||||
break;
|
||||
}
|
||||
body = head->body;
|
||||
pos = 0;
|
||||
for (i = head->num_clauses; i--; ) {
|
||||
int used = 0, j;
|
||||
pre_body = (Scheme_Compiled_Let_Value *)body;
|
||||
for (j = pre_body->count; j--; ) {
|
||||
if (scheme_optimize_is_used(body_info, pos+j)) {
|
||||
used = 1;
|
||||
break;
|
||||
}
|
||||
if (!used
|
||||
&& scheme_omittable_expr(pre_body->value, pre_body->count)) {
|
||||
for (j = pre_body->count; j--; ) {
|
||||
if (pre_body->flags[j] & SCHEME_WAS_USED) {
|
||||
pre_body->flags[j] -= SCHEME_WAS_USED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = pre_body->count; j--; ) {
|
||||
pre_body->flags[j] |= SCHEME_WAS_USED;
|
||||
}
|
||||
}
|
||||
pos += pre_body->count;
|
||||
body = pre_body->body;
|
||||
}
|
||||
if (!used
|
||||
&& scheme_omittable_expr(pre_body->value, pre_body->count)) {
|
||||
for (j = pre_body->count; j--; ) {
|
||||
if (pre_body->flags[j] & SCHEME_WAS_USED) {
|
||||
pre_body->flags[j] -= SCHEME_WAS_USED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j = pre_body->count; j--; ) {
|
||||
pre_body->flags[j] |= SCHEME_WAS_USED;
|
||||
}
|
||||
}
|
||||
pos += pre_body->count;
|
||||
body = pre_body->body;
|
||||
}
|
||||
|
||||
scheme_optimize_info_done(body_info);
|
||||
|
||||
if (is_rec && !not_simply_let_star) {
|
||||
/* We can simplify letrec to let* */
|
||||
SCHEME_LET_FLAGS(head) -= SCHEME_LET_RECURSIVE;
|
||||
SCHEME_LET_FLAGS(head) |= SCHEME_LET_STAR;
|
||||
}
|
||||
|
||||
return form;
|
||||
}
|
||||
|
||||
|
@ -2974,7 +3089,7 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
int i, pos, opos, rpos, recbox, num_rec_procs = 0, extra_alloc;
|
||||
int rec_proc_nonapply = 0;
|
||||
int max_let_depth = 0;
|
||||
int resolve_phase;
|
||||
int resolve_phase, num_skips;
|
||||
Scheme_Object **lifted_recs;
|
||||
|
||||
/* Find body: */
|
||||
|
@ -2992,35 +3107,44 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
for (i = head->num_clauses; i--; clv = (Scheme_Compiled_Let_Value *)clv->body) {
|
||||
int is_proc, is_lift;
|
||||
|
||||
is_proc = scheme_is_compiled_procedure(clv->value, 1, 1);
|
||||
if (is_proc)
|
||||
is_lift = 0;
|
||||
else
|
||||
is_lift = is_liftable(clv->value, head->count, 5);
|
||||
|
||||
if (!is_proc && !is_lift) {
|
||||
recbox = 1;
|
||||
break;
|
||||
if ((clv->count == 1)
|
||||
&& !(clv->flags[0] & SCHEME_WAS_USED)) {
|
||||
/* skip */
|
||||
} else {
|
||||
if (!is_lift) {
|
||||
/* is_proc must be true ... */
|
||||
int j;
|
||||
if (clv->count == 1)
|
||||
is_proc = scheme_is_compiled_procedure(clv->value, 1, 1);
|
||||
else
|
||||
is_proc = 0;
|
||||
|
||||
for (j = 0; j < clv->count; j++) {
|
||||
if (clv->flags[j] & SCHEME_WAS_SET_BANGED) {
|
||||
recbox = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (recbox)
|
||||
break;
|
||||
if (is_proc)
|
||||
is_lift = 0;
|
||||
else
|
||||
is_lift = is_liftable(clv->value, head->count, 5);
|
||||
|
||||
if (!is_proc && !is_lift) {
|
||||
recbox = 1;
|
||||
break;
|
||||
} else {
|
||||
if (!is_lift) {
|
||||
/* is_proc must be true ... */
|
||||
int j;
|
||||
|
||||
if (scheme_is_compiled_procedure(clv->value, 0, 0)) {
|
||||
num_rec_procs++;
|
||||
if (!(clv->flags[0] & SCHEME_WAS_ONLY_APPLIED))
|
||||
rec_proc_nonapply = 1;
|
||||
for (j = 0; j < clv->count; j++) {
|
||||
if (clv->flags[j] & SCHEME_WAS_SET_BANGED) {
|
||||
recbox = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (recbox)
|
||||
break;
|
||||
|
||||
if (scheme_is_compiled_procedure(clv->value, 0, 0)) {
|
||||
num_rec_procs++;
|
||||
if (!(clv->flags[0] & SCHEME_WAS_ONLY_APPLIED))
|
||||
rec_proc_nonapply = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3084,11 +3208,15 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
}
|
||||
lifts_frame_size = frame_size;
|
||||
|
||||
if ((clv->flags[0] & SCHEME_WAS_ONLY_APPLIED)
|
||||
&& SAME_TYPE(SCHEME_TYPE(clv->value), scheme_compiled_unclosed_procedure_type))
|
||||
le = scheme_resolve_closure_compilation(clv->value, linfo, 1, 1, 0, NULL);
|
||||
else
|
||||
le = scheme_resolve_expr(clv->value, linfo);
|
||||
if (skips[i]) {
|
||||
le = scheme_void;
|
||||
} else {
|
||||
if ((clv->flags[0] & SCHEME_WAS_ONLY_APPLIED)
|
||||
&& SAME_TYPE(SCHEME_TYPE(clv->value), scheme_compiled_unclosed_procedure_type))
|
||||
le = scheme_resolve_closure_compilation(clv->value, linfo, 1, 1, 0, NULL);
|
||||
else
|
||||
le = scheme_resolve_expr(clv->value, linfo);
|
||||
}
|
||||
|
||||
if (max_let_depth < linfo->max_let_depth + frame_size)
|
||||
max_let_depth = linfo->max_let_depth + frame_size;
|
||||
|
@ -3189,6 +3317,13 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
}
|
||||
}
|
||||
|
||||
num_skips = 0;
|
||||
clv = (Scheme_Compiled_Let_Value *)head->body;
|
||||
for (i = head->num_clauses; i--; clv = (Scheme_Compiled_Let_Value *)clv->body) {
|
||||
if ((clv->count == 1) && !(clv->flags[0] & SCHEME_WAS_USED))
|
||||
num_skips++;
|
||||
}
|
||||
|
||||
/* First assume that all letrec-bound procedures can be lifted to empty closures.
|
||||
Then try assuming that all letrec-bound procedures can be at least lifted.
|
||||
Then fall back to assuming no lifts. */
|
||||
|
@ -3201,10 +3336,10 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
resolve_phase = 2;
|
||||
|
||||
if (resolve_phase < 2) {
|
||||
linfo = scheme_resolve_info_extend(info, head->count - num_rec_procs, head->count, head->count);
|
||||
linfo = scheme_resolve_info_extend(info, head->count - num_rec_procs - num_skips, head->count, head->count);
|
||||
lifted_recs = MALLOC_N(Scheme_Object *, num_rec_procs);
|
||||
} else {
|
||||
linfo = scheme_resolve_info_extend(info, head->count, head->count, head->count);
|
||||
linfo = scheme_resolve_info_extend(info, head->count - num_skips, head->count, head->count);
|
||||
lifted_recs = NULL;
|
||||
}
|
||||
|
||||
|
@ -3218,38 +3353,46 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
for (i = head->num_clauses; i--; clv = (Scheme_Compiled_Let_Value *)clv->body) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < clv->count; j++) {
|
||||
int p, skip;
|
||||
Scheme_Object *lift;
|
||||
|
||||
skip = 0;
|
||||
if (num_rec_procs && scheme_is_compiled_procedure(clv->value, 0, 0)) {
|
||||
if (resolve_phase == 0) {
|
||||
lift = scheme_resolve_generate_stub_closure();
|
||||
lifted_recs[rpos] = lift;
|
||||
p = 0;
|
||||
} else if (resolve_phase == 1) {
|
||||
lift = scheme_resolve_generate_stub_lift();
|
||||
lifted_recs[rpos] = lift;
|
||||
p = 0;
|
||||
} else {
|
||||
lift = NULL;
|
||||
p = rpos;
|
||||
}
|
||||
rpos++;
|
||||
} else {
|
||||
p = pos++;
|
||||
lift = NULL;
|
||||
}
|
||||
|
||||
scheme_resolve_info_add_mapping(linfo, opos, p,
|
||||
((recbox
|
||||
|| (clv->flags[j] & SCHEME_WAS_SET_BANGED))
|
||||
? SCHEME_INFO_BOXED
|
||||
: 0),
|
||||
lift);
|
||||
|
||||
if ((clv->count == 1) && !(clv->flags[0] & SCHEME_WAS_USED)) {
|
||||
/* skipped */
|
||||
scheme_resolve_info_add_mapping(linfo, opos, 0, 0, NULL);
|
||||
opos++;
|
||||
} else {
|
||||
for (j = 0; j < clv->count; j++) {
|
||||
int p, skip;
|
||||
Scheme_Object *lift;
|
||||
|
||||
skip = 0;
|
||||
if (num_rec_procs
|
||||
&& (clv->count == 1)
|
||||
&& scheme_is_compiled_procedure(clv->value, 0, 0)) {
|
||||
if (resolve_phase == 0) {
|
||||
lift = scheme_resolve_generate_stub_closure();
|
||||
lifted_recs[rpos] = lift;
|
||||
p = 0;
|
||||
} else if (resolve_phase == 1) {
|
||||
lift = scheme_resolve_generate_stub_lift();
|
||||
lifted_recs[rpos] = lift;
|
||||
p = 0;
|
||||
} else {
|
||||
lift = NULL;
|
||||
p = rpos;
|
||||
}
|
||||
rpos++;
|
||||
} else {
|
||||
p = pos++;
|
||||
lift = NULL;
|
||||
}
|
||||
|
||||
scheme_resolve_info_add_mapping(linfo, opos, p,
|
||||
((recbox
|
||||
|| (clv->flags[j] & SCHEME_WAS_SET_BANGED))
|
||||
? SCHEME_INFO_BOXED
|
||||
: 0),
|
||||
lift);
|
||||
|
||||
opos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3265,7 +3408,10 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
rpos = 0; opos = 0;
|
||||
converted = 0;
|
||||
for (i = head->num_clauses; i--; clv = (Scheme_Compiled_Let_Value *)clv->body) {
|
||||
if (scheme_is_compiled_procedure(clv->value, 0, 0)) {
|
||||
if ((clv->count == 1) && !(clv->flags[0] & SCHEME_WAS_USED)) {
|
||||
/* skipped */
|
||||
} else if ((clv->count == 1)
|
||||
&& scheme_is_compiled_procedure(clv->value, 0, 0)) {
|
||||
Scheme_Object *lift, *old_lift;
|
||||
int old_convert_count;
|
||||
|
||||
|
@ -3310,7 +3456,9 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
clv = (Scheme_Compiled_Let_Value *)head->body;
|
||||
rpos = 0; opos = 0;
|
||||
for (i = head->num_clauses; i--; clv = (Scheme_Compiled_Let_Value *)clv->body) {
|
||||
if (scheme_is_compiled_procedure(clv->value, 0, 0)) {
|
||||
if ((clv->count == 1) && !(clv->flags[0] & SCHEME_WAS_USED)) {
|
||||
/* skipped */
|
||||
} else if ((clv->count == 1) && scheme_is_compiled_procedure(clv->value, 0, 0)) {
|
||||
Scheme_Object *lift;
|
||||
lift = lifted_recs[rpos];
|
||||
if (is_closed_reference(lift)) {
|
||||
|
@ -3360,72 +3508,78 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
clv = (Scheme_Compiled_Let_Value *)head->body;
|
||||
rpos = 0; opos = 0;
|
||||
for (i = head->num_clauses; i--; clv = (Scheme_Compiled_Let_Value *)clv->body) {
|
||||
int isproc;
|
||||
Scheme_Object *expr;
|
||||
if (!clv->value)
|
||||
isproc = 1;
|
||||
else
|
||||
isproc = scheme_is_compiled_procedure(clv->value, 0, 0);
|
||||
if (num_rec_procs && isproc) {
|
||||
if (!lifted_recs) {
|
||||
expr = scheme_resolve_closure_compilation(clv->value, val_linfo, 0, 0, 0, NULL);
|
||||
letrec->procs[rpos++] = expr;
|
||||
} else {
|
||||
if (!is_closed_reference(lifted_recs[rpos])) {
|
||||
/* Side-effect is to install lifted function: */
|
||||
(void)scheme_resolve_closure_compilation(clv->value, val_linfo, 1, 1, 0, lifted_recs[rpos]);
|
||||
}
|
||||
rpos++;
|
||||
}
|
||||
if ((clv->count == 1) && !(clv->flags[0] & SCHEME_WAS_USED)) {
|
||||
/* skipped */
|
||||
} else {
|
||||
int j;
|
||||
Scheme_Object *one_lifted;
|
||||
|
||||
expr = scheme_resolve_expr(clv->value, val_linfo);
|
||||
|
||||
lv = MALLOC_ONE_TAGGED(Scheme_Let_Value);
|
||||
if (last)
|
||||
last->body = (Scheme_Object *)lv;
|
||||
else if (last_body)
|
||||
SCHEME_CDR(last_body) = (Scheme_Object *)lv;
|
||||
int isproc;
|
||||
Scheme_Object *expr;
|
||||
if (!clv->value)
|
||||
isproc = 1;
|
||||
else if (clv->count == 1)
|
||||
isproc = scheme_is_compiled_procedure(clv->value, 0, 0);
|
||||
else
|
||||
first = (Scheme_Object *)lv;
|
||||
last = lv;
|
||||
last_body = NULL;
|
||||
|
||||
lv->iso.so.type = scheme_let_value_type;
|
||||
lv->value = expr;
|
||||
if (clv->count) {
|
||||
int li;
|
||||
li = scheme_resolve_info_lookup(linfo, clv->position, NULL, NULL, 0);
|
||||
lv->position = li;
|
||||
} else
|
||||
lv->position = 0;
|
||||
lv->count = clv->count;
|
||||
SCHEME_LET_AUTOBOX(lv) = recbox;
|
||||
|
||||
for (j = lv->count; j--; ) {
|
||||
if (!recbox
|
||||
&& (scheme_resolve_info_flags(linfo, opos + j, &one_lifted) & SCHEME_INFO_BOXED)) {
|
||||
GC_CAN_IGNORE Scheme_Object *pos;
|
||||
pos = scheme_make_integer(lv->position + j);
|
||||
if (SCHEME_LET_FLAGS(head) & (SCHEME_LET_STAR | SCHEME_LET_RECURSIVE)) {
|
||||
/* For let* or a let*-like letrec, we need to insert the boxes after each evaluation. */
|
||||
Scheme_Object *boxenv, *pr;
|
||||
pr = scheme_make_pair(pos, scheme_false);
|
||||
boxenv = scheme_make_syntax_resolved(BOXENV_EXPD, pr);
|
||||
if (last)
|
||||
last->body = boxenv;
|
||||
else
|
||||
SCHEME_CDR(last_body) = boxenv;
|
||||
last = NULL;
|
||||
last_body = pr;
|
||||
} else {
|
||||
/* For regular let, delay the boxing until all RHSs are
|
||||
evaluated. */
|
||||
boxes = scheme_make_pair(pos, boxes);
|
||||
isproc = 0;
|
||||
if (num_rec_procs && isproc) {
|
||||
if (!lifted_recs) {
|
||||
expr = scheme_resolve_closure_compilation(clv->value, val_linfo, 0, 0, 0, NULL);
|
||||
letrec->procs[rpos++] = expr;
|
||||
} else {
|
||||
if (!is_closed_reference(lifted_recs[rpos])) {
|
||||
/* Side-effect is to install lifted function: */
|
||||
(void)scheme_resolve_closure_compilation(clv->value, val_linfo, 1, 1, 0, lifted_recs[rpos]);
|
||||
}
|
||||
}
|
||||
rpos++;
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
Scheme_Object *one_lifted;
|
||||
|
||||
expr = scheme_resolve_expr(clv->value, val_linfo);
|
||||
|
||||
lv = MALLOC_ONE_TAGGED(Scheme_Let_Value);
|
||||
if (last)
|
||||
last->body = (Scheme_Object *)lv;
|
||||
else if (last_body)
|
||||
SCHEME_CDR(last_body) = (Scheme_Object *)lv;
|
||||
else
|
||||
first = (Scheme_Object *)lv;
|
||||
last = lv;
|
||||
last_body = NULL;
|
||||
|
||||
lv->iso.so.type = scheme_let_value_type;
|
||||
lv->value = expr;
|
||||
if (clv->count) {
|
||||
int li;
|
||||
li = scheme_resolve_info_lookup(linfo, clv->position, NULL, NULL, 0);
|
||||
lv->position = li;
|
||||
} else
|
||||
lv->position = 0;
|
||||
lv->count = clv->count;
|
||||
SCHEME_LET_AUTOBOX(lv) = recbox;
|
||||
|
||||
for (j = lv->count; j--; ) {
|
||||
if (!recbox
|
||||
&& (scheme_resolve_info_flags(linfo, opos + j, &one_lifted) & SCHEME_INFO_BOXED)) {
|
||||
GC_CAN_IGNORE Scheme_Object *pos;
|
||||
pos = scheme_make_integer(lv->position + j);
|
||||
if (SCHEME_LET_FLAGS(head) & (SCHEME_LET_STAR | SCHEME_LET_RECURSIVE)) {
|
||||
/* For let* or a let*-like letrec, we need to insert the boxes after each evaluation. */
|
||||
Scheme_Object *boxenv, *pr;
|
||||
pr = scheme_make_pair(pos, scheme_false);
|
||||
boxenv = scheme_make_syntax_resolved(BOXENV_EXPD, pr);
|
||||
if (last)
|
||||
last->body = boxenv;
|
||||
else
|
||||
SCHEME_CDR(last_body) = boxenv;
|
||||
last = NULL;
|
||||
last_body = pr;
|
||||
} else {
|
||||
/* For regular let, delay the boxing until all RHSs are
|
||||
evaluated. */
|
||||
boxes = scheme_make_pair(pos, boxes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
opos += clv->count;
|
||||
|
@ -3457,20 +3611,20 @@ scheme_resolve_lets(Scheme_Object *form, Resolve_Info *info)
|
|||
else
|
||||
first = body;
|
||||
|
||||
if (head->count + extra_alloc) {
|
||||
if (head->count + extra_alloc - num_skips) {
|
||||
Scheme_Let_Void *lvd;
|
||||
|
||||
lvd = MALLOC_ONE_TAGGED(Scheme_Let_Void);
|
||||
lvd->iso.so.type = scheme_let_void_type;
|
||||
lvd->body = first;
|
||||
lvd->count = head->count + extra_alloc;
|
||||
lvd->count = head->count + extra_alloc - num_skips;
|
||||
SCHEME_LET_AUTOBOX(lvd) = recbox;
|
||||
|
||||
first = (Scheme_Object *)lvd;
|
||||
}
|
||||
|
||||
if (info->max_let_depth < linfo->max_let_depth + head->count)
|
||||
info->max_let_depth = linfo->max_let_depth + head->count;
|
||||
if (info->max_let_depth < linfo->max_let_depth + head->count - num_skips + extra_alloc)
|
||||
info->max_let_depth = linfo->max_let_depth + head->count - num_skips + extra_alloc;
|
||||
|
||||
return first;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user