ipa-inline.c (check_maybe_up, [...]): New macros.

* ipa-inline.c (check_maybe_up, check_maybe_down, check_match):
	New macros.
	(can_inline_edge_p): Relax option matching for always inline functions.

From-SVN: r221714
This commit is contained in:
Jan Hubicka 2015-03-27 00:43:27 +01:00 committed by Jan Hubicka
parent 06d750319f
commit 8e926cb160
2 changed files with 54 additions and 41 deletions

View File

@ -1,3 +1,9 @@
2015-03-26 Jan Hubicka <hubicka@ucw.cz>
* ipa-inline.c (check_maybe_up, check_maybe_down, check_match):
New macros.
(can_inline_edge_p): Relax option matching for always inline functions.
2015-03-26 Uros Bizjak <ubizjak@gmail.com>
PR target/65561

View File

@ -298,6 +298,27 @@ sanitize_attrs_match_for_inline_p (const_tree caller, const_tree callee)
DECL_ATTRIBUTES (callee));
}
/* Used for flags where it is safe to inline when caller's value is
grater than callee's. */
#define check_maybe_up(flag) \
(opts_for_fn (caller->decl)->x_##flag \
!= opts_for_fn (callee->decl)->x_##flag \
&& (!always_inline \
|| opts_for_fn (caller->decl)->x_##flag \
< opts_for_fn (callee->decl)->x_##flag))
/* Used for flags where it is safe to inline when caller's value is
smaller than callee's. */
#define check_maybe_down(flag) \
(opts_for_fn (caller->decl)->x_##flag \
!= opts_for_fn (callee->decl)->x_##flag \
&& (!always_inline \
|| opts_for_fn (caller->decl)->x_##flag \
> opts_for_fn (callee->decl)->x_##flag))
/* Used for flags where exact match is needed for correctness. */
#define check_match(flag) \
(opts_for_fn (caller->decl)->x_##flag \
!= opts_for_fn (callee->decl)->x_##flag)
/* Decide if we can inline the edge and possibly update
inline_failed reason.
We check whether inlining is possible at all and whether
@ -401,74 +422,60 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
optimization attribute. */
else if (caller_tree != callee_tree)
{
bool always_inline =
(DECL_DISREGARD_INLINE_LIMITS (callee->decl)
&& lookup_attribute ("always_inline",
DECL_ATTRIBUTES (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 (caller->decl, flag_strict_overflow)
!= opt_for_fn (callee->decl, flag_strict_overflow))
|| (opt_for_fn (caller->decl, flag_wrapv)
!= opt_for_fn (callee->decl, flag_wrapv))
|| (opt_for_fn (caller->decl, flag_trapv)
!= opt_for_fn (callee->decl, flag_trapv))
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 contains memory
accesses that are not using alias-set zero anyway. */
|| (opt_for_fn (caller->decl, flag_strict_aliasing)
!= opt_for_fn (callee->decl, flag_strict_aliasing))
|| check_maybe_down (flag_strict_aliasing)
/* Strictly speaking only when the callee uses FP math. */
|| (opt_for_fn (caller->decl, flag_rounding_math)
!= opt_for_fn (callee->decl, flag_rounding_math))
|| (opt_for_fn (caller->decl, flag_trapping_math)
!= opt_for_fn (callee->decl, flag_trapping_math))
|| (opt_for_fn (caller->decl, flag_unsafe_math_optimizations)
!= opt_for_fn (callee->decl, flag_unsafe_math_optimizations))
|| (opt_for_fn (caller->decl, flag_finite_math_only)
!= opt_for_fn (callee->decl, flag_finite_math_only))
|| (opt_for_fn (caller->decl, flag_signaling_nans)
!= opt_for_fn (callee->decl, flag_signaling_nans))
|| (opt_for_fn (caller->decl, flag_cx_limited_range)
!= opt_for_fn (callee->decl, flag_cx_limited_range))
|| (opt_for_fn (caller->decl, flag_signed_zeros)
!= opt_for_fn (callee->decl, flag_signed_zeros))
|| (opt_for_fn (caller->decl, flag_associative_math)
!= opt_for_fn (callee->decl, flag_associative_math))
|| (opt_for_fn (caller->decl, flag_reciprocal_math)
!= opt_for_fn (callee->decl, flag_reciprocal_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. */
|| (opt_for_fn (caller->decl, flag_non_call_exceptions)
!= opt_for_fn (callee->decl, flag_non_call_exceptions)
|| (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)))
|| (!opt_for_fn (caller->decl, flag_exceptions)
&& opt_for_fn (callee->decl, flag_exceptions)
|| (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. */
|| (opt_for_fn (caller->decl, flag_errno_math)
!= opt_for_fn (callee->decl, flag_errno_math))
|| 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. */
|| (opt_for_fn (caller->decl, flag_devirtualize)
&& !opt_for_fn (callee->decl, flag_devirtualize)
&& (!early
|| (!DECL_DISREGARD_INLINE_LIMITS (callee->decl)
|| !lookup_attribute ("always_inline",
DECL_ATTRIBUTES (callee->decl))))))
|| (!early && check_maybe_down (flag_devirtualize)))
{
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)))
else if (always_inline)
;
/* When user added an attribute to the callee honor it. */
else if (lookup_attribute ("optimize", DECL_ATTRIBUTES (callee->decl))