|
|
- From a949ffe9554b5af5614d31b795805f56939a031b Mon Sep 17 00:00:00 2001
- From: Muh Muhten <muh.muhten@gmail.com>
- Date: Fri, 8 Feb 2019 16:52:04 -0500
- Subject: [PATCH 1/9] Improve linking time by marking subtrees with unbound
- symbols
-
- ---
- src/compile.c | 29 +++++++++++++++++++++++++----
- 1 file changed, 25 insertions(+), 4 deletions(-)
-
- --- a/src/compile.c
- +++ b/src/compile.c
- @@ -49,9 +49,10 @@ struct inst {
- // Unbound instructions (references to other things that may or may not
- // exist) are created by "gen_foo_unbound", and bindings are created by
- // block_bind(definition, body), which binds all instructions in
- - // body which are unboudn and refer to "definition" by name.
- + // body which are unbound and refer to "definition" by name.
- struct inst* bound_by;
- char* symbol;
- + int any_unbound;
-
- int nformals;
- int nactuals;
- @@ -73,6 +74,7 @@ static inst* inst_new(opcode op) {
- i->bytecode_pos = -1;
- i->bound_by = 0;
- i->symbol = 0;
- + i->any_unbound = 0;
- i->nformals = -1;
- i->nactuals = -1;
- i->subfn = gen_noop();
- @@ -156,6 +158,7 @@ block gen_const_global(jv constant, cons
- inst* i = inst_new(STORE_GLOBAL);
- i->imm.constant = constant;
- i->symbol = strdup(name);
- + i->any_unbound = 0;
- return inst_block(i);
- }
-
- @@ -211,6 +214,7 @@ block gen_op_unbound(opcode op, const ch
- assert(opcode_describe(op)->flags & OP_HAS_BINDING);
- inst* i = inst_new(op);
- i->symbol = strdup(name);
- + i->any_unbound = 1;
- return inst_block(i);
- }
-
- @@ -224,6 +228,7 @@ block gen_op_bound(opcode op, block bind
- assert(block_is_single(binder));
- block b = gen_op_unbound(op, binder.first->symbol);
- b.first->bound_by = binder.first;
- + b.first->any_unbound = 0;
- return b;
- }
-
- @@ -324,7 +329,7 @@ static int block_count_refs(block binder
- return nrefs;
- }
-
- -static int block_bind_subblock(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((opcode_describe(binder.first->op)->flags & bindflags) == (bindflags & ~OP_BIND_WILDCARD));
- assert(binder.first->symbol);
- @@ -336,6 +341,9 @@ static int block_bind_subblock(block bin
- binder.first->nformals = block_count_formals(binder);
- int nrefs = 0;
- for (inst* i = body.first; i; i = i->next) {
- + if (i->any_unbound == 0)
- + continue;
- +
- int flags = opcode_describe(i->op)->flags;
- if ((flags & bindflags) == (bindflags & ~OP_BIND_WILDCARD) && i->bound_by == 0 &&
- (!strcmp(i->symbol, binder.first->symbol) ||
- @@ -357,14 +365,25 @@ static int block_bind_subblock(block bin
- // a break whenever we come across a STOREV of *anonlabel...
- break_distance++;
- }
- +
- + i->any_unbound = (i->symbol && !i->bound_by);
- +
- // binding recurses into closures
- - nrefs += block_bind_subblock(binder, i->subfn, bindflags, break_distance);
- + nrefs += block_bind_subblock_inner(&i->any_unbound, binder, i->subfn, bindflags, break_distance);
- // binding recurses into argument list
- - nrefs += block_bind_subblock(binder, i->arglist, bindflags, break_distance);
- + nrefs += block_bind_subblock_inner(&i->any_unbound, binder, i->arglist, bindflags, break_distance);
- +
- + if (i->any_unbound)
- + *any_unbound = 1;
- }
- return nrefs;
- }
-
- +static int block_bind_subblock(block binder, block body, int bindflags, int break_distance) {
- + int any_unbound;
- + return block_bind_subblock_inner(&any_unbound, binder, body, bindflags, break_distance);
- +}
- +
- static int block_bind_each(block binder, block body, int bindflags) {
- assert(block_has_only_binders(binder, bindflags));
- bindflags |= OP_HAS_BINDING;
- @@ -550,6 +569,7 @@ block gen_function(const char* name, blo
- }
- i->subfn = body;
- i->symbol = strdup(name);
- + i->any_unbound = -1;
- i->arglist = formals;
- block b = inst_block(i);
- block_bind_subblock(b, b, OP_IS_CALL_PSEUDO | OP_HAS_BINDING, 0);
- @@ -1081,6 +1101,7 @@ block gen_cbinding(const struct cfunctio
- inst* i = inst_new(CLOSURE_CREATE_C);
- i->imm.cfunc = &cfunctions[cfunc];
- i->symbol = strdup(i->imm.cfunc->name);
- + i->any_unbound = 0;
- code = block_bind(inst_block(i), code, OP_IS_CALL_PSEUDO);
- }
- return code;
|