diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2011-02-17 16:18:24 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2011-02-17 16:18:24 +0000 |
commit | bb7e6d55dac07daafb45645002be2798f78c87b2 (patch) | |
tree | a5366c0ffa8ef61e2d0da52de00aa6d5a7cf2871 | |
parent | f181a8a73f8b1e0a36659eddcdd94f89ce897561 (diff) | |
download | gcc-bb7e6d55dac07daafb45645002be2798f78c87b2.zip gcc-bb7e6d55dac07daafb45645002be2798f78c87b2.tar.gz gcc-bb7e6d55dac07daafb45645002be2798f78c87b2.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 26 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 44 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 8 | ||||
-rw-r--r-- | gcc/ipa-inline.c | 3 | ||||
-rw-r--r-- | gcc/passes.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/debug/pr47106.C | 37 | ||||
-rw-r--r-- | gcc/tree-inline.c | 42 | ||||
-rw-r--r-- | gcc/tree-sra.c | 3 |
9 files changed, 109 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3762df3..9b6168c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 4772fea..897d0f9f 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1311,30 +1311,6 @@ create_stack_guard (void) 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) @@ -1379,23 +1355,17 @@ estimated_stack_frame_size (struct cgraph_node *node) { HOST_WIDE_INT size = 0; size_t i; - tree var, outer_block = DECL_INITIAL (current_function_decl); - unsigned ix; + 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 (DECL_STRUCT_FUNCTION (node->decl)); - - init_vars_expansion (); + push_cfun (fn); - 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); + 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) { diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 7a10ef4..049d1b9 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -246,13 +246,14 @@ cgraph_process_new_functions (void) 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); + else + compute_inline_parameters (node); free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_DOMINATORS); pop_cfun (); @@ -783,6 +784,11 @@ cgraph_analyze_function (struct cgraph_node *node) 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 diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 97e4807..176f994 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2006,9 +2006,6 @@ compute_inline_parameters (struct cgraph_node *node) 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; diff --git a/gcc/passes.c b/gcc/passes.c index bf1bd4b..a33a6af 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -729,7 +729,6 @@ init_optimization_passes (void) 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. */ @@ -747,12 +746,8 @@ init_optimization_passes (void) 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_inline_parameters); NEXT_PASS (pass_early_inline); NEXT_PASS (pass_all_early_optimizations); { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ba0a728..ad376c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/debug/pr47106.C b/gcc/testsuite/g++.dg/debug/pr47106.C new file mode 100644 index 0000000..079f424 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/pr47106.C @@ -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 ()); +} diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 8cfdb28..de30cfd 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -312,13 +312,17 @@ remap_decl (tree decl, copy_body_data *id) 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); - } + 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; } @@ -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. */ if (gimple_in_ssa_p (cfun) && TREE_CODE (var) == VAR_DECL) - { - get_var_ann (var); - add_referenced_var (var); - } + add_referenced_var (var); /* Declare this new variable. */ 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); if (gimple_in_ssa_p (cfun)) - { - get_var_ann (var); - add_referenced_var (var); - } + add_referenced_var (var); 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"); if (gimple_in_ssa_p (id->src_cfun)) - { - get_var_ann (temp); - add_referenced_var (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. */ @@ -4753,6 +4748,14 @@ copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy) 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; } @@ -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 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. */ diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 8ed8771..f28719f 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -4362,7 +4362,8 @@ convert_callers (struct cgraph_node *node, tree old_decl, } 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); BITMAP_FREE (recomputed_callers); |