Hi, this patch missed hunk adding CIF code that I commited now * cif-code.def (CILK_SPAWN): New code.
--- trunk/gcc/cif-code.def 2015/03/26 20:37:53 221709 +++ trunk/gcc/cif-code.def 2015/03/26 21:10:28 221710 @@ -124,6 +124,10 @@ DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR, N_("function attribute mismatch")) +/* We can't inline because of mismatched caller/callee attributes. */ +DEFCIFCODE(CILK_SPAWN, CIF_FINAL_ERROR, + N_("caller function contains cilk spawn")) + /* We proved that the call is unreachable. */ DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR, N_("unreachable")) I also noticed that this breaks one testcase which is cured by the following patch I am testing and will commit once it concludes. I apologize for the breakage. Honza * ipa-inline.c (check_maybe_up, check_maybe_down, check_match): New macros. (can_inline_edge_p): Relax option matching for always inline functions. Index: ipa-inline.c =================================================================== --- ipa-inline.c (revision 221706) +++ ipa-inline.c (working copy) @@ -298,6 +298,27 @@ sanitize_attrs_match_for_inline_p (const 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 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))