re PR debug/47106 (-fcompare-debug failure (length) with -fpartial-inlining -flto -fconserve-stack)

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.
	* g++.dg/debug/pr47106.C: New.

Co-Authored-By: Jan Hubicka <jh@suse.cz>

From-SVN: r170249
This commit is contained in:
Alexandre Oliva 2011-02-17 16:18:24 +00:00 committed by Jan Hubicka
parent f181a8a73f
commit bb7e6d55da
9 changed files with 109 additions and 68 deletions

View File

@ -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> 2011-02-17 Joseph Myers <joseph@codesourcery.com>
* config/sparc/sparc.h (CPP_ENDIAN_SPEC): Don't handle * config/sparc/sparc.h (CPP_ENDIAN_SPEC): Don't handle

View File

@ -1311,30 +1311,6 @@ create_stack_guard (void)
crtl->stack_protect_guard = guard; 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. */ /* Prepare for expanding variables. */
static void static void
init_vars_expansion (void) init_vars_expansion (void)
@ -1379,23 +1355,17 @@ estimated_stack_frame_size (struct cgraph_node *node)
{ {
HOST_WIDE_INT size = 0; HOST_WIDE_INT size = 0;
size_t i; size_t i;
tree var, outer_block = DECL_INITIAL (current_function_decl); tree var;
unsigned ix;
tree old_cur_fun_decl = current_function_decl; 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; current_function_decl = node->decl;
push_cfun (DECL_STRUCT_FUNCTION (node->decl)); push_cfun (fn);
init_vars_expansion (); gcc_checking_assert (gimple_referenced_vars (fn));
FOR_EACH_REFERENCED_VAR (fn, var, rvi)
FOR_EACH_LOCAL_DECL (cfun, ix, var) size += expand_one_var (var, true, false);
{
/* 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) if (stack_vars_num > 0)
{ {

View File

@ -246,13 +246,14 @@ cgraph_process_new_functions (void)
cgraph_analyze_function (node); cgraph_analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl)); push_cfun (DECL_STRUCT_FUNCTION (fndecl));
current_function_decl = fndecl; current_function_decl = fndecl;
compute_inline_parameters (node);
if ((cgraph_state == CGRAPH_STATE_IPA_SSA if ((cgraph_state == CGRAPH_STATE_IPA_SSA
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl))) && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
/* When not optimizing, be sure we run early local passes anyway /* When not optimizing, be sure we run early local passes anyway
to expand OMP. */ to expand OMP. */
|| !optimize) || !optimize)
execute_pass_list (pass_early_local_passes.pass.sub); execute_pass_list (pass_early_local_passes.pass.sub);
else
compute_inline_parameters (node);
free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_DOMINATORS);
pop_cfun (); pop_cfun ();
@ -783,6 +784,11 @@ cgraph_analyze_function (struct cgraph_node *node)
assign_assembler_name_if_neeeded (node->decl); 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 /* Make sure to gimplify bodies only once. During analyzing a
function we lower it, which will require gimplified nested function we lower it, which will require gimplified nested
functions, so we can end up here with an already gimplified functions, so we can end up here with an already gimplified

View File

@ -2006,9 +2006,6 @@ compute_inline_parameters (struct cgraph_node *node)
break; break;
node->local.can_change_signature = !e; 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); estimate_function_body_sizes (node);
/* Inlining characteristics are maintained by the cgraph_mark_inline. */ /* Inlining characteristics are maintained by the cgraph_mark_inline. */
node->global.time = inline_summary (node)->self_time; node->global.time = inline_summary (node)->self_time;

View File

@ -729,7 +729,6 @@ init_optimization_passes (void)
NEXT_PASS (pass_build_cfg); NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_warn_function_return); NEXT_PASS (pass_warn_function_return);
NEXT_PASS (pass_build_cgraph_edges); NEXT_PASS (pass_build_cgraph_edges);
NEXT_PASS (pass_inline_parameters);
*p = NULL; *p = NULL;
/* Interprocedural optimization passes. */ /* Interprocedural optimization passes. */
@ -747,12 +746,8 @@ init_optimization_passes (void)
NEXT_PASS (pass_build_ssa); NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_lower_vector); NEXT_PASS (pass_lower_vector);
NEXT_PASS (pass_early_warn_uninitialized); 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_rebuild_cgraph_edges);
NEXT_PASS (pass_inline_parameters);
NEXT_PASS (pass_early_inline); NEXT_PASS (pass_early_inline);
NEXT_PASS (pass_all_early_optimizations); NEXT_PASS (pass_all_early_optimizations);
{ {

View File

@ -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> 2011-02-17 Uros Bizjak <ubizjak@gmail.com>
PR target/43653 PR target/43653

View File

@ -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 ());
}

View File

@ -312,13 +312,17 @@ remap_decl (tree decl, copy_body_data *id)
walk_tree (&DECL_QUALIFIER (t), copy_tree_body_r, id, NULL); walk_tree (&DECL_QUALIFIER (t), copy_tree_body_r, id, NULL);
} }
if (cfun && gimple_in_ssa_p (cfun) if ((TREE_CODE (t) == VAR_DECL
&& (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == RESULT_DECL
|| TREE_CODE (t) == RESULT_DECL || TREE_CODE (t) == PARM_DECL)) || TREE_CODE (t) == PARM_DECL)
{ && id->src_fn && DECL_STRUCT_FUNCTION (id->src_fn)
get_var_ann (t); && gimple_referenced_vars (DECL_STRUCT_FUNCTION (id->src_fn))
add_referenced_var (t); /* 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; return t;
} }
@ -2547,10 +2551,7 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
/* We're actually using the newly-created var. */ /* We're actually using the newly-created var. */
if (gimple_in_ssa_p (cfun) && TREE_CODE (var) == VAR_DECL) if (gimple_in_ssa_p (cfun) && TREE_CODE (var) == VAR_DECL)
{ add_referenced_var (var);
get_var_ann (var);
add_referenced_var (var);
}
/* Declare this new variable. */ /* Declare this new variable. */
DECL_CHAIN (var) = *vars; DECL_CHAIN (var) = *vars;
@ -2857,10 +2858,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
var = copy_result_decl_to_var (result, id); var = copy_result_decl_to_var (result, id);
if (gimple_in_ssa_p (cfun)) if (gimple_in_ssa_p (cfun))
{ add_referenced_var (var);
get_var_ann (var);
add_referenced_var (var);
}
DECL_SEEN_IN_BIND_EXPR_P (var) = 1; DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
@ -2896,10 +2894,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
{ {
tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr"); tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr");
if (gimple_in_ssa_p (id->src_cfun)) if (gimple_in_ssa_p (id->src_cfun))
{ add_referenced_var (temp);
get_var_ann (temp);
add_referenced_var (temp);
}
insert_decl_map (id, result, temp); insert_decl_map (id, result, temp);
/* When RESULT_DECL is in SSA form, we need to use it's default_def /* When RESULT_DECL is in SSA form, we need to use it's default_def
SSA_NAME. */ SSA_NAME. */
@ -4753,6 +4748,14 @@ copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy)
new function. */ new function. */
DECL_CONTEXT (copy) = id->dst_fn; 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; return copy;
} }
@ -4864,7 +4867,6 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
as temporary variable later in function, the uses will be as temporary variable later in function, the uses will be
replaced by local variable. */ replaced by local variable. */
tree var = copy_decl_to_var (arg, id); tree var = copy_decl_to_var (arg, id);
get_var_ann (var);
add_referenced_var (var); add_referenced_var (var);
insert_decl_map (id, arg, var); insert_decl_map (id, arg, var);
/* Declare this new variable. */ /* Declare this new variable. */

View File

@ -4362,7 +4362,8 @@ convert_callers (struct cgraph_node *node, tree old_decl,
} }
for (cs = node->callers; cs; cs = cs->next_caller) for (cs = node->callers; cs; cs = cs->next_caller)
if (bitmap_set_bit (recomputed_callers, cs->caller->uid)) if (bitmap_set_bit (recomputed_callers, cs->caller->uid)
&& gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl)))
compute_inline_parameters (cs->caller); compute_inline_parameters (cs->caller);
BITMAP_FREE (recomputed_callers); BITMAP_FREE (recomputed_callers);