summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ir.c33
-rw-r--r--ir.h8
-rw-r--r--main.c5
-rw-r--r--peephole.c2
4 files changed, 29 insertions, 19 deletions
diff --git a/ir.c b/ir.c
index a91db1b..356a606 100644
--- a/ir.c
+++ b/ir.c
@@ -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);
}
diff --git a/ir.h b/ir.h
index d10005c..eb9b6b7 100644
--- a/ir.h
+++ b/ir.h
@@ -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) */
diff --git a/main.c b/main.c
index a1736f1..4c6c274 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/peephole.c b/peephole.c
index 06ded1a..24ae315 100644
--- a/peephole.c
+++ b/peephole.c
@@ -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;