From 2069733522922fc45cc87da0327e6dfcda74f1b2 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Tue, 5 Aug 2025 01:44:20 -0400 Subject: correction! equality is communative, but not _associative_ so constants can still be shuffled from left to right, not(X) from right to left, but the regrouping optimizations don't apply --- ir.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/ir.c b/ir.c index e1b86c6..c0de33c 100644 --- a/ir.c +++ b/ir.c @@ -245,6 +245,14 @@ Node *node_new_lit_bool(Proc *p, int b) { } static inline int node_op_communative(NodeType t) { + NodeType ops[] = { N_OP_ADD, N_OP_MUL, N_OP_AND, N_OP_XOR, N_OP_OR, N_CMP_EQL, N_CMP_NEQ }; + for (unsigned i = 0; i < sizeof ops / sizeof *ops; i++) { + if (ops[i] == t) return 1; + } + return 0; +} + +static inline int node_op_associative(NodeType t) { NodeType ops[] = { N_OP_ADD, N_OP_MUL, N_OP_AND, N_OP_XOR, N_OP_OR }; for (unsigned i = 0; i < sizeof ops / sizeof *ops; i++) { if (ops[i] == t) return 1; @@ -487,6 +495,14 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) { /* op(lit, X) -> op(X, lit) */ if (T(CAR(n), N_LIT) && !T(CDR(n), N_LIT)) return OP(CDR(n), CAR(n)); + /* op(X, not(Y)) -> op(not(Y), X) */ + /* shuffle not left to avoid conflict w/ literals */ + if (T(CDR(n), N_OP_NOT) && !T(CAR(n), N_OP_NOT)) { + return NODE(n->type, CDR(n), CAR(n)); + } + } + + if (node_op_associative(n->type)) { /* 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));*/ @@ -510,12 +526,6 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) { && C(CADR(n), CDR(n))) { return OP(OP(CAAR(n), CDR(n)), CADR(n)); } - - /* op(X, not(Y)) -> op(not(Y), X) */ - /* shuffle not left to avoid conflict w/ literals */ - if (T(CDR(n), N_OP_NOT) && !T(CAR(n), N_OP_NOT)) { - return NODE(n->type, CDR(n), CAR(n)); - } } /* optimize based on situations where the input is partly known (e.g. -- cgit v1.2.3