summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Dolan <mu@netsoc.tcd.ie>2013-05-15 01:37:15 +0100
committerStephen Dolan <mu@netsoc.tcd.ie>2013-05-15 01:37:15 +0100
commitf8644c31a3e6f4c3d9a95837c22a18fd27155510 (patch)
treebeae6b4437093607e394e99462812ba4ecb37cac
parent1e2851cdb3add02948e28ba2e80594794bbcffb3 (diff)
Only generate code for those builtin functions actually used.
Makes output of --debug-dump-disasm much simpler.
-rw-r--r--builtin.c4
-rw-r--r--compile.c24
-rw-r--r--compile.h1
3 files changed, 24 insertions, 5 deletions
diff --git a/builtin.c b/builtin.c
index 0b797142..47c13865 100644
--- a/builtin.c
+++ b/builtin.c
@@ -543,7 +543,7 @@ static block bind_bytecoded_builtins(block b) {
range));
}
- return block_bind(builtins, b, OP_IS_CALL_PSEUDO);
+ return block_bind_referenced(builtins, b, OP_IS_CALL_PSEUDO);
}
static const char* const jq_builtins[] = {
@@ -572,7 +572,7 @@ block builtins_bind(block b) {
block funcs;
int nerrors = jq_parse_library(&src, &funcs);
assert(!nerrors);
- b = block_bind(funcs, b, OP_IS_CALL_PSEUDO);
+ b = block_bind_referenced(funcs, b, OP_IS_CALL_PSEUDO);
locfile_free(&src);
}
b = bind_bytecoded_builtins(b);
diff --git a/compile.c b/compile.c
index d305c5c8..6c1e8f87 100644
--- a/compile.c
+++ b/compile.c
@@ -216,13 +216,14 @@ int block_has_only_binders(block binders, int bindflags) {
return 1;
}
-static void block_bind_subblock(block binder, block body, int bindflags) {
+static int block_bind_subblock(block binder, block body, int bindflags) {
assert(block_is_single(binder));
assert((opcode_describe(binder.first->op)->flags & bindflags) == bindflags);
assert(binder.first->symbol);
assert(binder.first->bound_by == 0 || binder.first->bound_by == binder.first);
binder.first->bound_by = binder.first;
+ int nrefs = 0;
for (inst* i = body.first; i; i = i->next) {
int flags = opcode_describe(i->op)->flags;
if ((flags & bindflags) == bindflags &&
@@ -230,12 +231,14 @@ static void block_bind_subblock(block binder, block body, int bindflags) {
!strcmp(i->symbol, binder.first->symbol)) {
// bind this instruction
i->bound_by = binder.first;
+ nrefs++;
}
// binding recurses into closures
- block_bind_subblock(binder, i->subfn, bindflags);
+ nrefs += block_bind_subblock(binder, i->subfn, bindflags);
// binding recurses into argument list
- block_bind_subblock(binder, i->arglist, bindflags);
+ nrefs += block_bind_subblock(binder, i->arglist, bindflags);
}
+ return nrefs;
}
static void block_bind_each(block binder, block body, int bindflags) {
@@ -251,6 +254,21 @@ block block_bind(block binder, block body, int bindflags) {
return block_join(binder, body);
}
+block block_bind_referenced(block binder, block body, int bindflags) {
+ assert(block_has_only_binders(binder, bindflags));
+ bindflags |= OP_HAS_BINDING;
+ block refd = gen_noop();
+ for (inst* curr; (curr = block_take(&binder));) {
+ block b = inst_block(curr);
+ if (block_bind_subblock(b, body, bindflags)) {
+ refd = BLOCK(refd, b);
+ } else {
+ block_free(b);
+ }
+ }
+ return block_join(refd, body);
+}
+
block gen_function(const char* name, block formals, block body) {
block_bind_each(formals, body, OP_IS_CALL_PSEUDO);
inst* i = inst_new(CLOSURE_CREATE);
diff --git a/compile.h b/compile.h
index 00a863c6..f3f70b44 100644
--- a/compile.h
+++ b/compile.h
@@ -50,6 +50,7 @@ void block_append(block* b, block b2);
block block_join(block a, block b);
int block_has_only_binders(block, int bindflags);
block block_bind(block binder, block body, int bindflags);
+block block_bind_referenced(block binder, block body, int bindflags);
int block_compile(block, struct locfile*, struct bytecode**);