Reimplement block_drop_unreferenced in linear time
This commit is contained in:
1 parent
9fa2e51099
commit
605bfb3577
1 file changed
+29
-21
+29
-21
@@ -53,6 +53,7 @@ struct inst {
|
|||||||
struct inst* bound_by;
|
struct inst* bound_by;
|
||||||
char* symbol;
|
char* symbol;
|
||||||
int any_unbound;
|
int any_unbound;
|
||||||
|
int referenced;
|
||||||
|
|
||||||
int nformals;
|
int nformals;
|
||||||
int nactuals;
|
int nactuals;
|
||||||
@@ -75,6 +76,7 @@ static inst* inst_new(opcode op) {
|
|||||||
i->bound_by = 0;
|
i->bound_by = 0;
|
||||||
i->symbol = 0;
|
i->symbol = 0;
|
||||||
i->any_unbound = 0;
|
i->any_unbound = 0;
|
||||||
|
i->referenced = 0;
|
||||||
i->nformals = -1;
|
i->nformals = -1;
|
||||||
i->nactuals = -1;
|
i->nactuals = -1;
|
||||||
i->subfn = gen_noop();
|
i->subfn = gen_noop();
|
||||||
@@ -465,30 +467,36 @@ block block_bind_referenced(block binder, block body, int bindflags) {
|
|||||||
return block_join(refd, body);
|
return block_join(refd, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void block_mark_referenced(block body) {
|
||||||
|
int saw_top = 0;
|
||||||
|
for (inst* i = body.last; i; i = i->prev) {
|
||||||
|
if (saw_top && i->bound_by == i && !i->referenced)
|
||||||
|
continue;
|
||||||
|
if (i->op == TOP) {
|
||||||
|
saw_top = 1;
|
||||||
|
}
|
||||||
|
if (i->bound_by) {
|
||||||
|
i->bound_by->referenced = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
block_mark_referenced(i->arglist);
|
||||||
|
block_mark_referenced(i->subfn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
block block_drop_unreferenced(block body) {
|
block block_drop_unreferenced(block body) {
|
||||||
inst* curr;
|
block_mark_referenced(body);
|
||||||
|
|
||||||
block refd = gen_noop();
|
block refd = gen_noop();
|
||||||
block unrefd = gen_noop();
|
inst* curr;
|
||||||
int drop;
|
while ((curr = block_take(&body))) {
|
||||||
do {
|
if (curr->bound_by == curr && !curr->referenced) {
|
||||||
drop = 0;
|
inst_free(curr);
|
||||||
while ((curr = block_take(&body)) && curr->op != TOP) {
|
} else {
|
||||||
block b = inst_block(curr);
|
refd = BLOCK(inst_block(curr), refd);
|
||||||
if (block_count_refs(b,refd) + block_count_refs(b,body) == 0) {
|
|
||||||
unrefd = BLOCK(unrefd, b);
|
|
||||||
drop++;
|
|
||||||
} else {
|
|
||||||
refd = BLOCK(refd, b);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (curr && curr->op == TOP) {
|
}
|
||||||
body = BLOCK(inst_block(curr),body);
|
return refd;
|
||||||
}
|
|
||||||
body = BLOCK(refd, body);
|
|
||||||
refd = gen_noop();
|
|
||||||
} while (drop != 0);
|
|
||||||
block_free(unrefd);
|
|
||||||
return body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jv block_take_imports(block* body) {
|
jv block_take_imports(block* body) {
|
||||||
|
|||||||
Reference in new issue
Block a user