Commit bb7e6d55 by Alexandre Oliva Committed by Jan Hubicka

re PR debug/47106 (-fcompare-debug failure (length) with -fpartial-inlining…

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
parent f181a8a7
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
......
...@@ -1311,30 +1311,6 @@ create_stack_guard (void) ...@@ -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) ...@@ -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 ();
FOR_EACH_LOCAL_DECL (cfun, ix, var) gcc_checking_assert (gimple_referenced_vars (fn));
{ FOR_EACH_REFERENCED_VAR (fn, var, rvi)
/* TREE_USED marks local variables that do not appear in lexical size += expand_one_var (var, true, false);
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)
{ {
......
...@@ -246,13 +246,14 @@ cgraph_process_new_functions (void) ...@@ -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) ...@@ -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
......
...@@ -2006,9 +2006,6 @@ compute_inline_parameters (struct cgraph_node *node) ...@@ -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;
......
...@@ -729,7 +729,6 @@ init_optimization_passes (void) ...@@ -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) ...@@ -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);
{ {
......
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
......
// { 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 ());
}
...@@ -312,13 +312,17 @@ remap_decl (tree decl, copy_body_data *id) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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. */
......
...@@ -4362,7 +4362,8 @@ convert_callers (struct cgraph_node *node, tree old_decl, ...@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment