]> granicus.if.org Git - jq/commitdiff
Only generate code for those builtin functions actually used.
authorStephen Dolan <mu@netsoc.tcd.ie>
Wed, 15 May 2013 00:37:15 +0000 (01:37 +0100)
committerStephen Dolan <mu@netsoc.tcd.ie>
Wed, 15 May 2013 00:37:15 +0000 (01:37 +0100)
Makes output of --debug-dump-disasm much simpler.

builtin.c
compile.c
compile.h

index 0b797142e197a340d25ee57b358e0ca4e2cf1839..47c13865101b7c96a09762cd93e1b64f5b54912d 100644 (file)
--- 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);
index d305c5c89d648baeff3a23d734d96ee1589ad299..6c1e8f87fdf89e7bf27a0bfbfd1970b84547cbb4 100644 (file)
--- 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);
index 00a863c6b9a538c29be74e9075a48f589ea2f7a9..f3f70b4461979ef1f5f5defbec1c5b7ae8f2dd08 100644 (file)
--- 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**);