diff options
| author | WormHeamer | 2025-08-08 02:30:00 -0400 |
|---|---|---|
| committer | WormHeamer | 2025-08-08 02:30:00 -0400 |
| commit | 374caf13f412f5062888bc2c49b011bec884e531 (patch) | |
| tree | e769764b9301709b147122bdbc4285be8d127229 | |
| parent | ff9dc0a669474afab22765f0daa91fe89afb40e5 (diff) | |
some comments &c
| -rw-r--r-- | main.c | 61 | ||||
| -rw-r--r-- | test.lang | 7 |
2 files changed, 54 insertions, 14 deletions
@@ -33,6 +33,27 @@ void unit_free(Unit *u) { Node *parse_expr(Lexer *l, Proc *p); +/* TODO: eliminate unused if-else statements at the end of compilation + * they don't get pruned out by peephole optimizations if there are phi + * nodes that are connected to keepalive (due to still being in scope). + * so probably this will have to be done in a separate step after the + * graph has been generated. + */ + +Node *ctrl(Proc *p, Node *n) { + if (!n) { + p->ctrl = node_new_lit(p, (Value) { + .type = { .lvl = T_XCTRL, .t = T_NONE } + }); + return NULL; + } + if (p->ctrl->val.type.lvl == T_XCTRL) { + return NULL; + } + p->ctrl = n; + return n; +} + void parse_return(Lexer *l, Proc *p) { lex_next(l); Node *n; @@ -52,9 +73,8 @@ void parse_return(Lexer *l, Proc *p) { 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 } - }); + ctrl(p, n); + ctrl(p, NULL); } void parse_let(Lexer *l, Proc *p) { @@ -131,7 +151,7 @@ void merge_scope(Lexer *l, Proc *p, ScopeNameList *before, ScopeNameList *ntrue, if (yes->node == b4->node && no->node == b4->node) continue; phi = node_new(p, N_PHI, p->ctrl, yes->node, no->node); } - fprintf(stderr, "phi('%.*s', %d, %d)\n", (int)b4->name.n, b4->name.s, phi->in.data[1]->id, phi->in.data[2]->id); + //fprintf(stderr, "phi('%.*s', %d, %d)\n", (int)b4->name.n, b4->name.s, phi->in.data[1]->id, phi->in.data[2]->id); phi = node_peephole(phi, p, l); NameBinding *b = scope_find(&p->scope, b4->name); assert(b); @@ -140,6 +160,26 @@ void merge_scope(Lexer *l, Proc *p, ScopeNameList *before, ScopeNameList *ntrue, node_remove(p, p->ctrl, p->keepalive); } +/* TODO: find out a way to encode known relations between nodes, based on the + * conditional, within the body of an if statement --- e.g., for a statement + * + * if a < 5 { + * if a < 10 { + * foo() + * } + * } else { + * if a > 3 { + * bar() + * } + * } + * + * we should be able to infer that the second condition is always true, because + * it's only reachable if a < 5, and 5 < 10. conversely, in the else branch, + * we know that a >= 5, and can use that to make assumptions on comparisons + * made there too! + * + */ + void parse_if(Lexer *l, Proc *p) { lex_next(l); Node *cond = parse_expr(l, p); @@ -170,20 +210,18 @@ void parse_if(Lexer *l, Proc *p) { if (cond->val.i) if_false->val.type.lvl = T_XCTRL; else if_true->val.type.lvl = T_XCTRL; } - p->ctrl = if_true; - fprintf(stderr, ":+ %d\n", p->ctrl->id); + ctrl(p, if_true); //assert(if_true->in.len > 0); lex_expected(l, TM_LBRACE); parse_block(l, p, &scope_true); ctrl_if = p->ctrl; node_add(p, ctrl_if, p->keepalive); - fprintf(stderr, ":- %d\n", p->ctrl->id); //assert(ctrl_if->in.len > 0); if (l->tok == TOK_ELSE) { for (int i = 0; i < scope_before.len; i++) { scope_update(scope_find(&p->scope, scope_before.data[i].name), scope_before.data[i].node, p); } - p->ctrl = if_false; + ctrl(p, if_false); lex_expect(l, TM_LBRACE); parse_block(l, p, &scope_false); ctrl_else = p->ctrl; @@ -208,7 +246,7 @@ void parse_if(Lexer *l, Proc *p) { assert(if_true->refs > 0); assert(if_false->refs > 0); } - p->ctrl = region; + ctrl(p, 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); @@ -217,12 +255,11 @@ 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); + node_del_out(region, 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); + ctrl(p, node_peephole(p->ctrl, p, l)); } } @@ -1,6 +1,9 @@ func main(a, b i64) i64 { if a < b { - return a + b + let t = a + a := b + b := t } - return b + /* TODO: error on failing to return from a function */ + return a + b } |
