summaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c62
1 files changed, 22 insertions, 40 deletions
diff --git a/ir.c b/ir.c
index a35c80c..62d6600 100644
--- a/ir.c
+++ b/ir.c
@@ -119,53 +119,42 @@ const char *node_type_name(NodeType t) {
}
void node_die(Node *n, Proc *p) {
+ assert(n->refs == 0);
n->prev_free = p->free_list;
p->free_list = n;
}
void node_del_out(Node *n, Node *p) {
- for (int i = 0; i < n->out.len; i++) {
+ for (int i = n->out.len - 1; i >= 0; i--) {
if (n->out.data[i] == p) {
p->refs--;
- if (i + 1 < n->out.len) {
- memmove(&n->out.data[i], &n->out.data[i + 1], sizeof(Node*) * (n->out.len - i - 1));
- }
n->out.len--;
- i--;
+ if (i < n->out.len) {
+ n->out.data[i] = n->out.data[n->out.len];
+ }
break;
}
}
}
void node_del_in(Node *n, Node *p) {
- for (int i = 0; i < n->in.len; i++) {
+ for (int i = n->in.len - 1; i >= 0; i--) {
if (n->in.data[i] == p) {
p->refs--;
- if (i + 1 < n->in.len) {
- memmove(&n->in.data[i], &n->in.data[i + 1], sizeof(Node*) * (n->in.len - i - 1));
- }
n->in.len--;
- i--;
+ if (i < n->in.len) {
+ memmove(&n->in.data[i], &n->in.data[i + 1], sizeof(Node*) * (n->in.len - i));
+ }
break;
}
}
}
void node_kill(Node *n, Proc *p) {
- 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);
- }
- 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);
- }
- node_die(n, p);
+ assert(n->refs > 0);
+ while (n->refs > 0 && n->in.len > 0) node_remove(p, n->in.data[0], n);
+ while (n->refs > 0 && n->out.len > 0) node_remove(p, n, n->out.data[0]);
+ assert(n->refs == 0);
}
void node_add_out(Proc *p, Node *a, Node *b) {
@@ -174,8 +163,7 @@ void node_add_out(Proc *p, Node *a, Node *b) {
}
void node_add_in(Proc *p, Node *a, Node *b) {
- assert(a->in.len < NODE_INPUT_MAX);
- a->in.data[a->in.len++] = b;
+ ZDA_PUSH(&a->in, b, &p->arena);
b->refs++;
}
@@ -194,8 +182,7 @@ void node_remove(Proc *p, Node *src, Node *dest) {
node_del_out(src, dest);
node_del_in(dest, src);
if (dest->refs < 1) node_die(dest, p);
- if (src->refs < 1) node_die(src, p);
- else if (src->out.len < 1) node_kill(src, p);
+ if (src->out.len < 1) node_kill(src, p);
}
static int global_node_count = 0;
@@ -364,14 +351,6 @@ Value node_compute(Node *n, Lexer *l) {
#include <stdio.h>
-/* replace an in[] with a peepholed ver */
-void node_peephole_in(Node *n, int idx, Proc *p, Lexer *l) {
- node_del_out(n->in.data[idx], n);
- Node *r = node_peephole(n->in.data[idx], p, l);
- node_add_out(p, r, n);
- n->in.data[idx] = r;
-}
-
#define NODE(...) node_peephole(node_new(p, __VA_ARGS__), p, l)
#define OP(...) NODE(n->type, __VA_ARGS__)
@@ -481,8 +460,8 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
if (T(CAR(n), N_LIT) && !T(CDR(n), N_LIT)) return OP(CDR(n), CAR(n));
/* op(X, op(Y,Z)) -> op(op(Y,Z), X) */
- if (!T(CAR(n), n->type) && T(CDR(n), n->type)
- && C(CAR(n), CDAR(n))) return OP(CDR(n), CAR(n));
+ /*if (!T(CAR(n), n->type) && T(CDR(n), n->type)
+ && C(CAR(n), CDAR(n))) return OP(CDR(n), CAR(n));*/
/* op(op(X,Y), op(Z, lit)) -> op(op(X, op(Y, Z)), lit) */
if (T(CAR(n), n->type) && T(CDR(n), n->type) && T(CDDR(n), N_LIT)
@@ -601,20 +580,23 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n);
break;
}
-
-
return NULL;
}
Node *node_peephole(Node *n, Proc *p, Lexer *l) {
+ assert(n->refs > 0);
+ node_add_out(p, n, p->keepalive);
Node *r = node_idealize(n, p, l);
if (r) {
r->src_pos = n->src_pos;
/* make sure r doesn't get deleted even if connected to n */
node_add_out(p, r, p->keepalive);
+ node_del_out(n, p->keepalive);
node_kill(n, p);
node_del_out(r, p->keepalive);
n = r;
+ } else {
+ node_del_out(n, p->keepalive);
}
/* FIXME: figure out why this shows the wrong position when in an assignment */
return n;