This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PR debug/47106] account used vars only once
Hi,
this is variant of patch I comitted after re-testing.
The change relative to previous version I sent is new tree-sra hunk avoiding
call of compute_inline_parameters on functions that are not in SSA yet and
cgraph_process_new_functions calling it in functions that arrive in SSA form
and thus are not early optimized.
Honza
Index: ChangeLog
===================================================================
*** ChangeLog (revision 170248)
--- ChangeLog (working copy)
***************
*** 1,3 ****
--- 1,29 ----
+ 2011-02-17 Alexandre Oliva <aoliva@redhat.com>
+ Jan Hubicka <jh@suse.cz>
+
+ PR debug/47106
+ PR debug/47402
+ * cfgexpand.c (account_used_vars_for_block): Remove.
+ (estimated_stack_frame_size): Use referenced vars.
+ * tree-inline.c (remap_decl): Only mark VAR_DECLs as referenced
+ that were referenced in the original function. Test src_fn
+ rather than cfun. Drop redundant get_var_ann.
+ (setup_one_parameter): Drop redundant get_var_ann.
+ (declare_return_variable): Likewise.
+ (copy_decl_for_dup_finish): Mark VAR_DECLs referenced in src_fn.
+ (copy_arguments_for_versioning): Drop redundant get_var_ann.
+ * ipa-inline.c (compute_inline_parameters): Do not compute
+ disregard_inline_limits here.
+ are not available.
+ (compute_inlinable_for_current, pass_inlinable): New.
+ (pass_inline_parameters): Require PROP_referenced_vars.
+ * cgraphunit.c (cgraph_process_new_functions): Don't run
+ compute_inline_parameters explicitly unless function is in
+ SSA form.
+ (cgraph_analyze_function): Set .disregard_inline_limits.
+ * tree-sra.c (convert_callers): Compute inliner parameters
+ only for functions already in SSA form.
+
2011-02-17 Joseph Myers <joseph@codesourcery.com>
* config/sparc/sparc.h (CPP_ENDIAN_SPEC): Don't handle
Index: cgraphunit.c
===================================================================
*** cgraphunit.c (revision 170240)
--- cgraphunit.c (working copy)
*************** cgraph_process_new_functions (void)
*** 246,258 ****
cgraph_analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
current_function_decl = fndecl;
- compute_inline_parameters (node);
if ((cgraph_state == CGRAPH_STATE_IPA_SSA
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
/* When not optimizing, be sure we run early local passes anyway
to expand OMP. */
|| !optimize)
execute_pass_list (pass_early_local_passes.pass.sub);
free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS);
pop_cfun ();
--- 246,259 ----
cgraph_analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
current_function_decl = fndecl;
if ((cgraph_state == CGRAPH_STATE_IPA_SSA
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
/* When not optimizing, be sure we run early local passes anyway
to expand OMP. */
|| !optimize)
execute_pass_list (pass_early_local_passes.pass.sub);
+ else
+ compute_inline_parameters (node);
free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS);
pop_cfun ();
*************** cgraph_analyze_function (struct cgraph_n
*** 783,788 ****
--- 784,794 ----
assign_assembler_name_if_neeeded (node->decl);
+ /* disregard_inline_limits affects topological order of the early optimization,
+ so we need to compute it ahead of rest of inline parameters. */
+ node->local.disregard_inline_limits
+ = DECL_DISREGARD_INLINE_LIMITS (node->decl);
+
/* Make sure to gimplify bodies only once. During analyzing a
function we lower it, which will require gimplified nested
functions, so we can end up here with an already gimplified
Index: testsuite/ChangeLog
===================================================================
*** testsuite/ChangeLog (revision 170248)
--- testsuite/ChangeLog (working copy)
***************
*** 1,3 ****
--- 1,10 ----
+ 2011-02-17 Alexandre Oliva <aoliva@redhat.com>
+ Jan Hubicka <jh@suse.cz>
+
+ PR debug/47106
+ PR debug/47402
+ * g++.dg/debug/pr47106.C: New.
+
2011-02-17 Uros Bizjak <ubizjak@gmail.com>
PR target/43653
Index: testsuite/g++.dg/debug/pr47106.C
===================================================================
*** testsuite/g++.dg/debug/pr47106.C (revision 0)
--- testsuite/g++.dg/debug/pr47106.C (revision 0)
***************
*** 0 ****
--- 1,37 ----
+ // { dg-do compile }
+ // { dg-options "-O -fpartial-inlining -flto -fconserve-stack -fcompare-debug" }
+
+ void end (int, int) __attribute__ ((__noreturn__));
+
+ struct S
+ {
+ int i;
+ S *s;
+ };
+
+ inline bool f (S *s)
+ {
+ if (!s->s)
+ end (0, 0);
+ return s->s == s;
+ }
+
+ inline bool
+ baz (S s1, S)
+ {
+ while (f (&s1));
+ }
+
+ inline bool
+ bar (S s1, S s2, S)
+ {
+ baz (s1, s2);
+ }
+
+ S getS ();
+
+ bool
+ foo ()
+ {
+ bar (getS (), getS (), getS ());
+ }
Index: ipa-inline.c
===================================================================
*** ipa-inline.c (revision 170240)
--- ipa-inline.c (working copy)
*************** compute_inline_parameters (struct cgraph
*** 2006,2014 ****
break;
node->local.can_change_signature = !e;
}
- if (node->local.inlinable && !node->local.disregard_inline_limits)
- node->local.disregard_inline_limits
- = DECL_DISREGARD_INLINE_LIMITS (node->decl);
estimate_function_body_sizes (node);
/* Inlining characteristics are maintained by the cgraph_mark_inline. */
node->global.time = inline_summary (node)->self_time;
--- 2006,2011 ----
Index: cfgexpand.c
===================================================================
*** cfgexpand.c (revision 170240)
--- cfgexpand.c (working copy)
*************** create_stack_guard (void)
*** 1311,1340 ****
crtl->stack_protect_guard = guard;
}
- /* A subroutine of expand_used_vars. Walk down through the BLOCK tree
- expanding variables. Those variables that can be put into registers
- are allocated pseudos; those that can't are put on the stack.
-
- TOPLEVEL is true if this is the outermost BLOCK. */
-
- static HOST_WIDE_INT
- account_used_vars_for_block (tree block, bool toplevel)
- {
- tree t;
- HOST_WIDE_INT size = 0;
-
- /* Expand all variables at this level. */
- for (t = BLOCK_VARS (block); t ; t = DECL_CHAIN (t))
- if (var_ann (t) && is_used_p (t))
- size += expand_one_var (t, toplevel, false);
-
- /* Expand all variables at containing levels. */
- for (t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t))
- size += account_used_vars_for_block (t, false);
-
- return size;
- }
-
/* Prepare for expanding variables. */
static void
init_vars_expansion (void)
--- 1311,1316 ----
*************** estimated_stack_frame_size (struct cgrap
*** 1379,1401 ****
{
HOST_WIDE_INT size = 0;
size_t i;
! tree var, outer_block = DECL_INITIAL (current_function_decl);
! unsigned ix;
tree old_cur_fun_decl = current_function_decl;
current_function_decl = node->decl;
! push_cfun (DECL_STRUCT_FUNCTION (node->decl));
! init_vars_expansion ();
!
! FOR_EACH_LOCAL_DECL (cfun, ix, var)
! {
! /* TREE_USED marks local variables that do not appear in lexical
! blocks. We don't want to expand those that do twice. */
! if (TREE_USED (var))
! size += expand_one_var (var, true, false);
! }
! size += account_used_vars_for_block (outer_block, true);
if (stack_vars_num > 0)
{
--- 1355,1371 ----
{
HOST_WIDE_INT size = 0;
size_t i;
! tree var;
tree old_cur_fun_decl = current_function_decl;
+ referenced_var_iterator rvi;
+ struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
current_function_decl = node->decl;
! push_cfun (fn);
! gcc_checking_assert (gimple_referenced_vars (fn));
! FOR_EACH_REFERENCED_VAR (fn, var, rvi)
! size += expand_one_var (var, true, false);
if (stack_vars_num > 0)
{
Index: tree-sra.c
===================================================================
*** tree-sra.c (revision 170240)
--- tree-sra.c (working copy)
*************** convert_callers (struct cgraph_node *nod
*** 4362,4368 ****
}
for (cs = node->callers; cs; cs = cs->next_caller)
! if (bitmap_set_bit (recomputed_callers, cs->caller->uid))
compute_inline_parameters (cs->caller);
BITMAP_FREE (recomputed_callers);
--- 4362,4369 ----
}
for (cs = node->callers; cs; cs = cs->next_caller)
! if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
! && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
compute_inline_parameters (cs->caller);
BITMAP_FREE (recomputed_callers);
Index: tree-inline.c
===================================================================
*** tree-inline.c (revision 170240)
--- tree-inline.c (working copy)
*************** remap_decl (tree decl, copy_body_data *i
*** 312,324 ****
walk_tree (&DECL_QUALIFIER (t), copy_tree_body_r, id, NULL);
}
! if (cfun && gimple_in_ssa_p (cfun)
! && (TREE_CODE (t) == VAR_DECL
! || TREE_CODE (t) == RESULT_DECL || TREE_CODE (t) == PARM_DECL))
! {
! get_var_ann (t);
! add_referenced_var (t);
! }
return t;
}
--- 312,328 ----
walk_tree (&DECL_QUALIFIER (t), copy_tree_body_r, id, NULL);
}
! if ((TREE_CODE (t) == VAR_DECL
! || TREE_CODE (t) == RESULT_DECL
! || TREE_CODE (t) == PARM_DECL)
! && id->src_fn && DECL_STRUCT_FUNCTION (id->src_fn)
! && gimple_referenced_vars (DECL_STRUCT_FUNCTION (id->src_fn))
! /* We don't want to mark as referenced VAR_DECLs that were
! not marked as such in the src function. */
! && (TREE_CODE (decl) != VAR_DECL
! || referenced_var_lookup (DECL_STRUCT_FUNCTION (id->src_fn),
! DECL_UID (decl))))
! add_referenced_var (t);
return t;
}
*************** setup_one_parameter (copy_body_data *id,
*** 2547,2556 ****
/* We're actually using the newly-created var. */
if (gimple_in_ssa_p (cfun) && TREE_CODE (var) == VAR_DECL)
! {
! get_var_ann (var);
! add_referenced_var (var);
! }
/* Declare this new variable. */
DECL_CHAIN (var) = *vars;
--- 2551,2557 ----
/* We're actually using the newly-created var. */
if (gimple_in_ssa_p (cfun) && TREE_CODE (var) == VAR_DECL)
! add_referenced_var (var);
/* Declare this new variable. */
DECL_CHAIN (var) = *vars;
*************** declare_return_variable (copy_body_data
*** 2857,2866 ****
var = copy_result_decl_to_var (result, id);
if (gimple_in_ssa_p (cfun))
! {
! get_var_ann (var);
! add_referenced_var (var);
! }
DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
--- 2858,2864 ----
var = copy_result_decl_to_var (result, id);
if (gimple_in_ssa_p (cfun))
! add_referenced_var (var);
DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
*************** declare_return_variable (copy_body_data
*** 2896,2905 ****
{
tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr");
if (gimple_in_ssa_p (id->src_cfun))
! {
! get_var_ann (temp);
! add_referenced_var (temp);
! }
insert_decl_map (id, result, temp);
/* When RESULT_DECL is in SSA form, we need to use it's default_def
SSA_NAME. */
--- 2894,2900 ----
{
tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr");
if (gimple_in_ssa_p (id->src_cfun))
! add_referenced_var (temp);
insert_decl_map (id, result, temp);
/* When RESULT_DECL is in SSA form, we need to use it's default_def
SSA_NAME. */
*************** copy_decl_for_dup_finish (copy_body_data
*** 4753,4758 ****
--- 4748,4761 ----
new function. */
DECL_CONTEXT (copy) = id->dst_fn;
+ if (TREE_CODE (decl) == VAR_DECL
+ /* C++ clones functions during parsing, before
+ referenced_vars. */
+ && gimple_referenced_vars (DECL_STRUCT_FUNCTION (id->src_fn))
+ && referenced_var_lookup (DECL_STRUCT_FUNCTION (id->src_fn),
+ DECL_UID (decl)))
+ add_referenced_var (copy);
+
return copy;
}
*************** copy_arguments_for_versioning (tree orig
*** 4864,4870 ****
as temporary variable later in function, the uses will be
replaced by local variable. */
tree var = copy_decl_to_var (arg, id);
- get_var_ann (var);
add_referenced_var (var);
insert_decl_map (id, arg, var);
/* Declare this new variable. */
--- 4867,4872 ----
Index: passes.c
===================================================================
*** passes.c (revision 170240)
--- passes.c (working copy)
*************** init_optimization_passes (void)
*** 729,735 ****
NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_warn_function_return);
NEXT_PASS (pass_build_cgraph_edges);
- NEXT_PASS (pass_inline_parameters);
*p = NULL;
/* Interprocedural optimization passes. */
--- 729,734 ----
*************** init_optimization_passes (void)
*** 747,758 ****
NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_lower_vector);
NEXT_PASS (pass_early_warn_uninitialized);
- /* Note that it is not strictly necessary to schedule an early
- inline pass here. However, some test cases (e.g.,
- g++.dg/other/p334435.C g++.dg/other/i386-1.C) expect extern
- inline functions to be inlined even at -O0. This does not
- happen during the first early inline pass. */
NEXT_PASS (pass_rebuild_cgraph_edges);
NEXT_PASS (pass_early_inline);
NEXT_PASS (pass_all_early_optimizations);
{
--- 746,753 ----
NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_lower_vector);
NEXT_PASS (pass_early_warn_uninitialized);
NEXT_PASS (pass_rebuild_cgraph_edges);
+ NEXT_PASS (pass_inline_parameters);
NEXT_PASS (pass_early_inline);
NEXT_PASS (pass_all_early_optimizations);
{