diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c020d438e6f..f07c715c562 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +1999-11-27 Mark Mitchell + + * decl2.c (finish_file): Call expand_body for inline functions + that will be written out but that do not yet have RTL. + * semantics.c (expand_body): Do not generate RTL For inline + functions that do not yet need to be written out. + 1999-11-25 Mark Mitchell * Make-lang.in (CXX_SRCS): Add optimize.c. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 7759b0a0e3f..23917cd7391 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3531,6 +3531,36 @@ finish_file () && DECL_INITIAL (decl) && (DECL_NEEDED_P (decl) || !DECL_COMDAT (decl))) DECL_EXTERNAL (decl) = 0; + + /* If we're going to need to write this function out, and + there's already a body for it, create RTL for it now. + (There might be no body if this is a method we haven't + gotten around to synthesizing yet.) */ + if (!DECL_EXTERNAL (decl) + && (DECL_NEEDED_P (decl) || !DECL_COMDAT (decl)) + && DECL_SAVED_TREE (decl) + && !DECL_SAVED_INSNS (decl) + && !TREE_ASM_WRITTEN (decl)) + { + int saved_not_really_extern; + + /* When we call finish_function in expand_body, it will + try to reset DECL_NOT_REALLY_EXTERN so we save and + restore it here. */ + saved_not_really = DECL_NOT_REALLY_EXTERN (decl); + /* Generate RTL for this function now that we know we + need it. */ + expand_body (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 + function has been written out so that we don't try to + expand it again. */ + if (flag_syntax_only) + TREE_ASM_WRITTEN (decl) = 1; + reconsider = 1; + } } if (saved_inlines_used diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 2d70cb9044e..fa69540ca3a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2535,6 +2535,39 @@ expand_body (fn) 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 we can't inline trees. */ + flag_inline_trees + /* Or if it's not an inline function. */ + && DECL_INLINE (fn) + /* Or if we have to keep all inline functions anyhow. */ + && !flag_keep_inline_functions + /* Or if we actually have a reference to the function. */ + && !DECL_NEEDED_P (fn) + /* Or if we're at the end-of-file, and this function is not + DECL_COMDAT. */ + && (!at_eof || DECL_COMDAT (fn)) + /* Or if this is a nested function. */ + && !hack_decl_function_context (fn)) + { + /* Give the function RTL now so that we can assign it to a + function pointer, etc. */ + make_function_rtl (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. */ + mark_inline_for_output (fn); + return; + } + /* Optimize the body of the function before expanding it. */ optimize_function (fn);