summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMuh Muhten <muh.muhten@gmail.com>2019-02-18 21:00:59 -0500
committerNico Williams <nico@cryptonector.com>2019-02-20 19:16:18 -0600
commit8edf58a95fdebfba7b6a6145e2f58cdb4f3eb64c (patch)
treee93323c4deb96300354dd2fe7ea405a30c40f202
parent88e1f59ec176ff37781b13bba065ed231ca5222f (diff)
Simplify definition of block_bind_referenced
-rw-r--r--src/compile.c49
1 files changed, 8 insertions, 41 deletions
diff --git a/src/compile.c b/src/compile.c
index 4f181fe4..9cbf683f 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -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) {