cgraphbuild.c (record_reference): Drop non-unit-at-a-time code.
* cgraphbuild.c (record_reference): Drop non-unit-at-a-time code. (build_cgraph_edges): Likewise. * cgraph.c (cgraph_node): Do not update assembler hash. (cgraph_remove_node): Drop non-unit-at-a-time code. * tree-pass.h (pass_O0_always_inline): Remove. * ipa-reference.c (gate_reference): Remove unit-at-a-time check. * toplev.c (process_options): Flag unit-at-a-time does not imply no section anchors. * cgraphunit.c: Update comments. (decide_is_function_needed): Drop non-unit-at-a-time mode. (cgraph_assemble_pending_functions): Remove. (cgraph_reset_node): Drop non-unit-at-a-time code. (cgraph_finalize_function): Likewise. (cgraph_analyze_function): Likewise. (cgraph_finalize_compilation_unit): Likewise. (cgraph_expand_function): Likewise. (cgraph_optimize): Likesise. (save_inline_function_body): Likewise. * ipa-pure-const.c (gate_pure_const): Drop flag_unit_at_a_time check. * tree-ssa-alias.c (maybe_be_aliased): Likewise. * ipa-inline.c: Update comments. (enum inlining_mode): remove INLINE_SPEED. (cgraph_clone_inlined_nodes): Drop unit-at-a-time check. (cgraph_mark_inline_edge): Likewise. (try_inline): Likewise. (cgraph_decide_inlining_incrementally): Likewise. (cgraph_gate_inlining): Remove. (cgraph_early_inlining): Remove flag_unit_at_a_time checks. (cgraph_gate_early_inlining): Likewise. (gate_inline_passes): Remove. (pass_inline_parameters, pass_ipa_inline): Remove gates. (cgraph_gate_O0_always_inline, cgraph_O0_always_inline, pass_O0_always_inline): Remove. * c-pch.c (c_pch_matching): Remove -funit-at-a-time. * dwarf2out.c (reference_to_unused): Remove flag_unit_at_a_time check. * opts.c (no_unit_at_a_time_default): Remove. (decode_options): Remove flag_unit_at_a_time reset and warning. * opts.h (no_unit_at_a_time_default): Remove. * c-decl.c (diagnose_mismatched_decls): Do not require inline keyword early in GNU dialect. (merge_decls): Update comment; drop unit-at-a-time check. (finish_decl): Likewise. (grok_declaration): Remove flag_inline_trees code. (finish_functions): Return on function returning non-void on all statics. * ipa-tye-escape.c (gate_type_escape_vars): Remove. * cfgexpand.c (expand_one_static_var): Remove. (expand_one_var): Remove expand_one_static_var call. (expand_used_vars_for_block): Remove flag_unit_a_time check. * c-opts.c (c_common_post_options): Remove flag_inline_trees code and flag_unit_at_a-time compatibility checks. * varasm.c (assemble_alias): Remove flag_unit_at_a_time check. * tree-inline.c (flag_inline_trees): Remove. (inlinable_function_p): Don't check it. (expand_call_inline): Remove non-unit-at-a-time code. * tree-inline.h (flag_inline_trees): Remove. * tree-optimize.c (execute_early_local_optimizations): Remove unit-at-a-time checks. (tree_rest_of_compilation): Likewise. * combine.c (setup_incoming_promotions): Likewise. * tree-profile.c (tree_gen_ic_func_profiler): Likewise. * tree-ssa-structalias.c (delete_points_to_sets): Likewise. * passes.c (pass_inline_parameters): Update comments; remove O0_alwaysinline pass. (execute_one_ipa_transform_pass): Do not reset in_gimple_form. (execute_one_pass): Likewise. * i386.c (ix86_function_regparm): Remove unit-at-a-time check. (ix86_function_sseregparm): Likewise. * arm.c (arm_function_in_section_p): Likewise. * bfin.c (bfin_load_pic_reg, bfin_function_ok_for_sibcall): Likewise. * varpool.c: Update comments. (decide_is_variable_needed): Remove unit-at-a-time checks. (varpool_finalize_decl): Likewise. * ada/utils.c (end_subprog_body): Remove inline trees check. * ada/misc.c (gnat_post_options): Do not set flag_inline_trees. * fortran/options.c (gfc_post_options): Remove flag_unline_trees code. * gcc.dg/winline-4.c: Remove. * gcc.dg/pch/valid-3.hs: Remove. * gcc.dg/pch/valid-3.c: Remove. * g++.old-deja/g++.brendan/crash52.C: Accept returning void warning * g++.old-deja/g++.jason/report.C: Likewise. * testsuite/g++.dg/warn/pr23075.C: We get returning void warning instead of control flow warning. * cp/decl.c (duplicate_decls): Update comment and unit-at-a-time. (grogfndecl): Drop flag_inline_trees code. * cp/pt.c (instantiate_decl): Drop flag_iline_trees code. * cp/lex.c (cxx_init): Do not set unit-at-a-time. * java/decl.c: Include cgraph.h (end_java_method): Remove non-unit-at-a-time code. (java_mark_decl_local): Likewise; sanity check that we don't touch finalized nodes. From-SVN: r138140
This commit is contained in:
parent
4a7bb85b7b
commit
7e8b322aa0
50 changed files with 222 additions and 599 deletions
|
@ -1,3 +1,79 @@
|
|||
2008-07-24 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cgraphbuild.c (record_reference): Drop non-unit-at-a-time code.
|
||||
(build_cgraph_edges): Likewise.
|
||||
* cgraph.c (cgraph_node): Do not update assembler hash.
|
||||
(cgraph_remove_node): Drop non-unit-at-a-time code.
|
||||
* tree-pass.h (pass_O0_always_inline): Remove.
|
||||
* ipa-reference.c (gate_reference): Remove unit-at-a-time check.
|
||||
* toplev.c (process_options): Flag unit-at-a-time does not imply
|
||||
no section anchors.
|
||||
* cgraphunit.c: Update comments.
|
||||
(decide_is_function_needed): Drop non-unit-at-a-time mode.
|
||||
(cgraph_assemble_pending_functions): Remove.
|
||||
(cgraph_reset_node): Drop non-unit-at-a-time code.
|
||||
(cgraph_finalize_function): Likewise.
|
||||
(cgraph_analyze_function): Likewise.
|
||||
(cgraph_finalize_compilation_unit): Likewise.
|
||||
(cgraph_expand_function): Likewise.
|
||||
(cgraph_optimize): Likesise.
|
||||
(save_inline_function_body): Likewise.
|
||||
* ipa-pure-const.c (gate_pure_const): Drop flag_unit_at_a_time check.
|
||||
* tree-ssa-alias.c (maybe_be_aliased): Likewise.
|
||||
* ipa-inline.c: Update comments.
|
||||
(enum inlining_mode): remove INLINE_SPEED.
|
||||
(cgraph_clone_inlined_nodes): Drop unit-at-a-time check.
|
||||
(cgraph_mark_inline_edge): Likewise.
|
||||
(try_inline): Likewise.
|
||||
(cgraph_decide_inlining_incrementally): Likewise.
|
||||
(cgraph_gate_inlining): Remove.
|
||||
(cgraph_early_inlining): Remove flag_unit_at_a_time checks.
|
||||
(cgraph_gate_early_inlining): Likewise.
|
||||
(gate_inline_passes): Remove.
|
||||
(pass_inline_parameters, pass_ipa_inline): Remove gates.
|
||||
(cgraph_gate_O0_always_inline, cgraph_O0_always_inline,
|
||||
pass_O0_always_inline): Remove.
|
||||
* c-pch.c (c_pch_matching): Remove -funit-at-a-time.
|
||||
* dwarf2out.c (reference_to_unused): Remove flag_unit_at_a_time check.
|
||||
* opts.c (no_unit_at_a_time_default): Remove.
|
||||
(decode_options): Remove flag_unit_at_a_time reset and warning.
|
||||
* opts.h (no_unit_at_a_time_default): Remove.
|
||||
* c-decl.c (diagnose_mismatched_decls): Do not require inline keyword
|
||||
early in GNU dialect.
|
||||
(merge_decls): Update comment; drop unit-at-a-time check.
|
||||
(finish_decl): Likewise.
|
||||
(grok_declaration): Remove flag_inline_trees code.
|
||||
(finish_functions): Return on function returning non-void on all
|
||||
statics.
|
||||
* ipa-tye-escape.c (gate_type_escape_vars): Remove.
|
||||
* cfgexpand.c (expand_one_static_var): Remove.
|
||||
(expand_one_var): Remove expand_one_static_var call.
|
||||
(expand_used_vars_for_block): Remove flag_unit_a_time check.
|
||||
* c-opts.c (c_common_post_options): Remove flag_inline_trees code
|
||||
and flag_unit_at_a-time compatibility checks.
|
||||
* varasm.c (assemble_alias): Remove flag_unit_at_a_time check.
|
||||
* tree-inline.c (flag_inline_trees): Remove.
|
||||
(inlinable_function_p): Don't check it.
|
||||
(expand_call_inline): Remove non-unit-at-a-time code.
|
||||
* tree-inline.h (flag_inline_trees): Remove.
|
||||
* tree-optimize.c (execute_early_local_optimizations): Remove
|
||||
unit-at-a-time checks.
|
||||
(tree_rest_of_compilation): Likewise.
|
||||
* combine.c (setup_incoming_promotions): Likewise.
|
||||
* tree-profile.c (tree_gen_ic_func_profiler): Likewise.
|
||||
* tree-ssa-structalias.c (delete_points_to_sets): Likewise.
|
||||
* passes.c (pass_inline_parameters): Update comments; remove
|
||||
O0_alwaysinline pass.
|
||||
(execute_one_ipa_transform_pass): Do not reset in_gimple_form.
|
||||
(execute_one_pass): Likewise.
|
||||
* i386.c (ix86_function_regparm): Remove unit-at-a-time check.
|
||||
(ix86_function_sseregparm): Likewise.
|
||||
* arm.c (arm_function_in_section_p): Likewise.
|
||||
* bfin.c (bfin_load_pic_reg, bfin_function_ok_for_sibcall): Likewise.
|
||||
* varpool.c: Update comments.
|
||||
(decide_is_variable_needed): Remove unit-at-a-time checks.
|
||||
(varpool_finalize_decl): Likewise.
|
||||
|
||||
2008-07-24 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* config/sh/sh.h (OPTIMIZATION_OPTIONS): Set flag_omit_frame_pointer
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2008-07-24 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* ada/utils.c (end_subprog_body): Remove inline trees check.
|
||||
* ada/misc.c (gnat_post_options): Do not set flag_inline_trees.
|
||||
|
||||
2008-07-25 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
|
||||
|
||||
* raise-gcc.c: Move tsystem.h before tm.h.
|
||||
|
|
|
@ -340,12 +340,8 @@ gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED)
|
|||
/* ??? The warning machinery is outsmarted by Ada. */
|
||||
warn_unused_parameter = 0;
|
||||
|
||||
flag_inline_trees = 1;
|
||||
|
||||
if (!flag_no_inline)
|
||||
flag_no_inline = 1;
|
||||
if (flag_inline_functions)
|
||||
flag_inline_trees = 2;
|
||||
|
||||
/* Force eliminate_unused_debug_types to 0 unless an explicit positive
|
||||
-f has been passed. This forces the default to 0 for Ada, which might
|
||||
|
|
|
@ -2217,8 +2217,7 @@ end_subprog_body (tree body)
|
|||
|
||||
/* Deal with inline. If declared inline or we should default to inline,
|
||||
set the flag in the decl. */
|
||||
DECL_INLINE (fndecl)
|
||||
= DECL_DECLARED_INLINE_P (fndecl) || flag_inline_trees == 2;
|
||||
DECL_INLINE (fndecl) = 1;
|
||||
|
||||
/* We handle pending sizes via the elaboration of types, so we don't
|
||||
need to save them. */
|
||||
|
|
45
gcc/c-decl.c
45
gcc/c-decl.c
|
@ -1515,30 +1515,6 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
|
|||
"noinline follows inline declaration ", newdecl);
|
||||
warned = true;
|
||||
}
|
||||
|
||||
/* Inline declaration after use or definition.
|
||||
??? Should we still warn about this now we have unit-at-a-time
|
||||
mode and can get it right?
|
||||
Definitely don't complain if the decls are in different translation
|
||||
units.
|
||||
C99 permits this, so don't warn in that case. (The function
|
||||
may not be inlined everywhere in function-at-a-time mode, but
|
||||
we still shouldn't warn.) */
|
||||
if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl)
|
||||
&& same_translation_unit_p (olddecl, newdecl)
|
||||
&& flag_gnu89_inline)
|
||||
{
|
||||
if (TREE_USED (olddecl))
|
||||
{
|
||||
warning (0, "%q+D declared inline after being called", olddecl);
|
||||
warned = true;
|
||||
}
|
||||
else if (DECL_INITIAL (olddecl))
|
||||
{
|
||||
warning (0, "%q+D declared inline after its definition", olddecl);
|
||||
warned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* PARM_DECL, VAR_DECL */
|
||||
{
|
||||
|
@ -1801,9 +1777,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
|||
if (new_is_definition && DECL_INITIAL (olddecl))
|
||||
{
|
||||
if (TREE_USED (olddecl)
|
||||
/* In unit-at-a-time mode we never inline re-defined extern
|
||||
inline functions. */
|
||||
&& !flag_unit_at_a_time
|
||||
/* We never inline re-defined extern inline functions.
|
||||
FIXME: This would be better handled by keeping both functions
|
||||
as separate declarations. */
|
||||
&& cgraph_function_possibly_inlined_p (olddecl))
|
||||
(*debug_hooks->outlining_inline_function) (olddecl);
|
||||
|
||||
|
@ -3618,10 +3594,6 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
|
|||
}
|
||||
}
|
||||
|
||||
/* If this was marked 'used', be sure it will be output. */
|
||||
if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
|
||||
mark_decl_referenced (decl);
|
||||
|
||||
if (TREE_CODE (decl) == TYPE_DECL)
|
||||
{
|
||||
if (!DECL_FILE_SCOPE_P (decl)
|
||||
|
@ -4878,10 +4850,7 @@ grokdeclarator (const struct c_declarator *declarator,
|
|||
if (initialized)
|
||||
DECL_INLINE (decl) = 1;
|
||||
}
|
||||
/* If -finline-functions, assume it can be inlined. This does
|
||||
two things: let the function be deferred until it is actually
|
||||
needed, and let dwarf2 know that the function is inlinable. */
|
||||
else if (flag_inline_trees == 2 && initialized)
|
||||
else if (initialized)
|
||||
DECL_INLINE (decl) = 1;
|
||||
}
|
||||
else
|
||||
|
@ -6755,9 +6724,9 @@ finish_function (void)
|
|||
&& !MAIN_NAME_P (DECL_NAME (fndecl))
|
||||
/* Or if they didn't actually specify a return type. */
|
||||
&& !C_FUNCTION_IMPLICIT_INT (fndecl)
|
||||
/* Normally, with -Wreturn-type, flow will complain. Unless we're an
|
||||
inline function, as we might never be compiled separately. */
|
||||
&& DECL_INLINE (fndecl))
|
||||
/* Normally, with -Wreturn-type, flow will complain, but we might
|
||||
optimize out static functions. */
|
||||
&& !TREE_PUBLIC (fndecl))
|
||||
{
|
||||
warning (OPT_Wreturn_type,
|
||||
"no return statement in function returning non-void");
|
||||
|
|
19
gcc/c-opts.c
19
gcc/c-opts.c
|
@ -1018,13 +1018,9 @@ c_common_post_options (const char **pfilename)
|
|||
C_COMMON_OVERRIDE_OPTIONS;
|
||||
#endif
|
||||
|
||||
flag_inline_trees = 1;
|
||||
|
||||
/* Use tree inlining. */
|
||||
if (!flag_no_inline)
|
||||
flag_no_inline = 1;
|
||||
if (flag_inline_functions)
|
||||
flag_inline_trees = 2;
|
||||
|
||||
/* By default we use C99 inline semantics in GNU99 or C99 mode. C99
|
||||
inline semantics are not supported in GNU89 or C89 mode. */
|
||||
|
@ -1033,14 +1029,6 @@ c_common_post_options (const char **pfilename)
|
|||
else if (!flag_gnu89_inline && !flag_isoc99)
|
||||
error ("-fno-gnu89-inline is only supported in GNU99 or C99 mode");
|
||||
|
||||
/* If we are given more than one input file, we must use
|
||||
unit-at-a-time mode. */
|
||||
if (num_in_fnames > 1)
|
||||
flag_unit_at_a_time = 1;
|
||||
|
||||
if (pch_file && !flag_unit_at_a_time)
|
||||
sorry ("Precompiled headers require -funit-at-a-time");
|
||||
|
||||
/* Default to ObjC sjlj exception handling if NeXT runtime. */
|
||||
if (flag_objc_sjlj_exceptions < 0)
|
||||
flag_objc_sjlj_exceptions = flag_next_runtime;
|
||||
|
@ -1091,12 +1079,7 @@ c_common_post_options (const char **pfilename)
|
|||
if (c_dialect_cxx ())
|
||||
{
|
||||
if (!flag_no_inline)
|
||||
{
|
||||
flag_inline_trees = 1;
|
||||
flag_no_inline = 1;
|
||||
}
|
||||
if (flag_inline_functions)
|
||||
flag_inline_trees = 2;
|
||||
flag_no_inline = 1;
|
||||
}
|
||||
|
||||
/* In C, -Wconversion enables -Wsign-conversion (unless disabled
|
||||
|
|
|
@ -45,7 +45,6 @@ static const struct c_pch_matching
|
|||
const char *flag_name;
|
||||
} pch_matching[] = {
|
||||
{ &flag_exceptions, "-fexceptions" },
|
||||
{ &flag_unit_at_a_time, "-funit-at-a-time" }
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
|
@ -617,28 +617,6 @@ expand_one_stack_var (tree var)
|
|||
expand_one_stack_var_at (var, offset);
|
||||
}
|
||||
|
||||
/* A subroutine of expand_one_var. Called to assign rtl
|
||||
to a TREE_STATIC VAR_DECL. */
|
||||
|
||||
static void
|
||||
expand_one_static_var (tree var)
|
||||
{
|
||||
/* In unit-at-a-time all the static variables are expanded at the end
|
||||
of compilation process. */
|
||||
if (flag_unit_at_a_time)
|
||||
return;
|
||||
/* If this is an inlined copy of a static local variable,
|
||||
look up the original. */
|
||||
var = DECL_ORIGIN (var);
|
||||
|
||||
/* If we've already processed this variable because of that, do nothing. */
|
||||
if (TREE_ASM_WRITTEN (var))
|
||||
return;
|
||||
|
||||
/* Otherwise, just emit the variable. */
|
||||
rest_of_decl_compilation (var, 0, 0);
|
||||
}
|
||||
|
||||
/* A subroutine of expand_one_var. Called to assign rtl to a VAR_DECL
|
||||
that will reside in a hard register. */
|
||||
|
||||
|
@ -742,10 +720,7 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
|
|||
else if (DECL_HAS_VALUE_EXPR_P (var))
|
||||
;
|
||||
else if (TREE_STATIC (var))
|
||||
{
|
||||
if (really_expand)
|
||||
expand_one_static_var (var);
|
||||
}
|
||||
;
|
||||
else if (DECL_RTL_SET_P (var))
|
||||
;
|
||||
else if (TREE_TYPE (var) == error_mark_node)
|
||||
|
@ -790,12 +765,7 @@ expand_used_vars_for_block (tree block, bool toplevel)
|
|||
|
||||
/* Expand all variables at this level. */
|
||||
for (t = BLOCK_VARS (block); t ; t = TREE_CHAIN (t))
|
||||
if (TREE_USED (t)
|
||||
/* Force local static variables to be output when marked by
|
||||
used attribute. For unit-at-a-time, cgraph code already takes
|
||||
care of this. */
|
||||
|| (!flag_unit_at_a_time && TREE_STATIC (t)
|
||||
&& DECL_PRESERVE_P (t)))
|
||||
if (TREE_USED (t))
|
||||
expand_one_var (t, toplevel, true);
|
||||
|
||||
this_sv_num = stack_vars_num;
|
||||
|
|
13
gcc/cgraph.c
13
gcc/cgraph.c
|
@ -412,17 +412,6 @@ cgraph_node (tree decl)
|
|||
node->master_clone = node;
|
||||
}
|
||||
|
||||
/* This code can go away once flag_unit_at_a_mode is removed. */
|
||||
if (assembler_name_hash)
|
||||
{
|
||||
tree name = DECL_ASSEMBLER_NAME (node->decl);
|
||||
slot = ((struct cgraph_node **)
|
||||
htab_find_slot_with_hash (assembler_name_hash, name,
|
||||
decl_assembler_name_hash (name),
|
||||
INSERT));
|
||||
if (!*slot)
|
||||
*slot = node;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -894,7 +883,7 @@ cgraph_remove_node (struct cgraph_node *node)
|
|||
htab_clear_slot (assembler_name_hash, slot);
|
||||
}
|
||||
|
||||
if (kill_body && flag_unit_at_a_time)
|
||||
if (kill_body)
|
||||
cgraph_release_function_body (node);
|
||||
node->decl = NULL;
|
||||
if (node->call_site_hash)
|
||||
|
|
|
@ -38,6 +38,7 @@ static tree
|
|||
record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
tree t = *tp;
|
||||
tree decl;
|
||||
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
|
@ -52,32 +53,23 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
|
|||
|
||||
case FDESC_EXPR:
|
||||
case ADDR_EXPR:
|
||||
if (flag_unit_at_a_time)
|
||||
{
|
||||
/* Record dereferences to the functions. This makes the
|
||||
functions reachable unconditionally. */
|
||||
tree decl = TREE_OPERAND (*tp, 0);
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
cgraph_mark_needed_node (cgraph_node (decl));
|
||||
}
|
||||
/* Record dereferences to the functions. This makes the
|
||||
functions reachable unconditionally. */
|
||||
decl = TREE_OPERAND (*tp, 0);
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
cgraph_mark_needed_node (cgraph_node (decl));
|
||||
break;
|
||||
|
||||
case OMP_PARALLEL:
|
||||
if (flag_unit_at_a_time)
|
||||
{
|
||||
if (OMP_PARALLEL_FN (*tp))
|
||||
cgraph_mark_needed_node (cgraph_node (OMP_PARALLEL_FN (*tp)));
|
||||
}
|
||||
if (OMP_PARALLEL_FN (*tp))
|
||||
cgraph_mark_needed_node (cgraph_node (OMP_PARALLEL_FN (*tp)));
|
||||
break;
|
||||
|
||||
case OMP_TASK:
|
||||
if (flag_unit_at_a_time)
|
||||
{
|
||||
if (OMP_TASK_FN (*tp))
|
||||
cgraph_mark_needed_node (cgraph_node (OMP_TASK_FN (*tp)));
|
||||
if (OMP_TASK_COPYFN (*tp))
|
||||
cgraph_mark_needed_node (cgraph_node (OMP_TASK_COPYFN (*tp)));
|
||||
}
|
||||
if (OMP_TASK_FN (*tp))
|
||||
cgraph_mark_needed_node (cgraph_node (OMP_TASK_FN (*tp)));
|
||||
if (OMP_TASK_COPYFN (*tp))
|
||||
cgraph_mark_needed_node (cgraph_node (OMP_TASK_COPYFN (*tp)));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -187,8 +179,7 @@ build_cgraph_edges (void)
|
|||
{
|
||||
tree decl = TREE_VALUE (step);
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& (TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
|
||||
&& flag_unit_at_a_time)
|
||||
&& (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
|
||||
varpool_finalize_decl (decl);
|
||||
else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
|
||||
walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
|
||||
|
|
184
gcc/cgraphunit.c
184
gcc/cgraphunit.c
|
@ -45,7 +45,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
This function is called once (source level) compilation unit is finalized
|
||||
and it will no longer change.
|
||||
|
||||
In the unit-at-a-time the call-graph construction and local function
|
||||
In the the call-graph construction and local function
|
||||
analysis takes place here. Bodies of unreachable functions are released
|
||||
to conserve memory usage.
|
||||
|
||||
|
@ -77,9 +77,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
??? On the tree-ssa genericizing should take place here and we will avoid
|
||||
need for these hooks (replacing them by genericizing hook)
|
||||
|
||||
We implement two compilation modes.
|
||||
|
||||
- unit-at-a-time: In this mode analyzing of all functions is deferred
|
||||
Analyzing of all functions is deferred
|
||||
to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.
|
||||
|
||||
In cgraph_finalize_compilation_unit the reachable functions are
|
||||
|
@ -105,23 +103,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
|
||||
??? Reorganize code so variables are output very last and only if they
|
||||
really has been referenced by produced code, so we catch more cases
|
||||
where reference has been optimized out.
|
||||
|
||||
- non-unit-at-a-time
|
||||
|
||||
All functions are variables are output as early as possible to conserve
|
||||
memory consumption. This may or may not result in less memory used but
|
||||
it is still needed for some legacy code that rely on particular ordering
|
||||
of things output from the compiler.
|
||||
|
||||
Varpool data structures are not used and variables are output directly.
|
||||
|
||||
Functions are output early using call of
|
||||
cgraph_assemble_pending_function from cgraph_finalize_function. The
|
||||
decision on whether function is needed is made more conservative so
|
||||
uninlinable static functions are needed too. During the call-graph
|
||||
construction the edge destinations are not marked as reachable and it
|
||||
is completely relied upon assemble_variable to mark them. */
|
||||
where reference has been optimized out. */
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
@ -326,13 +308,11 @@ cgraph_build_cdtor_fns (void)
|
|||
|
||||
/* Determine if function DECL is needed. That is, visible to something
|
||||
either outside this translation unit, something magic in the system
|
||||
configury, or (if not doing unit-at-a-time) to something we haven't
|
||||
seen yet. */
|
||||
configury. */
|
||||
|
||||
static bool
|
||||
decide_is_function_needed (struct cgraph_node *node, tree decl)
|
||||
{
|
||||
tree origin;
|
||||
if (MAIN_NAME_P (DECL_NAME (decl))
|
||||
&& TREE_PUBLIC (decl))
|
||||
{
|
||||
|
@ -344,9 +324,6 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
|
|||
if (node->local.externally_visible)
|
||||
return true;
|
||||
|
||||
if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
|
||||
return true;
|
||||
|
||||
/* ??? If the assembler name is set by hand, it is possible to assemble
|
||||
the name later after finalizing the function and the fact is noticed
|
||||
in assemble_name then. This is arguably a bug. */
|
||||
|
@ -389,32 +366,6 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
|
|||
if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
|
||||
return true;
|
||||
|
||||
if (flag_unit_at_a_time)
|
||||
return false;
|
||||
|
||||
/* If not doing unit at a time, then we'll only defer this function
|
||||
if its marked for inlining. Otherwise we want to emit it now. */
|
||||
|
||||
/* "extern inline" functions are never output locally. */
|
||||
if (DECL_EXTERNAL (decl))
|
||||
return false;
|
||||
/* Nested functions of extern inline function shall not be emit unless
|
||||
we inlined the origin. */
|
||||
for (origin = decl_function_context (decl); origin;
|
||||
origin = decl_function_context (origin))
|
||||
if (DECL_EXTERNAL (origin))
|
||||
return false;
|
||||
/* We want to emit COMDAT functions only when absolutely necessary. */
|
||||
if (DECL_COMDAT (decl))
|
||||
return false;
|
||||
if (!DECL_INLINE (decl)
|
||||
|| (!node->local.disregard_inline_limits
|
||||
/* When declared inline, defer even the uninlinable functions.
|
||||
This allows them to be eliminated when unused. */
|
||||
&& !DECL_DECLARED_INLINE_P (decl)
|
||||
&& (!node->local.inlinable || !cgraph_default_inline_p (node, NULL))))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -487,39 +438,6 @@ cgraph_process_new_functions (void)
|
|||
return output;
|
||||
}
|
||||
|
||||
/* When not doing unit-at-a-time, output all functions enqueued.
|
||||
Return true when such a functions were found. */
|
||||
|
||||
static bool
|
||||
cgraph_assemble_pending_functions (void)
|
||||
{
|
||||
bool output = false;
|
||||
|
||||
if (flag_unit_at_a_time || errorcount || sorrycount)
|
||||
return false;
|
||||
|
||||
cgraph_output_pending_asms ();
|
||||
|
||||
while (cgraph_nodes_queue)
|
||||
{
|
||||
struct cgraph_node *n = cgraph_nodes_queue;
|
||||
|
||||
cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
|
||||
n->next_needed = NULL;
|
||||
if (!n->global.inlined_to
|
||||
&& !n->alias
|
||||
&& !DECL_EXTERNAL (n->decl))
|
||||
{
|
||||
cgraph_expand_function (n);
|
||||
output = true;
|
||||
}
|
||||
output |= cgraph_process_new_functions ();
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/* As an GCC extension we allow redefinition of the function. The
|
||||
semantics when both copies of bodies differ is not well defined.
|
||||
We replace the old body with new body so in unit at a time mode
|
||||
|
@ -533,12 +451,11 @@ cgraph_assemble_pending_functions (void)
|
|||
static void
|
||||
cgraph_reset_node (struct cgraph_node *node)
|
||||
{
|
||||
/* If node->output is set, then this is a unit-at-a-time compilation
|
||||
and we have already begun whole-unit analysis. This is *not*
|
||||
testing for whether we've already emitted the function. That
|
||||
case can be sort-of legitimately seen with real function
|
||||
redefinition errors. I would argue that the front end should
|
||||
never present us with such a case, but don't enforce that for now. */
|
||||
/* If node->output is set, then we have already begun whole-unit analysis.
|
||||
This is *not* testing for whether we've already emitted the function.
|
||||
That case can be sort-of legitimately seen with real function redefinition
|
||||
errors. I would argue that the front end should never present us with
|
||||
such a case, but don't enforce that for now. */
|
||||
gcc_assert (!node->output);
|
||||
|
||||
/* Reset our data structures so we can analyze the function again. */
|
||||
|
@ -549,18 +466,6 @@ cgraph_reset_node (struct cgraph_node *node)
|
|||
node->local.redefined_extern_inline = true;
|
||||
node->local.finalized = false;
|
||||
|
||||
if (!flag_unit_at_a_time)
|
||||
{
|
||||
struct cgraph_node *n, *next;
|
||||
|
||||
for (n = cgraph_nodes; n; n = next)
|
||||
{
|
||||
next = n->next;
|
||||
if (n->global.inlined_to == node)
|
||||
cgraph_remove_node (n);
|
||||
}
|
||||
}
|
||||
|
||||
cgraph_node_remove_callees (node);
|
||||
|
||||
/* We may need to re-queue the node for assembling in case
|
||||
|
@ -609,11 +514,6 @@ cgraph_finalize_function (tree decl, bool nested)
|
|||
lower_nested_functions (decl);
|
||||
gcc_assert (!node->nested);
|
||||
|
||||
/* If not unit at a time, then we need to create the call graph
|
||||
now, so that called functions can be queued and emitted now. */
|
||||
if (!flag_unit_at_a_time)
|
||||
cgraph_analyze_function (node);
|
||||
|
||||
if (decide_is_function_needed (node, decl))
|
||||
cgraph_mark_needed_node (node);
|
||||
|
||||
|
@ -623,14 +523,6 @@ cgraph_finalize_function (tree decl, bool nested)
|
|||
if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
|
||||
cgraph_mark_reachable_node (node);
|
||||
|
||||
/* If not unit at a time, go ahead and emit everything we've found
|
||||
to be reachable at this time. */
|
||||
if (!nested)
|
||||
{
|
||||
if (!cgraph_assemble_pending_functions ())
|
||||
ggc_collect ();
|
||||
}
|
||||
|
||||
/* If we've not yet emitted decl, tell the debug info about it. */
|
||||
if (!TREE_ASM_WRITTEN (decl))
|
||||
(*debug_hooks->deferred_inline_function) (decl);
|
||||
|
@ -638,6 +530,9 @@ cgraph_finalize_function (tree decl, bool nested)
|
|||
/* Possibly warn about unused parameters. */
|
||||
if (warn_unused_parameter)
|
||||
do_warn_unused_parameter (decl);
|
||||
|
||||
if (!nested)
|
||||
ggc_collect ();
|
||||
}
|
||||
|
||||
/* C99 extern inline keywords allow changing of declaration after function
|
||||
|
@ -855,16 +750,6 @@ cgraph_analyze_function (struct cgraph_node *node)
|
|||
cgraph_lower_function (node);
|
||||
node->analyzed = true;
|
||||
|
||||
if (!flag_unit_at_a_time && !sorrycount && !errorcount)
|
||||
{
|
||||
bitmap_obstack_initialize (NULL);
|
||||
tree_register_cfg_hooks ();
|
||||
execute_pass_list (pass_early_local_passes.pass.sub);
|
||||
free_dominance_info (CDI_POST_DOMINATORS);
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
bitmap_obstack_release (NULL);
|
||||
}
|
||||
|
||||
pop_cfun ();
|
||||
current_function_decl = NULL;
|
||||
}
|
||||
|
@ -1072,14 +957,6 @@ cgraph_finalize_compilation_unit (void)
|
|||
|
||||
finish_aliases_1 ();
|
||||
|
||||
if (!flag_unit_at_a_time)
|
||||
{
|
||||
cgraph_output_pending_asms ();
|
||||
cgraph_assemble_pending_functions ();
|
||||
varpool_output_debug_info ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!quiet_flag)
|
||||
{
|
||||
fprintf (stderr, "\nAnalyzing compilation unit\n");
|
||||
|
@ -1147,8 +1024,7 @@ cgraph_expand_function (struct cgraph_node *node)
|
|||
/* We ought to not compile any inline clones. */
|
||||
gcc_assert (!node->global.inlined_to);
|
||||
|
||||
if (flag_unit_at_a_time)
|
||||
announce_function (decl);
|
||||
announce_function (decl);
|
||||
|
||||
gcc_assert (node->lowered);
|
||||
|
||||
|
@ -1372,16 +1248,6 @@ cgraph_optimize (void)
|
|||
/* Call functions declared with the "constructor" or "destructor"
|
||||
attribute. */
|
||||
cgraph_build_cdtor_fns ();
|
||||
if (!flag_unit_at_a_time)
|
||||
{
|
||||
cgraph_assemble_pending_functions ();
|
||||
cgraph_process_new_functions ();
|
||||
cgraph_state = CGRAPH_STATE_FINISHED;
|
||||
cgraph_output_pending_asms ();
|
||||
varpool_assemble_pending_decls ();
|
||||
varpool_output_debug_info ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Frontend may output common variables after the unit has been finalized.
|
||||
It is safe to deal with them here as they are always zero initialized. */
|
||||
|
@ -1453,8 +1319,7 @@ cgraph_optimize (void)
|
|||
verify_cgraph ();
|
||||
/* Double check that all inline clones are gone and that all
|
||||
function bodies have been released from memory. */
|
||||
if (flag_unit_at_a_time
|
||||
&& !(sorrycount || errorcount))
|
||||
if (!(sorrycount || errorcount))
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
bool error_found = false;
|
||||
|
@ -1683,29 +1548,10 @@ save_inline_function_body (struct cgraph_node *node)
|
|||
|
||||
cgraph_lower_function (node);
|
||||
|
||||
/* In non-unit-at-a-time we construct full fledged clone we never output to
|
||||
assembly file. This clone is pointed out by inline_decl of original function
|
||||
and inlining infrastructure knows how to deal with this. */
|
||||
if (!flag_unit_at_a_time)
|
||||
{
|
||||
struct cgraph_edge *e;
|
||||
|
||||
first_clone = cgraph_clone_node (node, node->count, 0, CGRAPH_FREQ_BASE,
|
||||
false);
|
||||
first_clone->needed = 0;
|
||||
first_clone->reachable = 1;
|
||||
/* Recursively clone all bodies. */
|
||||
for (e = first_clone->callees; e; e = e->next_callee)
|
||||
if (!e->inline_failed)
|
||||
cgraph_clone_inlined_nodes (e, true, false);
|
||||
}
|
||||
else
|
||||
first_clone = node->next_clone;
|
||||
first_clone = node->next_clone;
|
||||
|
||||
first_clone->decl = copy_node (node->decl);
|
||||
node->next_clone = NULL;
|
||||
if (!flag_unit_at_a_time)
|
||||
node->inline_decl = first_clone->decl;
|
||||
first_clone->prev_clone = NULL;
|
||||
cgraph_insert_node_to_hashtable (first_clone);
|
||||
gcc_assert (first_clone == cgraph_node (first_clone->decl));
|
||||
|
|
|
@ -1340,8 +1340,7 @@ setup_incoming_promotions (rtx first)
|
|||
function lie within the current compilation unit. (This does
|
||||
take into account the exporting of a function via taking its
|
||||
address, and so forth.) */
|
||||
if (flag_unit_at_a_time)
|
||||
strictly_local = cgraph_local_info (current_function_decl)->local;
|
||||
strictly_local = cgraph_local_info (current_function_decl)->local;
|
||||
|
||||
/* The mode and signedness of the argument before any promotions happen
|
||||
(equal to the mode of the pseudo holding it at that stage). */
|
||||
|
|
|
@ -3267,11 +3267,6 @@ arm_function_in_section_p (tree decl, section *section)
|
|||
/* If DECL_SECTION_NAME is set, assume it is trustworthy. */
|
||||
if (!DECL_SECTION_NAME (decl))
|
||||
{
|
||||
/* Only cater for unit-at-a-time mode, where we know that the user
|
||||
cannot later specify a section for DECL. */
|
||||
if (!flag_unit_at_a_time)
|
||||
return false;
|
||||
|
||||
/* Make sure that we will not create a unique section for DECL. */
|
||||
if (flag_function_sections || DECL_ONE_ONLY (decl))
|
||||
return false;
|
||||
|
|
|
@ -1129,8 +1129,7 @@ bfin_load_pic_reg (rtx dest)
|
|||
struct cgraph_local_info *i = NULL;
|
||||
rtx addr, insn;
|
||||
|
||||
if (flag_unit_at_a_time)
|
||||
i = cgraph_local_info (current_function_decl);
|
||||
i = cgraph_local_info (current_function_decl);
|
||||
|
||||
/* Functions local to the translation unit don't need to reload the
|
||||
pic reg, since the caller always passes a usable one. */
|
||||
|
@ -1906,6 +1905,7 @@ static bool
|
|||
bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
|
||||
tree exp ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct cgraph_local_info *this_func, *called_func;
|
||||
e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
|
||||
if (fkind != SUBROUTINE)
|
||||
return false;
|
||||
|
@ -1917,17 +1917,10 @@ bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
|
|||
not need to reload P5 in the prologue, but the sibcall wil pop P5 in the
|
||||
sibcall epilogue, and we end up with the wrong value in P5. */
|
||||
|
||||
if (!flag_unit_at_a_time || decl == NULL)
|
||||
/* Not enough information. */
|
||||
return false;
|
||||
|
||||
{
|
||||
struct cgraph_local_info *this_func, *called_func;
|
||||
|
||||
this_func = cgraph_local_info (current_function_decl);
|
||||
called_func = cgraph_local_info (decl);
|
||||
return !called_func->local || this_func->local;
|
||||
}
|
||||
this_func = cgraph_local_info (current_function_decl);
|
||||
called_func = cgraph_local_info (decl);
|
||||
return !called_func->local || this_func->local;
|
||||
}
|
||||
|
||||
/* Emit RTL insns to initialize the variable parts of a trampoline at
|
||||
|
|
|
@ -4210,7 +4210,7 @@ ix86_function_regparm (const_tree type, const_tree decl)
|
|||
|
||||
/* Use register calling convention for local functions when possible. */
|
||||
if (decl && TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& flag_unit_at_a_time && !profile_flag)
|
||||
&& !profile_flag)
|
||||
{
|
||||
/* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */
|
||||
struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
|
||||
|
@ -4297,7 +4297,7 @@ ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
|
|||
|
||||
/* For local functions, pass up to SSE_REGPARM_MAX SFmode
|
||||
(and DFmode for SSE2) arguments in SSE registers. */
|
||||
if (decl && TARGET_SSE_MATH && flag_unit_at_a_time && !profile_flag)
|
||||
if (decl && TARGET_SSE_MATH && !profile_flag)
|
||||
{
|
||||
/* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */
|
||||
struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2008-07-23 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cp/decl.c (duplicate_decls): Update comment and unit-at-a-time.
|
||||
(grogfndecl): Drop flag_inline_trees code.
|
||||
* cp/pt.c (instantiate_decl): Drop flag_iline_trees code.
|
||||
* cp/lex.c (cxx_init): Do not set unit-at-a-time.
|
||||
|
||||
2008-07-23 Jason Merrill <jason@redhat.com>
|
||||
|
||||
Implement defaulted/deleted functions as per N2346
|
||||
|
|
|
@ -1954,8 +1954,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|
|||
}
|
||||
else if (new_defines_function && DECL_INITIAL (olddecl))
|
||||
{
|
||||
/* C++ is always in in unit-at-a-time mode, so we never
|
||||
inline re-defined extern inline functions. */
|
||||
/* Never inline re-defined extern inline functions.
|
||||
FIXME: this could be better handled by keeping both
|
||||
function as separate declarations. */
|
||||
DECL_INLINE (newdecl) = 0;
|
||||
DECL_UNINLINABLE (newdecl) = 1;
|
||||
}
|
||||
|
@ -6643,7 +6644,7 @@ grokfndecl (tree ctype,
|
|||
/* We inline functions that are explicitly declared inline, or, when
|
||||
the user explicitly asks us to, all functions. */
|
||||
if (DECL_DECLARED_INLINE_P (decl)
|
||||
|| (flag_inline_trees == 2 && !DECL_INLINE (decl) && funcdef_flag))
|
||||
|| (!DECL_INLINE (decl) && funcdef_flag))
|
||||
DECL_INLINE (decl) = 1;
|
||||
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
|
|
11
gcc/cp/lex.c
11
gcc/cp/lex.c
|
@ -247,17 +247,6 @@ cxx_init (void)
|
|||
|
||||
cxx_init_decl_processing ();
|
||||
|
||||
/* The fact that G++ uses COMDAT for many entities (inline
|
||||
functions, template instantiations, virtual tables, etc.) mean
|
||||
that it is fundamentally unreliable to try to make decisions
|
||||
about whether or not to output a particular entity until the end
|
||||
of the compilation. However, the inliner requires that functions
|
||||
be provided to the back end if they are to be inlined.
|
||||
Therefore, we always use unit-at-a-time mode; in that mode, we
|
||||
can provide entities to the back end and it will decide what to
|
||||
emit based on what is actually needed. */
|
||||
flag_unit_at_a_time = 1;
|
||||
|
||||
if (c_common_init () == false)
|
||||
{
|
||||
input_location = saved_loc;
|
||||
|
|
|
@ -15222,7 +15222,6 @@ instantiate_decl (tree d, int defer_ok,
|
|||
job, even though we'll not be emitting a copy of this
|
||||
function. */
|
||||
if (!(TREE_CODE (d) == FUNCTION_DECL
|
||||
&& flag_inline_trees
|
||||
&& DECL_DECLARED_INLINE_P (d)))
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -10448,8 +10448,6 @@ reference_to_unused (tree * tp, int * walk_subtrees,
|
|||
if (DECL_P (*tp) && ! TREE_PUBLIC (*tp) && ! TREE_USED (*tp)
|
||||
&& ! TREE_ASM_WRITTEN (*tp))
|
||||
return *tp;
|
||||
else if (!flag_unit_at_a_time)
|
||||
return NULL_TREE;
|
||||
/* ??? The C++ FE emits debug information for using decls, so
|
||||
putting gcc_unreachable here falls over. See PR31899. For now
|
||||
be conservative. */
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2008-07-24 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* fortran/options.c (gfc_post_options): Remove flag_unline_trees code.
|
||||
|
||||
2008-07-24 Daniel Kraft <d@domob.eu>
|
||||
|
||||
PR fortran/33141
|
||||
|
|
|
@ -293,13 +293,9 @@ gfc_post_options (const char **pfilename)
|
|||
gfc_warning_now ("'-fd-lines-as-code' has no effect in free form");
|
||||
}
|
||||
|
||||
flag_inline_trees = 1;
|
||||
|
||||
/* Use tree inlining. */
|
||||
if (!flag_no_inline)
|
||||
flag_no_inline = 1;
|
||||
if (flag_inline_functions)
|
||||
flag_inline_trees = 2;
|
||||
|
||||
/* If -pedantic, warn about the use of GNU extensions. */
|
||||
if (pedantic && (gfc_option.allow_std & GFC_STD_GNU) != 0)
|
||||
|
|
118
gcc/ipa-inline.c
118
gcc/ipa-inline.c
|
@ -60,7 +60,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
|
||||
cgraph_decide_inlining implements heuristics taking whole callgraph
|
||||
into account, while cgraph_decide_inlining_incrementally considers
|
||||
only one function at a time and is used in non-unit-at-a-time mode.
|
||||
only one function at a time and is used by early inliner.
|
||||
|
||||
The inliner itself is split into several passes:
|
||||
|
||||
|
@ -82,15 +82,13 @@ along with GCC; see the file COPYING3. If not see
|
|||
to do inlining expanding code size it might result in unbounded growth of
|
||||
whole unit.
|
||||
|
||||
This is the main inlining pass in non-unit-at-a-time.
|
||||
|
||||
With unit-at-a-time the pass is run during conversion into SSA form.
|
||||
Only functions already converted into SSA form are inlined, so the
|
||||
conversion must happen in topological order on the callgraph (that is
|
||||
maintained by pass manager). The functions after inlining are early
|
||||
optimized so the early inliner sees unoptimized function itself, but
|
||||
all considered callees are already optimized allowing it to unfold
|
||||
abstraction penalty on C++ effectively and cheaply.
|
||||
The pass is run during conversion into SSA form. Only functions already
|
||||
converted into SSA form are inlined, so the conversion must happen in
|
||||
topological order on the callgraph (that is maintained by pass manager).
|
||||
The functions after inlining are early optimized so the early inliner sees
|
||||
unoptimized function itself, but all considered callees are already
|
||||
optimized allowing it to unfold abstraction penalty on C++ effectively and
|
||||
cheaply.
|
||||
|
||||
pass_ipa_early_inlining
|
||||
|
||||
|
@ -150,16 +148,11 @@ along with GCC; see the file COPYING3. If not see
|
|||
In SIZE mode, only functions that reduce function body size after inlining
|
||||
are inlined, this is used during early inlining.
|
||||
|
||||
In SPEED mode, all small functions are inlined. This might result in
|
||||
unbounded growth of compilation unit and is used only in non-unit-at-a-time
|
||||
mode.
|
||||
|
||||
in ALL mode, everything is inlined. This is used during flattening. */
|
||||
enum inlining_mode {
|
||||
INLINE_NONE = 0,
|
||||
INLINE_ALWAYS_INLINE,
|
||||
INLINE_SIZE,
|
||||
INLINE_SPEED,
|
||||
INLINE_ALL
|
||||
};
|
||||
static bool
|
||||
|
@ -211,8 +204,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, bool update_o
|
|||
In that case just go ahead and re-use it. */
|
||||
if (!e->callee->callers->next_caller
|
||||
&& !e->callee->needed
|
||||
&& !cgraph_new_nodes
|
||||
&& flag_unit_at_a_time)
|
||||
&& !cgraph_new_nodes)
|
||||
{
|
||||
gcc_assert (!e->callee->global.inlined_to);
|
||||
if (DECL_SAVED_TREE (e->callee->decl))
|
||||
|
@ -262,7 +254,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original)
|
|||
gcc_assert (e->inline_failed);
|
||||
e->inline_failed = NULL;
|
||||
|
||||
if (!e->callee->global.inlined && flag_unit_at_a_time)
|
||||
if (!e->callee->global.inlined)
|
||||
DECL_POSSIBLY_INLINED (e->callee->decl) = true;
|
||||
e->callee->global.inlined = true;
|
||||
|
||||
|
@ -1299,13 +1291,13 @@ try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth)
|
|||
if (e->inline_failed)
|
||||
cgraph_mark_inline (e);
|
||||
|
||||
/* In order to fully inline always_inline functions at -O0, we need to
|
||||
/* In order to fully inline always_inline functions, we need to
|
||||
recurse here, since the inlined functions might not be processed by
|
||||
incremental inlining at all yet.
|
||||
|
||||
Also flattening needs to be done recursively. */
|
||||
|
||||
if (!flag_unit_at_a_time || mode == INLINE_ALL || always_inline)
|
||||
if (mode == INLINE_ALL || always_inline)
|
||||
cgraph_decide_inlining_incrementally (e->callee, mode, depth + 1);
|
||||
callee->aux = (void *)(size_t) callee_mode;
|
||||
return true;
|
||||
|
@ -1495,20 +1487,11 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
|
|||
}
|
||||
if (cgraph_default_inline_p (e->callee, &failed_reason))
|
||||
inlined |= try_inline (e, mode, depth);
|
||||
else if (!flag_unit_at_a_time)
|
||||
e->inline_failed = failed_reason;
|
||||
}
|
||||
node->aux = (void *)(size_t) old_mode;
|
||||
return inlined;
|
||||
}
|
||||
|
||||
/* When inlining shall be performed. */
|
||||
static bool
|
||||
cgraph_gate_inlining (void)
|
||||
{
|
||||
return flag_inline_trees;
|
||||
}
|
||||
|
||||
/* Because inlining might remove no-longer reachable nodes, we need to
|
||||
keep the array visible to garbage collector to avoid reading collected
|
||||
out nodes. */
|
||||
|
@ -1526,9 +1509,7 @@ cgraph_early_inlining (void)
|
|||
|
||||
if (sorrycount || errorcount)
|
||||
return 0;
|
||||
if (cgraph_decide_inlining_incrementally (node,
|
||||
flag_unit_at_a_time || optimize_size
|
||||
? INLINE_SIZE : INLINE_SPEED, 0))
|
||||
if (cgraph_decide_inlining_incrementally (node, INLINE_SIZE, 0))
|
||||
{
|
||||
timevar_push (TV_INTEGRATION);
|
||||
todo = optimize_inline_calls (current_function_decl);
|
||||
|
@ -1541,7 +1522,7 @@ cgraph_early_inlining (void)
|
|||
static bool
|
||||
cgraph_gate_early_inlining (void)
|
||||
{
|
||||
return flag_inline_trees && flag_early_inlining;
|
||||
return flag_early_inlining;
|
||||
}
|
||||
|
||||
struct gimple_opt_pass pass_early_inline =
|
||||
|
@ -1567,7 +1548,7 @@ struct gimple_opt_pass pass_early_inline =
|
|||
static bool
|
||||
cgraph_gate_ipa_early_inlining (void)
|
||||
{
|
||||
return (flag_inline_trees && flag_early_inlining
|
||||
return (flag_early_inlining
|
||||
&& (flag_branch_probabilities || flag_test_coverage
|
||||
|| profile_arc_flag));
|
||||
}
|
||||
|
@ -1626,19 +1607,12 @@ compute_inline_parameters_for_current (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* When inlining shall be performed. */
|
||||
static bool
|
||||
gate_inline_passes (void)
|
||||
{
|
||||
return flag_inline_trees;
|
||||
}
|
||||
|
||||
struct gimple_opt_pass pass_inline_parameters =
|
||||
{
|
||||
{
|
||||
GIMPLE_PASS,
|
||||
NULL, /* name */
|
||||
gate_inline_passes, /* gate */
|
||||
NULL, /* gate */
|
||||
compute_inline_parameters_for_current,/* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
|
@ -1746,7 +1720,7 @@ struct ipa_opt_pass pass_ipa_inline =
|
|||
{
|
||||
IPA_PASS,
|
||||
"inline", /* name */
|
||||
cgraph_gate_inlining, /* gate */
|
||||
NULL, /* gate */
|
||||
cgraph_decide_inlining, /* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
|
@ -1769,62 +1743,4 @@ struct ipa_opt_pass pass_ipa_inline =
|
|||
};
|
||||
|
||||
|
||||
/* When inlining shall be performed. */
|
||||
static bool
|
||||
cgraph_gate_O0_always_inline (void)
|
||||
{
|
||||
return !flag_unit_at_a_time || !flag_inline_trees;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
cgraph_O0_always_inline (void)
|
||||
{
|
||||
struct cgraph_node *node = cgraph_node (current_function_decl);
|
||||
unsigned int todo = 0;
|
||||
bool inlined;
|
||||
|
||||
if (sorrycount || errorcount)
|
||||
return 0;
|
||||
inlined = cgraph_decide_inlining_incrementally (node, INLINE_SPEED, 0);
|
||||
/* We might need the body of this function so that we can expand
|
||||
it inline somewhere else. */
|
||||
if (cgraph_preserve_function_body_p (current_function_decl))
|
||||
save_inline_function_body (node);
|
||||
if (inlined || warn_inline)
|
||||
{
|
||||
timevar_push (TV_INTEGRATION);
|
||||
todo = optimize_inline_calls (current_function_decl);
|
||||
timevar_pop (TV_INTEGRATION);
|
||||
}
|
||||
/* In non-unit-at-a-time we must mark all referenced functions as needed. */
|
||||
if (!flag_unit_at_a_time)
|
||||
{
|
||||
struct cgraph_edge *e;
|
||||
for (e = node->callees; e; e = e->next_callee)
|
||||
if (e->callee->analyzed)
|
||||
cgraph_mark_needed_node (e->callee);
|
||||
}
|
||||
return todo | execute_fixup_cfg ();
|
||||
}
|
||||
|
||||
struct gimple_opt_pass pass_O0_always_inline =
|
||||
{
|
||||
{
|
||||
GIMPLE_PASS,
|
||||
"always_inline", /* name */
|
||||
cgraph_gate_O0_always_inline, /* gate */
|
||||
cgraph_O0_always_inline, /* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
0, /* static_pass_number */
|
||||
TV_INLINE_HEURISTICS, /* tv_id */
|
||||
0, /* properties_required */
|
||||
PROP_cfg, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_dump_func | TODO_verify_flow
|
||||
| TODO_verify_stmts /* todo_flags_finish */
|
||||
}
|
||||
};
|
||||
|
||||
#include "gt-ipa-inline.h"
|
||||
|
|
|
@ -1212,7 +1212,7 @@ ipa_unregister_cgraph_hooks (void)
|
|||
void
|
||||
free_all_ipa_structures_after_ipa_cp (void)
|
||||
{
|
||||
if (!flag_indirect_inlining || !flag_inline_trees)
|
||||
if (!flag_indirect_inlining)
|
||||
{
|
||||
ipa_free_all_edge_args ();
|
||||
ipa_free_all_node_params ();
|
||||
|
|
|
@ -771,7 +771,7 @@ static_execute (void)
|
|||
static bool
|
||||
gate_pure_const (void)
|
||||
{
|
||||
return (flag_unit_at_a_time != 0 && flag_ipa_pure_const
|
||||
return (flag_ipa_pure_const
|
||||
/* Don't bother doing anything if the program has errors. */
|
||||
&& !(errorcount || sorrycount));
|
||||
}
|
||||
|
|
|
@ -1314,7 +1314,7 @@ static_execute (void)
|
|||
static bool
|
||||
gate_reference (void)
|
||||
{
|
||||
return (flag_unit_at_a_time != 0 && flag_ipa_reference
|
||||
return (flag_ipa_reference
|
||||
/* Don't bother doing anything if the program has errors. */
|
||||
&& !(errorcount || sorrycount));
|
||||
}
|
||||
|
|
|
@ -2192,7 +2192,7 @@ type_escape_execute (void)
|
|||
static bool
|
||||
gate_type_escape_vars (void)
|
||||
{
|
||||
return (flag_unit_at_a_time != 0 && flag_ipa_type_escape
|
||||
return (flag_ipa_type_escape
|
||||
/* Don't bother doing anything if the program has errors. */
|
||||
&& !(errorcount || sorrycount));
|
||||
}
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2008-07-24 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* java/decl.c: Include cgraph.h
|
||||
(end_java_method): Remove non-unit-at-a-time code.
|
||||
(java_mark_decl_local): Likewise; sanity check that we don't touch
|
||||
finalized nodes.
|
||||
|
||||
2008-07-15 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* lang.c (java_init_options): Enable unit-at-a-time by default.
|
||||
|
|
|
@ -49,6 +49,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|||
#include "version.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "langhooks.h"
|
||||
#include "cgraph.h"
|
||||
|
||||
#if defined (DEBUG_JAVA_BINDING_LEVELS)
|
||||
extern void indent (void);
|
||||
|
@ -1797,14 +1798,6 @@ end_java_method (void)
|
|||
|
||||
finish_method (fndecl);
|
||||
|
||||
if (! flag_unit_at_a_time)
|
||||
{
|
||||
/* Nulling these fields when we no longer need them saves
|
||||
memory. */
|
||||
DECL_SAVED_TREE (fndecl) = NULL;
|
||||
DECL_STRUCT_FUNCTION (fndecl) = NULL;
|
||||
DECL_INITIAL (fndecl) = NULL_TREE;
|
||||
}
|
||||
current_function_decl = NULL_TREE;
|
||||
}
|
||||
|
||||
|
@ -1854,15 +1847,12 @@ java_mark_decl_local (tree decl)
|
|||
{
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
|
||||
/* If we've already constructed DECL_RTL, give encode_section_info
|
||||
a second chance, now that we've changed the flags. */
|
||||
/* ??? Ideally, we'd have flag_unit_at_a_time set, and not have done
|
||||
anything that would have referenced DECL_RTL so far. But at the
|
||||
moment we force flag_unit_at_a_time off due to excessive memory
|
||||
consumption when compiling large jar files. Which probably means
|
||||
that we need to re-order how we process jar files... */
|
||||
if (DECL_RTL_SET_P (decl))
|
||||
make_decl_rtl (decl);
|
||||
#ifdef ENABLE_CHECKING
|
||||
/* Double check that we didn't pass the function to the callgraph early. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
gcc_assert (!cgraph_node (decl)->local.finalized);
|
||||
#endif
|
||||
gcc_assert (!DECL_RTL_SET_P (decl));
|
||||
}
|
||||
|
||||
/* Given appropriate target support, G++ will emit hidden aliases for native
|
||||
|
|
|
@ -535,8 +535,6 @@ java_post_options (const char **pfilename)
|
|||
/* Use tree inlining. */
|
||||
if (!flag_no_inline)
|
||||
flag_no_inline = 1;
|
||||
if (flag_inline_functions)
|
||||
flag_inline_trees = 2;
|
||||
|
||||
/* An absolute requirement: if we're not using indirect dispatch, we
|
||||
must always verify everything. */
|
||||
|
|
19
gcc/opts.c
19
gcc/opts.c
|
@ -333,11 +333,6 @@ bool use_gnu_debug_info_extensions;
|
|||
/* The default visibility for all symbols (unless overridden) */
|
||||
enum symbol_visibility default_visibility = VISIBILITY_DEFAULT;
|
||||
|
||||
/* Disable unit-at-a-time for frontends that might be still broken in this
|
||||
respect. */
|
||||
|
||||
bool no_unit_at_a_time_default;
|
||||
|
||||
/* Global visibility options. */
|
||||
struct visibility_flags visibility_options;
|
||||
|
||||
|
@ -872,13 +867,11 @@ decode_options (unsigned int argc, const char **argv)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!flag_unit_at_a_time)
|
||||
{
|
||||
flag_section_anchors = 0;
|
||||
flag_toplevel_reorder = 0;
|
||||
flag_unit_at_a_time = 1;
|
||||
}
|
||||
if (!flag_toplevel_reorder)
|
||||
{
|
||||
|
@ -1109,16 +1102,6 @@ decode_options (unsigned int argc, const char **argv)
|
|||
if (flag_really_no_inline == 2)
|
||||
flag_really_no_inline = flag_no_inline;
|
||||
|
||||
/* Inlining of functions called just once will only work if we can look
|
||||
at the complete translation unit. */
|
||||
if (flag_inline_functions_called_once && !flag_unit_at_a_time)
|
||||
{
|
||||
flag_inline_functions_called_once = 0;
|
||||
warning (OPT_Wdisabled_optimization,
|
||||
"-funit-at-a-time is required for inlining of functions "
|
||||
"that are only called once");
|
||||
}
|
||||
|
||||
/* The optimization to partition hot and cold basic blocks into separate
|
||||
sections of the .o and executable files does not work (currently)
|
||||
with exception handling. This is because there is no support for
|
||||
|
|
|
@ -64,7 +64,6 @@ extern const struct cl_option cl_options[];
|
|||
extern const unsigned int cl_options_count;
|
||||
extern const char *const lang_names[];
|
||||
extern const unsigned int cl_lang_count;
|
||||
extern bool no_unit_at_a_time_default;
|
||||
|
||||
#define CL_PARAMS (1 << 18) /* Fake entry. Used to display --param info with --help. */
|
||||
#define CL_WARNING (1 << 19) /* Enables an (optional) warning message. */
|
||||
|
|
11
gcc/passes.c
11
gcc/passes.c
|
@ -180,7 +180,7 @@ rest_of_decl_compilation (tree decl,
|
|||
/* Don't output anything when a tentative file-scope definition
|
||||
is seen. But at end of compilation, do output code for them.
|
||||
|
||||
We do output all variables when unit-at-a-time is active and rely on
|
||||
We do output all variables and rely on
|
||||
callgraph code to defer them except for forward declarations
|
||||
(see gcc.c-torture/compile/920624-1.c) */
|
||||
if ((at_end
|
||||
|
@ -523,9 +523,7 @@ init_optimization_passes (void)
|
|||
NEXT_PASS (pass_inline_parameters);
|
||||
*p = NULL;
|
||||
|
||||
/* Interprocedural optimization passes.
|
||||
All these passes are ignored in -fno-unit-at-a-time
|
||||
except for subpasses of early_local_passes. */
|
||||
/* Interprocedural optimization passes. */
|
||||
p = &all_ipa_passes;
|
||||
NEXT_PASS (pass_ipa_function_and_variable_visibility);
|
||||
NEXT_PASS (pass_ipa_early_inline);
|
||||
|
@ -593,7 +591,6 @@ init_optimization_passes (void)
|
|||
/* These passes are run after IPA passes on every function that is being
|
||||
output to the assembler file. */
|
||||
p = &all_passes;
|
||||
NEXT_PASS (pass_O0_always_inline);
|
||||
NEXT_PASS (pass_all_optimizations);
|
||||
{
|
||||
struct opt_pass **p = &pass_all_optimizations.pass.sub;
|
||||
|
@ -1228,8 +1225,6 @@ execute_one_ipa_transform_pass (struct cgraph_node *node,
|
|||
pass_fini_dump_file (pass);
|
||||
|
||||
current_pass = NULL;
|
||||
/* Reset in_gimple_form to not break non-unit-at-a-time mode. */
|
||||
in_gimple_form = false;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1329,8 +1324,6 @@ execute_one_pass (struct opt_pass *pass)
|
|||
|| pass->type != RTL_PASS);
|
||||
|
||||
current_pass = NULL;
|
||||
/* Reset in_gimple_form to not break non-unit-at-a-time mode. */
|
||||
in_gimple_form = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2008-07-24 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* gcc.dg/winline-4.c: Remove.
|
||||
* gcc.dg/pch/valid-3.hs: Remove.
|
||||
* gcc.dg/pch/valid-3.c: Remove.
|
||||
* g++.old-deja/g++.brendan/crash52.C: Accept returning void warning
|
||||
* g++.old-deja/g++.jason/report.C: Likewise.
|
||||
* testsuite/g++.dg/warn/pr23075.C: We get returning void warning
|
||||
instead of control flow warning.
|
||||
|
||||
2008-07-24 Daniel Kraft <d@domob.eu>
|
||||
|
||||
PR fortran/33141
|
||||
|
|
|
@ -6,4 +6,4 @@ int
|
|||
foo (void)
|
||||
{
|
||||
return; // { dg-error "with no value" }
|
||||
} // { dg-bogus "control reaches end" }
|
||||
} // { dg-warning "no return statement" }
|
||||
|
|
|
@ -10,4 +10,4 @@ public:
|
|||
|
||||
A &f(A &a) {// { dg-error "" } new decl.*
|
||||
std::cout << "Blah\n";
|
||||
}
|
||||
} // { dg-error "no return statement" }
|
||||
|
|
|
@ -56,7 +56,7 @@ bar2 baz (X::Y y) // { dg-error "" } in this context
|
|||
bar2 wa [5];
|
||||
wa[0] = baz(f);
|
||||
undef2 (1); // { dg-error "" } implicit declaration
|
||||
}
|
||||
} // { dg-error "no return statement" }
|
||||
|
||||
int ninny ()
|
||||
{
|
||||
|
@ -71,4 +71,4 @@ int ninny ()
|
|||
int darg (char X::*p)
|
||||
{
|
||||
undef3 (1); // { dg-error "" } implicit declaration
|
||||
}
|
||||
} // { dg-error "no return statement" }
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
/* { dg-options "-I. -Winvalid-pch -fno-unit-at-a-time" } */
|
||||
|
||||
#include "valid-3.h"/* { dg-warning "settings for -funit-at-a-time do not match" } */
|
||||
/* { dg-error "No such file" "no such file" { target *-*-* } 3 } */
|
||||
/* { dg-error "they were invalid" "invalid files" { target *-*-* } 3 } */
|
||||
int x;
|
|
@ -1,3 +0,0 @@
|
|||
/* { dg-options "-I. -Winvalid-pch -funit-at-a-time" } */
|
||||
|
||||
extern int x;
|
|
@ -1,11 +0,0 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-Winline -O1 -fno-unit-at-a-time" } */
|
||||
|
||||
inline int q(void); /* { dg-warning "body not available" } */
|
||||
inline int t(void)
|
||||
{
|
||||
return q(); /* { dg-warning "called from here" } */
|
||||
}
|
||||
int q(void)
|
||||
{
|
||||
}
|
|
@ -1702,9 +1702,6 @@ process_options (void)
|
|||
if (flag_asynchronous_unwind_tables)
|
||||
flag_unwind_tables = 1;
|
||||
|
||||
if (!flag_unit_at_a_time)
|
||||
flag_section_anchors = 0;
|
||||
|
||||
if (flag_value_profile_transformations)
|
||||
flag_profile_values = 1;
|
||||
|
||||
|
|
|
@ -90,13 +90,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
|
||||
See the CALL_EXPR handling case in copy_body_r (). */
|
||||
|
||||
/* 0 if we should not perform inlining.
|
||||
1 if we should expand functions calls inline at the tree level.
|
||||
2 if we should consider *all* functions to be inline
|
||||
candidates. */
|
||||
|
||||
int flag_inline_trees = 0;
|
||||
|
||||
/* To Do:
|
||||
|
||||
o In order to make inlining-on-trees work, we pessimized
|
||||
|
@ -2100,24 +2093,6 @@ inlinable_function_p (tree fn)
|
|||
if (!DECL_SAVED_TREE (fn))
|
||||
return false;
|
||||
|
||||
/* If we're not inlining at all, then we cannot inline this function. */
|
||||
else if (!flag_inline_trees)
|
||||
inlinable = false;
|
||||
|
||||
/* Only try to inline functions if DECL_INLINE is set. This should be
|
||||
true for all functions declared `inline', and for all other functions
|
||||
as well with -finline-functions.
|
||||
|
||||
Don't think of disregarding DECL_INLINE when flag_inline_trees == 2;
|
||||
it's the front-end that must set DECL_INLINE in this case, because
|
||||
dwarf2out loses if a function that does not have DECL_INLINE set is
|
||||
inlined anyway. That is why we have both DECL_INLINE and
|
||||
DECL_DECLARED_INLINE_P. */
|
||||
/* FIXME: When flag_inline_trees dies, the check for flag_unit_at_a_time
|
||||
here should be redundant. */
|
||||
else if (!DECL_INLINE (fn) && !flag_unit_at_a_time)
|
||||
inlinable = false;
|
||||
|
||||
else if (inline_forbidden_p (fn))
|
||||
{
|
||||
/* See if we should warn about uninlinable functions. Previously,
|
||||
|
@ -2674,7 +2649,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
|
|||
where previous inlining turned indirect call into direct call by
|
||||
constant propagating arguments. In all other cases we hit a bug
|
||||
(incorrect node sharing is most common reason for missing edges. */
|
||||
gcc_assert (dest->needed || !flag_unit_at_a_time);
|
||||
gcc_assert (dest->needed);
|
||||
cgraph_create_edge (id->dst_node, dest, stmt,
|
||||
bb->count, CGRAPH_FREQ_BASE,
|
||||
bb->loop_depth)->inline_failed
|
||||
|
@ -2699,7 +2674,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
|
|||
|
||||
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))
|
||||
/* Avoid warnings during early inline pass. */
|
||||
&& (!flag_unit_at_a_time || cgraph_global_info_ready))
|
||||
&& cgraph_global_info_ready)
|
||||
{
|
||||
sorry ("inlining failed in call to %q+F: %s", fn, reason);
|
||||
sorry ("called from here");
|
||||
|
@ -2709,7 +2684,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
|
|||
&& strlen (reason)
|
||||
&& !lookup_attribute ("noinline", DECL_ATTRIBUTES (fn))
|
||||
/* Avoid warnings during early inline pass. */
|
||||
&& (!flag_unit_at_a_time || cgraph_global_info_ready))
|
||||
&& cgraph_global_info_ready)
|
||||
{
|
||||
warning (OPT_Winline, "inlining failed in call to %q+F: %s",
|
||||
fn, reason);
|
||||
|
|
|
@ -157,11 +157,4 @@ extern tree remap_type (tree type, copy_body_data *id);
|
|||
|
||||
extern HOST_WIDE_INT estimated_stack_frame_size (void);
|
||||
|
||||
/* 0 if we should not perform inlining.
|
||||
1 if we should expand functions calls inline at the tree level.
|
||||
2 if we should consider *all* functions to be inline
|
||||
candidates. */
|
||||
|
||||
extern int flag_inline_trees;
|
||||
|
||||
#endif /* GCC_TREE_INLINE_H */
|
||||
|
|
|
@ -115,7 +115,7 @@ execute_early_local_optimizations (void)
|
|||
cgraph state so newly inserted functions are also early optimized.
|
||||
However we execute early local optimizations for lately inserted
|
||||
functions, in that case don't reset cgraph state back to IPA_SSA. */
|
||||
if (flag_unit_at_a_time && cgraph_state < CGRAPH_STATE_IPA_SSA)
|
||||
if (cgraph_state < CGRAPH_STATE_IPA_SSA)
|
||||
cgraph_state = CGRAPH_STATE_IPA_SSA;
|
||||
return 0;
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ tree_rest_of_compilation (tree fndecl)
|
|||
|
||||
timevar_push (TV_EXPAND);
|
||||
|
||||
gcc_assert (!flag_unit_at_a_time || cgraph_global_info_ready);
|
||||
gcc_assert (cgraph_global_info_ready);
|
||||
|
||||
node = cgraph_node (fndecl);
|
||||
|
||||
|
@ -448,20 +448,17 @@ tree_rest_of_compilation (tree fndecl)
|
|||
}
|
||||
}
|
||||
|
||||
if (!flag_inline_trees)
|
||||
DECL_SAVED_TREE (fndecl) = NULL;
|
||||
if (DECL_STRUCT_FUNCTION (fndecl) == 0
|
||||
&& !cgraph_node (fndecl)->origin)
|
||||
{
|
||||
DECL_SAVED_TREE (fndecl) = NULL;
|
||||
if (DECL_STRUCT_FUNCTION (fndecl) == 0
|
||||
&& !cgraph_node (fndecl)->origin)
|
||||
{
|
||||
/* Stop pointing to the local nodes about to be freed.
|
||||
But DECL_INITIAL must remain nonzero so we know this
|
||||
was an actual function definition.
|
||||
For a nested function, this is done in c_pop_function_context.
|
||||
If rest_of_compilation set this to 0, leave it 0. */
|
||||
if (DECL_INITIAL (fndecl) != 0)
|
||||
DECL_INITIAL (fndecl) = error_mark_node;
|
||||
}
|
||||
/* Stop pointing to the local nodes about to be freed.
|
||||
But DECL_INITIAL must remain nonzero so we know this
|
||||
was an actual function definition.
|
||||
For a nested function, this is done in c_pop_function_context.
|
||||
If rest_of_compilation set this to 0, leave it 0. */
|
||||
if (DECL_INITIAL (fndecl) != 0)
|
||||
DECL_INITIAL (fndecl) = error_mark_node;
|
||||
}
|
||||
|
||||
input_location = saved_loc;
|
||||
|
|
|
@ -504,7 +504,6 @@ extern struct rtl_opt_pass pass_final;
|
|||
extern struct rtl_opt_pass pass_rtl_seqabstr;
|
||||
extern struct gimple_opt_pass pass_release_ssa_names;
|
||||
extern struct gimple_opt_pass pass_early_inline;
|
||||
extern struct gimple_opt_pass pass_O0_always_inline;
|
||||
extern struct gimple_opt_pass pass_inline_parameters;
|
||||
extern struct gimple_opt_pass pass_all_early_optimizations;
|
||||
extern struct gimple_opt_pass pass_update_address_taken;
|
||||
|
|
|
@ -311,11 +311,8 @@ tree_gen_ic_func_profiler (void)
|
|||
tree stmt1, stmt2;
|
||||
tree tree_uid, cur_func;
|
||||
|
||||
if (flag_unit_at_a_time)
|
||||
{
|
||||
if (!c_node->needed)
|
||||
return;
|
||||
}
|
||||
if (!c_node->needed)
|
||||
return;
|
||||
|
||||
tree_init_edge_profiler ();
|
||||
|
||||
|
|
|
@ -3714,17 +3714,7 @@ may_be_aliased (tree var)
|
|||
if (!TREE_STATIC (var))
|
||||
return false;
|
||||
|
||||
/* If we're in unit-at-a-time mode, then we must have seen all
|
||||
occurrences of address-of operators, and so we can trust
|
||||
TREE_ADDRESSABLE. Otherwise we can only be sure the variable
|
||||
isn't addressable if it's local to the current function. */
|
||||
if (flag_unit_at_a_time)
|
||||
return false;
|
||||
|
||||
if (decl_function_context (var) == current_function_decl)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The following is based on code in add_stmt_operand to ensure that the
|
||||
|
|
|
@ -5559,8 +5559,7 @@ delete_points_to_sets (void)
|
|||
static bool
|
||||
gate_ipa_pta (void)
|
||||
{
|
||||
return (flag_unit_at_a_time != 0
|
||||
&& flag_ipa_pta
|
||||
return (flag_ipa_pta
|
||||
/* Don't bother doing anything if the program has errors. */
|
||||
&& !(errorcount || sorrycount));
|
||||
}
|
||||
|
|
|
@ -2228,7 +2228,7 @@ contains_pointers_p (tree type)
|
|||
}
|
||||
}
|
||||
|
||||
/* In unit-at-a-time mode, we delay assemble_external processing until
|
||||
/* We delay assemble_external processing until
|
||||
the compilation unit is finalized. This is the best we can do for
|
||||
right now (i.e. stage 3 of GCC 4.0) - the right thing is to delay
|
||||
it all the way to final. See PR 17982 for further discussion. */
|
||||
|
@ -5380,7 +5380,7 @@ assemble_alias (tree decl, tree target)
|
|||
|
||||
/* If the target has already been emitted, we don't have to queue the
|
||||
alias. This saves a tad of memory. */
|
||||
if (!flag_unit_at_a_time || cgraph_global_info_ready)
|
||||
if (cgraph_global_info_ready)
|
||||
target_decl = find_decl_and_mark_needed (decl, target);
|
||||
else
|
||||
target_decl= NULL;
|
||||
|
|
|
@ -61,7 +61,7 @@ struct varpool_node *varpool_nodes;
|
|||
maintained in forward order. GTY is needed to make it friendly to
|
||||
PCH.
|
||||
|
||||
During unit-at-a-time compilation we construct the queue of needed variables
|
||||
During compilation we construct the queue of needed variables
|
||||
twice: first time it is during cgraph construction, second time it is at the
|
||||
end of compilation in VARPOOL_REMOVE_UNREFERENCED_DECLS so we can avoid
|
||||
optimized out variables being output.
|
||||
|
@ -214,17 +214,13 @@ varpool_reset_queue (void)
|
|||
|
||||
/* Determine if variable DECL is needed. That is, visible to something
|
||||
either outside this translation unit, something magic in the system
|
||||
configury, or (if not doing unit-at-a-time) to something we haven't
|
||||
seen yet. */
|
||||
configury */
|
||||
bool
|
||||
decide_is_variable_needed (struct varpool_node *node, tree decl)
|
||||
{
|
||||
/* If the user told us it is used, then it must be so. */
|
||||
if (node->externally_visible || node->force_output)
|
||||
return true;
|
||||
if (!flag_unit_at_a_time
|
||||
&& lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
|
||||
return true;
|
||||
|
||||
/* ??? If the assembler name is set by hand, it is possible to assemble
|
||||
the name later after finalizing the function and the fact is noticed
|
||||
|
@ -257,7 +253,7 @@ decide_is_variable_needed (struct varpool_node *node, tree decl)
|
|||
|
||||
/* When not reordering top level variables, we have to assume that
|
||||
we are going to keep everything. */
|
||||
if (flag_unit_at_a_time && flag_toplevel_reorder)
|
||||
if (flag_toplevel_reorder)
|
||||
return false;
|
||||
|
||||
/* We want to emit COMDAT variables only when absolutely necessary. */
|
||||
|
@ -280,7 +276,7 @@ varpool_finalize_decl (tree decl)
|
|||
if this function has already run. */
|
||||
if (node->finalized)
|
||||
{
|
||||
if (cgraph_global_info_ready || (!flag_unit_at_a_time && !flag_openmp))
|
||||
if (cgraph_global_info_ready)
|
||||
varpool_assemble_pending_decls ();
|
||||
return;
|
||||
}
|
||||
|
@ -295,7 +291,7 @@ varpool_finalize_decl (tree decl)
|
|||
there. */
|
||||
else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
|
||||
varpool_mark_needed_node (node);
|
||||
if (cgraph_global_info_ready || (!flag_unit_at_a_time && !flag_openmp))
|
||||
if (cgraph_global_info_ready)
|
||||
varpool_assemble_pending_decls ();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue