diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 70 |
1 files changed, 40 insertions, 30 deletions
@@ -85,7 +85,7 @@ void parse_assign(Lexer *l, Proc *p) { } } -void merge_scope(Proc *p, ScopeNameList *na, ScopeNameList *nb) { +void merge_scope(Lexer *l, Proc *p, ScopeNameList *na, ScopeNameList *nb) { for (ScopeFrame *f = p->scope.tail; f; f = f->prev) { for (NameBinding *b = f->latest; b; b = b->prev) { int i, j; @@ -94,20 +94,21 @@ void merge_scope(Proc *p, ScopeNameList *na, ScopeNameList *nb) { if (i >= na->len && j >= nb->len) continue; /* no change */ Node *phi; if (i >= na->len) { + if (nb->data[j].node == b->node) continue; phi = node_new(p, N_PHI, p->ctrl, b->node, nb->data[j].node); } else if (j >= na->len) { - phi = node_new(p, N_PHI, p->ctrl, na->data[i].node, b->node); + if (na->data[i].node == b->node) continue; + phi = node_new(p, N_PHI, p->ctrl, b->node, na->data[i].node); } else { + if (na->data[i].node == b->node && nb->data[j].node == b->node) continue; phi = node_new(p, N_PHI, p->ctrl, na->data[i].node, nb->data[j].node); } - node_add(p, phi, p->keepalive); node_remove(p, b->node, p->keepalive); + phi = node_peephole(phi, p, l); + node_add(p, phi, p->keepalive); b->node = phi; } } - - for (int i = 0; i < na->len; i++) node_remove(p, na->data[i].node, p->keepalive); - for (int i = 0; i < nb->len; i++) node_remove(p, nb->data[i].node, p->keepalive); } void parse_if(Lexer *l, Proc *p) { @@ -117,21 +118,21 @@ void parse_if(Lexer *l, Proc *p) { Node *if_node = node_new(p, N_IF_ELSE, p->ctrl, cond); if_node->val = (Value) { .type = { T_TOP, T_TUPLE, NULL }, - .tuple = { - .len = 2, - .cap = 0, - .data = (Value[2]) { - { .type = { T_CTRL, T_NONE, NULL } }, - { .type = { T_CTRL, T_NONE, NULL } }, - } - } + .tuple = { 0 } }; - Node *if_true = node_new(p, N_PROJ, if_node); - Node *if_false = node_new(p, N_PROJ, if_node); + ZDA_PUSH(&p->arena, &if_node->val.tuple, (Value) { .type = { T_CTRL, T_NONE, NULL } }); + ZDA_PUSH(&p->arena, &if_node->val.tuple, (Value) { .type = { T_CTRL, T_NONE, NULL } }); + if_node = node_peephole(if_node, p, l); + Node *if_true = node_peephole(node_new(p, N_PROJ, if_node), p, l); + Node *if_false = node_peephole(node_new(p, N_PROJ, if_node), p, l); ScopeNameList scope_before = { 0 }, scope_true = { 0 }, scope_false = { 0 }; if_true->val.i = 0; if_false->val.i = 1; scope_collect(&p->scope, p, &scope_before, &p->arena); + if (cond->val.type.lvl == T_CONST) { + if (cond->val.i) if_false->val.type.lvl = T_XCTRL; + else if_true->val.type.lvl = T_XCTRL; + } NODE_KEEP(p, cond, { p->ctrl = if_true; lex_expected(l, TM_LBRACE); @@ -147,12 +148,19 @@ void parse_if(Lexer *l, Proc *p) { } }); if (ctrl_else) { - p->ctrl = node_new(p, N_REGION, ctrl_if, ctrl_else); - merge_scope(p, &scope_true, &scope_false); + p->ctrl = node_peephole(node_new(p, N_REGION, ctrl_if, ctrl_else), p, l); + node_add(p, p->ctrl, p->keepalive); + merge_scope(l, p, &scope_true, &scope_false); + node_remove(p, p->ctrl, p->keepalive); } else { - p->ctrl = node_new(p, N_REGION, ctrl_if, if_false); - merge_scope(p, &scope_before, &scope_true); + p->ctrl = node_peephole(node_new(p, N_REGION, ctrl_if, if_false), p, l); + node_add(p, p->ctrl, p->keepalive); + merge_scope(l, p, &scope_true, &scope_before); + node_remove(p, p->ctrl, p->keepalive); } + scope_uncollect(&p->scope, p, &scope_true); + scope_uncollect(&p->scope, p, &scope_false); + scope_uncollect(&p->scope, p, &scope_before); } void parse_stmt(Lexer *l, Proc *p) { @@ -214,12 +222,12 @@ void parse_args_list(Lexer *l, Proc *proc) { lex_expect(l, TM_IDENT | TM_COMMA); if (l->tok == TOK_COMMA) continue; Value v = (Value) { .type = parse_type(l, proc) }; - ZDA_PUSH(&proc->arena, &start->val.tuple, v); lex_expected(l, TM_RPAREN | TM_COMMA); for (int j = 0; j < id; j++) { Node *proj = node_new(proc, N_PROJ, proc->start); proj->val.type = v.type; proj->val.i = i++; + ZDA_PUSH(&proc->arena, &start->val.tuple, v); scope_bind(&proc->scope, idbuf[j].name, proj, idbuf[j].pos, proc); } id = 0; @@ -264,7 +272,7 @@ Node *parse_term(Lexer *l, Proc *p) { default: return node; } if (post_op == N_START) return node; - return node_peephole(node_new(p, post_op, node), p, l); + return node_peephole(node_new(p, post_op, NULL, node), p, l); } if (l->tok == TOK_LPAREN) { lex_next(l); @@ -299,7 +307,7 @@ Node *parse_term(Lexer *l, Proc *p) { lex_next(l); } if (op_after != N_START) { - node = node_new(p, op_after, node_peephole(node, p, l)); + node = node_new(p, op_after, NULL, node_peephole(node, p, l)); } return node_peephole(node, p, l); } @@ -340,7 +348,7 @@ Node *parse_expr(Lexer *l, Proc *p) { NODE_KEEP(p, lhs, { rhs = parse_expr(l, p); }); - lhs = node_peephole(node_new(p, nt, lhs, rhs), p, l); + lhs = node_peephole(node_new(p, nt, NULL, lhs, rhs), p, l); } lhs->src_pos = (LexSpan) { pos.ofs, l->pos.ofs - pos.ofs }; return lhs; @@ -373,9 +381,6 @@ void parse_unit(Lexer *l) { void node_print(Node *n, Proc *p) { if (n->walked) return; - const char *colors[] = { - "red", "blue", "cyan", "green", "orange", "magenta", - }; if (n->type == N_START) { Str s = S(""); int c = n->val.tuple.len; @@ -398,11 +403,12 @@ void node_print(Node *n, Proc *p) { break; } } else if (n->type == N_PROJ) { - printf("\t%d [label=\"PROJ(%ld)\", shape=record]", n->id, n->val.i); + Str d = type_desc(&n->in.data[0]->val.tuple.data[n->val.i].type, &p->arena); + printf("\t%d [label=\"%ld | %.*s\", shape=record]", n->id, n->val.i, (int)d.n, d.s); } else { printf("\t%d [label=\"%s\", shape=record]", n->id, node_type_name(n->type)); } - printf(" [color=%s]\n", colors[n->id % (sizeof colors / sizeof *colors)]); + printf("\n"); n->walked = 1; for (int i = 0; i < n->out.len; i++) { Node *o = n->out.data[i]; @@ -411,7 +417,11 @@ void node_print(Node *n, Proc *p) { } else { int j; for (j = 0; j < o->in.len && o->in.data[j] != n; j++); - printf("\t%d -> %d [color=%s,headlabel=%d]\n", n->id, o->id, colors[o->id % (sizeof colors / sizeof *colors)], j); + if (j == 0) { + printf("\t%d -> %d [color=red,headlabel=%d]\n", n->id, o->id, j); + } else { + printf("\t%d -> %d [headlabel=%d]\n", n->id, o->id, j); + } } } for (int i = 0; i < n->out.len; i++) { |
