aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-06-14 12:20:04 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-06-14 12:20:04 +0200
commit23e025db703c84f0f22c667faff15d4ac2b86e64 (patch)
tree7d867f9565cd9257c7d517aca18d5cc8c2137d5a
parent585334d41d1a255f612d6470ba9b7bd383cdd5e4 (diff)
downloadgcc-23e025db703c84f0f22c667faff15d4ac2b86e64.zip
gcc-23e025db703c84f0f22c667faff15d4ac2b86e64.tar.gz
gcc-23e025db703c84f0f22c667faff15d4ac2b86e64.tar.bz2
re PR tree-optimization/71520 (Missing cross-jumping of switch cases)
PR tree-optimization/71520 * tree-ssa-tail-merge.c (find_duplicate): Handle labels. (replace_block_by): Move user labels from bb1 to bb2. * gcc.dg/tree-ssa/pr71520.c: New test. From-SVN: r237427
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr71520.c90
-rw-r--r--gcc/tree-ssa-tail-merge.c35
4 files changed, 136 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 40e60a3..1a3e5fd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-06-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/71520
+ * tree-ssa-tail-merge.c (find_duplicate): Handle labels.
+ (replace_block_by): Move user labels from bb1 to bb2.
+
2016-06-14 Richard Biener <rguenther@suse.de>
PR middle-end/71310
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8763aad..a616614 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-06-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/71520
+ * gcc.dg/tree-ssa/pr71520.c: New test.
+
2016-06-14 Richard Biener <rguenther@suse.de>
PR tree-optimization/71521
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71520.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71520.c
new file mode 100644
index 0000000..f647a5b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71520.c
@@ -0,0 +1,90 @@
+/* PR tree-optimization/71520 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void bar (int);
+
+void
+foo (int x)
+{
+ switch (x)
+ {
+ case 1:
+ case 12:
+ case 28:
+ case 174:
+ bar (1);
+ bar (2);
+ break;
+ case 3:
+ case 7:
+ case 78:
+ case 96:
+ case 121:
+ default:
+ bar (3);
+ bar (4);
+ bar (5);
+ bar (6);
+ break;
+ case 8:
+ case 13:
+ case 27:
+ case 19:
+ case 118:
+ bar (3);
+ bar (4);
+ bar (5);
+ bar (6);
+ break;
+ case 4:
+ bar (7);
+ break;
+ }
+}
+
+void
+baz (int x)
+{
+ switch (x)
+ {
+ case 1:
+ case 12:
+ case 28:
+ case 174:
+ bar (8);
+ bar (9);
+ break;
+ case 3:
+ case 7:
+ case 78:
+ case 96:
+ case 121:
+ default:
+ lab1:
+ lab2:
+ bar (10);
+ bar (11);
+ bar (12);
+ bar (13);
+ break;
+ case 8:
+ case 13:
+ case 27:
+ case 19:
+ case 118:
+ lab3:
+ lab4:
+ bar (10);
+ bar (11);
+ bar (12);
+ bar (13);
+ break;
+ case 4:
+ bar (14);
+ break;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "bar \\\(3\\\);" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bar \\\(10\\\);" 1 "optimized" } } */
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index 3df41fd..042d964 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -1265,6 +1265,10 @@ find_duplicate (same_succ *same_succ, basic_block bb1, basic_block bb2)
gimple *stmt1 = gsi_stmt (gsi1);
gimple *stmt2 = gsi_stmt (gsi2);
+ if (gimple_code (stmt1) == GIMPLE_LABEL
+ && gimple_code (stmt2) == GIMPLE_LABEL)
+ break;
+
if (!gimple_equal_p (same_succ, stmt1, stmt2))
return;
@@ -1277,6 +1281,20 @@ find_duplicate (same_succ *same_succ, basic_block bb1, basic_block bb2)
gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped);
}
+ while (!gsi_end_p (gsi1) && gimple_code (gsi_stmt (gsi1)) == GIMPLE_LABEL)
+ {
+ tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi1)));
+ if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
+ return;
+ gsi_prev (&gsi1);
+ }
+ while (!gsi_end_p (gsi2) && gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL)
+ {
+ tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)));
+ if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
+ return;
+ gsi_prev (&gsi2);
+ }
if (!(gsi_end_p (gsi1) && gsi_end_p (gsi2)))
return;
@@ -1555,6 +1573,23 @@ replace_block_by (basic_block bb1, basic_block bb2)
e2->probability = GCOV_COMPUTE_SCALE (e2->count, out_sum);
}
+ /* Move over any user labels from bb1 after the bb2 labels. */
+ gimple_stmt_iterator gsi1 = gsi_start_bb (bb1);
+ if (!gsi_end_p (gsi1) && gimple_code (gsi_stmt (gsi1)) == GIMPLE_LABEL)
+ {
+ gimple_stmt_iterator gsi2 = gsi_after_labels (bb2);
+ while (!gsi_end_p (gsi1)
+ && gimple_code (gsi_stmt (gsi1)) == GIMPLE_LABEL)
+ {
+ tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi1)));
+ gcc_assert (!DECL_NONLOCAL (label) && !FORCED_LABEL (label));
+ if (DECL_ARTIFICIAL (label))
+ gsi_next (&gsi1);
+ else
+ gsi_move_before (&gsi1, &gsi2);
+ }
+ }
+
/* Clear range info from all stmts in BB2 -- this transformation
could make them out of date. */
reset_flow_sensitive_info_in_bb (bb2);