diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-09-11 08:46:23 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-09-11 06:46:23 +0000 |
commit | 412c4af7f17e3211b83bc66a4a1599e5f74eb167 (patch) | |
tree | 2c571d839379bebb75313b494193d5ccf49e6fa5 /gcc | |
parent | cf92ae7f061c922227f76feaeb443c01fbe5c195 (diff) | |
download | gcc-412c4af7f17e3211b83bc66a4a1599e5f74eb167.zip gcc-412c4af7f17e3211b83bc66a4a1599e5f74eb167.tar.gz gcc-412c4af7f17e3211b83bc66a4a1599e5f74eb167.tar.bz2 |
re PR middle-end/63186 (Undefined .L* symbols because of fnsplit)
PR tree-optimization/63186
* ipa-split.c (test_nonssa_use): Skip nonforced labels.
(mark_nonssa_use): Likewise.
(verify_non_ssa_vars): Verify all header blocks for label
definitions.
* gcc.dg/pr63186.c: New testcase.
From-SVN: r215149
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/ipa-split.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr63186.c | 30 |
4 files changed, 77 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a6b5258..2427048 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-09-10 Jan Hubicka <hubicka@ucw.cz> + + PR tree-optimization/63186 + * ipa-split.c (test_nonssa_use): Skip nonforced labels. + (mark_nonssa_use): Likewise. + (verify_non_ssa_vars): Verify all header blocks for label + definitions. + 2014-09-11 Alexander Ivchenko <alexander.ivchenko@intel.com> Maxim Kuznetsov <maxim.kuznetsov@intel.com> Anna Tikhonova <anna.tikhonova@intel.com> diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 3762d6a..fde4365 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -167,7 +167,11 @@ test_nonssa_use (gimple, tree t, tree, void *data) || (TREE_CODE (t) == VAR_DECL && auto_var_in_fn_p (t, current_function_decl)) || TREE_CODE (t) == RESULT_DECL - || TREE_CODE (t) == LABEL_DECL) + /* Normal labels are part of CFG and will be handled gratefuly. + Forced labels however can be used directly by statements and + need to stay in one partition along with their uses. */ + || (TREE_CODE (t) == LABEL_DECL + && FORCED_LABEL (t))) return bitmap_bit_p ((bitmap)data, DECL_UID (t)); /* For DECL_BY_REFERENCE, the return value is actually a pointer. We want @@ -213,6 +217,7 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars, edge e; edge_iterator ei; bool ok = true; + basic_block bb; FOR_EACH_EDGE (e, ei, current->entry_bb->preds) if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) @@ -225,8 +230,8 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars, while (!worklist.is_empty ()) { gimple_stmt_iterator bsi; - basic_block bb = worklist.pop (); + bb = worklist.pop (); FOR_EACH_EDGE (e, ei, bb->preds) if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) && bitmap_set_bit (seen, e->src->index)) @@ -250,10 +255,10 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars, if (gimple_code (stmt) == GIMPLE_LABEL && test_nonssa_use (stmt, gimple_label_label (stmt), NULL_TREE, non_ssa_vars)) - { - ok = false; - goto done; - } + { + ok = false; + goto done; + } } for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) { @@ -286,6 +291,27 @@ verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars, } } } + + /* Verify that the rest of function does not define any label + used by the split part. */ + FOR_EACH_BB_FN (bb, cfun) + if (!bitmap_bit_p (current->split_bbs, bb->index) + && !bitmap_bit_p (seen, bb->index)) + { + gimple_stmt_iterator bsi; + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + if (gimple_code (gsi_stmt (bsi)) == GIMPLE_LABEL + && test_nonssa_use (gsi_stmt (bsi), + gimple_label_label (gsi_stmt (bsi)), + NULL_TREE, non_ssa_vars)) + { + ok = false; + goto done; + } + else if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL) + break; + } + done: BITMAP_FREE (seen); worklist.release (); @@ -735,7 +761,8 @@ mark_nonssa_use (gimple, tree t, tree, void *data) if ((TREE_CODE (t) == VAR_DECL && auto_var_in_fn_p (t, current_function_decl)) || TREE_CODE (t) == RESULT_DECL - || TREE_CODE (t) == LABEL_DECL) + || (TREE_CODE (t) == LABEL_DECL + && FORCED_LABEL (t))) bitmap_set_bit ((bitmap)data, DECL_UID (t)); /* For DECL_BY_REFERENCE, the return value is actually a pointer. We want diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 197297a7..1432e77 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-09-10 Jan Hubicka <hubicka@ucw.cz> + + PR tree-optimization/63186 + * gcc.dg/pr63186.c: New testcase. + 2014-09-10 Xinliang David Li <davidxl@google.com> PR target/63209 diff --git a/gcc/testsuite/gcc.dg/pr63186.c b/gcc/testsuite/gcc.dg/pr63186.c new file mode 100644 index 0000000..b364875 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63186.c @@ -0,0 +1,30 @@ +/* { dg-do link } */ +/* { dg-options "-O2" } */ +void *a; +int b, c, d; + +void +bar () +{ + switch (c) + { + case 0: + lab: + __asm__ (""); + return; + default: + break; + } + b = 0; + d = 0; + a = &&lab; +} + +void +foo () +{ + bar (); +} +main() +{ +} |