summaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
authorWormHeamer2025-08-07 22:19:31 -0400
committerWormHeamer2025-08-07 22:19:31 -0400
commit027b6d8f62281f5b513a2b7bfcc02ea833c2cfd2 (patch)
treef989eac0b424d379dc542635b10837217ec3aa76 /ir.c
parent9c8861a1ad58954f40d599c83405c720e0d2e07b (diff)
i thiiiink if statement peepholes work now?
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/ir.c b/ir.c
index d527bfe..a9fcd44 100644
--- a/ir.c
+++ b/ir.c
@@ -171,6 +171,10 @@ void node_del_in(Node *n, Node *p) {
}
void node_kill(Node *n, Proc *p) {
+ if (p->ctrl == n) {
+ /* probably this is fine */
+ p->ctrl = CTRL(n);
+ }
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);
@@ -462,6 +466,7 @@ static inline int node_known_not_equiv(Node *a, Node *b) {
static int node_equiv_input(Node *a, Node *b) {
if (a->in.len != b->in.len) return 0;
+ if (CTRL(a) != CTRL(b)) return 0;
/* note that this means the order of inputs isn't guaranteed, so be
* careful what you use this procedure for */
if ((node_op_communative(a->type) || node_op_communative(b->type))
@@ -470,7 +475,7 @@ static int node_equiv_input(Node *a, Node *b) {
/* assuming input count is 2 */
return 1;
}
- for (int i = 0; i < a->in.len; i++) {
+ for (int i = 1; i < a->in.len; i++) {
if (!node_equiv(IN(a, i), IN(b, i))) return 0;
}
return 1;
@@ -548,6 +553,12 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) {
if (T(CDR(n), N_OP_NOT) && !T(CAR(n), N_OP_NOT)) {
return NODE(n->type, CDR(n), CAR(n));
}
+
+ if (T(CAR(n), N_PHI) && T(CDR(n), N_PHI) && CTRL(CAR(n)) == CTRL(CDR(n))
+ && ((node_equiv(CAAR(n), CDAR(n)) && node_equiv(CADR(n), CDDR(n)))
+ || (node_equiv(CADR(n), CDAR(n)) && node_equiv(CAAR(n), CDDR(n))))) {
+ return OP(CAAR(n), CDAR(n));
+ }
}
if (node_op_associative(n->type)) {
@@ -711,14 +722,18 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n);
}
break;
+ case N_PROJ:
+ if (T(CTRL(n), N_IF_ELSE) && CTRL(n)->val.type.t == T_TUPLE) {
+ if (CTRL(n)->val.tuple.data[(n->val.i + 1) % CTRL(n)->val.tuple.len].type.lvl == T_XCTRL) {
+ return CTRL(CTRL(n));
+ }
+ }
+ break;
+
case N_PHI:
if (same) return CAR(n);
- if (IN(CTRL(n), 1)->val.type.lvl == T_XCTRL) {
- return CAR(n);
- }
- if (IN(CTRL(n), 0)->val.type.lvl == T_XCTRL) {
- return CDR(n);
- }
+ if (IN(CTRL(n), 1)->val.type.lvl == T_XCTRL) return CAR(n);
+ if (IN(CTRL(n), 0)->val.type.lvl == T_XCTRL) return CDR(n);
break;
default: