summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWormHeamer2025-08-04 23:05:46 -0400
committerWormHeamer2025-08-04 23:05:46 -0400
commita4eca17c4156863108cd9bec7834bbb1681c0bf7 (patch)
treec979e040bdf40277800972acc0f0f35824a774d0
parent88b01f43312eeceba87a1378be5cd63bb11f167f (diff)
NODE_KEEP macro
-rw-r--r--ir.c11
-rw-r--r--ir.h5
-rw-r--r--main.c10
-rw-r--r--test.lang2
4 files changed, 13 insertions, 15 deletions
diff --git a/ir.c b/ir.c
index 62d6600..a6f0c04 100644
--- a/ir.c
+++ b/ir.c
@@ -585,18 +585,11 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n);
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);
+ NODE_KEEP(p, r, node_kill(n, p));
+ return r;
}
/* FIXME: figure out why this shows the wrong position when in an assignment */
return n;
diff --git a/ir.h b/ir.h
index 799a0e0..681f3ae 100644
--- a/ir.h
+++ b/ir.h
@@ -107,6 +107,11 @@ typedef struct {
Scope scope;
} Proc;
+#define NODE_KEEP(p, n, ...)\
+ do { Node *keep_node = n;\
+ node_add_out(p, keep_node, p->keepalive); __VA_ARGS__;\
+ node_del_out(keep_node, p->keepalive); } while(0)
+
void node_kill(Node *n, Proc *p);
void node_die(Node *n, Proc *p);
void node_del_out(Node *n, Node *p);
diff --git a/main.c b/main.c
index 8533e49..3ce67dc 100644
--- a/main.c
+++ b/main.c
@@ -245,11 +245,11 @@ Node *parse_expr(Lexer *l, Proc *p) {
lex_next(l);
/* necessary because if lhs is a deduplicated literal, it may be an input to rhs
* and therefore culled by peephole optimizations */
- node_add(p, lhs, p->keepalive);
- Node *rhs = parse_expr(l, p);
- Node *n = node_peephole(node_new(p, nt, lhs, rhs), p, l);
- node_remove(p, lhs, p->keepalive);
- lhs = n;
+ Node *rhs;
+ NODE_KEEP(p, lhs, {
+ rhs = parse_expr(l, p);
+ });
+ lhs = node_peephole(node_new(p, nt, lhs, rhs), p, l);
}
lhs->src_pos = (LexSpan) { pos.ofs, l->pos.ofs - pos.ofs };
return lhs;
diff --git a/test.lang b/test.lang
index c2661a4..1d84f4b 100644
--- a/test.lang
+++ b/test.lang
@@ -11,5 +11,5 @@
proc main(a i64) {
let x = (a + -a) = (a xor a)
let y = (a + a) = (a * 2)
- return x & y & (a = a) & ((a + 2) <> a)
+ return x & y & (a = a) & ((a + 2) <> a) & (a = ~a)
}