On Thu, 22 Jan 2015, Jan Hubicka wrote: > > > > As said in the other thread - this makes sure we don't perform inlining > > that might end up generating invalid code. It also preserves > > user-provided optimize attributes more properly. > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. > > > > Richard. > > > > 2015-01-22 Richard Biener <rguent...@suse.de> > > > > * ipa-inline.c (can_inline_edge_p): Disable inlining of edges > > with IL incompatible options. Properly honor user optimize > > attributes. > > Thanks, in fact I had similar patch in queue, just wanted to catch you on IRC > and discuss posibility of making this a flag in common.opt
Sure - I briefly considered this but we're in stage4 now so I was just fixing the obvious correctness issues. We also have to fix /* Don't inline if the callee can throw non-call exceptions but the caller cannot. FIXME: this is obviously wrong for LTO where STRUCT_FUNCTION is missing. Move the flag into cgraph node or mirror it in the inline summary. */ else if (callee_fun && callee_fun->can_throw_non_call_exceptions && !(caller_fun && caller_fun->can_throw_non_call_exceptions)) { e->inline_failed = CIF_NON_CALL_EXCEPTIONS; inlinable = false; } in some way (eventually we can just use opt_for_fn ()->flag_non_call_exceptions). Richard. > Honza > > > > Index: gcc/ipa-inline.c > > =================================================================== > > --- gcc/ipa-inline.c (revision 219929) > > +++ gcc/ipa-inline.c (working copy) > > @@ -404,17 +404,56 @@ can_inline_edge_p (struct cgraph_edge *e > > optimization attribute. */ > > else if (caller_tree != callee_tree) > > { > > - /* gcc.dg/pr43564.c. Look at forced inline even in -O0. */ > > - if (DECL_DISREGARD_INLINE_LIMITS (callee->decl)) > > + /* There are some options that change IL semantics which means > > + we cannot inline in these cases for correctness reason. > > + Not even for always_inline declared functions. */ > > + /* Strictly speaking only when the callee contains signed integer > > + math where overflow is undefined. */ > > + if ((opt_for_fn (e->caller->decl, flag_strict_overflow) > > + != opt_for_fn (e->caller->decl, flag_strict_overflow)) > > + || (opt_for_fn (e->caller->decl, flag_wrapv) > > + != opt_for_fn (e->caller->decl, flag_wrapv)) > > + || (opt_for_fn (e->caller->decl, flag_trapv) > > + != opt_for_fn (e->caller->decl, flag_trapv)) > > + /* Strictly speaking only when the callee contains memory > > + accesses that are not using alias-set zero anyway. */ > > + || (opt_for_fn (e->caller->decl, flag_strict_aliasing) > > + != opt_for_fn (e->caller->decl, flag_strict_aliasing)) > > + /* Strictly speaking only when the callee uses FP math. */ > > + || (opt_for_fn (e->caller->decl, flag_rounding_math) > > + != opt_for_fn (e->caller->decl, flag_rounding_math)) > > + || (opt_for_fn (e->caller->decl, flag_trapping_math) > > + != opt_for_fn (e->caller->decl, flag_trapping_math)) > > + || (opt_for_fn (e->caller->decl, flag_unsafe_math_optimizations) > > + != opt_for_fn (e->caller->decl, flag_unsafe_math_optimizations)) > > + || (opt_for_fn (e->caller->decl, flag_finite_math_only) > > + != opt_for_fn (e->caller->decl, flag_finite_math_only)) > > + || (opt_for_fn (e->caller->decl, flag_signaling_nans) > > + != opt_for_fn (e->caller->decl, flag_signaling_nans)) > > + || (opt_for_fn (e->caller->decl, flag_cx_limited_range) > > + != opt_for_fn (e->caller->decl, flag_cx_limited_range)) > > + || (opt_for_fn (e->caller->decl, flag_signed_zeros) > > + != opt_for_fn (e->caller->decl, flag_signed_zeros)) > > + || (opt_for_fn (e->caller->decl, flag_associative_math) > > + != opt_for_fn (e->caller->decl, flag_associative_math)) > > + || (opt_for_fn (e->caller->decl, flag_reciprocal_math) > > + != opt_for_fn (e->caller->decl, flag_reciprocal_math)) > > + /* Strictly speaking only when the callee contains function > > + calls that may end up setting errno. */ > > + || (opt_for_fn (e->caller->decl, flag_errno_math) > > + != opt_for_fn (e->caller->decl, flag_errno_math))) > > + { > > + e->inline_failed = CIF_OPTIMIZATION_MISMATCH; > > + inlinable = false; > > + } > > + /* gcc.dg/pr43564.c. Apply user-forced inline even at -O0. */ > > + else if (DECL_DISREGARD_INLINE_LIMITS (callee->decl) > > + && lookup_attribute ("always_inline", > > + DECL_ATTRIBUTES (callee->decl))) > > ; > > - /* When user added an attribute, honnor it. */ > > - else if ((lookup_attribute ("optimize", DECL_ATTRIBUTES > > (caller->decl)) > > - || lookup_attribute ("optimize", > > - DECL_ATTRIBUTES (callee->decl))) > > - && ((opt_for_fn (caller->decl, optimize) > > - > opt_for_fn (callee->decl, optimize)) > > - || (opt_for_fn (caller->decl, optimize_size) > > - != opt_for_fn (callee->decl, optimize_size)))) > > + /* When user added an attribute to the callee honor it. */ > > + else if (lookup_attribute ("optimize", DECL_ATTRIBUTES > > (callee->decl)) > > + && opts_for_fn (caller->decl) != opts_for_fn (callee->decl)) > > { > > e->inline_failed = CIF_OPTIMIZATION_MISMATCH; > > inlinable = false; > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)