diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 20307ddb31cf..63da104969f8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2011-11-09 Richard Guenther + + 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. + 2011-11-09 Richard Guenther PR tree-optimization/51039 diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c index fc6ceb43aa1b..862c5b08e3a8 100644 --- a/gcc/gimple-streamer-in.c +++ b/gcc/gimple-streamer-in.c @@ -219,11 +219,18 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, } 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; diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 1820b0cb323b..91aa6123d913 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -1961,20 +1961,6 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 66a534b34359..2d4a6aab2128 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-11-09 Richard Guenther + + PR tree-optimization/51039 + * gcc.dg/pr51039.c: New testcase. + 2011-11-09 Jakub Jelinek * lib/target-supports.exp (check_effective_target_vect_cond_mixed): diff --git a/gcc/testsuite/gcc.dg/pr51039.c b/gcc/testsuite/gcc.dg/pr51039.c new file mode 100644 index 000000000000..863a6ff16457 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr51039.c @@ -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); +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index d81cc670bf4f..b733c88ff14f 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3227,6 +3227,16 @@ verify_gimple_call (gimple stmt) } } + /* 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; }