diff options
| -rw-r--r-- | ir.c | 30 | ||||
| -rw-r--r-- | main.c | 28 | ||||
| -rw-r--r-- | test.lang | 8 |
3 files changed, 56 insertions, 10 deletions
@@ -722,8 +722,17 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n); } break; + case N_RETURN: + if (CTRL(n)->val.type.lvl == T_XCTRL) return CTRL(n); + break; + case N_PROJ: if (T(CTRL(n), N_IF_ELSE) && CTRL(n)->val.type.t == T_TUPLE) { + if (CTRL(n)->val.tuple.data[n->val.i].type.lvl == T_XCTRL) { + return node_new_lit(p, (Value) { + .type = { .lvl = T_XCTRL, .t = T_NONE } + }); + } if (CTRL(n)->val.tuple.data[(n->val.i + 1) % CTRL(n)->val.tuple.len].type.lvl == T_XCTRL) { return CTRL(CTRL(n)); } @@ -736,6 +745,27 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n); if (IN(CTRL(n), 0)->val.type.lvl == T_XCTRL) return CDR(n); break; + case N_REGION: + { + int live_in = 0; + for (int i = 0; i < n->in.len; i++) { + if (IN(n, i)->val.type.lvl != T_XCTRL) live_in++; + } + if (live_in == 1) { + for (int i = 0; i < n->in.len; i++) { + if (IN(n, i)->val.type.lvl != T_XCTRL) { + return IN(n, i); + } + } + } + if (live_in == 0) { + return node_new_lit(p, (Value) { + .type = { .lvl = T_XCTRL, .t = T_NONE } + }); + } + } + break; + default: break; } @@ -48,8 +48,13 @@ void parse_return(Lexer *l, Proc *p) { } n = node_new(p, N_RETURN, p->ctrl, e); } - node_add(p, n, p->stop); - p->ctrl = n; + n = node_peephole(n, p, l); + if (n->val.type.lvl != T_XCTRL) { + node_add(p, n, p->stop); + } + p->ctrl = node_new_lit(p, (Value) { + .type = { .lvl = T_XCTRL, .t = T_NONE } + }); } void parse_let(Lexer *l, Proc *p) { @@ -154,11 +159,11 @@ void parse_if(Lexer *l, Proc *p) { if_false->val.i = 1; if_true = node_peephole(if_true, p, l); if_false = node_peephole(if_false, p, l); + node_remove(p, if_node, p->keepalive); assert(if_true->in.len > 0); assert(if_false->in.len > 0); node_add(p, if_true, p->keepalive); node_add(p, if_false, p->keepalive); - node_remove(p, if_node, p->keepalive); ScopeNameList scope_before = { 0 }, scope_true = { 0 }, scope_false = { 0 }; scope_collect(&p->scope, p, &scope_before, &p->arena); if (cond->val.type.lvl == T_CONST) { @@ -184,20 +189,26 @@ void parse_if(Lexer *l, Proc *p) { ctrl_else = p->ctrl; node_add(p, ctrl_else, p->keepalive); } + Node *ctrl_was = p->ctrl; + //node_add(p, ctrl_was, p->keepalive); + Node *region; if (ctrl_else) { //assert(ctrl_if->in.len > 0); //assert(ctrl_else->in.len > 0); - p->ctrl = node_peephole(node_new(p, N_REGION, ctrl_if, ctrl_else), p, l); + region = node_new(p, N_REGION, ctrl_if, ctrl_else); + node_add_out(p, region, p->keepalive); node_remove(p, ctrl_if, p->keepalive); node_remove(p, ctrl_else, p->keepalive); } else { //assert(ctrl_if->in.len > 0); //assert(if_false->in.len > 0); - p->ctrl = node_peephole(node_new(p, N_REGION, ctrl_if, if_false), p, l); + region = node_new(p, N_REGION, ctrl_if, if_false); + node_add_out(p, region, p->keepalive); node_remove(p, ctrl_if, p->keepalive); assert(if_true->refs > 0); assert(if_false->refs > 0); } + p->ctrl = region; node_remove(p, if_true, p->keepalive); node_remove(p, if_false, p->keepalive); //p->ctrl = node_peephole(node_new(p, N_REGION, if_true, if_false), p, l); @@ -206,6 +217,13 @@ void parse_if(Lexer *l, Proc *p) { scope_uncollect(&p->scope, p, &scope_true); scope_uncollect(&p->scope, p, &scope_false); scope_uncollect(&p->scope, p, &scope_before); + fprintf(stderr, "%ld\n", p->ctrl->out.len); + node_del_out(p->ctrl, p->keepalive); + assert(p->ctrl == region); + /* make sure we're not orphaning any phi nodes*/ + if (p->ctrl->out.len < 1) { + p->ctrl = node_peephole(p->ctrl, p, l); + } } void parse_stmt(Lexer *l, Proc *p) { @@ -1,8 +1,6 @@ func main(a, b i64) i64 { - if true { - a := 3 - } else { - a := 5 + if a < b { + return a + b } - return a + return b } |
