mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
f181a8a73f
commit
bb7e6d55da
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
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);
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ());
|
||||||
|
}
|
|
@ -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. */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue