diff options
author | Martin Jambor <mjambor@suse.cz> | 2021-11-04 18:01:20 +0100 |
---|---|---|
committer | Martin Jambor <mjambor@suse.cz> | 2021-11-04 18:08:29 +0100 |
commit | 1ece90ffa9ce63b416296bd662b8117d9b538913 (patch) | |
tree | 90f287c0c0ffa6d8397a3f151d8cdee39f05e05d /gcc/tree-inline.c | |
parent | 7237c5b698b57dead425a215805a88b52d7823b0 (diff) | |
download | gcc-1ece90ffa9ce63b416296bd662b8117d9b538913.zip gcc-1ece90ffa9ce63b416296bd662b8117d9b538913.tar.gz gcc-1ece90ffa9ce63b416296bd662b8117d9b538913.tar.bz2 |
ipa-sra: Improve debug info for removed parameters (PR 93385)
In spring I added code eliminating any statements using parameters
removed by IPA passes (to fix PR 93385). That patch fixed issues such
as divisions by zero that such code could perform but it only reset
all affected debug bind statements, this one updates them with
expressions which can allow the debugger to print the removed value -
see the added test-case for an example.
Even though I originally did not want to create DEBUG_EXPR_DECLs for
intermediate values, I ended up doing so, because otherwise the code
started creating statements like
# DEBUG __aD.198693 => &MEM[(const struct _Alloc_nodeD.171110 *)D#195]._M_tD.184726->_M_implD.171154
which not only is a bit scary but also gimple-fold ICEs on
it. Therefore I decided they are probably quite necessary.
The patch simply notes each removed SSA name present in a debug
statement and then works from it backwards, looking if it can
reconstruct the expression it represents (which can fail if a
non-degenerate PHI node is in the way). If it can, it populates two
hash maps with those expressions so that 1) removed assignments are
replaced with a debug bind defining a new intermediate debug_decl_expr
and 2) existing debug binds that refer to SSA names that are bing
removed now refer to corresponding debug_decl_exprs.
If a removed parameter is passed to another function, the debugging
information still cannot describe its value there - see the xfailed
test in the testcase. I sort of know what needs to be done but that
needs a little bit more of IPA infrastructure on top of this patch and
so I would like to get this patch reviewed first.
Bootstrapped and tested on x86_64-linux, i686-linux and (long time
ago) on aarch64-linux. Also LTO-bootstrapped and on x86_64-linux.
Perhaps it is good to go to trunk?
Thanks,
Martin
gcc/ChangeLog:
2021-03-29 Martin Jambor <mjambor@suse.cz>
PR ipa/93385
* ipa-param-manipulation.h (class ipa_param_body_adjustments): New
members remap_with_debug_expressions, m_dead_ssa_debug_equiv,
m_dead_stmt_debug_equiv and prepare_debug_expressions. Added
parameter to mark_dead_statements.
* ipa-param-manipulation.c: Include tree-phinodes.h and cfgexpand.h.
(ipa_param_body_adjustments::mark_dead_statements): New parameter
debugstack, push into it all SSA names used in debug statements,
produce m_dead_ssa_debug_equiv mapping for the removed param.
(replace_with_mapped_expr): New function.
(ipa_param_body_adjustments::remap_with_debug_expressions): Likewise.
(ipa_param_body_adjustments::prepare_debug_expressions): Likewise.
(ipa_param_body_adjustments::common_initialization): Gather and
procecc SSA which will be removed but are in debug statements. Simplify.
(ipa_param_body_adjustments::ipa_param_body_adjustments): Initialize
new members.
* tree-inline.c (remap_gimple_stmt): Create a debug bind when possible
when avoiding a copy of an unnecessary statement. Remap removed SSA
names in existing debug statements.
(tree_function_versioning): Do not create DEBUG_EXPR_DECL for removed
parameters if we have already done so.
gcc/testsuite/ChangeLog:
2021-03-29 Martin Jambor <mjambor@suse.cz>
PR ipa/93385
* gcc.dg/guality/ipa-sra-1.c: New test.
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index b2c58ac..d78e439 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1529,7 +1529,21 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id) if (!is_gimple_debug (stmt) && id->param_body_adjs && id->param_body_adjs->m_dead_stmts.contains (stmt)) - return NULL; + { + tree *dval = id->param_body_adjs->m_dead_stmt_debug_equiv.get (stmt); + if (!dval) + return NULL; + + gcc_assert (is_gimple_assign (stmt)); + tree lhs = gimple_assign_lhs (stmt); + tree *dvar = id->param_body_adjs->m_dead_ssa_debug_equiv.get (lhs); + gdebug *bind = gimple_build_debug_bind (*dvar, *dval, stmt); + if (id->reset_location) + gimple_set_location (bind, input_location); + id->debug_stmts.safe_push (bind); + gimple_seq_add_stmt (&stmts, bind); + return stmts; + } /* Begin by recognizing trees that we'll completely rewrite for the inlining context. Our output for these trees is completely @@ -1807,15 +1821,13 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id) if (gimple_debug_bind_p (stmt)) { - tree value; + tree var = gimple_debug_bind_get_var (stmt); + tree value = gimple_debug_bind_get_value (stmt); if (id->param_body_adjs && id->param_body_adjs->m_dead_stmts.contains (stmt)) - value = NULL_TREE; - else - value = gimple_debug_bind_get_value (stmt); - gdebug *copy - = gimple_build_debug_bind (gimple_debug_bind_get_var (stmt), - value, stmt); + id->param_body_adjs->remap_with_debug_expressions (&value); + + gdebug *copy = gimple_build_debug_bind (var, value, stmt); if (id->reset_location) gimple_set_location (copy, input_location); id->debug_stmts.safe_push (copy); @@ -6452,7 +6464,6 @@ tree_function_versioning (tree old_decl, tree new_decl, in the debug info that var (whole DECL_ORIGIN is the parm PARM_DECL) is optimized away, but could be looked up at the call site as value of D#X there. */ - tree vexpr; gimple_stmt_iterator cgsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun))); gimple *def_temp; @@ -6460,17 +6471,25 @@ tree_function_versioning (tree old_decl, tree new_decl, i = vec_safe_length (*debug_args); do { + tree vexpr = NULL_TREE; i -= 2; while (var != NULL_TREE && DECL_ABSTRACT_ORIGIN (var) != (**debug_args)[i]) var = TREE_CHAIN (var); if (var == NULL_TREE) break; - vexpr = make_node (DEBUG_EXPR_DECL); tree parm = (**debug_args)[i]; - DECL_ARTIFICIAL (vexpr) = 1; - TREE_TYPE (vexpr) = TREE_TYPE (parm); - SET_DECL_MODE (vexpr, DECL_MODE (parm)); + if (tree parm_ddef = ssa_default_def (id.src_cfun, parm)) + if (tree *d + = param_body_adjs->m_dead_ssa_debug_equiv.get (parm_ddef)) + vexpr = *d; + if (!vexpr) + { + vexpr = make_node (DEBUG_EXPR_DECL); + DECL_ARTIFICIAL (vexpr) = 1; + TREE_TYPE (vexpr) = TREE_TYPE (parm); + SET_DECL_MODE (vexpr, DECL_MODE (parm)); + } def_temp = gimple_build_debug_bind (var, vexpr, NULL); gsi_insert_before (&cgsi, def_temp, GSI_NEW_STMT); def_temp = gimple_build_debug_source_bind (vexpr, parm, NULL); |