> > 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;
}