diff options
| -rw-r--r-- | ir.c | 23 |
1 files changed, 19 insertions, 4 deletions
@@ -23,6 +23,7 @@ extern int no_opt; #define CDDAR(n) CAR(CDDR(n)) #define CDDDR(n) CDR(CDDR(n)) #define T(a,b) ((a)->type == b) +#define T2(a,b,t) ((a)->type == t && (b)->type == t) /* types */ @@ -535,7 +536,7 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) { && C(CAR(n), CDAR(n))) return OP(CDR(n), CAR(n));*/ /* op(op(X,Y), op(Z, lit)) -> op(op(X, op(Y, Z)), lit) */ - if (T(CAR(n), n->type) && T(CDR(n), n->type) && T(CDDR(n), N_LIT) + if (T2(CAR(n), CDR(n), n->type) && T(CDDR(n), N_LIT) && C(CAAR(n), CDAR(n)) && C(CAR(n), CDR(n))) { return OP(OP(CAAR(n), OP(CADR(n), CDAR(n))), CDDR(n)); } @@ -580,6 +581,10 @@ Node *node_idealize(Node *n, Proc *p, Lexer *l) { } 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)); + if (T(CAR(n), N_OP_SUB) && T(CDR(n), N_OP_SUB) + && node_equiv(CAAR(n), CDDR(n)) && node_equiv(CADR(n), CDAR(n))) { + return node_new_lit_i64(p, 0); + } goto zero_no_effect; case N_OP_SUB: if (same) return node_new_lit_i64(p, 0); @@ -680,6 +685,7 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n); } if (node_op_comparison(n->type)) { + /* cmp(2a, a + b) -> cmp(a, b) */ 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)); @@ -688,16 +694,25 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n); 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)); } + /* cmp(a + b, a + c) -> cmp(b, c) */ 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 (T2(CAR(n), CDR(n), N_OP_SUB)) { + /* cmp(a - b, b - a) -> cmp(a, b) */ + if (node_equiv(CAAR(n), CDDR(n)) && node_equiv(CADR(n), CDAR(n))) { + return NODE(n->type, CAAR(n), CDAR(n)); + } + /* cmp(a - b, c - b) -> flipcmp(a, c) */ + if (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)) { + /* cmp(-a, -b) -> flipcmp(a, b) */ + if (T2(CAR(n), CDR(n), N_OP_NEG)) { return NODE(node_cmp_flip_sign(n->type), CAAR(n), CDAR(n)); } } |
