Hi, this patch fixes second part of problem in PR51680 and moves it out of regression land. The PR is still valid about fact that we should inline process_fun_at even when it is called many times because further inlining of add1 simplifies it enough. Unfortunately I don't think this can be easilly done in 4.7 timeframe. For 4.8 we can use Maxim's code to produce benefits for inliner to bypass the limits in such cases.
Bootstrapped/regtested x86_64-linux, comitted. Honza /* { dg-do compile } */ /* { dg-options "-O2 -fdump-ipa-inline" } */ extern void process (float); template<typename Fun, typename T> void process_fun_at (const Fun &fun, T x) { process (fun (x)); } static float add1 (float x) { return x + 1; } void test (float i) { process_fun_at (add1, i); } /* { dg-final { scan-ipa-dump-times "Inlined into" 2 "inline" } } */ /* { dg-final { cleanup-ipa-dump "inline" } } */ Index: ChangeLog =================================================================== --- ChangeLog (revision 182993) +++ ChangeLog (working copy) @@ -1,5 +1,11 @@ 2012-01-08 Jan Hubicka <j...@suse.cz> + PR tree-optimize/51680 + * ipa-inline-analyss.c (evaluate_properties_for_edge): Fix conditoin on when + known_vals needs to be computed; cleanup. + +2012-01-08 Jan Hubicka <j...@suse.cz> + PR tree-optimize/51694 * ipa-cp.c (ipa_get_indirect_edge_target): Add bounds checks. Index: ipa-inline-analysis.c =================================================================== --- ipa-inline-analysis.c (revision 182992) +++ ipa-inline-analysis.c (working copy) @@ -718,7 +718,7 @@ evaluate_properties_for_edge (struct cgr { struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL); struct inline_summary *info = inline_summary (callee); - int i; + VEC (tree, heap) *known_vals = NULL; if (clause_ptr) *clause_ptr = inline_p ? 0 : 1 << predicate_not_inlined_condition; @@ -728,13 +728,13 @@ evaluate_properties_for_edge (struct cgr *known_binfos_ptr = NULL; if (ipa_node_params_vector + && !e->call_stmt_cannot_inline_p && ((clause_ptr && info->conds) || known_vals_ptr || known_binfos_ptr)) { struct ipa_node_params *parms_info; struct ipa_edge_args *args = IPA_EDGE_REF (e); struct inline_edge_summary *es = inline_edge_summary (e); int i, count = ipa_get_cs_argument_count (args); - VEC (tree, heap) *known_vals = NULL; if (e->caller->global.inlined_to) parms_info = IPA_NODE_REF (e->caller->global.inlined_to); @@ -752,9 +752,9 @@ evaluate_properties_for_edge (struct cgr ipa_get_ith_jump_func (args, i)); if (cst) { - if (info->conds && TREE_CODE (cst) != TREE_BINFO) + if (known_vals && TREE_CODE (cst) != TREE_BINFO) VEC_replace (tree, known_vals, i, cst); - else if (known_binfos_ptr != NULL) + else if (known_binfos_ptr != NULL && TREE_CODE (cst) == TREE_BINFO) VEC_replace (tree, *known_binfos_ptr, i, cst); } else if (inline_p @@ -763,20 +763,16 @@ evaluate_properties_for_edge (struct cgr i)->change_prob) VEC_replace (tree, known_vals, i, error_mark_node); } - - if (clause_ptr && info->conds) - *clause_ptr = evaluate_conditions_for_known_args (callee, inline_p, - known_vals); - - if (known_vals_ptr) - *known_vals_ptr = known_vals; - else - VEC_free (tree, heap, known_vals); } - if (clause_ptr && !info->conds) - for (i = 0; i < (int)VEC_length (condition, info->conds); i++) - *clause_ptr |= 1 << (i + predicate_first_dynamic_condition); + if (clause_ptr) + *clause_ptr = evaluate_conditions_for_known_args (callee, inline_p, + known_vals); + + if (known_vals_ptr) + *known_vals_ptr = known_vals; + else + VEC_free (tree, heap, known_vals); }