diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-06-14 12:20:04 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-06-14 12:20:04 +0200 |
commit | 23e025db703c84f0f22c667faff15d4ac2b86e64 (patch) | |
tree | 7d867f9565cd9257c7d517aca18d5cc8c2137d5a /gcc/tree-ssa-tail-merge.c | |
parent | 585334d41d1a255f612d6470ba9b7bd383cdd5e4 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc/tree-ssa-tail-merge.c')
-rw-r--r-- | gcc/tree-ssa-tail-merge.c | 35 |
1 files changed, 35 insertions, 0 deletions
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); |