re PR ipa/65873 (Failure to inline always_inline memcpy)
PR ipa/65873 * ipa-inline.c (can_inline_edge_p): Allow early inlining of always inlines across optimization boundary. From-SVN: r223107
This commit is contained in:
parent
fe1814cf84
commit
ddb3773a12
|
@ -1,3 +1,9 @@
|
|||
2015-05-12 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR ipa/65873
|
||||
* ipa-inline.c (can_inline_edge_p): Allow early inlining of always
|
||||
inlines across optimization boundary.
|
||||
|
||||
2015-05-12 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* config/mmix/mmix.c, config/msp430/msp430.c: Add space between
|
||||
|
|
|
@ -427,46 +427,55 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
|
|||
&& lookup_attribute ("always_inline",
|
||||
DECL_ATTRIBUTES (callee->decl)));
|
||||
|
||||
/* Until GCC 4.9 we did not check the semantics alterning flags
|
||||
bellow and inline across optimization boundry.
|
||||
Enabling checks bellow breaks several packages by refusing
|
||||
to inline library always_inline functions. See PR65873.
|
||||
Disable the check for early inlining for now until better solution
|
||||
is found. */
|
||||
if (always_inline && early)
|
||||
;
|
||||
/* 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 ((check_maybe_up (flag_strict_overflow)
|
||||
/* this flag is set by optimize. Allow inlining across
|
||||
optimize boundary. */
|
||||
&& (!opt_for_fn (caller->decl, optimize)
|
||||
== !opt_for_fn (callee->decl, optimize) || !always_inline))
|
||||
|| check_match (flag_wrapv)
|
||||
|| check_match (flag_trapv)
|
||||
/* Strictly speaking only when the callee uses FP math. */
|
||||
|| check_maybe_up (flag_rounding_math)
|
||||
|| check_maybe_up (flag_trapping_math)
|
||||
|| check_maybe_down (flag_unsafe_math_optimizations)
|
||||
|| check_maybe_down (flag_finite_math_only)
|
||||
|| check_maybe_up (flag_signaling_nans)
|
||||
|| check_maybe_down (flag_cx_limited_range)
|
||||
|| check_maybe_up (flag_signed_zeros)
|
||||
|| check_maybe_down (flag_associative_math)
|
||||
|| check_maybe_down (flag_reciprocal_math)
|
||||
/* We do not want to make code compiled with exceptions to be brought
|
||||
into a non-EH function unless we know that the callee does not
|
||||
throw. This is tracked by DECL_FUNCTION_PERSONALITY. */
|
||||
|| (check_match (flag_non_call_exceptions)
|
||||
/* TODO: We also may allow bringing !flag_non_call_exceptions
|
||||
to flag_non_call_exceptions function, but that may need
|
||||
extra work in tree-inline to add the extra EH edges. */
|
||||
&& (!opt_for_fn (callee->decl, flag_non_call_exceptions)
|
||||
|| DECL_FUNCTION_PERSONALITY (callee->decl)))
|
||||
|| (check_maybe_up (flag_exceptions)
|
||||
&& DECL_FUNCTION_PERSONALITY (callee->decl))
|
||||
/* Strictly speaking only when the callee contains function
|
||||
calls that may end up setting errno. */
|
||||
|| check_maybe_up (flag_errno_math)
|
||||
/* When devirtualization is diabled for callee, it is not safe
|
||||
to inline it as we possibly mangled the type info.
|
||||
Allow early inlining of always inlines. */
|
||||
|| (!early && check_maybe_down (flag_devirtualize)))
|
||||
else if ((check_maybe_up (flag_strict_overflow)
|
||||
/* this flag is set by optimize. Allow inlining across
|
||||
optimize boundary. */
|
||||
&& (!opt_for_fn (caller->decl, optimize)
|
||||
== !opt_for_fn (callee->decl, optimize) || !always_inline))
|
||||
|| check_match (flag_wrapv)
|
||||
|| check_match (flag_trapv)
|
||||
/* Strictly speaking only when the callee uses FP math. */
|
||||
|| check_maybe_up (flag_rounding_math)
|
||||
|| check_maybe_up (flag_trapping_math)
|
||||
|| check_maybe_down (flag_unsafe_math_optimizations)
|
||||
|| check_maybe_down (flag_finite_math_only)
|
||||
|| check_maybe_up (flag_signaling_nans)
|
||||
|| check_maybe_down (flag_cx_limited_range)
|
||||
|| check_maybe_up (flag_signed_zeros)
|
||||
|| check_maybe_down (flag_associative_math)
|
||||
|| check_maybe_down (flag_reciprocal_math)
|
||||
/* We do not want to make code compiled with exceptions to be
|
||||
brought into a non-EH function unless we know that the callee
|
||||
does not throw.
|
||||
This is tracked by DECL_FUNCTION_PERSONALITY. */
|
||||
|| (check_match (flag_non_call_exceptions)
|
||||
/* TODO: We also may allow bringing !flag_non_call_exceptions
|
||||
to flag_non_call_exceptions function, but that may need
|
||||
extra work in tree-inline to add the extra EH edges. */
|
||||
&& (!opt_for_fn (callee->decl, flag_non_call_exceptions)
|
||||
|| DECL_FUNCTION_PERSONALITY (callee->decl)))
|
||||
|| (check_maybe_up (flag_exceptions)
|
||||
&& DECL_FUNCTION_PERSONALITY (callee->decl))
|
||||
/* Strictly speaking only when the callee contains function
|
||||
calls that may end up setting errno. */
|
||||
|| check_maybe_up (flag_errno_math)
|
||||
/* When devirtualization is diabled for callee, it is not safe
|
||||
to inline it as we possibly mangled the type info.
|
||||
Allow early inlining of always inlines. */
|
||||
|| (!early && check_maybe_down (flag_devirtualize)))
|
||||
{
|
||||
e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
|
||||
inlinable = false;
|
||||
|
@ -481,6 +490,17 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
|
|||
e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
|
||||
inlinable = false;
|
||||
}
|
||||
/* If explicit optimize attribute are not used, the mismatch is caused
|
||||
by different command line options used to build different units.
|
||||
Do not care about COMDAT functions - those are intended to be
|
||||
optimized with the optimization flags of module they are used in.
|
||||
Also do not care about mixing up size/speed optimization when
|
||||
DECL_DISREGARD_INLINE_LIMITS is set. */
|
||||
else if ((callee->merged
|
||||
&& !lookup_attribute ("optimize",
|
||||
DECL_ATTRIBUTES (caller->decl)))
|
||||
|| DECL_DISREGARD_INLINE_LIMITS (callee->decl))
|
||||
;
|
||||
/* If mismatch is caused by merging two LTO units with different
|
||||
optimizationflags we want to be bit nicer. However never inline
|
||||
if one of functions is not optimized at all. */
|
||||
|
|
Loading…
Reference in New Issue