ipa-inline.c (can_inline_edge_p): Match opt_for_fn on inline target; also match flag_...
authorJan Hubicka <hubicka@ucw.cz>
Sun, 1 Mar 2015 01:08:47 +0000 (02:08 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 1 Mar 2015 01:08:47 +0000 (01:08 +0000)
* ipa-inline.c (can_inline_edge_p): Match opt_for_fn on inline
target; also match flag_ipa_devirt.

From-SVN: r221084

gcc/ChangeLog
gcc/ipa-inline.c

index 5d792b1dc2b3379e615b324d03d3b7b563038aa0..ee6f7fe7fd9a8e5983c9fcd144621b3525145b0a 100644 (file)
@@ -1,5 +1,9 @@
-2015-03-01  Martin Liska  <mliska@suse.cz>
+2015-02-28  Jan Hubicka  <hubicka@ucw.cz>
 
+       * ipa-inline.c (can_inline_edge_p): Match opt_for_fn on inline
+       target; also match flag_ipa_devirt.
+
+2015-03-01  Martin Liska  <mliska@suse.cz>
            Jan Hubicka   <hubicka@ucw.cz>
 
        * ipa-icf-gimple.c (func_checker::compare_variable_decl):
index c445f0a7a5d5d13c111b57917872e5e8ac2a1c5e..db77d12e85fe441fe74458d6ec4c368e59b9fff9 100644 (file)
@@ -310,7 +310,7 @@ sanitize_attrs_match_for_inline_p (const_tree caller, const_tree callee)
 
 static bool
 can_inline_edge_p (struct cgraph_edge *e, bool report,
-                  bool disregard_limits = false)
+                  bool disregard_limits = false, bool early = false)
 {
   bool inlinable = true;
   enum availability avail;
@@ -409,39 +409,48 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
         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))
+      if ((opt_for_fn (caller->decl, flag_strict_overflow)
+          != opt_for_fn (caller->decl, flag_strict_overflow))
+         || (opt_for_fn (caller->decl, flag_wrapv)
+             != opt_for_fn (caller->decl, flag_wrapv))
+         || (opt_for_fn (caller->decl, flag_trapv)
+             != opt_for_fn (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))
+         || (opt_for_fn (caller->decl, flag_strict_aliasing)
+             != opt_for_fn (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))
+         || (opt_for_fn (caller->decl, flag_rounding_math)
+             != opt_for_fn (caller->decl, flag_rounding_math))
+         || (opt_for_fn (caller->decl, flag_trapping_math)
+             != opt_for_fn (caller->decl, flag_trapping_math))
+         || (opt_for_fn (caller->decl, flag_unsafe_math_optimizations)
+             != opt_for_fn (caller->decl, flag_unsafe_math_optimizations))
+         || (opt_for_fn (caller->decl, flag_finite_math_only)
+             != opt_for_fn (caller->decl, flag_finite_math_only))
+         || (opt_for_fn (caller->decl, flag_signaling_nans)
+             != opt_for_fn (caller->decl, flag_signaling_nans))
+         || (opt_for_fn (caller->decl, flag_cx_limited_range)
+             != opt_for_fn (caller->decl, flag_cx_limited_range))
+         || (opt_for_fn (caller->decl, flag_signed_zeros)
+             != opt_for_fn (caller->decl, flag_signed_zeros))
+         || (opt_for_fn (caller->decl, flag_associative_math)
+             != opt_for_fn (caller->decl, flag_associative_math))
+         || (opt_for_fn (caller->decl, flag_reciprocal_math)
+             != opt_for_fn (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)))
+         || (opt_for_fn (caller->decl, flag_errno_math)
+             != opt_for_fn (caller->decl, 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))))))
        {
          e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
          inlinable = false;
@@ -532,7 +541,7 @@ can_early_inline_edge_p (struct cgraph_edge *e)
        fprintf (dump_file, "  edge not inlinable: not in SSA form\n");
       return false;
     }
-  if (!can_inline_edge_p (e, true))
+  if (!can_inline_edge_p (e, true, false, true))
     return false;
   return true;
 }