From 8e926cb1609e8a29930cd50f1d240592331d7565 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 27 Mar 2015 00:43:27 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++ gcc/ipa-inline.c | 89 ++++++++++++++++++++++++++---------------------- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0d4d17287f2..14cfadca409 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-03-26 Jan Hubicka + + * 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 PR target/65561 diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 49af4cec13d..24b25a0e318 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -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)) -- 2.30.2