This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [LTO merge][14/15] cgraph/gimple/ipa changes
On Tue, 29 Sep 2009, Richard Guenther wrote:
> On Tue, 29 Sep 2009, Jan Hubicka wrote:
>
> > > On Tue, Sep 29, 2009 at 9:24 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
> > > >> + ? ? ?/* Note that it is not strictly necessary to schedule an early
> > > >> + ? ? ?inline pass here. ?However, some test cases (e.g.,
> > > >> + ? ? ?g++.dg/other/p334435.C g++.dg/other/i386-1.C) expect extern
> > > >> + ? ? ?inline functions to be inlined even at -O0. ?This does not
> > > >> + ? ? ?happen during the first early inline pass. ?*/
> > > >
> > > > The planned fixes for extern inline stuff didn't happen, I guess?
> > >
> > > Right. I think what should happen is that the early inlining
> > > phase from running cc1 should do all always_inline inlines
> > > (thus the IPA inliner never should see not inlined always_inline
> > > functions), and after that we'll simply ignore always_inline
> > > (in particular always_inline doesn't count cross TUs but is strictly
> > > local to a single TU).
> >
> > Early inlining works in topological order. In the case of cyclic
> > cgraphs it can't always pick all alternatives (and even if you schedule
> > two oftem)
> >
> > With current handling of extern inline stuff we are losing optimization
> > oppurtunities here. Early inliner is quite conservative in addition to
> > not being handle cycles well, so now static inline is getting handled
> > more aggressively than extern inline. We really need proper
> > representation of extern inline behaviour)
> > >
> > > Somehow always-inline "opportunities" leak to the IPA inliner
> > > even without LTO.
> >
> > I wonder about cross-TU always-inline behaviour. Is it really something
> > we need to disable? Similarly with flatten.
>
> always-inline is a correctness thing - I'd rather not sorry() because
> during LTO the inlining fails. All always-inline required inlines
> should have been resolved per TU.
That is, like the following patch illustrates (but of course does not
implement properly because of the profile thing) -- this is a very
simple IPA inliner that inlines all always_inline edges. It should
suffice to run this one at -O0 and after it has run we should error
for all remaining always_inline edges (and thus we should be able
to remove all always_inline bodies at that point). We also should
warn about taking the address of always_inline functions - we cannot
guarantee to discover all indirect calls to such functions.
The pass in a very simple way deals with always_inline cycles - it
just inlines the calls once and then would sorry () because of
the remaining ones.
Comments?
Thanks,
Richard.
Index: ipa-inline.c
===================================================================
--- ipa-inline.c (revision 152323)
+++ ipa-inline.c (working copy)
@@ -1626,13 +1626,43 @@ struct gimple_opt_pass pass_early_inline
}
};
+/* Perform inlining of always_inline functions. */
+
+static unsigned int
+cgraph_ipa_early_inlining (void)
+{
+ struct cgraph_node *node;
+ struct cgraph_edge *edge;
+
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ if (!node->local.disregard_inline_limits)
+ continue;
+
+ for (edge = node->callers; edge; edge = edge->next_caller)
+ {
+ push_cfun (DECL_STRUCT_FUNCTION (edge->caller->decl));
+ current_function_decl = edge->caller->decl;
+ cgraph_mark_inline_edge (edge, false, NULL);
+ optimize_inline_calls (current_function_decl);
+#if 0
+ /* This needs plumbing similar to optimize_inline_calls. */
+ if (!expand_call_inline (edge->call_stmt))
+ /* FIXME error out */;
+#endif
+ current_function_decl = NULL;
+ pop_cfun ();
+ }
+ }
+
+ return 0;
+}
+
/* When inlining shall be performed. */
static bool
cgraph_gate_ipa_early_inlining (void)
{
- return (flag_early_inlining
- && (flag_branch_probabilities || flag_test_coverage
- || profile_arc_flag));
+ return 1;
}
/* IPA pass wrapper for early inlining pass. We need to run early inlining
@@ -1643,7 +1673,7 @@ struct simple_ipa_opt_pass pass_ipa_earl
SIMPLE_IPA_PASS,
"einline_ipa", /* name */
cgraph_gate_ipa_early_inlining, /* gate */
- NULL, /* execute */
+ cgraph_ipa_early_inlining, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */