183 lines
7.1 KiB
Diff
183 lines
7.1 KiB
Diff
|
2015-01-30 Jakub Jelinek <jakub@redhat.com>
|
||
|
|
||
|
PR debug/64817
|
||
|
* cfgexpand.c (deep_ter_debug_map): New variable.
|
||
|
(avoid_deep_ter_for_debug): New function.
|
||
|
(expand_debug_expr): If TERed SSA_NAME is in
|
||
|
deep_ter_debug_map, use the corresponding DEBUG_EXPR_DECL
|
||
|
instead of trying to expand SSA_NAME's def stmt.
|
||
|
(expand_debug_locations): When expanding debug bind
|
||
|
of a DEBUG_EXPR_DECL to corresponding SSA_NAME,
|
||
|
temporarily remove the DEBUG_EXPR_DECL from deep_ter_debug_map's
|
||
|
value.
|
||
|
(pass_expand::execute): Call avoid_deep_ter_for_debug on
|
||
|
all debug bind stmts. Delete deep_ter_debug_map after
|
||
|
expand_debug_location if non-NULL and clear it.
|
||
|
|
||
|
* gcc.dg/pr64817-1.c: New test.
|
||
|
* gcc.dg/pr64817-2.c: New test.
|
||
|
|
||
|
--- gcc/cfgexpand.c.jj 2015-01-28 21:24:56.000000000 +0100
|
||
|
+++ gcc/cfgexpand.c 2015-01-30 13:22:46.002579984 +0100
|
||
|
@@ -3767,6 +3767,48 @@ convert_debug_memory_address (machine_mo
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
+/* Map from SSA_NAMEs to corresponding DEBUG_EXPR_DECLs created
|
||
|
+ by avoid_deep_ter_for_debug. */
|
||
|
+
|
||
|
+hash_map<tree, tree> *deep_ter_debug_map;
|
||
|
+
|
||
|
+/* Split too deep TER chains for debug stmts using debug temporaries. */
|
||
|
+
|
||
|
+static void
|
||
|
+avoid_deep_ter_for_debug (gimple stmt, int depth)
|
||
|
+{
|
||
|
+ use_operand_p use_p;
|
||
|
+ ssa_op_iter iter;
|
||
|
+ FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||
|
+ {
|
||
|
+ tree use = USE_FROM_PTR (use_p);
|
||
|
+ if (TREE_CODE (use) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (use))
|
||
|
+ continue;
|
||
|
+ gimple g = get_gimple_for_ssa_name (use);
|
||
|
+ if (g == NULL)
|
||
|
+ continue;
|
||
|
+ if (depth > 6 && !stmt_ends_bb_p (g))
|
||
|
+ {
|
||
|
+ if (deep_ter_debug_map == NULL)
|
||
|
+ deep_ter_debug_map = new hash_map<tree, tree>;
|
||
|
+
|
||
|
+ tree &vexpr = deep_ter_debug_map->get_or_insert (use);
|
||
|
+ if (vexpr != NULL)
|
||
|
+ continue;
|
||
|
+ vexpr = make_node (DEBUG_EXPR_DECL);
|
||
|
+ gimple def_temp = gimple_build_debug_bind (vexpr, use, g);
|
||
|
+ DECL_ARTIFICIAL (vexpr) = 1;
|
||
|
+ TREE_TYPE (vexpr) = TREE_TYPE (use);
|
||
|
+ DECL_MODE (vexpr) = TYPE_MODE (TREE_TYPE (use));
|
||
|
+ gimple_stmt_iterator gsi = gsi_for_stmt (g);
|
||
|
+ gsi_insert_after (&gsi, def_temp, GSI_NEW_STMT);
|
||
|
+ avoid_deep_ter_for_debug (def_temp, 0);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ avoid_deep_ter_for_debug (g, depth + 1);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
/* Return an RTX equivalent to the value of the parameter DECL. */
|
||
|
|
||
|
static rtx
|
||
|
@@ -4654,7 +4696,16 @@ expand_debug_expr (tree exp)
|
||
|
gimple g = get_gimple_for_ssa_name (exp);
|
||
|
if (g)
|
||
|
{
|
||
|
- op0 = expand_debug_expr (gimple_assign_rhs_to_tree (g));
|
||
|
+ tree t = NULL_TREE;
|
||
|
+ if (deep_ter_debug_map)
|
||
|
+ {
|
||
|
+ tree *slot = deep_ter_debug_map->get (exp);
|
||
|
+ if (slot)
|
||
|
+ t = *slot;
|
||
|
+ }
|
||
|
+ if (t == NULL_TREE)
|
||
|
+ t = gimple_assign_rhs_to_tree (g);
|
||
|
+ op0 = expand_debug_expr (t);
|
||
|
if (!op0)
|
||
|
return NULL;
|
||
|
}
|
||
|
@@ -4961,6 +5012,25 @@ expand_debug_locations (void)
|
||
|
if (INSN_VAR_LOCATION_STATUS (insn)
|
||
|
== VAR_INIT_STATUS_UNINITIALIZED)
|
||
|
val = expand_debug_source_expr (value);
|
||
|
+ /* The avoid_deep_ter_for_debug function inserts
|
||
|
+ debug bind stmts after SSA_NAME definition, with the
|
||
|
+ SSA_NAME as the whole bind location. Disable temporarily
|
||
|
+ expansion of that SSA_NAME into the DEBUG_EXPR_DECL
|
||
|
+ being defined in this DEBUG_INSN. */
|
||
|
+ else if (deep_ter_debug_map && TREE_CODE (value) == SSA_NAME)
|
||
|
+ {
|
||
|
+ tree *slot = deep_ter_debug_map->get (value);
|
||
|
+ if (slot)
|
||
|
+ {
|
||
|
+ if (*slot == INSN_VAR_LOCATION_DECL (insn))
|
||
|
+ *slot = NULL_TREE;
|
||
|
+ else
|
||
|
+ slot = NULL;
|
||
|
+ }
|
||
|
+ val = expand_debug_expr (value);
|
||
|
+ if (slot)
|
||
|
+ *slot = INSN_VAR_LOCATION_DECL (insn);
|
||
|
+ }
|
||
|
else
|
||
|
val = expand_debug_expr (value);
|
||
|
gcc_assert (last == get_last_insn ());
|
||
|
@@ -5821,6 +5891,15 @@ pass_expand::execute (function *fun)
|
||
|
timevar_pop (TV_OUT_OF_SSA);
|
||
|
SA.partition_to_pseudo = XCNEWVEC (rtx, SA.map->num_partitions);
|
||
|
|
||
|
+ if (MAY_HAVE_DEBUG_STMTS && flag_tree_ter)
|
||
|
+ {
|
||
|
+ gimple_stmt_iterator gsi;
|
||
|
+ FOR_EACH_BB_FN (bb, cfun)
|
||
|
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
||
|
+ if (gimple_debug_bind_p (gsi_stmt (gsi)))
|
||
|
+ avoid_deep_ter_for_debug (gsi_stmt (gsi), 0);
|
||
|
+ }
|
||
|
+
|
||
|
/* Make sure all values used by the optimization passes have sane
|
||
|
defaults. */
|
||
|
reg_renumber = 0;
|
||
|
@@ -6008,6 +6087,12 @@ pass_expand::execute (function *fun)
|
||
|
if (MAY_HAVE_DEBUG_INSNS)
|
||
|
expand_debug_locations ();
|
||
|
|
||
|
+ if (deep_ter_debug_map)
|
||
|
+ {
|
||
|
+ delete deep_ter_debug_map;
|
||
|
+ deep_ter_debug_map = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
/* Free stuff we no longer need after GIMPLE optimizations. */
|
||
|
free_dominance_info (CDI_DOMINATORS);
|
||
|
free_dominance_info (CDI_POST_DOMINATORS);
|
||
|
--- gcc/testsuite/gcc.dg/pr64817-1.c.jj 2015-01-30 13:33:05.061143850 +0100
|
||
|
+++ gcc/testsuite/gcc.dg/pr64817-1.c 2015-01-30 13:32:33.000000000 +0100
|
||
|
@@ -0,0 +1,20 @@
|
||
|
+/* PR debug/64817 */
|
||
|
+/* { dg-do compile } */
|
||
|
+/* { dg-options "-O3 -g" } */
|
||
|
+
|
||
|
+int a, b, d;
|
||
|
+
|
||
|
+void
|
||
|
+foo (void)
|
||
|
+{
|
||
|
+ for (b = 0; b < 9; b++)
|
||
|
+ {
|
||
|
+ int e;
|
||
|
+ for (d = 0; d < 5; d++)
|
||
|
+ {
|
||
|
+ a &= 231;
|
||
|
+ a ^= 14;
|
||
|
+ }
|
||
|
+ e = (a ^= 1) < 0;
|
||
|
+ }
|
||
|
+}
|
||
|
--- gcc/testsuite/gcc.dg/pr64817-2.c.jj 2015-01-20 10:01:16.345964420 +0100
|
||
|
+++ gcc/testsuite/gcc.dg/pr64817-2.c 2015-01-30 18:37:49.055911292 +0100
|
||
|
@@ -0,0 +1,13 @@
|
||
|
+/* PR debug/64817 */
|
||
|
+/* { dg-do compile } */
|
||
|
+/* { dg-options "-O3 -g" } */
|
||
|
+
|
||
|
+int a;
|
||
|
+
|
||
|
+void
|
||
|
+foo (void)
|
||
|
+{
|
||
|
+ int e;
|
||
|
+ a = ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((a & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) & 231) ^ 14) ^ 1;
|
||
|
+ e = (a < 0);
|
||
|
+}
|