Re: [PATCH 09/10] Experiment with using optinfo in gimple-loop-interchange.cc

2018-06-04 Thread Richard Biener
On Sat, Jun 2, 2018 at 12:22 AM David Malcolm  wrote:
>
> On Fri, 2018-06-01 at 17:31 +0200, Richard Biener wrote:
> > On June 1, 2018 3:40:15 PM GMT+02:00, David Malcolm  > com> wrote:
> > > On Fri, 2018-06-01 at 11:50 +0200, Richard Biener wrote:
> > > > On Tue, May 29, 2018 at 10:33 PM David Malcolm  > > > om>
> > > > wrote:
> > > > >
> > > > > This was an experiment to try to capture information on a
> > > > > loop optimization.
> > > > >
> > > > > gcc/ChangeLog:
> > > > > * gimple-loop-interchange.cc
> > > > > (should_interchange_loops):
> > > > > Add
> > > > > optinfo note when interchange gives better data
> > > > > locality
> > > > > behavior.
> > > > > (tree_loop_interchange::interchange): Add
> > > > > OPTINFO_SCOPE.
> > > > > Add optinfo for successful and unsuccessful
> > > > > interchanges.
> > > > > (prepare_perfect_loop_nest): Add OPTINFO_SCOPE.  Add
> > > > > optinfo note.
> > > > > (pass_linterchange::execute): Add OPTINFO_SCOPE.
> > > > > ---
> > > > >  gcc/gimple-loop-interchange.cc | 36
> > > > > +++-
> > > > >  1 file changed, 35 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-
> > > > > interchange.cc
> > > > > index eb35263..cd32288 100644
> > > > > --- a/gcc/gimple-loop-interchange.cc
> > > > > +++ b/gcc/gimple-loop-interchange.cc
> > > > > @@ -1556,7 +1556,19 @@ should_interchange_loops (unsigned
> > > > > i_idx,
> > > > > unsigned o_idx,
> > > > >ratio = innermost_loops_p ? INNER_STRIDE_RATIO :
> > > > > OUTER_STRIDE_RATIO;
> > > > >/* Do interchange if it gives better data locality
> > > > > behavior.  */
> > > > >if (wi::gtu_p (iloop_strides, wi::mul (oloop_strides,
> > > > > ratio)))
> > > > > -return true;
> > > > > +{
> > > > > +  if (optinfo_enabled_p ())
> > > > > +   OPTINFO_NOTE ((gimple *)NULL) // FIXME
> > > > > + << "interchange gives better data locality behavior:
> > > > > "
> > > > > + << "iloop_strides: "
> > > > > + << decu (iloop_strides)
> > > > > + << " > (oloop_strides: "
> > > > > + << decu (oloop_strides)
> > > > > + << " * ratio: "
> > > > > + << decu (ratio)
> > > > > + << ")";
> > > >
> > > > Just randomly inside the thread.
> > > >
> > > > NOO!
> > > >
> > > > :/
> > > > Please do _not_ add more stream-like APIs.  How do you expect
> > > > translators to deal with those?
> > > >
> > > > Yes, I'm aware of the graphite-* ones and I dislike those very
> > > > much.
> > > >
> > > > What's wrong with the existing dump API?
> > >
> > > The existing API suffers from a "wall of text" problem:
> > >
> > > * although it's possible to filter based on various criteria (the
> > > optgroup tags, specific passes, success vs failure), it's not
> > > possible
> > > to filter base on code hotness: the -fopt-info API works purely in
> > > terms of location_t.  So all of the messages about the hottest
> > > functions in the workload are intermingled with all of the other
> > > messages about all of the other functions.
> >
> > True
> >
> > > * some of the text notes refer to function entry, but all of these
> > > are
> > > emitted "at the same level": there's no way to see the nesting of
> > > these
> > > function-entry logs, and where other notes are in relation to
> > > them.
> > > For example, in:
> > >
> > >  test.c:8:3: note: === analyzing loop ===
> > >  test.c:8:3: note: === analyze_loop_nest ===
> > >  test.c:8:3: note: === vect_analyze_loop_form ===
> > >  test.c:8:3: note: === get_loop_niters ===
> > > test.c:8:3: note: symbolic number of iterations is (unsigned int)
> > > n_9(D)
> > > test.c:8:3: note: not vectorized: loop contains function calls or
> > > data
> > > references that cannot be analyzed
> > >  test.c:8:3: note: vectorized 0 loops in function
> > >
> > > there's no way to tell that the "vect_analyze_loop_form" is in fact
> > > inside the call to "analyze_loop_nest", and where the "symbolic
> > > number
> > > of iterations" messages is coming from in relation to them.  This
> > > may
> > > not seem significant here, but I'm quoting a small example;
> > > vectorization typically leads to dozens of messages, with a deep
> > > nesting structure (where that structure isn't visible in the -fopt-
> > > info
> > >
> > > output).
> >
> > True. The same issue exists for diagnostics BTW. Indeed, being able
> > to collapse 'sections' in dump files, opt-info or diagnostics sounds
> > useful.
> >
> > Note that for dump files and opt-info the level argument was sort of
> > designed to do that.
>
> Are you referring to the indentation argument here?

No, to MSG_NOTE vs. MSG_MISSED_OPTIMIZATION , etc.

> > >
> > > The existing API is throwing data away:
> > >
> > > * as noted above, by working purely with a location_t, the
> > > execution
> > > count isn't associated with the messages.  The output format purely
> > > giv

Re: [PATCH 09/10] Experiment with using optinfo in gimple-loop-interchange.cc

2018-06-01 Thread David Malcolm
On Fri, 2018-06-01 at 17:31 +0200, Richard Biener wrote:
> On June 1, 2018 3:40:15 PM GMT+02:00, David Malcolm  com> wrote:
> > On Fri, 2018-06-01 at 11:50 +0200, Richard Biener wrote:
> > > On Tue, May 29, 2018 at 10:33 PM David Malcolm  > > om>
> > > wrote:
> > > > 
> > > > This was an experiment to try to capture information on a
> > > > loop optimization.
> > > > 
> > > > gcc/ChangeLog:
> > > > * gimple-loop-interchange.cc
> > > > (should_interchange_loops):
> > > > Add
> > > > optinfo note when interchange gives better data
> > > > locality
> > > > behavior.
> > > > (tree_loop_interchange::interchange): Add
> > > > OPTINFO_SCOPE.
> > > > Add optinfo for successful and unsuccessful
> > > > interchanges.
> > > > (prepare_perfect_loop_nest): Add OPTINFO_SCOPE.  Add
> > > > optinfo note.
> > > > (pass_linterchange::execute): Add OPTINFO_SCOPE.
> > > > ---
> > > >  gcc/gimple-loop-interchange.cc | 36
> > > > +++-
> > > >  1 file changed, 35 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-
> > > > interchange.cc
> > > > index eb35263..cd32288 100644
> > > > --- a/gcc/gimple-loop-interchange.cc
> > > > +++ b/gcc/gimple-loop-interchange.cc
> > > > @@ -1556,7 +1556,19 @@ should_interchange_loops (unsigned
> > > > i_idx,
> > > > unsigned o_idx,
> > > >ratio = innermost_loops_p ? INNER_STRIDE_RATIO :
> > > > OUTER_STRIDE_RATIO;
> > > >/* Do interchange if it gives better data locality
> > > > behavior.  */
> > > >if (wi::gtu_p (iloop_strides, wi::mul (oloop_strides,
> > > > ratio)))
> > > > -return true;
> > > > +{
> > > > +  if (optinfo_enabled_p ())
> > > > +   OPTINFO_NOTE ((gimple *)NULL) // FIXME
> > > > + << "interchange gives better data locality behavior:
> > > > "
> > > > + << "iloop_strides: "
> > > > + << decu (iloop_strides)
> > > > + << " > (oloop_strides: "
> > > > + << decu (oloop_strides)
> > > > + << " * ratio: "
> > > > + << decu (ratio)
> > > > + << ")";
> > > 
> > > Just randomly inside the thread.
> > > 
> > > NOO!
> > > 
> > > :/
> > > Please do _not_ add more stream-like APIs.  How do you expect
> > > translators to deal with those?
> > > 
> > > Yes, I'm aware of the graphite-* ones and I dislike those very
> > > much.
> > > 
> > > What's wrong with the existing dump API?
> > 
> > The existing API suffers from a "wall of text" problem:
> > 
> > * although it's possible to filter based on various criteria (the
> > optgroup tags, specific passes, success vs failure), it's not
> > possible
> > to filter base on code hotness: the -fopt-info API works purely in
> > terms of location_t.  So all of the messages about the hottest
> > functions in the workload are intermingled with all of the other
> > messages about all of the other functions.
> 
> True
> 
> > * some of the text notes refer to function entry, but all of these
> > are
> > emitted "at the same level": there's no way to see the nesting of
> > these
> > function-entry logs, and where other notes are in relation to
> > them. 
> > For example, in:
> > 
> >  test.c:8:3: note: === analyzing loop ===
> >  test.c:8:3: note: === analyze_loop_nest ===
> >  test.c:8:3: note: === vect_analyze_loop_form ===
> >  test.c:8:3: note: === get_loop_niters ===
> > test.c:8:3: note: symbolic number of iterations is (unsigned int)
> > n_9(D)
> > test.c:8:3: note: not vectorized: loop contains function calls or
> > data
> > references that cannot be analyzed
> >  test.c:8:3: note: vectorized 0 loops in function
> > 
> > there's no way to tell that the "vect_analyze_loop_form" is in fact
> > inside the call to "analyze_loop_nest", and where the "symbolic
> > number
> > of iterations" messages is coming from in relation to them.  This
> > may
> > not seem significant here, but I'm quoting a small example;
> > vectorization typically leads to dozens of messages, with a deep
> > nesting structure (where that structure isn't visible in the -fopt-
> > info
> > 
> > output).
> 
> True. The same issue exists for diagnostics BTW. Indeed, being able
> to collapse 'sections' in dump files, opt-info or diagnostics sounds
> useful. 
> 
> Note that for dump files and opt-info the level argument was sort of
> designed to do that. 

Are you referring to the indentation argument here?

> > 
> > The existing API is throwing data away:
> > 
> > * as noted above, by working purely with a location_t, the
> > execution
> > count isn't associated with the messages.  The output format purely
> > gives file/line/column information, but doesn't cover the inlining
> > chain.   For C++ templates it doesn't specify which instance of a
> > template is being optimized.
> 
> It might be useful to enhance the interface by allowing different
> kind of 'locations'. 

In patch 3 of the kit there's a class optinfo_location, which can be
constructed

Re: [PATCH 09/10] Experiment with using optinfo in gimple-loop-interchange.cc

2018-06-01 Thread Richard Biener
On June 1, 2018 3:40:15 PM GMT+02:00, David Malcolm  wrote:
>On Fri, 2018-06-01 at 11:50 +0200, Richard Biener wrote:
>> On Tue, May 29, 2018 at 10:33 PM David Malcolm 
>> wrote:
>> > 
>> > This was an experiment to try to capture information on a
>> > loop optimization.
>> > 
>> > gcc/ChangeLog:
>> > * gimple-loop-interchange.cc (should_interchange_loops):
>> > Add
>> > optinfo note when interchange gives better data locality
>> > behavior.
>> > (tree_loop_interchange::interchange): Add OPTINFO_SCOPE.
>> > Add optinfo for successful and unsuccessful interchanges.
>> > (prepare_perfect_loop_nest): Add OPTINFO_SCOPE.  Add
>> > optinfo note.
>> > (pass_linterchange::execute): Add OPTINFO_SCOPE.
>> > ---
>> >  gcc/gimple-loop-interchange.cc | 36
>> > +++-
>> >  1 file changed, 35 insertions(+), 1 deletion(-)
>> > 
>> > diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-
>> > interchange.cc
>> > index eb35263..cd32288 100644
>> > --- a/gcc/gimple-loop-interchange.cc
>> > +++ b/gcc/gimple-loop-interchange.cc
>> > @@ -1556,7 +1556,19 @@ should_interchange_loops (unsigned i_idx,
>> > unsigned o_idx,
>> >ratio = innermost_loops_p ? INNER_STRIDE_RATIO :
>> > OUTER_STRIDE_RATIO;
>> >/* Do interchange if it gives better data locality behavior.  */
>> >if (wi::gtu_p (iloop_strides, wi::mul (oloop_strides, ratio)))
>> > -return true;
>> > +{
>> > +  if (optinfo_enabled_p ())
>> > +   OPTINFO_NOTE ((gimple *)NULL) // FIXME
>> > + << "interchange gives better data locality behavior: "
>> > + << "iloop_strides: "
>> > + << decu (iloop_strides)
>> > + << " > (oloop_strides: "
>> > + << decu (oloop_strides)
>> > + << " * ratio: "
>> > + << decu (ratio)
>> > + << ")";
>> 
>> Just randomly inside the thread.
>> 
>> NOO!
>> 
>> :/
>
>> Please do _not_ add more stream-like APIs.  How do you expect
>> translators to deal with those?
>> 
>> Yes, I'm aware of the graphite-* ones and I dislike those very much.
>> 
>> What's wrong with the existing dump API?
>
>The existing API suffers from a "wall of text" problem:
>
>* although it's possible to filter based on various criteria (the
>optgroup tags, specific passes, success vs failure), it's not possible
>to filter base on code hotness: the -fopt-info API works purely in
>terms of location_t.  So all of the messages about the hottest
>functions in the workload are intermingled with all of the other
>messages about all of the other functions.

True

>* some of the text notes refer to function entry, but all of these are
>emitted "at the same level": there's no way to see the nesting of these
>function-entry logs, and where other notes are in relation to them. 
>For example, in:
>
>  test.c:8:3: note: === analyzing loop ===
>  test.c:8:3: note: === analyze_loop_nest ===
>  test.c:8:3: note: === vect_analyze_loop_form ===
>  test.c:8:3: note: === get_loop_niters ===
>test.c:8:3: note: symbolic number of iterations is (unsigned int)
>n_9(D)
>test.c:8:3: note: not vectorized: loop contains function calls or data
>references that cannot be analyzed
>  test.c:8:3: note: vectorized 0 loops in function
>
>there's no way to tell that the "vect_analyze_loop_form" is in fact
>inside the call to "analyze_loop_nest", and where the "symbolic number
>of iterations" messages is coming from in relation to them.  This may
>not seem significant here, but I'm quoting a small example;
>vectorization typically leads to dozens of messages, with a deep
>nesting structure (where that structure isn't visible in the -fopt-info
>
>output).

True. The same issue exists for diagnostics BTW. Indeed, being able to collapse 
'sections' in dump files, opt-info or diagnostics sounds useful. 

Note that for dump files and opt-info the level argument was sort of designed 
to do that. 

>
>The existing API is throwing data away:
>
>* as noted above, by working purely with a location_t, the execution
>count isn't associated with the messages.  The output format purely
>gives file/line/column information, but doesn't cover the inlining
>chain.   For C++ templates it doesn't specify which instance of a
>template is being optimized.

It might be useful to enhance the interface by allowing different kind of 
'locations'. 

>* there's no metadata about where the messages are coming from.  It's
>easy to get at the current pass internally, but the messages don't
>capture that.  Figuring out where a message came from requires grepping
>the GCC source code.  The prototype I posted captures the __FILE__ and
>__LINE__ within the gcc source for every message emitted, and which
>pass instance emitted it.

The opt info group was supposed to captures this to the level interesting for a 
user. 

>* The current output format is of the form:
> "FILE:LINE:COLUMN: free-form text\n"
>This is only machine-readable up to a point: if a program is

Re: [PATCH 09/10] Experiment with using optinfo in gimple-loop-interchange.cc

2018-06-01 Thread David Malcolm
On Fri, 2018-06-01 at 11:50 +0200, Richard Biener wrote:
> On Tue, May 29, 2018 at 10:33 PM David Malcolm 
> wrote:
> > 
> > This was an experiment to try to capture information on a
> > loop optimization.
> > 
> > gcc/ChangeLog:
> > * gimple-loop-interchange.cc (should_interchange_loops):
> > Add
> > optinfo note when interchange gives better data locality
> > behavior.
> > (tree_loop_interchange::interchange): Add OPTINFO_SCOPE.
> > Add optinfo for successful and unsuccessful interchanges.
> > (prepare_perfect_loop_nest): Add OPTINFO_SCOPE.  Add
> > optinfo note.
> > (pass_linterchange::execute): Add OPTINFO_SCOPE.
> > ---
> >  gcc/gimple-loop-interchange.cc | 36
> > +++-
> >  1 file changed, 35 insertions(+), 1 deletion(-)
> > 
> > diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-
> > interchange.cc
> > index eb35263..cd32288 100644
> > --- a/gcc/gimple-loop-interchange.cc
> > +++ b/gcc/gimple-loop-interchange.cc
> > @@ -1556,7 +1556,19 @@ should_interchange_loops (unsigned i_idx,
> > unsigned o_idx,
> >ratio = innermost_loops_p ? INNER_STRIDE_RATIO :
> > OUTER_STRIDE_RATIO;
> >/* Do interchange if it gives better data locality behavior.  */
> >if (wi::gtu_p (iloop_strides, wi::mul (oloop_strides, ratio)))
> > -return true;
> > +{
> > +  if (optinfo_enabled_p ())
> > +   OPTINFO_NOTE ((gimple *)NULL) // FIXME
> > + << "interchange gives better data locality behavior: "
> > + << "iloop_strides: "
> > + << decu (iloop_strides)
> > + << " > (oloop_strides: "
> > + << decu (oloop_strides)
> > + << " * ratio: "
> > + << decu (ratio)
> > + << ")";
> 
> Just randomly inside the thread.
> 
> NOO!
> 
> :/

> Please do _not_ add more stream-like APIs.  How do you expect
> translators to deal with those?
> 
> Yes, I'm aware of the graphite-* ones and I dislike those very much.
> 
> What's wrong with the existing dump API?

The existing API suffers from a "wall of text" problem:

* although it's possible to filter based on various criteria (the
optgroup tags, specific passes, success vs failure), it's not possible
to filter base on code hotness: the -fopt-info API works purely in
terms of location_t.  So all of the messages about the hottest
functions in the workload are intermingled with all of the other
messages about all of the other functions.

* some of the text notes refer to function entry, but all of these are
emitted "at the same level": there's no way to see the nesting of these
function-entry logs, and where other notes are in relation to them. 
For example, in:

  test.c:8:3: note: === analyzing loop ===
  test.c:8:3: note: === analyze_loop_nest ===
  test.c:8:3: note: === vect_analyze_loop_form ===
  test.c:8:3: note: === get_loop_niters ===
  test.c:8:3: note: symbolic number of iterations is (unsigned int) n_9(D)
  test.c:8:3: note: not vectorized: loop contains function calls or data 
references that cannot be analyzed
  test.c:8:3: note: vectorized 0 loops in function

there's no way to tell that the "vect_analyze_loop_form" is in fact
inside the call to "analyze_loop_nest", and where the "symbolic number
of iterations" messages is coming from in relation to them.  This may
not seem significant here, but I'm quoting a small example;
vectorization typically leads to dozens of messages, with a deep
nesting structure (where that structure isn't visible in the -fopt-info 
output).

The existing API is throwing data away:

* as noted above, by working purely with a location_t, the execution
count isn't associated with the messages.  The output format purely
gives file/line/column information, but doesn't cover the inlining
chain.   For C++ templates it doesn't specify which instance of a
template is being optimized.

* there's no metadata about where the messages are coming from.  It's
easy to get at the current pass internally, but the messages don't
capture that.  Figuring out where a message came from requires grepping
the GCC source code.  The prototype I posted captures the __FILE__ and
__LINE__ within the gcc source for every message emitted, and which
pass instance emitted it.

* The current output format is of the form:
 "FILE:LINE:COLUMN: free-form text\n"
This is only machine-readable up to a point: if a program is parsing
it, all it has is the free-form text.  The prototype I posted captures
what kinds of things are in the text (statements, trees, symtab_nodes),
and captures location information for them, so that visualizations of
the dumps can provide useful links.

There's no API-level grouping of messages, beyond looking for newline
characters.

I'm probably re-hashing a lot of the material in the cover letter here:
"[PATCH 00/10] RFC: Prototype of compiler-assisted performance analysis"
  https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01675.html


I'd like to provide a machine-readable ou

Re: [PATCH 09/10] Experiment with using optinfo in gimple-loop-interchange.cc

2018-06-01 Thread Richard Biener
On Tue, May 29, 2018 at 10:33 PM David Malcolm  wrote:
>
> This was an experiment to try to capture information on a
> loop optimization.
>
> gcc/ChangeLog:
> * gimple-loop-interchange.cc (should_interchange_loops): Add
> optinfo note when interchange gives better data locality behavior.
> (tree_loop_interchange::interchange): Add OPTINFO_SCOPE.
> Add optinfo for successful and unsuccessful interchanges.
> (prepare_perfect_loop_nest): Add OPTINFO_SCOPE.  Add
> optinfo note.
> (pass_linterchange::execute): Add OPTINFO_SCOPE.
> ---
>  gcc/gimple-loop-interchange.cc | 36 +++-
>  1 file changed, 35 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc
> index eb35263..cd32288 100644
> --- a/gcc/gimple-loop-interchange.cc
> +++ b/gcc/gimple-loop-interchange.cc
> @@ -1556,7 +1556,19 @@ should_interchange_loops (unsigned i_idx, unsigned 
> o_idx,
>ratio = innermost_loops_p ? INNER_STRIDE_RATIO : OUTER_STRIDE_RATIO;
>/* Do interchange if it gives better data locality behavior.  */
>if (wi::gtu_p (iloop_strides, wi::mul (oloop_strides, ratio)))
> -return true;
> +{
> +  if (optinfo_enabled_p ())
> +   OPTINFO_NOTE ((gimple *)NULL) // FIXME
> + << "interchange gives better data locality behavior: "
> + << "iloop_strides: "
> + << decu (iloop_strides)
> + << " > (oloop_strides: "
> + << decu (oloop_strides)
> + << " * ratio: "
> + << decu (ratio)
> + << ")";

Just randomly inside the thread.

NOO!

:/

Please do _not_ add more stream-like APIs.  How do you expect
translators to deal with those?

Yes, I'm aware of the graphite-* ones and I dislike those very much.

What's wrong with the existing dump API?

Richard.

> +  return true;
> +}
>if (wi::gtu_p (iloop_strides, oloop_strides))
>  {
>/* Or it creates more invariant memory references.  */
> @@ -1578,6 +1590,8 @@ bool
>  tree_loop_interchange::interchange (vec datarefs,
> vec ddrs)
>  {
> +  OPTINFO_SCOPE ("tree_loop_interchange::interchange", m_loop_nest[0]);
> +
>location_t loc = find_loop_location (m_loop_nest[0]);
>bool changed_p = false;
>/* In each iteration we try to interchange I-th loop with (I+1)-th loop.
> @@ -1628,6 +1642,10 @@ tree_loop_interchange::interchange 
> (vec datarefs,
> fprintf (dump_file,
>  "Loop_pair is interchanged\n\n",
>  oloop.m_loop->num, iloop.m_loop->num);
> + if (optinfo_enabled_p ())
> +   OPTINFO_SUCCESS (oloop.m_loop)
> + << optinfo_printf ("Loop_pair is 
> interchanged",
> +oloop.m_loop->num, iloop.m_loop->num);
>
>   changed_p = true;
>   interchange_loops (iloop, oloop);
> @@ -1641,6 +1659,10 @@ tree_loop_interchange::interchange 
> (vec datarefs,
> fprintf (dump_file,
>  "Loop_pair is not interchanged\n\n",
>  oloop.m_loop->num, iloop.m_loop->num);
> + if (optinfo_enabled_p ())
> +   OPTINFO_FAILURE (oloop.m_loop)
> + << optinfo_printf ("Loop_pair is not 
> interchanged",
> +oloop.m_loop->num, iloop.m_loop->num);
> }
>  }
>simple_dce_from_worklist (m_dce_seeds);
> @@ -1648,6 +1670,9 @@ tree_loop_interchange::interchange 
> (vec datarefs,
>if (changed_p)
>  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
>  "loops interchanged in loop nest\n");
> +  if (optinfo_enabled_p ())
> +OPTINFO_SUCCESS (m_loop_nest[0])
> +  << "loops interchanged in loop nest";
>
>return changed_p;
>  }
> @@ -1971,6 +1996,8 @@ static bool
>  prepare_perfect_loop_nest (struct loop *loop, vec *loop_nest,
>vec *datarefs, vec *ddrs)
>  {
> +  OPTINFO_SCOPE ("prepare_perfect_loop_nest", loop);
> +
>struct loop *start_loop = NULL, *innermost = loop;
>struct loop *outermost = loops_for_fn (cfun)->tree_root;
>
> @@ -2029,6 +2056,12 @@ prepare_perfect_loop_nest (struct loop *loop, 
> vec *loop_nest,
>   fprintf (dump_file,
>"\nConsider loop interchange for loop_nest<%d - %d>\n",
>start_loop->num, innermost->num);
> +   if (optinfo_enabled_p ())
> + {
> +   OPTINFO_NOTE (start_loop)
> + << optinfo_printf ("consider loop interchange for loop_nest<%d 
> - %d>",
> +start_loop->num, innermost->num);
> + }
>
> if (loop != start_loop)
>   prune_access_strides_not_in_loop (start_loop, innermost, *datarefs);
> @@ -2061,6 +2094,7 @@ pass_linterchange::execute (function *fun)
>struct loop *loop;
>FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
>  {
> +  OPTINFO_SCOPE ("considering loop for in

[PATCH 09/10] Experiment with using optinfo in gimple-loop-interchange.cc

2018-05-29 Thread David Malcolm
This was an experiment to try to capture information on a
loop optimization.

gcc/ChangeLog:
* gimple-loop-interchange.cc (should_interchange_loops): Add
optinfo note when interchange gives better data locality behavior.
(tree_loop_interchange::interchange): Add OPTINFO_SCOPE.
Add optinfo for successful and unsuccessful interchanges.
(prepare_perfect_loop_nest): Add OPTINFO_SCOPE.  Add
optinfo note.
(pass_linterchange::execute): Add OPTINFO_SCOPE.
---
 gcc/gimple-loop-interchange.cc | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc
index eb35263..cd32288 100644
--- a/gcc/gimple-loop-interchange.cc
+++ b/gcc/gimple-loop-interchange.cc
@@ -1556,7 +1556,19 @@ should_interchange_loops (unsigned i_idx, unsigned o_idx,
   ratio = innermost_loops_p ? INNER_STRIDE_RATIO : OUTER_STRIDE_RATIO;
   /* Do interchange if it gives better data locality behavior.  */
   if (wi::gtu_p (iloop_strides, wi::mul (oloop_strides, ratio)))
-return true;
+{
+  if (optinfo_enabled_p ())
+   OPTINFO_NOTE ((gimple *)NULL) // FIXME
+ << "interchange gives better data locality behavior: "
+ << "iloop_strides: "
+ << decu (iloop_strides)
+ << " > (oloop_strides: "
+ << decu (oloop_strides)
+ << " * ratio: "
+ << decu (ratio)
+ << ")";
+  return true;
+}
   if (wi::gtu_p (iloop_strides, oloop_strides))
 {
   /* Or it creates more invariant memory references.  */
@@ -1578,6 +1590,8 @@ bool
 tree_loop_interchange::interchange (vec datarefs,
vec ddrs)
 {
+  OPTINFO_SCOPE ("tree_loop_interchange::interchange", m_loop_nest[0]);
+
   location_t loc = find_loop_location (m_loop_nest[0]);
   bool changed_p = false;
   /* In each iteration we try to interchange I-th loop with (I+1)-th loop.
@@ -1628,6 +1642,10 @@ tree_loop_interchange::interchange 
(vec datarefs,
fprintf (dump_file,
 "Loop_pair is interchanged\n\n",
 oloop.m_loop->num, iloop.m_loop->num);
+ if (optinfo_enabled_p ())
+   OPTINFO_SUCCESS (oloop.m_loop)
+ << optinfo_printf ("Loop_pair is 
interchanged",
+oloop.m_loop->num, iloop.m_loop->num);
 
  changed_p = true;
  interchange_loops (iloop, oloop);
@@ -1641,6 +1659,10 @@ tree_loop_interchange::interchange 
(vec datarefs,
fprintf (dump_file,
 "Loop_pair is not interchanged\n\n",
 oloop.m_loop->num, iloop.m_loop->num);
+ if (optinfo_enabled_p ())
+   OPTINFO_FAILURE (oloop.m_loop)
+ << optinfo_printf ("Loop_pair is not 
interchanged",
+oloop.m_loop->num, iloop.m_loop->num);
}
 }
   simple_dce_from_worklist (m_dce_seeds);
@@ -1648,6 +1670,9 @@ tree_loop_interchange::interchange (vec 
datarefs,
   if (changed_p)
 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
 "loops interchanged in loop nest\n");
+  if (optinfo_enabled_p ())
+OPTINFO_SUCCESS (m_loop_nest[0])
+  << "loops interchanged in loop nest";
 
   return changed_p;
 }
@@ -1971,6 +1996,8 @@ static bool
 prepare_perfect_loop_nest (struct loop *loop, vec *loop_nest,
   vec *datarefs, vec *ddrs)
 {
+  OPTINFO_SCOPE ("prepare_perfect_loop_nest", loop);
+
   struct loop *start_loop = NULL, *innermost = loop;
   struct loop *outermost = loops_for_fn (cfun)->tree_root;
 
@@ -2029,6 +2056,12 @@ prepare_perfect_loop_nest (struct loop *loop, 
vec *loop_nest,
  fprintf (dump_file,
   "\nConsider loop interchange for loop_nest<%d - %d>\n",
   start_loop->num, innermost->num);
+   if (optinfo_enabled_p ())
+ {
+   OPTINFO_NOTE (start_loop)
+ << optinfo_printf ("consider loop interchange for loop_nest<%d - 
%d>",
+start_loop->num, innermost->num);
+ }
 
if (loop != start_loop)
  prune_access_strides_not_in_loop (start_loop, innermost, *datarefs);
@@ -2061,6 +2094,7 @@ pass_linterchange::execute (function *fun)
   struct loop *loop;
   FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
 {
+  OPTINFO_SCOPE ("considering loop for interchange", loop);
   vec loop_nest = vNULL;
   vec datarefs = vNULL;
   vec ddrs = vNULL;
-- 
1.8.5.3