diff options
| -rw-r--r-- | ir.c | 33 | ||||
| -rw-r--r-- | ir.h | 8 | ||||
| -rw-r--r-- | main.c | 5 | ||||
| -rw-r--r-- | peephole.c | 2 |
4 files changed, 29 insertions, 19 deletions
@@ -30,7 +30,6 @@ void nodelist_fit(NodeList *l, u32 sz, Arena *a) { void nodelist_push(NodeList *l, Node *n, Arena *a) { nodelist_fit(l, l->len + 1, a); Node **p = nodelist_nth(l, l->len++); - if (n) n->refs++; *p = n; } @@ -38,7 +37,6 @@ void nodelist_remove(NodeList *l, Node *n) { Node **data = nodelist_data(l); for (unsigned i = 0; i < l->len; i++) { if (data[i] == n) { - if (n) n->refs--; l->len--; if (i < l->len) { memmove(&data[i], &data[i+1], (l->len - i) * sizeof(Node *)); @@ -54,7 +52,6 @@ void nodelist_remove_unordered(NodeList *l, Node *p) { while (i) { i--; if (data[i] == p) { - if (p) p->refs--; l->len--; if (i < l->len) { data[i] = data[l->len]; @@ -76,7 +73,6 @@ const char *node_type_name(NodeType t) { } void node_die(Node *n, Graph *p) { - assert(n->refs == 0); assert(n->op != N_DEAD); n->op = N_DEAD; n->prev_free = p->pool->free_list; @@ -91,14 +87,28 @@ void node_del_in(Node *n, Node *p) { nodelist_remove(&n->in, p); } +static inline int node_should_die(Node *n) { + return n->in.len == 0 && n->out.len == 0; +} + void node_kill(Node *n, Graph *p) { if (p->ctrl == n) { /* probably this is fine */ p->ctrl = CTRL(n); } - while (n->refs > 0 && n->in.len > 0) node_remove(p, IN(n, 0), n); - while (n->refs > 0 && n->out.len > 0) node_remove(p, n, OUT(n, 0)); - assert(n->refs == 0); + for (u32 i = 0; i < n->in.len; i++) { + Node *o = IN(n, i); + if (o) { + node_del_out(o, n); + if (node_should_die(o)) node_die(o, p); + } + } + for (u32 i = 0; i < n->out.len; i++) { + Node *o = OUT(n, i); + node_del_in(o, n); + if (node_should_die(o)) node_die(o, p); + } + node_die(n, p); } void node_add_out(Graph *p, Node *a, Node *b) { @@ -111,7 +121,6 @@ void node_add_in(Graph *p, Node *a, Node *b) { void node_set_in(Graph *p, Node *n, int idx, Node *to) { Node *in = IN(n, idx); - if (in) in->refs--; node_add_out(p, to, n); node_del_out(in, n); IN(n, idx) = to; @@ -135,7 +144,7 @@ void node_add(Graph *p, Node *src, Node *dest) { void node_remove(Graph *p, Node *src, Node *dest) { assert(dest->op != N_DEAD); node_del_in(dest, src); - if (dest->refs < 1) node_die(dest, p); + if (node_should_die(dest)) node_die(dest, p); if (src) { assert(src->op != N_DEAD); node_del_out(src, dest); @@ -151,7 +160,11 @@ Node *node_new_empty(Graph *p, NodeType t) { n = p->pool->free_list; assert(n->op == N_DEAD); p->pool->free_list = n->prev_free; - memset(n, 0, sizeof(Node)); + n->in.len = 0; + n->out.len = 0; + n->walked = 0; + n->src_pos = (LexSpan) { 0 }; + n->val = (Value) { 0 }; } else { n = new(p->pool->arena, Node); } @@ -110,21 +110,21 @@ typedef struct { } NodeList; typedef struct Node { - int id, refs; union { struct Node *prev_free; struct { - int walked; - NodeType op; - LexSpan src_pos; NodeList in; /* note: index 0 used for control flow */ NodeList out; + int walked; + LexSpan src_pos; union { Type type; Value val; }; }; }; + int id; + NodeType op; } Node; /* convenience macros (lisp-inspired lol) */ @@ -256,8 +256,6 @@ void parse_if(Lexer *l, Proc *p) { region = node_new(g, N_REGION, ctrl_if, if_false); node_add_out(g, region, g->keepalive); node_remove(g, ctrl_if, g->keepalive); - assert(if_true->refs > 0); - assert(if_false->refs > 0); } ctrl(g, region); node_remove(g, if_true, g->keepalive); @@ -540,8 +538,7 @@ Node *parse_expr(Lexer *l, Proc *p, Type *twant) { Graph *g = &p->graph; Node *lhs = parse_term(l, p, twant); NodeType nt = tok_to_bin_op(l->tok);; - if (lhs->refs <= 0) lex_error(l, LE_ERROR, S("dead lhs")); - assert(lhs->refs > 0); + if (lhs->op == N_DEAD) lex_error(l, LE_ERROR, S("dead lhs")); if (nt != N_START) { lex_next(l); /* necessary because if lhs is a deduplicated literal, it may be an input to rhs @@ -617,7 +617,7 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n); } Node *node_peephole(Node *n, Graph *p, Lexer *l) { - assert(n->refs > 0); + assert(n->op != N_DEAD); Node *r = node_idealize(n, p, l); if (r) { r->src_pos = n->src_pos; |
