Commit 8cd2462c by Jan Hubicka Committed by Jan Hubicka

decl2.c (defer_fn): Set DECL_DEFER_OUTPUT.

	* decl2.c (defer_fn): Set DECL_DEFER_OUTPUT.
	(finish-file): Do not process function with DECL_DEFER_OUTPUT clear;
	clear DECL_DEFER_OUTPUT once function is processed; avoid flags
	massaging.

	* cp-tree.h (DECL_NEEDED_P): Support unit-at-a-time
	(expand_or_defer_fn): Declare.
	(lower_function): Declare.
	* decl.c (start_cleanup_fn): Use expand_or_defer_fn.
	* decl2.c: Include cgraph.h and varpool.h
	(maybe_emit_vtables):  Make explicit instantations as needed.
	(mark_member_pointers, lower_function): New functions.
	(finish_file): Do unit-at-a-time.
	* method.c (synthesize_method): Use expand_or_defer_fn.
	* optimize.c (maybe_clone_body): Use expand_or_defer_fn.
	* parser.c (cp_parser_function_definition_after_decl): Use
	expand_or_defer_fn.
	* pt.c (instantiate_decl): Likewise.
	* semantics.c: Include cgraph.h
	(expand_or_defer_fn): Break out from ...
	(expand_body): ... here; deal with unit-at-a-time.
	* cp-lang.c (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION,
	LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Define.

From-SVN: r68801
parent 093354e0
Wed Jul 2 00:36:48 CEST 2003 Jan Hubicka <jh@suse.cz>
* decl2.c (defer_fn): Set DECL_DEFER_OUTPUT.
(finish-file): Do not process function with DECL_DEFER_OUTPUT clear;
clear DECL_DEFER_OUTPUT once function is processed; avoid flags
massaging.
* cp-tree.h (DECL_NEEDED_P): Support unit-at-a-time
(expand_or_defer_fn): Declare.
(lower_function): Declare.
* decl.c (start_cleanup_fn): Use expand_or_defer_fn.
* decl2.c: Include cgraph.h and varpool.h
(maybe_emit_vtables): Make explicit instantations as needed.
(mark_member_pointers, lower_function): New functions.
(finish_file): Do unit-at-a-time.
* method.c (synthesize_method): Use expand_or_defer_fn.
* optimize.c (maybe_clone_body): Use expand_or_defer_fn.
* parser.c (cp_parser_function_definition_after_decl): Use
expand_or_defer_fn.
* pt.c (instantiate_decl): Likewise.
* semantics.c: Include cgraph.h
(expand_or_defer_fn): Break out from ...
(expand_body): ... here; deal with unit-at-a-time.
* cp-lang.c (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION,
LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Define.
2003-07-01 Mark Mitchell <mark@codesourcery.com> 2003-07-01 Mark Mitchell <mark@codesourcery.com>
* call.c (resolve_scoped_fn_name): Return error_mark_node for * call.c (resolve_scoped_fn_name): Return error_mark_node for
......
...@@ -240,7 +240,7 @@ cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h stack.h \ ...@@ -240,7 +240,7 @@ cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h stack.h \
cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \ cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \
debug.h gt-cp-decl.h gtype-cp.h timevar.h debug.h gt-cp-decl.h gtype-cp.h timevar.h
cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \ cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \
output.h except.h toplev.h $(RTL_H) c-common.h gt-cp-decl2.h output.h except.h toplev.h $(RTL_H) c-common.h gt-cp-decl2.h cgraph.h
cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h $(TM_P_H) \ cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h $(TM_P_H) \
diagnostic.h diagnostic.h
cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \ cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
...@@ -271,7 +271,7 @@ cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h diagnostic.h \ ...@@ -271,7 +271,7 @@ cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h diagnostic.h \
gt-cp-repo.h gt-cp-repo.h
cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h \ cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h \
flags.h debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \ flags.h debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
tree-inline.h tree-inline.h cgraph.h
cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h
cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \ cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \
input.h $(PARAMS_H) debug.h tree-inline.h input.h $(PARAMS_H) debug.h tree-inline.h
......
...@@ -2749,7 +2749,7 @@ build_user_type_conversion (tree totype, tree expr, int flags) ...@@ -2749,7 +2749,7 @@ build_user_type_conversion (tree totype, tree expr, int flags)
tree tree
resolve_scoped_fn_name (tree scope, tree name) resolve_scoped_fn_name (tree scope, tree name)
{ {
tree fn; tree fn = NULL_TREE;
tree template_args = NULL_TREE; tree template_args = NULL_TREE;
bool is_template_id = TREE_CODE (name) == TEMPLATE_ID_EXPR; bool is_template_id = TREE_CODE (name) == TEMPLATE_ID_EXPR;
......
...@@ -150,6 +150,11 @@ static bool cp_var_mod_type_p (tree); ...@@ -150,6 +150,11 @@ static bool cp_var_mod_type_p (tree);
#undef LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE #undef LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE
#define LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE prepare_assemble_variable #define LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE prepare_assemble_variable
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION expand_body
#undef LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION
#define LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION lower_function
#undef LANG_HOOKS_MAKE_TYPE #undef LANG_HOOKS_MAKE_TYPE
#define LANG_HOOKS_MAKE_TYPE cxx_make_type #define LANG_HOOKS_MAKE_TYPE cxx_make_type
#undef LANG_HOOKS_TYPE_FOR_MODE #undef LANG_HOOKS_TYPE_FOR_MODE
......
...@@ -1746,7 +1746,7 @@ struct lang_decl GTY(()) ...@@ -1746,7 +1746,7 @@ struct lang_decl GTY(())
((at_eof && TREE_PUBLIC (DECL) && !DECL_COMDAT (DECL)) \ ((at_eof && TREE_PUBLIC (DECL) && !DECL_COMDAT (DECL)) \
|| (DECL_ASSEMBLER_NAME_SET_P (DECL) \ || (DECL_ASSEMBLER_NAME_SET_P (DECL) \
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL))) \ && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL))) \
|| (flag_syntax_only && TREE_USED (DECL))) || (((flag_syntax_only || flag_unit_at_a_time) && TREE_USED (DECL))))
/* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the /* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
declaration. Some entities (like a member function in a local declaration. Some entities (like a member function in a local
...@@ -3800,6 +3800,7 @@ extern tree get_guard (tree); ...@@ -3800,6 +3800,7 @@ extern tree get_guard (tree);
extern tree get_guard_cond (tree); extern tree get_guard_cond (tree);
extern tree set_guard (tree); extern tree set_guard (tree);
extern void prepare_assemble_variable (tree); extern void prepare_assemble_variable (tree);
extern void lower_function (tree);
extern void cp_error_at (const char *msgid, ...); extern void cp_error_at (const char *msgid, ...);
extern void cp_warning_at (const char *msgid, ...); extern void cp_warning_at (const char *msgid, ...);
...@@ -4151,6 +4152,7 @@ extern void clear_out_block (void); ...@@ -4151,6 +4152,7 @@ extern void clear_out_block (void);
extern tree begin_global_stmt_expr (void); extern tree begin_global_stmt_expr (void);
extern tree finish_global_stmt_expr (tree); extern tree finish_global_stmt_expr (tree);
extern tree check_template_template_default_arg (tree); extern tree check_template_template_default_arg (tree);
extern void expand_or_defer_fn (tree);
/* in tree.c */ /* in tree.c */
extern void lang_check_failed (const char *, int, extern void lang_check_failed (const char *, int,
......
...@@ -8446,7 +8446,7 @@ start_cleanup_fn (void) ...@@ -8446,7 +8446,7 @@ start_cleanup_fn (void)
static void static void
end_cleanup_fn (void) end_cleanup_fn (void)
{ {
expand_body (finish_function (0)); expand_or_defer_fn (finish_function (0));
pop_from_top_level (); pop_from_top_level ();
} }
......
...@@ -46,6 +46,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -46,6 +46,8 @@ Boston, MA 02111-1307, USA. */
#include "cpplib.h" #include "cpplib.h"
#include "target.h" #include "target.h"
#include "c-common.h" #include "c-common.h"
#include "cgraph.h"
#include "tree-inline.h"
extern cpp_reader *parse_in; extern cpp_reader *parse_in;
/* This structure contains information about the initializations /* This structure contains information about the initializations
...@@ -1187,6 +1189,7 @@ defer_fn (tree fn) ...@@ -1187,6 +1189,7 @@ defer_fn (tree fn)
if (DECL_DEFERRED_FN (fn)) if (DECL_DEFERRED_FN (fn))
return; return;
DECL_DEFERRED_FN (fn) = 1; DECL_DEFERRED_FN (fn) = 1;
DECL_DEFER_OUTPUT (fn) = 1;
if (!deferred_fns) if (!deferred_fns)
VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns"); VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
...@@ -1671,6 +1674,11 @@ maybe_emit_vtables (tree ctype) ...@@ -1671,6 +1674,11 @@ maybe_emit_vtables (tree ctype)
/* Write it out. */ /* Write it out. */
import_export_vtable (vtbl, ctype, 1); import_export_vtable (vtbl, ctype, 1);
mark_vtable_entries (vtbl); mark_vtable_entries (vtbl);
/* If we know that DECL is needed, mark it as such for the varpool. */
if (CLASSTYPE_EXPLICIT_INSTANTIATION (ctype))
cgraph_varpool_mark_needed_node (cgraph_varpool_node (vtbl));
if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0) if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
store_init_value (vtbl, DECL_INITIAL (vtbl)); store_init_value (vtbl, DECL_INITIAL (vtbl));
...@@ -2010,7 +2018,7 @@ finish_objects (int method_type, int initp, tree body) ...@@ -2010,7 +2018,7 @@ finish_objects (int method_type, int initp, tree body)
/* Finish up. */ /* Finish up. */
finish_compound_stmt (/*has_no_scope=*/0, body); finish_compound_stmt (/*has_no_scope=*/0, body);
fn = finish_function (0); fn = finish_function (0);
expand_body (fn); expand_or_defer_fn (fn);
/* When only doing semantic analysis, and no RTL generation, we /* When only doing semantic analysis, and no RTL generation, we
can't call functions that directly emit assembly code; there is can't call functions that directly emit assembly code; there is
...@@ -2163,7 +2171,7 @@ finish_static_storage_duration_function (tree body) ...@@ -2163,7 +2171,7 @@ finish_static_storage_duration_function (tree body)
{ {
/* Close out the function. */ /* Close out the function. */
finish_compound_stmt (/*has_no_scope=*/0, body); finish_compound_stmt (/*has_no_scope=*/0, body);
expand_body (finish_function (0)); expand_or_defer_fn (finish_function (0));
} }
/* Return the information about the indicated PRIORITY level. If no /* Return the information about the indicated PRIORITY level. If no
...@@ -2550,6 +2558,26 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data) ...@@ -2550,6 +2558,26 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
return 0; return 0;
} }
/* Callgraph code does not understand the member pointers. Mark the methods
referenced as used. */
static tree
mark_member_pointers (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED)
{
if (TREE_CODE (*tp) == PTRMEM_CST)
cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (*tp)), 1);
return 0;
}
/* Called via LANGHOOK_CALLGRAPH_LOWER_FUNCTION. It is supposed to lower
frontend specific constructs that would otherwise confuse the middle end. */
void
lower_function (tree fn)
{
walk_tree_without_duplicates (&DECL_SAVED_TREE (fn), mark_member_pointers,
NULL);
}
/* This routine is called from the last rule in yyparse (). /* This routine is called from the last rule in yyparse ().
Its job is to create all the code needed to initialize and Its job is to create all the code needed to initialize and
destroy the global aggregates. We do the destruction destroy the global aggregates. We do the destruction
...@@ -2787,20 +2815,16 @@ finish_file () ...@@ -2787,20 +2815,16 @@ finish_file ()
if (!DECL_EXTERNAL (decl) if (!DECL_EXTERNAL (decl)
&& DECL_NEEDED_P (decl) && DECL_NEEDED_P (decl)
&& DECL_SAVED_TREE (decl) && DECL_SAVED_TREE (decl)
&& !TREE_ASM_WRITTEN (decl)) && !TREE_ASM_WRITTEN (decl)
&& (!flag_unit_at_a_time
|| !cgraph_node (decl)->local.finalized))
{ {
int saved_not_really_extern; /* We will output the function; no longer consider it in this
loop. */
/* When we call finish_function in expand_body, it will DECL_DEFER_OUTPUT (decl) = 0;
try to reset DECL_NOT_REALLY_EXTERN so we save and
restore it here. */
saved_not_really_extern = DECL_NOT_REALLY_EXTERN (decl);
/* Generate RTL for this function now that we know we /* Generate RTL for this function now that we know we
need it. */ need it. */
expand_body (decl); expand_or_defer_fn (decl);
/* Undo the damage done by finish_function. */
DECL_EXTERNAL (decl) = 0;
DECL_NOT_REALLY_EXTERN (decl) = saved_not_really_extern;
/* If we're compiling -fsyntax-only pretend that this /* If we're compiling -fsyntax-only pretend that this
function has been written out so that we don't try to function has been written out so that we don't try to
expand it again. */ expand it again. */
...@@ -2810,10 +2834,6 @@ finish_file () ...@@ -2810,10 +2834,6 @@ finish_file ()
} }
} }
if (deferred_fns_used
&& wrapup_global_declarations (&VARRAY_TREE (deferred_fns, 0),
deferred_fns_used))
reconsider = true;
if (walk_namespaces (wrapup_globals_for_namespace, /*data=*/0)) if (walk_namespaces (wrapup_globals_for_namespace, /*data=*/0))
reconsider = true; reconsider = true;
...@@ -2883,6 +2903,12 @@ finish_file () ...@@ -2883,6 +2903,12 @@ finish_file ()
linkage now. */ linkage now. */
pop_lang_context (); pop_lang_context ();
if (flag_unit_at_a_time)
{
cgraph_finalize_compilation_unit ();
cgraph_optimize ();
}
/* Now, issue warnings about static, but not defined, functions, /* Now, issue warnings about static, but not defined, functions,
etc., and emit debugging information. */ etc., and emit debugging information. */
walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider); walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider);
......
...@@ -581,7 +581,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -581,7 +581,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
/* Re-enable access control. */ /* Re-enable access control. */
pop_deferring_access_checks (); pop_deferring_access_checks ();
expand_body (finish_function (0)); expand_or_defer_fn (finish_function (0));
} }
pop_from_top_level (); pop_from_top_level ();
...@@ -862,7 +862,7 @@ synthesize_method (tree fndecl) ...@@ -862,7 +862,7 @@ synthesize_method (tree fndecl)
} }
finish_function_body (stmt); finish_function_body (stmt);
expand_body (finish_function (0)); expand_or_defer_fn (finish_function (0));
extract_interface_info (); extract_interface_info ();
if (! context) if (! context)
......
...@@ -265,7 +265,7 @@ maybe_clone_body (tree fn) ...@@ -265,7 +265,7 @@ maybe_clone_body (tree fn)
/* Now, expand this function into RTL, if appropriate. */ /* Now, expand this function into RTL, if appropriate. */
finish_function (0); finish_function (0);
BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn); BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
expand_body (clone); expand_or_defer_fn (clone);
pop_from_top_level (); pop_from_top_level ();
} }
......
...@@ -13855,7 +13855,7 @@ cp_parser_function_definition_after_declarator (cp_parser* parser, ...@@ -13855,7 +13855,7 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
fn = finish_function ((ctor_initializer_p ? 1 : 0) | fn = finish_function ((ctor_initializer_p ? 1 : 0) |
(inline_p ? 2 : 0)); (inline_p ? 2 : 0));
/* Generate code for it, if necessary. */ /* Generate code for it, if necessary. */
expand_body (fn); expand_or_defer_fn (fn);
/* Restore the saved values. */ /* Restore the saved values. */
parser->in_unbraced_linkage_specification_p parser->in_unbraced_linkage_specification_p
= saved_in_unbraced_linkage_specification_p; = saved_in_unbraced_linkage_specification_p;
......
...@@ -10942,7 +10942,7 @@ instantiate_decl (tree d, int defer_ok) ...@@ -10942,7 +10942,7 @@ instantiate_decl (tree d, int defer_ok)
/* Finish the function. */ /* Finish the function. */
d = finish_function (0); d = finish_function (0);
expand_body (d); expand_or_defer_fn (d);
} }
/* We're not deferring instantiation any more. */ /* We're not deferring instantiation any more. */
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "output.h" #include "output.h"
#include "timevar.h" #include "timevar.h"
#include "debug.h" #include "debug.h"
#include "cgraph.h"
/* There routines provide a modular interface to perform many parsing /* There routines provide a modular interface to perform many parsing
operations. They may therefore be used during actual parsing, or operations. They may therefore be used during actual parsing, or
...@@ -2279,69 +2280,9 @@ expand_body (tree fn) ...@@ -2279,69 +2280,9 @@ expand_body (tree fn)
{ {
location_t saved_loc; location_t saved_loc;
tree saved_function; tree saved_function;
/* When the parser calls us after finishing the body of a template if (flag_unit_at_a_time && !cgraph_global_info_ready)
function, we don't really want to expand the body. When we're abort ();
processing an in-class definition of an inline function,
PROCESSING_TEMPLATE_DECL will no longer be set here, so we have
to look at the function itself. */
if (processing_template_decl
|| (DECL_LANG_SPECIFIC (fn)
&& DECL_TEMPLATE_INFO (fn)
&& uses_template_parms (DECL_TI_ARGS (fn))))
{
/* Normally, collection only occurs in rest_of_compilation. So,
if we don't collect here, we never collect junk generated
during the processing of templates until we hit a
non-template function. */
ggc_collect ();
return;
}
/* Replace AGGR_INIT_EXPRs with appropriate CALL_EXPRs. */
walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
simplify_aggr_init_exprs_r,
NULL);
/* If this is a constructor or destructor body, we have to clone
it. */
if (maybe_clone_body (fn))
{
/* We don't want to process FN again, so pretend we've written
it out, even though we haven't. */
TREE_ASM_WRITTEN (fn) = 1;
return;
}
/* There's no reason to do any of the work here if we're only doing
semantic analysis; this code just generates RTL. */
if (flag_syntax_only)
return;
/* If possible, avoid generating RTL for this function. Instead,
just record it as an inline function, and wait until end-of-file
to decide whether to write it out or not. */
if (/* We have to generate RTL if it's not an inline function. */
(DECL_INLINE (fn) || DECL_COMDAT (fn))
/* Or if we have to emit code for inline functions anyhow. */
&& !flag_keep_inline_functions
/* Or if we actually have a reference to the function. */
&& !DECL_NEEDED_P (fn))
{
/* Set DECL_EXTERNAL so that assemble_external will be called as
necessary. We'll clear it again in finish_file. */
if (!DECL_EXTERNAL (fn))
{
DECL_NOT_REALLY_EXTERN (fn) = 1;
DECL_EXTERNAL (fn) = 1;
}
/* Remember this function. In finish_file we'll decide if
we actually need to write this function out. */
defer_fn (fn);
/* Let the back-end know that this function exists. */
(*debug_hooks->deferred_inline_function) (fn);
return;
}
/* Compute the appropriate object-file linkage for inline /* Compute the appropriate object-file linkage for inline
functions. */ functions. */
...@@ -2413,6 +2354,108 @@ expand_body (tree fn) ...@@ -2413,6 +2354,108 @@ expand_body (tree fn)
emit_associated_thunks (fn); emit_associated_thunks (fn);
} }
/* Generate RTL for FN. */
void
expand_or_defer_fn (fn)
tree fn;
{
/* When the parser calls us after finishing the body of a template
function, we don't really want to expand the body. When we're
processing an in-class definition of an inline function,
PROCESSING_TEMPLATE_DECL will no longer be set here, so we have
to look at the function itself. */
if (processing_template_decl
|| (DECL_LANG_SPECIFIC (fn)
&& DECL_TEMPLATE_INFO (fn)
&& uses_template_parms (DECL_TI_ARGS (fn))))
{
/* Normally, collection only occurs in rest_of_compilation. So,
if we don't collect here, we never collect junk generated
during the processing of templates until we hit a
non-template function. */
ggc_collect ();
return;
}
/* Replace AGGR_INIT_EXPRs with appropriate CALL_EXPRs. */
walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
simplify_aggr_init_exprs_r,
NULL);
/* If this is a constructor or destructor body, we have to clone
it. */
if (maybe_clone_body (fn))
{
/* We don't want to process FN again, so pretend we've written
it out, even though we haven't. */
TREE_ASM_WRITTEN (fn) = 1;
return;
}
/* There's no reason to do any of the work here if we're only doing
semantic analysis; this code just generates RTL. */
if (flag_syntax_only)
return;
if (flag_unit_at_a_time && cgraph_global_info_ready)
abort ();
if (flag_unit_at_a_time && !cgraph_global_info_ready)
{
if (at_eof)
{
/* Compute the appropriate object-file linkage for inline
functions. */
if (DECL_DECLARED_INLINE_P (fn))
import_export_decl (fn);
cgraph_finalize_function (fn, DECL_SAVED_TREE (fn));
}
else
{
if (!DECL_EXTERNAL (fn))
{
DECL_NOT_REALLY_EXTERN (fn) = 1;
DECL_EXTERNAL (fn) = 1;
}
/* Remember this function. In finish_file we'll decide if
we actually need to write this function out. */
defer_fn (fn);
/* Let the back-end know that this function exists. */
(*debug_hooks->deferred_inline_function) (fn);
}
return;
}
/* If possible, avoid generating RTL for this function. Instead,
just record it as an inline function, and wait until end-of-file
to decide whether to write it out or not. */
if (/* We have to generate RTL if it's not an inline function. */
(DECL_INLINE (fn) || DECL_COMDAT (fn))
/* Or if we have to emit code for inline functions anyhow. */
&& !flag_keep_inline_functions
/* Or if we actually have a reference to the function. */
&& !DECL_NEEDED_P (fn))
{
/* Set DECL_EXTERNAL so that assemble_external will be called as
necessary. We'll clear it again in finish_file. */
if (!DECL_EXTERNAL (fn))
{
DECL_NOT_REALLY_EXTERN (fn) = 1;
DECL_EXTERNAL (fn) = 1;
}
/* Remember this function. In finish_file we'll decide if
we actually need to write this function out. */
defer_fn (fn);
/* Let the back-end know that this function exists. */
(*debug_hooks->deferred_inline_function) (fn);
return;
}
expand_body (fn);
}
/* Helper function for walk_tree, used by finish_function to override all /* Helper function for walk_tree, used by finish_function to override all
the RETURN_STMTs and pertinent CLEANUP_STMTs for the named return the RETURN_STMTs and pertinent CLEANUP_STMTs for the named return
value optimization. */ value optimization. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment