Simplify definition of block_bind_referenced
This commit is contained in:
1 parent
88e1f59ec1
commit
8edf58a95f
1 file changed
+8
-41
+8
-41
@@ -317,20 +317,6 @@ static int block_count_actuals(block b) {
|
||||
return args;
|
||||
}
|
||||
|
||||
static int block_count_refs(block binder, block body) {
|
||||
int nrefs = 0;
|
||||
for (inst* i = body.first; i; i = i->next) {
|
||||
if (i != binder.first && i->bound_by == binder.first) {
|
||||
nrefs++;
|
||||
}
|
||||
// counting recurses into closures
|
||||
nrefs += block_count_refs(binder, i->subfn);
|
||||
// counting recurses into argument list
|
||||
nrefs += block_count_refs(binder, i->arglist);
|
||||
}
|
||||
return nrefs;
|
||||
}
|
||||
|
||||
static int block_bind_subblock_inner(int* any_unbound, block binder, block body, int bindflags, int break_distance) {
|
||||
assert(block_is_single(binder));
|
||||
assert((opcode_describe(binder.first->op)->flags & bindflags) == (bindflags & ~OP_BIND_WILDCARD));
|
||||
@@ -434,37 +420,18 @@ block block_bind_library(block binder, block body, int bindflags, const char *li
|
||||
return body; // We don't return a join because we don't want those sticking around...
|
||||
}
|
||||
|
||||
// Bind binder to body and throw away any defs in binder not referenced
|
||||
// (directly or indirectly) from body.
|
||||
// Bind binder to body, then throw it away if not referenced.
|
||||
block block_bind_referenced(block binder, block body, int bindflags) {
|
||||
assert(block_is_single(binder));
|
||||
assert(block_has_only_binders(binder, bindflags));
|
||||
bindflags |= OP_HAS_BINDING;
|
||||
block refd = gen_noop();
|
||||
block unrefd = gen_noop();
|
||||
int nrefs;
|
||||
for (int last_kept = 0, kept = 0; ; ) {
|
||||
for (inst* curr; (curr = block_take(&binder));) {
|
||||
block b = inst_block(curr);
|
||||
nrefs = block_bind_each(b, body, bindflags);
|
||||
// Check if this binder is referenced from any of the ones we
|
||||
// already know are referenced by body.
|
||||
nrefs += block_count_refs(b, refd);
|
||||
nrefs += block_count_refs(b, body);
|
||||
if (nrefs) {
|
||||
refd = BLOCK(refd, b);
|
||||
kept++;
|
||||
} else {
|
||||
unrefd = BLOCK(unrefd, b);
|
||||
}
|
||||
}
|
||||
if (kept == last_kept)
|
||||
break;
|
||||
last_kept = kept;
|
||||
binder = unrefd;
|
||||
unrefd = gen_noop();
|
||||
|
||||
if (block_bind_subblock(binder, body, bindflags, 0) == 0) {
|
||||
block_free(binder);
|
||||
} else {
|
||||
body = BLOCK(binder, body);
|
||||
}
|
||||
block_free(unrefd);
|
||||
return block_join(refd, body);
|
||||
return body;
|
||||
}
|
||||
|
||||
static void block_mark_referenced(block body) {
|
||||
|
||||
Reference in new issue
Block a user