optimizer: fix calculation of used local variables (again)
Mostly reverts a52a08146a
, then repairs the problem in a way
that does not add variables unnecessarily to nested closures.
This commit is contained in:
parent
01458e22fa
commit
537292ef45
|
@ -17,7 +17,6 @@ static int mark_optimize_info_MARK(void *p, struct NewGC *gc) {
|
||||||
gcMARK2(i->cp, gc);
|
gcMARK2(i->cp, gc);
|
||||||
gcMARK2(i->top_level_consts, gc);
|
gcMARK2(i->top_level_consts, gc);
|
||||||
gcMARK2(i->transitive_use_var, gc);
|
gcMARK2(i->transitive_use_var, gc);
|
||||||
gcMARK2(i->transitive_uses_to, gc);
|
|
||||||
gcMARK2(i->context, gc);
|
gcMARK2(i->context, gc);
|
||||||
gcMARK2(i->logger, gc);
|
gcMARK2(i->logger, gc);
|
||||||
gcMARK2(i->types, gc);
|
gcMARK2(i->types, gc);
|
||||||
|
@ -41,7 +40,6 @@ static int mark_optimize_info_FIXUP(void *p, struct NewGC *gc) {
|
||||||
gcFIXUP2(i->cp, gc);
|
gcFIXUP2(i->cp, gc);
|
||||||
gcFIXUP2(i->top_level_consts, gc);
|
gcFIXUP2(i->top_level_consts, gc);
|
||||||
gcFIXUP2(i->transitive_use_var, gc);
|
gcFIXUP2(i->transitive_use_var, gc);
|
||||||
gcFIXUP2(i->transitive_uses_to, gc);
|
|
||||||
gcFIXUP2(i->context, gc);
|
gcFIXUP2(i->context, gc);
|
||||||
gcFIXUP2(i->logger, gc);
|
gcFIXUP2(i->logger, gc);
|
||||||
gcFIXUP2(i->types, gc);
|
gcFIXUP2(i->types, gc);
|
||||||
|
|
|
@ -1411,7 +1411,6 @@ mark_optimize_info {
|
||||||
gcMARK2(i->cp, gc);
|
gcMARK2(i->cp, gc);
|
||||||
gcMARK2(i->top_level_consts, gc);
|
gcMARK2(i->top_level_consts, gc);
|
||||||
gcMARK2(i->transitive_use_var, gc);
|
gcMARK2(i->transitive_use_var, gc);
|
||||||
gcMARK2(i->transitive_uses_to, gc);
|
|
||||||
gcMARK2(i->context, gc);
|
gcMARK2(i->context, gc);
|
||||||
gcMARK2(i->logger, gc);
|
gcMARK2(i->logger, gc);
|
||||||
gcMARK2(i->types, gc);
|
gcMARK2(i->types, gc);
|
||||||
|
|
|
@ -92,7 +92,6 @@ struct Optimize_Info
|
||||||
|
|
||||||
Scheme_IR_Local *transitive_use_var; /* set when optimizing a letrec-bound procedure
|
Scheme_IR_Local *transitive_use_var; /* set when optimizing a letrec-bound procedure
|
||||||
to record variables that were added to `uses` */
|
to record variables that were added to `uses` */
|
||||||
struct Optimize_Info *transitive_uses_to; /* points to frame with relevant `transitive_use_var` */
|
|
||||||
|
|
||||||
Scheme_Object *context; /* for logging */
|
Scheme_Object *context; /* for logging */
|
||||||
Scheme_Logger *logger;
|
Scheme_Logger *logger;
|
||||||
|
@ -137,6 +136,8 @@ static void increment_use_count(Scheme_IR_Local *var, int as_rator);
|
||||||
static Optimize_Info *optimize_info_add_frame(Optimize_Info *info, int orig, int current, int flags);
|
static Optimize_Info *optimize_info_add_frame(Optimize_Info *info, int orig, int current, int flags);
|
||||||
static void optimize_info_done(Optimize_Info *info, Optimize_Info *parent);
|
static void optimize_info_done(Optimize_Info *info, Optimize_Info *parent);
|
||||||
|
|
||||||
|
static void register_transitive_uses(Scheme_IR_Local *var, Optimize_Info *info);
|
||||||
|
|
||||||
static void optimize_info_seq_init(Optimize_Info *info, Optimize_Info_Sequence *info_seq);
|
static void optimize_info_seq_init(Optimize_Info *info, Optimize_Info_Sequence *info_seq);
|
||||||
static void optimize_info_seq_step(Optimize_Info *info, Optimize_Info_Sequence *info_seq);
|
static void optimize_info_seq_step(Optimize_Info *info, Optimize_Info_Sequence *info_seq);
|
||||||
static void optimize_info_seq_done(Optimize_Info *info, Optimize_Info_Sequence *info_seq);
|
static void optimize_info_seq_done(Optimize_Info *info, Optimize_Info_Sequence *info_seq);
|
||||||
|
@ -5828,7 +5829,6 @@ static void start_transitive_use_record(Optimize_Info *to_info, Optimize_Info *i
|
||||||
return;
|
return;
|
||||||
|
|
||||||
info->transitive_use_var = var;
|
info->transitive_use_var = var;
|
||||||
info->transitive_uses_to = to_info;
|
|
||||||
|
|
||||||
/* Restore use flags, if any, saved from before: */
|
/* Restore use flags, if any, saved from before: */
|
||||||
if (var->optimize.transitive_uses)
|
if (var->optimize.transitive_uses)
|
||||||
|
@ -5842,7 +5842,6 @@ static void end_transitive_use_record(Optimize_Info *info)
|
||||||
|
|
||||||
if (var != info->next->transitive_use_var) {
|
if (var != info->next->transitive_use_var) {
|
||||||
info->transitive_use_var = info->next->transitive_use_var;
|
info->transitive_use_var = info->next->transitive_use_var;
|
||||||
info->transitive_uses_to = info->next->transitive_uses_to;
|
|
||||||
|
|
||||||
if (var->optimize.transitive_uses)
|
if (var->optimize.transitive_uses)
|
||||||
flip_transitive(var->optimize.transitive_uses, 0);
|
flip_transitive(var->optimize.transitive_uses, 0);
|
||||||
|
@ -6469,6 +6468,26 @@ scheme_optimize_lets(Scheme_Object *form, Optimize_Info *info, int for_inline, i
|
||||||
else
|
else
|
||||||
head->body = body;
|
head->body = body;
|
||||||
|
|
||||||
|
/* Propagate any use from formerly tentative uses: */
|
||||||
|
while (1) {
|
||||||
|
int changed = 0;
|
||||||
|
body = head->body;
|
||||||
|
for (i = head->num_clauses; i--; ) {
|
||||||
|
pre_body = (Scheme_IR_Let_Value *)body;
|
||||||
|
for (j = pre_body->count; j--; ) {
|
||||||
|
if (pre_body->vars[j]->optimize_used
|
||||||
|
&& pre_body->vars[j]->optimize.transitive_uses) {
|
||||||
|
register_transitive_uses(pre_body->vars[j], body_info);
|
||||||
|
changed = 1;
|
||||||
|
pre_body->vars[j]->optimize.transitive_uses = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body = pre_body->body;
|
||||||
|
}
|
||||||
|
if (!changed)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
info->single_result = body_info->single_result;
|
info->single_result = body_info->single_result;
|
||||||
info->preserves_marks = body_info->preserves_marks;
|
info->preserves_marks = body_info->preserves_marks;
|
||||||
info->vclock = body_info->vclock;
|
info->vclock = body_info->vclock;
|
||||||
|
@ -8122,53 +8141,6 @@ void scheme_optimize_info_never_inline(Optimize_Info *oi)
|
||||||
oi->inline_fuel = -1;
|
oi->inline_fuel = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_transitive(Scheme_IR_Local *var, Optimize_Info *info);
|
|
||||||
static void register_use_at(Scheme_IR_Local *var, Optimize_Info *info);
|
|
||||||
|
|
||||||
static Scheme_Object *transitive_k(void)
|
|
||||||
{
|
|
||||||
Scheme_Thread *p = scheme_current_thread;
|
|
||||||
Scheme_IR_Local *var = SCHEME_VAR(p->ku.k.p1);
|
|
||||||
Optimize_Info *info = (Optimize_Info *)p->ku.k.p2;
|
|
||||||
|
|
||||||
p->ku.k.p1 = NULL;
|
|
||||||
p->ku.k.p2 = NULL;
|
|
||||||
|
|
||||||
register_transitive(var, info);
|
|
||||||
|
|
||||||
return scheme_false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void register_transitive(Scheme_IR_Local *var, Optimize_Info *info)
|
|
||||||
{
|
|
||||||
Scheme_Hash_Table *ht;
|
|
||||||
Scheme_IR_Local *tvar;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
#ifdef DO_STACK_CHECK
|
|
||||||
# include "mzstkchk.h"
|
|
||||||
{
|
|
||||||
Scheme_Thread *p = scheme_current_thread;
|
|
||||||
|
|
||||||
p->ku.k.p1 = (void *)var;
|
|
||||||
p->ku.k.p2 = (void *)info;
|
|
||||||
|
|
||||||
scheme_handle_stack_overflow(transitive_k);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ht = var->optimize.transitive_uses;
|
|
||||||
|
|
||||||
for (j = 0; j < ht->size; j++) {
|
|
||||||
if (ht->vals[j]) {
|
|
||||||
tvar = SCHEME_VAR(ht->keys[j]);
|
|
||||||
register_use_at(tvar, info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void propagate_used_variables(Optimize_Info *info)
|
static void propagate_used_variables(Optimize_Info *info)
|
||||||
{
|
{
|
||||||
Scheme_Hash_Table *ht;
|
Scheme_Hash_Table *ht;
|
||||||
|
@ -8261,7 +8233,7 @@ static int optimize_any_uses(Optimize_Info *info, Scheme_IR_Let_Value *at_irlv,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_use_at(Scheme_IR_Local *var, Optimize_Info *info)
|
static void register_use(Scheme_IR_Local *var, Optimize_Info *info)
|
||||||
{
|
{
|
||||||
if (var->optimize.lambda_depth < info->lambda_depth)
|
if (var->optimize.lambda_depth < info->lambda_depth)
|
||||||
scheme_hash_set(info->uses, (Scheme_Object *)var, scheme_true);
|
scheme_hash_set(info->uses, (Scheme_Object *)var, scheme_true);
|
||||||
|
@ -8271,7 +8243,7 @@ static void register_use_at(Scheme_IR_Local *var, Optimize_Info *info)
|
||||||
|
|
||||||
if (info->transitive_use_var
|
if (info->transitive_use_var
|
||||||
&& (var->optimize.lambda_depth
|
&& (var->optimize.lambda_depth
|
||||||
<= info->transitive_uses_to->lambda_depth)) {
|
<= info->transitive_use_var->optimize.lambda_depth)) {
|
||||||
Scheme_Hash_Table *ht = info->transitive_use_var->optimize.transitive_uses;
|
Scheme_Hash_Table *ht = info->transitive_use_var->optimize.transitive_uses;
|
||||||
|
|
||||||
if (!ht) {
|
if (!ht) {
|
||||||
|
@ -8280,9 +8252,22 @@ static void register_use_at(Scheme_IR_Local *var, Optimize_Info *info)
|
||||||
}
|
}
|
||||||
scheme_hash_set(ht, (Scheme_Object *)var, scheme_true);
|
scheme_hash_set(ht, (Scheme_Object *)var, scheme_true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (var->optimize.transitive_uses)
|
static void register_transitive_uses(Scheme_IR_Local *var, Optimize_Info *info)
|
||||||
register_transitive(var, info);
|
{
|
||||||
|
Scheme_Hash_Table *ht;
|
||||||
|
Scheme_IR_Local *tvar;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
ht = var->optimize.transitive_uses;
|
||||||
|
|
||||||
|
for (j = 0; j < ht->size; j++) {
|
||||||
|
if (ht->vals[j]) {
|
||||||
|
tvar = SCHEME_VAR(ht->keys[j]);
|
||||||
|
register_use(tvar, info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8357,7 +8342,7 @@ static Scheme_Object *optimize_info_lookup(Optimize_Info *info, Scheme_Object *v
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!closure_ok)
|
if (!closure_ok)
|
||||||
register_use_at(SCHEME_VAR(var), info);
|
register_use(SCHEME_VAR(var), info);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -8413,7 +8398,6 @@ static Optimize_Info *optimize_info_add_frame(Optimize_Info *info, int orig, int
|
||||||
naya->lambda_depth = info->lambda_depth + ((flags & SCHEME_LAMBDA_FRAME) ? 1 : 0);
|
naya->lambda_depth = info->lambda_depth + ((flags & SCHEME_LAMBDA_FRAME) ? 1 : 0);
|
||||||
naya->uses = info->uses;
|
naya->uses = info->uses;
|
||||||
naya->transitive_use_var = info->transitive_use_var;
|
naya->transitive_use_var = info->transitive_use_var;
|
||||||
naya->transitive_uses_to = info->transitive_uses_to;
|
|
||||||
|
|
||||||
return naya;
|
return naya;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user