--- /dev/null
+// { dg-do compile }
+// { dg-options "-Os -fdump-tree-optimized" }
+
+struct Potato {
+ int size;
+ bool isMashed;
+};
+
+int dont_be_here();
+
+int patatino(int a) {
+ if (a > 5 && a % 2 == 0 && a != 10) {
+ return a * 2;
+ } else {
+ Potato spud;
+ spud.size = a;
+ spud.isMashed = false;
+
+ for (int i = 0; i < 10; i++) {
+ if (i > 10 && i < 5 && a == -1) {
+ for (int j = 0; j < 5; j++) {
+ spud.size += j;
+ }
+ }
+ }
+
+ for (int k = 0; k < 10 && a == -100 && spud.size > 1000; k++) {
+ for (int l = 0; l < 5; l++) {
+ spud.size += l * k;
+ }
+ }
+
+ for (int m = 0; m < 10 && a == -1000 && spud.size < -1000; m++) {
+ dont_be_here();
+ }
+
+ if (a > 10000 && spud.size < -10000) {
+ spud.size *= 2;
+ }
+
+ for (int n = 0; n < 10 && a == -2000 && spud.size > 2000; n++) {
+ for (int o = 0; o < 5; o++) {
+ spud.size -= o * n;
+ }
+ }
+
+ return spud.size;
+ }
+}
+
+// { dg-final { scan-tree-dump-not "dont_be_here" "optimized" } }
+// { dg-final { scan-tree-dump-times "if " 3 "optimized" } }
tree sameval_base = NULL_TREE;
poly_int64 soff, doff;
unsigned n_executable = 0;
- edge_iterator ei;
- edge e, sameval_e = NULL;
+ edge sameval_e = NULL;
/* TODO: We could check for this in initialization, and replace this
with a gcc_assert. */
if (!inserted)
gimple_set_plf (phi, GF_PLF_1, false);
+ basic_block bb = gimple_bb (phi);
+
+ /* For the equivalence handling below make sure to first process an
+ edge with a non-constant. */
+ auto_vec<edge, 2> preds;
+ preds.reserve_exact (EDGE_COUNT (bb->preds));
+ bool seen_nonconstant = false;
+ for (unsigned i = 0; i < EDGE_COUNT (bb->preds); ++i)
+ {
+ edge e = EDGE_PRED (bb, i);
+ preds.quick_push (e);
+ if (!seen_nonconstant)
+ {
+ tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
+ if (TREE_CODE (def) == SSA_NAME)
+ {
+ seen_nonconstant = true;
+ if (i != 0)
+ std::swap (preds[0], preds[i]);
+ }
+ }
+ }
+
/* See if all non-TOP arguments have the same value. TOP is
equivalent to everything, so we can ignore it. */
- basic_block bb = gimple_bb (phi);
- FOR_EACH_EDGE (e, ei, bb->preds)
+ for (edge e : preds)
if (e->flags & EDGE_EXECUTABLE)
{
tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
}
continue;
}
- /* If on all previous edges the value was equal to def
- we can change sameval to def. */
- if (EDGE_COUNT (bb->preds) == 2
- && (val = vn_nary_op_get_predicated_value
- (vnresult, EDGE_PRED (bb, 0)))
- && integer_truep (val)
- && !(e->flags & EDGE_DFS_BACK))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Predication says ");
- print_generic_expr (dump_file, def, TDF_NONE);
- fprintf (dump_file, " and ");
- print_generic_expr (dump_file, sameval, TDF_NONE);
- fprintf (dump_file, " are equal on edge %d -> %d\n",
- EDGE_PRED (bb, 0)->src->index,
- EDGE_PRED (bb, 0)->dest->index);
- }
- sameval = def;
- continue;
- }
}
}
sameval = NULL_TREE;