On Wed, 9 Nov 2011, Richard Guenther wrote:

> 
> This fixes PR51039 - another case of mismatches with respect to
> gimple_call_cannot_inline_p and gimple_check_call_matching_types.
> The code in ipa-inline-analysis.c looks out-of-place and it doesn't
> check for a conservative setting - thus the patch removes the
> code and instead adds verification code to the gimple checker.
> 
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

This is what I ended up applying.

Richard.

2011-11-09  Richard Guenther  <rguent...@suse.de>

        PR tree-optimization/51039
        * tree-cfg.c (verify_gimple_call): Verify that
        gimple_call_cannot_inline_p is returning a conservative
        correct result according to gimple_check_call_matching_types.
        * ipa-inline-analysis.c (estimate_function_body_sizes): Remove
        code dealing with un-inlinablility.
        * gimple-streamer-in.c (input_gimple_stmt): Update the
        non-inlinable flag.

        * gcc.dg/pr51039.c: New testcase.

Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c      (revision 181196)
--- gcc/tree-cfg.c      (working copy)
*************** verify_gimple_call (gimple stmt)
*** 3227,3232 ****
--- 3300,3315 ----
        }
      }
  
+   /* Verify that if we have a direct call and the argument/return
+      types have mismatches the call is properly marked as noninlinable.  */
+   if (fndecl
+       && !gimple_call_cannot_inline_p (stmt)
+       && !gimple_check_call_matching_types (stmt, fndecl))
+     {
+       error ("gimple call cannot be inlined but is not marked so");
+       return true;
+     }
+ 
    return false;
  }
  
Index: gcc/ipa-inline-analysis.c
===================================================================
*** gcc/ipa-inline-analysis.c   (revision 181196)
--- gcc/ipa-inline-analysis.c   (working copy)
*************** estimate_function_body_sizes (struct cgr
*** 1961,1980 ****
              es->call_stmt_time = this_time;
              es->loop_depth = bb->loop_depth;
              edge_set_predicate (edge, &bb_predicate);
- 
-             /* Do not inline calls where we cannot triviall work around
-                mismatches in argument or return types.  */
-             if (edge->callee
-                 && cgraph_function_or_thunk_node (edge->callee, NULL)
-                 && !gimple_check_call_matching_types
-                      (stmt, cgraph_function_or_thunk_node (edge->callee,
-                       NULL)->decl))
-               {
-                 edge->call_stmt_cannot_inline_p = true;
-                 gimple_call_set_cannot_inline (stmt, true);
-               }
-             else
-               gcc_assert (!gimple_call_cannot_inline_p (stmt));
            }
  
          /* TODO: When conditional jump or swithc is known to be constant, but
--- 1961,1966 ----
Index: gcc/testsuite/gcc.dg/pr51039.c
===================================================================
*** gcc/testsuite/gcc.dg/pr51039.c      (revision 0)
--- gcc/testsuite/gcc.dg/pr51039.c      (revision 0)
***************
*** 0 ****
--- 1,17 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -finline-small-functions -fno-ipa-pure-const" } */
+ 
+ float baz (void)
+ {
+   return 0;
+ }
+ 
+ static inline int bar (int (*ibaz) (void))
+ {
+   return ibaz ();
+ }
+ 
+ void foo (void)
+ {
+   bar((int (*)(void))baz);
+ }
Index: gcc/gimple-streamer-in.c
===================================================================
*** gcc/gimple-streamer-in.c    (revision 181196)
--- gcc/gimple-streamer-in.c    (working copy)
*************** input_gimple_stmt (struct lto_input_bloc
*** 219,229 ****
--- 219,236 ----
        }
        if (is_gimple_call (stmt))
        {
+         tree fndecl;
          if (gimple_call_internal_p (stmt))
            gimple_call_set_internal_fn
              (stmt, streamer_read_enum (ib, internal_fn, IFN_LAST));
          else
            gimple_call_set_fntype (stmt, stream_read_tree (ib, data_in));
+         /* Update the non-inlinable flag conservatively.  */
+         fndecl = gimple_call_fndecl (stmt);
+         if (fndecl
+             && !gimple_call_cannot_inline_p (stmt)
+             && !gimple_check_call_matching_types (stmt, fndecl))
+           gimple_call_set_cannot_inline (stmt, true);
        }
        break;
  

Reply via email to