summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--peephole.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/peephole.c b/peephole.c
index d8846f5..b30a052 100644
--- a/peephole.c
+++ b/peephole.c
@@ -196,6 +196,7 @@ static inline int node_sub_add_equiv(Node *a, Node *b) {
static int node_equiv_input(Node *a, Node *b);
+/* TODO: separate out equivalence as in complete identity vs. just same value */
static int node_equiv(Node *a, Node *b) {
/* will doing this recursively be too slow? */
if (a == b) return 1;
@@ -217,6 +218,7 @@ static inline int node_known_not_equiv_ord(Node *a, Node *b) {
return 0;
}
static inline int node_known_not_equiv(Node *a, Node *b) {
+ if (node_cmp_incompat(a->op, b->op) && node_equiv_input(a, b)) return 1;
return node_known_not_equiv_ord(a, b) || node_known_not_equiv_ord(b, a);
}
@@ -486,6 +488,10 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n);
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);
+ if (((T(CAR(n), N_CMP_LTE) && T(CDR(n), N_CMP_GTE)) || (T(CAR(n), N_CMP_GTE) && T(CDR(n), N_CMP_LTE)))
+ && node_equiv_input(CAR(n), CDR(n))) {
+ return NODE(N_CMP_EQL, CAAR(n), CADR(n));
+ }
break;
case N_CMP_NEQ:
if (same) return node_new_lit_bool(p, 0);
@@ -560,6 +566,13 @@ zero_no_effect: if (node_eql_i64(CAR(n), 0)) return CDR(n);
}
} break;
+ case N_OP_SHL:
+ case N_OP_SHR:
+ /* a (<< | >>) 0 -> a */
+ /* 0 (<< | >>) a -> 0 */
+ if (node_eql_i64(CDR(n), 0) || node_eql_i64(CAR(n), 0)) return CAR(n);
+ break;
+
default:
break;
}