130 lines
3.5 KiB
Diff
130 lines
3.5 KiB
Diff
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.
|
|
|
|
* gcc.dg/pr63186.c: New testcase.
|
|
|
|
--- gcc/ipa-split.c (revision 215148)
|
|
+++ gcc/ipa-split.c (revision 215149)
|
|
@@ -167,7 +167,11 @@ test_nonssa_use (gimple, tree t, tree, v
|
|
|| (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
|
|
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
|
|
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
|
|
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
|
|
}
|
|
}
|
|
}
|
|
+
|
|
+ /* 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, v
|
|
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
|
|
--- gcc/testsuite/gcc.dg/pr63186.c (revision 0)
|
|
+++ gcc/testsuite/gcc.dg/pr63186.c (revision 215149)
|
|
@@ -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()
|
|
+{
|
|
+}
|