diff options
Diffstat (limited to 'ir.c')
| -rw-r--r-- | ir.c | 14 |
1 files changed, 14 insertions, 0 deletions
@@ -384,6 +384,16 @@ static inline int node_equiv(Node *a, Node *b) { return 1; } +/* of necessity, this has to be pretty conservative */ +/* TODO: figure out a more thorough way of comparing node graphs */ +static inline int node_known_not_equiv_ord(Node *a, Node *b) { + if ((T(b, N_OP_ADD) || T(b, N_OP_SUB)) && node_equiv(a, CAR(b)) && !node_eql_i64(CDR(b), 0)) return 1; + return 0; +} +static inline int node_known_not_equiv(Node *a, Node *b) { + return node_known_not_equiv_ord(a, b) || node_known_not_equiv_ord(b, a); +} + static inline int node_equiv_input(Node *a, Node *b) { if (a->in.len != b->in.len) return 0; for (int i = 0; i < a->in.len; i++) { @@ -563,12 +573,16 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n); break; case N_CMP_EQL: if (same) return node_new_lit_bool(p, 1); + if (node_known_not_equiv(CAR(n), CDR(n))) return node_new_lit_bool(p, 0); if (BOOL_EQ(CDR(n), 1)) return CAR(n); if (BOOL_EQ(CDR(n), 0)) return NODE(N_OP_NOT, CAR(n)); if (T(CAR(n), N_OP_NOT) && node_equiv(CDR(n), CAAR(n))) return node_new_lit_bool(p, 0); break; case N_CMP_NEQ: if (same) return node_new_lit_bool(p, 0); + if (node_known_not_equiv(CAR(n), CDR(n))) return node_new_lit_bool(p, 1); + if (BOOL_EQ(CDR(n), 0)) return CAR(n); + if (BOOL_EQ(CDR(n), 1)) return NODE(N_OP_NOT, CAR(n)); break; case N_CMP_LES: if (same) return node_new_lit_bool(p, 0); |
