diff options
Diffstat (limited to 'ir.c')
| -rw-r--r-- | ir.c | 62 |
1 files changed, 22 insertions, 40 deletions
@@ -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; |
