aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-09-11 08:46:23 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-09-11 06:46:23 +0000
commit412c4af7f17e3211b83bc66a4a1599e5f74eb167 (patch)
tree2c571d839379bebb75313b494193d5ccf49e6fa5 /gcc
parentcf92ae7f061c922227f76feaeb443c01fbe5c195 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/ipa-split.c41
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr63186.c30
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()
+{
+}