From f8644c31a3e6f4c3d9a95837c22a18fd27155510 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Wed, 15 May 2013 01:37:15 +0100 Subject: Only generate code for those builtin functions actually used. Makes output of --debug-dump-disasm much simpler. --- builtin.c | 4 ++-- compile.c | 24 +++++++++++++++++++++--- compile.h | 1 + 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**); -- cgit v1.2.3