From 3cdc850f2a7dbf1e170242417d67acf8d7e7b0d8 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Sun, 3 Aug 2025 20:59:53 -0400 Subject: expand and clarify type system, fix double-free of nodes --- ir.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'ir.c') diff --git a/ir.c b/ir.c index c75113e..0ef19b9 100644 --- a/ir.c +++ b/ir.c @@ -3,9 +3,20 @@ extern int no_opt; +/* types */ + +int type_eql(Type *a, Type *b) { + if (a->t != b->t) return 0; + if (a->next != b->next) return 0; + return a->next ? type_eql(a->next, b->next) : 1; +} + +/* nodes */ + const char *node_type_name(NodeType t) { const char *names[] = { "start", + "projection", "return", "keepalive", "literal", @@ -50,18 +61,19 @@ void node_del_in(Node *n, Node *p) { } void node_kill(Node *n, Proc *p) { - for (int i = 0; i < n->in.len; i++) { + if (n->refs < 1) return; + while (n->in.len > 0) { + int i = --n->in.len; node_del_out(n->in.data[i], n); n->in.data[i]->refs--; if (n->in.data[i]->out.len < 1) node_kill(n->in.data[i], p); } - for (int i = 0; i < n->out.len; i++) { + while (n->out.len > 0) { + int i = --n->out.len; node_del_in(n->out.data[i], n); n->out.data[i]->refs--; if (n->out.data[i]->refs < 1) node_die(n->out.data[i], p); } - n->in.len = 0; - n->out.len = 0; node_die(n, p); } @@ -116,7 +128,7 @@ Node *node_dedup_lit(Proc *p, Value v) { * how many literals even usually occur in a procedure? */ for (int i = 0; i < p->start->out.len; i++) { Node *t = p->start->out.data[i]; - if (t->type == N_LIT && t->val.type == v.type && t->val.i == v.i) { + if (t->type == N_LIT && type_eql(&t->val.type, &v.type) && t->val.i == v.i) { return t; } } @@ -124,7 +136,7 @@ Node *node_dedup_lit(Proc *p, Value v) { } Node *node_new_lit_i64(Proc *p, int64_t i) { - Value v = (Value) { T_INT, { .i = i } }; + Value v = (Value) { { .lvl = T_CONST, .t = T_INT }, { .i = i } }; Node *t = node_dedup_lit(p, v); if (t) return t; Node *n = node_new(p, N_LIT, p->start); @@ -141,21 +153,24 @@ static inline int node_op_communative(NodeType t) { } Value node_compute(Node *n, Lexer *l) { - Type lit_type = T_BOT; + Type lit_type = { .lvl = T_BOT }; Node **in = n->in.data; for (int i = 0; i < n->in.len; i++) { Node *p = in[i]; - if (p->type != N_LIT) break; - if (p->val.type != lit_type) { - if (lit_type == T_BOT) { + if (p->val.type.lvl != T_CONST) { + lit_type.lvl = T_BOT; + break; + } + if (!type_eql(&p->val.type, &lit_type)) { + if (lit_type.lvl == T_BOT) { lit_type = p->val.type; } else { - lit_type = T_BOT; + lit_type.lvl = T_BOT; break; } } } - if (lit_type == T_INT) { + if (lit_type.lvl == T_CONST && lit_type.t == T_INT) { Value v = { .type = lit_type }; switch (n->type) { case N_OP_NEG: v.i = -in[0]->val.i; break; @@ -187,7 +202,7 @@ Node *node_peephole(Node *n, Proc *p, Lexer *l) { if (n->type != N_LIT) { Value v = node_compute(n, l); - if (v.type > T_CONST) { + if (v.type.lvl == T_CONST) { node_kill(n, p); Node *t = node_dedup_lit(p, v); if (t) return t; @@ -310,8 +325,8 @@ NameBinding *scope_bind(Scope *scope, Str name, Node *value, LexSpan pos, Proc * NameBinding *scope_update(Scope *scope, Str name, Node *to, Proc *proc) { NameBinding *b = scope_find(scope, name); if (!b) return NULL; - node_remove(proc, b->node, proc->keepalive); node_add(proc, to, proc->keepalive); + node_remove(proc, b->node, proc->keepalive); b->node = to; return b; } -- cgit v1.2.3