diff options
| author | WormHeamer | 2025-08-05 03:07:49 -0400 |
|---|---|---|
| committer | WormHeamer | 2025-08-05 03:07:49 -0400 |
| commit | a91fca16568584a9d18160819a4e56d1c4c1c00a (patch) | |
| tree | 25aeaf5fe989ae9eeff275c9e964381c87417f6d /ir.c | |
| parent | 3fba1bedb530b7115a012035846ff000031d56fc (diff) | |
add a bunch of rules to simplify comparisons
Diffstat (limited to 'ir.c')
| -rw-r--r-- | ir.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -261,6 +261,14 @@ static inline int node_op_associative(NodeType t) { return 0; } +static inline int node_op_comparison(NodeType t) { + NodeType ops[] = { N_CMP_EQL, N_CMP_NEQ, N_CMP_LES, N_CMP_GTR, N_CMP_LTE, N_CMP_GTE }; + for (unsigned i = 0; i < sizeof ops / sizeof *ops; i++) { + if (ops[i] == t) return 1; + } + return 0; +} + /* when applied to the same input, at least one must be true */ static inline NodeType node_cmp_opposite(NodeType a) { struct { NodeType l, r; } pairs[] = { @@ -275,6 +283,16 @@ static inline NodeType node_cmp_opposite(NodeType a) { return N_NONE; } +static inline NodeType node_cmp_flip_sign(NodeType a) { + switch (a) { + case N_CMP_LES: return N_CMP_GTR; + case N_CMP_LTE: return N_CMP_GTE; + case N_CMP_GTR: return N_CMP_LES; + case N_CMP_GTE: return N_CMP_LTE; + default: return a; + } +} + /* when applied to the same input, at least one must be false */ static inline int node_cmp_incompat(NodeType a, NodeType b) { struct { NodeType l, r; } pairs[] = { @@ -661,6 +679,29 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n); break; } + if (node_op_comparison(n->type)) { + if (T(CAR(n), N_OP_SHL) && T(CDR(n), N_OP_ADD) && node_eql_i64(CADR(n), 1)) { + if (node_equiv(CAAR(n), CDAR(n))) return NODE(n->type, CAAR(n), CDDR(n)); + if (node_equiv(CAAR(n), CDDR(n))) return NODE(n->type, CAAR(n), CDAR(n)); + } + if (T(CDR(n), N_OP_SHL) && T(CAR(n), N_OP_ADD) && node_eql_i64(CDDR(n), 1)) { + if (node_equiv(CDAR(n), CAAR(n))) return NODE(n->type, CDAR(n), CADR(n)); + if (node_equiv(CDAR(n), CADR(n))) return NODE(n->type, CDAR(n), CAAR(n)); + } + if (node_op_associative(CAR(n)->type) && T(CAR(n), CDR(n)->type)) { + if (node_equiv(CAAR(n), CDAR(n))) return NODE(n->type, CADR(n), CDDR(n)); + if (node_equiv(CADR(n), CDAR(n))) return NODE(n->type, CAAR(n), CDDR(n)); + if (node_equiv(CAAR(n), CDDR(n))) return NODE(n->type, CADR(n), CDAR(n)); + if (node_equiv(CADR(n), CDDR(n))) return NODE(n->type, CAAR(n), CDAR(n)); + } + if (T(CAR(n), N_OP_SUB) && T(CAR(n), N_OP_SUB) && node_equiv(CAAR(n), CDAR(n))) { + return NODE(node_cmp_flip_sign(n->type), CADR(n), CDDR(n)); + } + if (T(CAR(n), N_OP_NEG) && T(CDR(n), N_OP_NEG)) { + return NODE(node_cmp_flip_sign(n->type), CAAR(n), CDAR(n)); + } + } + return NULL; } |
