summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWormHeamer2025-08-04 17:38:23 -0400
committerWormHeamer2025-08-04 17:38:23 -0400
commit22aa7559a37c49def05e8a43b12561b17a4af258 (patch)
tree028a9a9883cbc54ec21ed0332c77d838bda6a9b8
parent3db2e548d80d0bfa213d0df73833b1b1b4e0a4f7 (diff)
make NodeInputs statically sized, peephole a + ~a and a ^ ~a
-rw-r--r--ir.c15
-rw-r--r--ir.h12
-rw-r--r--test.lang2
3 files changed, 26 insertions, 3 deletions
diff --git a/ir.c b/ir.c
index 2e1fe8e..a35c80c 100644
--- a/ir.c
+++ b/ir.c
@@ -174,7 +174,8 @@ void node_add_out(Proc *p, Node *a, Node *b) {
}
void node_add_in(Proc *p, Node *a, Node *b) {
- ZDA_PUSH(&a->in, b, &p->arena);
+ assert(a->in.len < NODE_INPUT_MAX);
+ a->in.data[a->in.len++] = b;
b->refs++;
}
@@ -517,6 +518,13 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
break;
case N_OP_ADD:
if (same) return NODE(N_OP_MUL, CAR(n), node_new_lit_i64(p, 2));
+ if (CAR(n)->val.type.t == T_INT) {
+ /* a + ~a = -1 */
+ if (T(CAR(n), N_OP_NOT) && node_equiv(CAAR(n), CDR(n))) return node_new_lit_i64(p, -1);
+ if (T(CDR(n), N_OP_NOT) && node_equiv(CDAR(n), CAR(n))) return node_new_lit_i64(p, -1);
+ }
+ if (T(CAR(n), N_OP_NEG)) return NODE(N_OP_SUB, CDR(n), CAAR(n));
+ if (T(CDR(n), N_OP_NEG)) return NODE(N_OP_SUB, CAR(n), CDAR(n));
goto zero_no_effect;
case N_OP_SUB:
if (same) return node_new_lit_i64(p, 0);
@@ -561,6 +569,11 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
if (node_cmp_opposite(CAR(n)->type, CDR(n)->type) && node_equiv_input(CAR(n), CDR(n))) {
return node_new_lit_bool(p, 1);
}
+ if (CAR(n)->val.type.t == T_INT) {
+ /* a ^ ~a = -1 */
+ if (T(CAR(n), N_OP_NOT) && node_equiv(CAAR(n), CDR(n))) return node_new_lit_i64(p, -1);
+ if (T(CDR(n), N_OP_NOT) && node_equiv(CDAR(n), CAR(n))) return node_new_lit_i64(p, -1);
+ }
zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n);
if (node_eql_i64(CDR(n), 0)) return CAR(n);
break;
diff --git a/ir.h b/ir.h
index 1cb3def..112ab8e 100644
--- a/ir.h
+++ b/ir.h
@@ -62,6 +62,15 @@ typedef enum {
const char *node_type_name(NodeType t);
+#define NODE_INPUT_MAX 2
+
+typedef struct {
+ struct Node *data[NODE_INPUT_MAX];
+ ptrdiff_t len;
+} NodeInputs;
+
+typedef DYNARR(struct Node *) NodeOutputs;
+
typedef struct Node {
union {
struct Node *prev_free;
@@ -70,7 +79,8 @@ typedef struct Node {
int walked;
NodeType type;
LexSpan src_pos;
- DYNARR(struct Node *) in, out;
+ NodeInputs in;
+ NodeOutputs out;
Value val;
};
};
diff --git a/test.lang b/test.lang
index 9e9dd9b..2277fc3 100644
--- a/test.lang
+++ b/test.lang
@@ -9,6 +9,6 @@
// also single-line now
proc main(a i64) {
- return a xor ~a
+ return a + -a
// (true = 0) = (a xor b)
}