Simplify definition of block_bind_referenced

This commit is contained in:
Muh Muhten authored and Nico Williams committed 2019-02-20 19:16:18 -06:00
1 parent 88e1f59ec1
commit 8edf58a95f
1 file changed
+8 -41
+8 -41
View File
@@ -317,20 +317,6 @@ static int block_count_actuals(block b) {
return args; 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) { static int block_bind_subblock_inner(int* any_unbound, block binder, block body, int bindflags, int break_distance) {
assert(block_is_single(binder)); assert(block_is_single(binder));
assert((opcode_describe(binder.first->op)->flags & bindflags) == (bindflags & ~OP_BIND_WILDCARD)); 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... 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 // Bind binder to body, then throw it away if not referenced.
// (directly or indirectly) from body.
block block_bind_referenced(block binder, block body, int bindflags) { block block_bind_referenced(block binder, block body, int bindflags) {
assert(block_is_single(binder));
assert(block_has_only_binders(binder, bindflags)); assert(block_has_only_binders(binder, bindflags));
bindflags |= OP_HAS_BINDING; bindflags |= OP_HAS_BINDING;
block refd = gen_noop();
block unrefd = gen_noop(); if (block_bind_subblock(binder, body, bindflags, 0) == 0) {
int nrefs; block_free(binder);
for (int last_kept = 0, kept = 0; ; ) { } else {
for (inst* curr; (curr = block_take(&binder));) { body = BLOCK(binder, body);
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();
} }
block_free(unrefd); return body;
return block_join(refd, body);
} }
static void block_mark_referenced(block body) { static void block_mark_referenced(block body) {