summaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/ir.c b/ir.c
index 4f360b5..c296e9a 100644
--- a/ir.c
+++ b/ir.c
@@ -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));
}
}