> > On Sun, 28 Oct 2012, Jan Hubicka wrote: > > > > >Bootstrapped/regtested x86_64-linux. > > > > > >Honza > > > > > > * ipa-inline.c (edge_badness): Reduce precision; use scc hints. > > > (inline_small_functions): Fix dumps; update all callees after inlining. > > > * ipa-inline.h (INLINE_HINT_in_scc, INLINE_HINT_same_scc): New > > > constants. > > > (inline summary): Add SCC_NO. > > > * ipa-inline-analysis.c (dump_inline_hints): Dump SCC hints. > > > (reset_inline_summary): Reset scc_no. > > > (estimate_node_size_and_time): Set in_scc hint. > > > (do_estimate_edge_time): Add same_scc hint. > > > (do_estimate_edge_hints): Likewise. > > > > Hello, > > > > I haven't tried bisecting or anything, but bootstrap is broken on > > x86_64-linux: > > Hmm, sorry, that is indeed mine. I am testing a fix. Hi, this is patch I comitted after regtesting and making sure that it gets past the failure point in the bootstrap. The issue s showing only on specific (most?) setups, it is an overflow in badness metric.
I also constructed testcase for the hint and found out there are two cases I need to deal with, too. First the linked list holding SCC components is not cyclic, this looks like a bug - I do not see how it can reliably work, but I will look into that incrementaly. Second I do not want to handle simple recursion as SCCs since those are understood by the inliner well, so when SCC gets collapsed into a single node and self recursive edge is created, we ought to ignore its SCC flag. Honza * gcc.dg/ipa/inlinehint-3.c: New testcase. * ipa-inline.c (edge_badness): Fix overflow. (inline_small_functions): Initialize SCCs correctly. (do_estimate_edge_time, do_estimate_edge_hints): Skip self recursive ufnctions in SCC hints. Index: testsuite/gcc.dg/ipa/inlinehint-3.c =================================================================== *** testsuite/gcc.dg/ipa/inlinehint-3.c (revision 0) --- testsuite/gcc.dg/ipa/inlinehint-3.c (revision 0) *************** *** 0 **** --- 1,37 ---- + /* { dg-options "-O3 -c -fdump-ipa-inline-details -fno-early-inlining -fno-ipa-cp" } */ + void abort (void); + int sum; + int a[10]; + int + scc_next (int c) + { + int i; + for (i=0;i<c;i++) + a[i]=c; + scc_entry (c); + } + int + scc_entry (int c) + { + int i; + for (i=0;i<c;i++) + sum+=a[i]; + if (c--) + scc_next (c); + return sum; + } + main() + { + int sum; + int i; + for (i=0;i<10;i++) + scc_entry (i); + if (sum < 0) + abort (); + return 0; + } + /* { dg-final { scan-ipa-dump "in_scc" "inline" } } */ + /* { dg-final { scan-ipa-dump "same_scc" "inline" } } */ + /* Main is not in scc, the two functions are. */ + /* { dg-final { scan-ipa-dump-times "In SCC" 2 "inline" } } */ + /* { dg-final { cleanup-ipa-dump "inline" } } */ Index: ipa-inline.c =================================================================== *** ipa-inline.c (revision 192889) --- ipa-inline.c (working copy) *************** edge_badness (struct cgraph_edge *edge, *** 861,869 **** We might mix the valud into the fraction by taking into account relative growth of the unit, but for now just add the number into resulting fraction. */ ! if (badness > INT_MAX / 4) { ! badness = INT_MAX / 4; if (dump) fprintf (dump_file, "Badness overflow\n"); } --- 861,869 ---- We might mix the valud into the fraction by taking into account relative growth of the unit, but for now just add the number into resulting fraction. */ ! if (badness > INT_MAX / 8) { ! badness = INT_MAX / 8; if (dump) fprintf (dump_file, "Badness overflow\n"); } *************** inline_small_functions (void) *** 1360,1367 **** if (!DECL_EXTERNAL (node->symbol.decl)) initial_size += info->size; ! info->scc_no = (dfs && dfs->next_cycle && dfs->next_cycle != node ! ? dfs->scc_no + 1 : 0); } for (edge = node->callers; edge; edge = edge->next_caller) --- 1360,1378 ---- if (!DECL_EXTERNAL (node->symbol.decl)) initial_size += info->size; ! if (dfs && dfs->next_cycle) ! { ! struct cgraph_node *n2; ! int id = dfs->scc_no + 1; ! for (n2 = node; n2; ! n2 = ((struct ipa_dfs_info *) node->symbol.aux)->next_cycle) ! { ! struct inline_summary *info2 = inline_summary (n2); ! if (info2->scc_no) ! break; ! info2->scc_no = id; ! } ! } } for (edge = node->callers; edge; edge = edge->next_caller) Index: ipa-inline-analysis.c =================================================================== *** ipa-inline-analysis.c (revision 192888) --- ipa-inline-analysis.c (working copy) *************** dump_inline_summary (FILE * f, struct cg *** 1375,1380 **** --- 1375,1383 ---- (int) s->estimated_self_stack_size); fprintf (f, " global stack: %i\n", (int) s->estimated_stack_size); + if (s->scc_no) + fprintf (f, " In SCC: %i\n", + (int) s->scc_no); for (i = 0; VEC_iterate (size_time_entry, s->entry, i, e); i++) *************** do_estimate_edge_time (struct cgraph_edg *** 3348,3354 **** VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size = size + (size >= 0); if (inline_summary (to)->scc_no ! && inline_summary (to)->scc_no == inline_summary (callee)->scc_no) hints |= INLINE_HINT_same_scc; VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).hints = hints + 1; --- 3351,3358 ---- VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size = size + (size >= 0); if (inline_summary (to)->scc_no ! && inline_summary (to)->scc_no == inline_summary (callee)->scc_no ! && !cgraph_edge_recursive_p (edge)) hints |= INLINE_HINT_same_scc; VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).hints = hints + 1; *************** do_estimate_edge_hints (struct cgraph_ed *** 3439,3445 **** VEC_free (tree, heap, known_binfos); VEC_free (ipa_agg_jump_function_p, heap, known_aggs); if (inline_summary (to)->scc_no ! && inline_summary (to)->scc_no == inline_summary (callee)->scc_no) hints |= INLINE_HINT_same_scc; return hints; } --- 3443,3450 ---- VEC_free (tree, heap, known_binfos); VEC_free (ipa_agg_jump_function_p, heap, known_aggs); if (inline_summary (to)->scc_no ! && inline_summary (to)->scc_no == inline_summary (callee)->scc_no ! && !cgraph_edge_recursive_p (edge)) hints |= INLINE_HINT_same_scc; return hints; }