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;