diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-02-01 18:26:17 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-02-01 18:26:17 +0100 |
commit | dfde35b359c23dd0d1542f9fbb2ddb5bad3272fe (patch) | |
tree | 94ca412c24ccc67dd6fdffbc04a5139e57e8e436 /gcc | |
parent | 516db2dd078c8f9fac7a3dd3ec9ef383570b1dfb (diff) | |
download | gcc-dfde35b359c23dd0d1542f9fbb2ddb5bad3272fe.zip gcc-dfde35b359c23dd0d1542f9fbb2ddb5bad3272fe.tar.gz gcc-dfde35b359c23dd0d1542f9fbb2ddb5bad3272fe.tar.bz2 |
re PR debug/64817 (compilation hangs at -O3 with -g enabled on x86_64-linux-gnu)
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.
From-SVN: r220320
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 87 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr64817-1.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr64817-2.c | 13 |
5 files changed, 141 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dca250c..ce07fba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2015-02-01 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. + 2015-02-01 Oleg Endo <olegendo@gcc.gnu.org> PR target/64851 diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 4d8ba32..12021de 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -3767,6 +3767,48 @@ convert_debug_memory_address (machine_mode mode, rtx x, return x; } +/* Map from SSA_NAMEs to corresponding DEBUG_EXPR_DECLs created + by avoid_deep_ter_for_debug. */ + +static 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3d55251..9e3485d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-02-01 Jakub Jelinek <jakub@redhat.com> + + PR debug/64817 + * gcc.dg/pr64817-1.c: New test. + * gcc.dg/pr64817-2.c: New test. + 2015-02-01 Oleg Endo <olegendo@gcc.gnu.org> PR target/64851 diff --git a/gcc/testsuite/gcc.dg/pr64817-1.c b/gcc/testsuite/gcc.dg/pr64817-1.c new file mode 100644 index 0000000..9d016da --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr64817-1.c @@ -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; + } +} diff --git a/gcc/testsuite/gcc.dg/pr64817-2.c b/gcc/testsuite/gcc.dg/pr64817-2.c new file mode 100644 index 0000000..89532a95 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr64817-2.c @@ -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); +} |