Re: Where did my function go?

2020-10-21 Thread Jan Hubicka
> On Wed, Oct 21, 2020 at 5:21 AM Gary Oblock  wrote:
> >
> > >IPA transforms happens when get_body is called.  With LTO this also
> > >trigger reading the body from disk.  So if you want to see all bodies
> > >and work on them, you can simply call get_body on everything but it will
> > >result in increased memory use since everything will be loaded form disk
> > >and expanded (by inlining) at once instead of doing it on per-function
> > >basis.
> > Jan,
> >
> > Doing
> >
> > FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node) node->get_body ();
> >
> > instead of
> >
> > FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node) node->get_untransformed_body ();
> >
> > instantaneously breaks everything...
> 
> I think during WPA you cannot do ->get_body (), only
> ->get_untransformed_body ().  But
> we don't know yet where in the IPA process you're experiencing the issue.

Originally get_body is designed to work in WPA as well: the info about
what transforms are to be applied is kept in a vector with per-function
granuality. But there may be some issues as this path is untested and
i.e ipa-sra/ipa-prop does quite difficult transformations these days.
What happens?

Honza
> 
> Richard.
> 
> > Am I missing something?
> >
> > Gary
> > ____________
> > From: Jan Hubicka 
> > Sent: Tuesday, October 20, 2020 4:34 AM
> > To: Richard Biener 
> > Cc: GCC Development ; Gary Oblock 
> > 
> > Subject: Re: Where did my function go?
> >
> > [EXTERNAL EMAIL NOTICE: This email originated from an external sender. 
> > Please be mindful of safe email handling and proprietary information 
> > protection practices.]
> >
> >
> > > > On Tue, Oct 20, 2020 at 1:02 PM Martin Jambor  wrote:
> > > > >
> > > > > Hi,
> > > > >
> > > > > On Tue, Oct 20 2020, Richard Biener wrote:
> > > > > > On Mon, Oct 19, 2020 at 7:52 PM Gary Oblock 
> > > > > >  wrote:
> > > > > >>
> > > > > >> Richard,
> > > > > >>
> > > > > >> I guess that will work for me. However, since it
> > > > > >> was decided to remove an identical function,
> > > > > >> why weren't the calls to it adjusted to reflect it?
> > > > > >> If the call wasn't transformed that means it will
> > > > > >> be mapped at some later time. Is that mapping
> > > > > >> available to look at? Because using that would
> > > > > >> also be a potential solution (assuming call
> > > > > >> graph information exists for the deleted function.)
> > > > > >
> > > > > > I'm not sure how the transitional cgraph looks like
> > > > > > during WPA analysis (which is what we're talking about?),
> > > > > > but definitely the IL is unmodified in that state.
> > > > > >
> > > > > > Maybe Martin has an idea.
> > > > > >
> > > > >
> > > > > Exactly, the cgraph_edges is where the correct call information is
> > > > > stored until the inlining transformation phase calls
> > > > > cgraph_edge::redirect_call_stmt_to_callee is called on it - inlining 
> > > > > is
> > > > > a special pass in this regard that performs this IPA-infrastructure
> > > > > function in addition to actual inlining.
> > > > >
> > > > > In cgraph means the callee itself but also information in
> > > > > e->callee->clone.param_adjustments which might be interesting for any
> > > > > struct-reorg-like optimizations (...and in future possibly in other
> > > > > transformation summaries).
> > > > >
> > > > > The late IPA passes are in very unfortunate spot here since they run
> > > > > before the real-IPA transformation phases but after unreachable node
> > > > > removals and after clone materializations and so can see some but not
> > > > > all of the changes performed by real IPA passes.  The reason for that 
> > > > > is
> > > > > good cache locality when late IPA passes are either not run at all or
> > > > > only look at small portion of the compilation unit.  In such case IPA
> > > > > transformations of a function are followed by all the late passes
> > > > > working on the same function.
> >

Re: Where did my function go?

2020-10-21 Thread Richard Biener via Gcc
On Wed, Oct 21, 2020 at 5:21 AM Gary Oblock  wrote:
>
> >IPA transforms happens when get_body is called.  With LTO this also
> >trigger reading the body from disk.  So if you want to see all bodies
> >and work on them, you can simply call get_body on everything but it will
> >result in increased memory use since everything will be loaded form disk
> >and expanded (by inlining) at once instead of doing it on per-function
> >basis.
> Jan,
>
> Doing
>
> FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node) node->get_body ();
>
> instead of
>
> FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node) node->get_untransformed_body ();
>
> instantaneously breaks everything...

I think during WPA you cannot do ->get_body (), only
->get_untransformed_body ().  But
we don't know yet where in the IPA process you're experiencing the issue.

Richard.

> Am I missing something?
>
> Gary
> 
> From: Jan Hubicka 
> Sent: Tuesday, October 20, 2020 4:34 AM
> To: Richard Biener 
> Cc: GCC Development ; Gary Oblock 
> Subject: Re: Where did my function go?
>
> [EXTERNAL EMAIL NOTICE: This email originated from an external sender. Please 
> be mindful of safe email handling and proprietary information protection 
> practices.]
>
>
> > > On Tue, Oct 20, 2020 at 1:02 PM Martin Jambor  wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Tue, Oct 20 2020, Richard Biener wrote:
> > > > > On Mon, Oct 19, 2020 at 7:52 PM Gary Oblock 
> > > > >  wrote:
> > > > >>
> > > > >> Richard,
> > > > >>
> > > > >> I guess that will work for me. However, since it
> > > > >> was decided to remove an identical function,
> > > > >> why weren't the calls to it adjusted to reflect it?
> > > > >> If the call wasn't transformed that means it will
> > > > >> be mapped at some later time. Is that mapping
> > > > >> available to look at? Because using that would
> > > > >> also be a potential solution (assuming call
> > > > >> graph information exists for the deleted function.)
> > > > >
> > > > > I'm not sure how the transitional cgraph looks like
> > > > > during WPA analysis (which is what we're talking about?),
> > > > > but definitely the IL is unmodified in that state.
> > > > >
> > > > > Maybe Martin has an idea.
> > > > >
> > > >
> > > > Exactly, the cgraph_edges is where the correct call information is
> > > > stored until the inlining transformation phase calls
> > > > cgraph_edge::redirect_call_stmt_to_callee is called on it - inlining is
> > > > a special pass in this regard that performs this IPA-infrastructure
> > > > function in addition to actual inlining.
> > > >
> > > > In cgraph means the callee itself but also information in
> > > > e->callee->clone.param_adjustments which might be interesting for any
> > > > struct-reorg-like optimizations (...and in future possibly in other
> > > > transformation summaries).
> > > >
> > > > The late IPA passes are in very unfortunate spot here since they run
> > > > before the real-IPA transformation phases but after unreachable node
> > > > removals and after clone materializations and so can see some but not
> > > > all of the changes performed by real IPA passes.  The reason for that is
> > > > good cache locality when late IPA passes are either not run at all or
> > > > only look at small portion of the compilation unit.  In such case IPA
> > > > transformations of a function are followed by all the late passes
> > > > working on the same function.
> > > >
> > > > Late IPA passes are unfortunately second class citizens and I would
> > > > strongly recommend not to use them since they do not fit into our
> > > > otherwise robust IPA framework very well.  We could probably provide a
> > > > mechanism that would allow late IPA passes to run all normal IPA
> > > > transformations on a function so they could clearly see what they are
> > > > looking at, but extensive use would slow compilation down so its use
> > > > would be frowned upon at the very least.
> > >
> > > So IPA PTA does get_body () on the nodes it wants to analyze and I
> > > thought that triggers any pending IPA transforms?
> >
> > Yes, it does (and 

Re: Where did my function go?

2020-10-20 Thread Gary Oblock via Gcc
>IPA transforms happens when get_body is called.  With LTO this also
>trigger reading the body from disk.  So if you want to see all bodies
>and work on them, you can simply call get_body on everything but it will
>result in increased memory use since everything will be loaded form disk
>and expanded (by inlining) at once instead of doing it on per-function
>basis.
Jan,

Doing

FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node) node->get_body ();

instead of

FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node) node->get_untransformed_body ();

instantaneously breaks everything...

Am I missing something?

Gary

From: Jan Hubicka 
Sent: Tuesday, October 20, 2020 4:34 AM
To: Richard Biener 
Cc: GCC Development ; Gary Oblock 
Subject: Re: Where did my function go?

[EXTERNAL EMAIL NOTICE: This email originated from an external sender. Please 
be mindful of safe email handling and proprietary information protection 
practices.]


> > On Tue, Oct 20, 2020 at 1:02 PM Martin Jambor  wrote:
> > >
> > > Hi,
> > >
> > > On Tue, Oct 20 2020, Richard Biener wrote:
> > > > On Mon, Oct 19, 2020 at 7:52 PM Gary Oblock  
> > > > wrote:
> > > >>
> > > >> Richard,
> > > >>
> > > >> I guess that will work for me. However, since it
> > > >> was decided to remove an identical function,
> > > >> why weren't the calls to it adjusted to reflect it?
> > > >> If the call wasn't transformed that means it will
> > > >> be mapped at some later time. Is that mapping
> > > >> available to look at? Because using that would
> > > >> also be a potential solution (assuming call
> > > >> graph information exists for the deleted function.)
> > > >
> > > > I'm not sure how the transitional cgraph looks like
> > > > during WPA analysis (which is what we're talking about?),
> > > > but definitely the IL is unmodified in that state.
> > > >
> > > > Maybe Martin has an idea.
> > > >
> > >
> > > Exactly, the cgraph_edges is where the correct call information is
> > > stored until the inlining transformation phase calls
> > > cgraph_edge::redirect_call_stmt_to_callee is called on it - inlining is
> > > a special pass in this regard that performs this IPA-infrastructure
> > > function in addition to actual inlining.
> > >
> > > In cgraph means the callee itself but also information in
> > > e->callee->clone.param_adjustments which might be interesting for any
> > > struct-reorg-like optimizations (...and in future possibly in other
> > > transformation summaries).
> > >
> > > The late IPA passes are in very unfortunate spot here since they run
> > > before the real-IPA transformation phases but after unreachable node
> > > removals and after clone materializations and so can see some but not
> > > all of the changes performed by real IPA passes.  The reason for that is
> > > good cache locality when late IPA passes are either not run at all or
> > > only look at small portion of the compilation unit.  In such case IPA
> > > transformations of a function are followed by all the late passes
> > > working on the same function.
> > >
> > > Late IPA passes are unfortunately second class citizens and I would
> > > strongly recommend not to use them since they do not fit into our
> > > otherwise robust IPA framework very well.  We could probably provide a
> > > mechanism that would allow late IPA passes to run all normal IPA
> > > transformations on a function so they could clearly see what they are
> > > looking at, but extensive use would slow compilation down so its use
> > > would be frowned upon at the very least.
> >
> > So IPA PTA does get_body () on the nodes it wants to analyze and I
> > thought that triggers any pending IPA transforms?
>
> Yes, it does (and get_untransormed_body does not)
And to bit correct Maritn's explanation: the late IPA passes are
intended to work, though I was mostly planning them for prototyping true
ipa passes and also possibly for implementing passes that inspect only
few functions.

IPA transforms happens when get_body is called.  With LTO this also
trigger reading the body from disk.  So if you want to see all bodies
and work on them, you can simply call get_body on everything but it will
result in increased memory use since everything will be loaded form disk
and expanded (by inlining) at once instead of doing it on per-function
basis.

get_body is simply mean to arrange the body on demand.  The passmanager
uses it before late passes are executed and ipa-pta uses it before it
builds constraints (that is not good for reasons described above).

Clone materialization is also triggered by get_body. The clone
materialization pass mostly happens to remove unreachable function
bodies. I plan to get rid of it, since as we are now better on doing ipa
transforms it brings in a lot of bodies already. For cc1plus it is well
over 1GB of memory.

Honza
>
> Honza
> >
> > Richard.
> >
> > > Martin
> > >


Re: Where did my function go?

2020-10-20 Thread Martin Jambor
Hi,

On Tue, Oct 20 2020, Jan Hubicka wrote:
>> On Tue, Oct 20, 2020 at 1:02 PM Martin Jambor  wrote:
>> >
>> > Hi,
>> >
>> > On Tue, Oct 20 2020, Richard Biener wrote:
>> > > On Mon, Oct 19, 2020 at 7:52 PM Gary Oblock  
>> > > wrote:
>> > >>
>> > >> Richard,
>> > >>
>> > >> I guess that will work for me. However, since it
>> > >> was decided to remove an identical function,
>> > >> why weren't the calls to it adjusted to reflect it?
>> > >> If the call wasn't transformed that means it will
>> > >> be mapped at some later time. Is that mapping
>> > >> available to look at? Because using that would
>> > >> also be a potential solution (assuming call
>> > >> graph information exists for the deleted function.)
>> > >
>> > > I'm not sure how the transitional cgraph looks like
>> > > during WPA analysis (which is what we're talking about?),
>> > > but definitely the IL is unmodified in that state.
>> > >
>> > > Maybe Martin has an idea.
>> > >
>> >
>> > Exactly, the cgraph_edges is where the correct call information is
>> > stored until the inlining transformation phase calls
>> > cgraph_edge::redirect_call_stmt_to_callee is called on it - inlining is
>> > a special pass in this regard that performs this IPA-infrastructure
>> > function in addition to actual inlining.
>> >
>> > In cgraph means the callee itself but also information in
>> > e->callee->clone.param_adjustments which might be interesting for any
>> > struct-reorg-like optimizations (...and in future possibly in other
>> > transformation summaries).
>> >
>> > The late IPA passes are in very unfortunate spot here since they run
>> > before the real-IPA transformation phases but after unreachable node
>> > removals and after clone materializations and so can see some but not
>> > all of the changes performed by real IPA passes.  The reason for that is
>> > good cache locality when late IPA passes are either not run at all or
>> > only look at small portion of the compilation unit.  In such case IPA
>> > transformations of a function are followed by all the late passes
>> > working on the same function.
>> >
>> > Late IPA passes are unfortunately second class citizens and I would
>> > strongly recommend not to use them since they do not fit into our
>> > otherwise robust IPA framework very well.  We could probably provide a
>> > mechanism that would allow late IPA passes to run all normal IPA
>> > transformations on a function so they could clearly see what they are
>> > looking at, but extensive use would slow compilation down so its use
>> > would be frowned upon at the very least.
>> 
>> So IPA PTA does get_body () on the nodes it wants to analyze and I
>> thought that triggers any pending IPA transforms?
>
> Yes, it does (and get_untransormed_body does not)
>

Oh, sorry, I forgot that the function does this in conjunction to
streaming the function in.  So, we actually have the mechanism but it
has the described issues.

Martin





Re: Where did my function go?

2020-10-20 Thread Jan Hubicka
> > On Tue, Oct 20, 2020 at 1:02 PM Martin Jambor  wrote:
> > >
> > > Hi,
> > >
> > > On Tue, Oct 20 2020, Richard Biener wrote:
> > > > On Mon, Oct 19, 2020 at 7:52 PM Gary Oblock  
> > > > wrote:
> > > >>
> > > >> Richard,
> > > >>
> > > >> I guess that will work for me. However, since it
> > > >> was decided to remove an identical function,
> > > >> why weren't the calls to it adjusted to reflect it?
> > > >> If the call wasn't transformed that means it will
> > > >> be mapped at some later time. Is that mapping
> > > >> available to look at? Because using that would
> > > >> also be a potential solution (assuming call
> > > >> graph information exists for the deleted function.)
> > > >
> > > > I'm not sure how the transitional cgraph looks like
> > > > during WPA analysis (which is what we're talking about?),
> > > > but definitely the IL is unmodified in that state.
> > > >
> > > > Maybe Martin has an idea.
> > > >
> > >
> > > Exactly, the cgraph_edges is where the correct call information is
> > > stored until the inlining transformation phase calls
> > > cgraph_edge::redirect_call_stmt_to_callee is called on it - inlining is
> > > a special pass in this regard that performs this IPA-infrastructure
> > > function in addition to actual inlining.
> > >
> > > In cgraph means the callee itself but also information in
> > > e->callee->clone.param_adjustments which might be interesting for any
> > > struct-reorg-like optimizations (...and in future possibly in other
> > > transformation summaries).
> > >
> > > The late IPA passes are in very unfortunate spot here since they run
> > > before the real-IPA transformation phases but after unreachable node
> > > removals and after clone materializations and so can see some but not
> > > all of the changes performed by real IPA passes.  The reason for that is
> > > good cache locality when late IPA passes are either not run at all or
> > > only look at small portion of the compilation unit.  In such case IPA
> > > transformations of a function are followed by all the late passes
> > > working on the same function.
> > >
> > > Late IPA passes are unfortunately second class citizens and I would
> > > strongly recommend not to use them since they do not fit into our
> > > otherwise robust IPA framework very well.  We could probably provide a
> > > mechanism that would allow late IPA passes to run all normal IPA
> > > transformations on a function so they could clearly see what they are
> > > looking at, but extensive use would slow compilation down so its use
> > > would be frowned upon at the very least.
> > 
> > So IPA PTA does get_body () on the nodes it wants to analyze and I
> > thought that triggers any pending IPA transforms?
> 
> Yes, it does (and get_untransormed_body does not)
And to bit correct Maritn's explanation: the late IPA passes are
intended to work, though I was mostly planning them for prototyping true
ipa passes and also possibly for implementing passes that inspect only
few functions.

IPA transforms happens when get_body is called.  With LTO this also
trigger reading the body from disk.  So if you want to see all bodies
and work on them, you can simply call get_body on everything but it will
result in increased memory use since everything will be loaded form disk
and expanded (by inlining) at once instead of doing it on per-function
basis.

get_body is simply mean to arrange the body on demand.  The passmanager
uses it before late passes are executed and ipa-pta uses it before it
builds constraints (that is not good for reasons described above).

Clone materialization is also triggered by get_body. The clone
materialization pass mostly happens to remove unreachable function
bodies. I plan to get rid of it, since as we are now better on doing ipa
transforms it brings in a lot of bodies already. For cc1plus it is well
over 1GB of memory.

Honza
> 
> Honza
> > 
> > Richard.
> > 
> > > Martin
> > >


Re: Where did my function go?

2020-10-20 Thread Jan Hubicka
> On Tue, Oct 20, 2020 at 1:02 PM Martin Jambor  wrote:
> >
> > Hi,
> >
> > On Tue, Oct 20 2020, Richard Biener wrote:
> > > On Mon, Oct 19, 2020 at 7:52 PM Gary Oblock  
> > > wrote:
> > >>
> > >> Richard,
> > >>
> > >> I guess that will work for me. However, since it
> > >> was decided to remove an identical function,
> > >> why weren't the calls to it adjusted to reflect it?
> > >> If the call wasn't transformed that means it will
> > >> be mapped at some later time. Is that mapping
> > >> available to look at? Because using that would
> > >> also be a potential solution (assuming call
> > >> graph information exists for the deleted function.)
> > >
> > > I'm not sure how the transitional cgraph looks like
> > > during WPA analysis (which is what we're talking about?),
> > > but definitely the IL is unmodified in that state.
> > >
> > > Maybe Martin has an idea.
> > >
> >
> > Exactly, the cgraph_edges is where the correct call information is
> > stored until the inlining transformation phase calls
> > cgraph_edge::redirect_call_stmt_to_callee is called on it - inlining is
> > a special pass in this regard that performs this IPA-infrastructure
> > function in addition to actual inlining.
> >
> > In cgraph means the callee itself but also information in
> > e->callee->clone.param_adjustments which might be interesting for any
> > struct-reorg-like optimizations (...and in future possibly in other
> > transformation summaries).
> >
> > The late IPA passes are in very unfortunate spot here since they run
> > before the real-IPA transformation phases but after unreachable node
> > removals and after clone materializations and so can see some but not
> > all of the changes performed by real IPA passes.  The reason for that is
> > good cache locality when late IPA passes are either not run at all or
> > only look at small portion of the compilation unit.  In such case IPA
> > transformations of a function are followed by all the late passes
> > working on the same function.
> >
> > Late IPA passes are unfortunately second class citizens and I would
> > strongly recommend not to use them since they do not fit into our
> > otherwise robust IPA framework very well.  We could probably provide a
> > mechanism that would allow late IPA passes to run all normal IPA
> > transformations on a function so they could clearly see what they are
> > looking at, but extensive use would slow compilation down so its use
> > would be frowned upon at the very least.
> 
> So IPA PTA does get_body () on the nodes it wants to analyze and I
> thought that triggers any pending IPA transforms?

Yes, it does (and get_untransormed_body does not)

Honza
> 
> Richard.
> 
> > Martin
> >


Re: Where did my function go?

2020-10-20 Thread Richard Biener via Gcc
On Tue, Oct 20, 2020 at 1:02 PM Martin Jambor  wrote:
>
> Hi,
>
> On Tue, Oct 20 2020, Richard Biener wrote:
> > On Mon, Oct 19, 2020 at 7:52 PM Gary Oblock  
> > wrote:
> >>
> >> Richard,
> >>
> >> I guess that will work for me. However, since it
> >> was decided to remove an identical function,
> >> why weren't the calls to it adjusted to reflect it?
> >> If the call wasn't transformed that means it will
> >> be mapped at some later time. Is that mapping
> >> available to look at? Because using that would
> >> also be a potential solution (assuming call
> >> graph information exists for the deleted function.)
> >
> > I'm not sure how the transitional cgraph looks like
> > during WPA analysis (which is what we're talking about?),
> > but definitely the IL is unmodified in that state.
> >
> > Maybe Martin has an idea.
> >
>
> Exactly, the cgraph_edges is where the correct call information is
> stored until the inlining transformation phase calls
> cgraph_edge::redirect_call_stmt_to_callee is called on it - inlining is
> a special pass in this regard that performs this IPA-infrastructure
> function in addition to actual inlining.
>
> In cgraph means the callee itself but also information in
> e->callee->clone.param_adjustments which might be interesting for any
> struct-reorg-like optimizations (...and in future possibly in other
> transformation summaries).
>
> The late IPA passes are in very unfortunate spot here since they run
> before the real-IPA transformation phases but after unreachable node
> removals and after clone materializations and so can see some but not
> all of the changes performed by real IPA passes.  The reason for that is
> good cache locality when late IPA passes are either not run at all or
> only look at small portion of the compilation unit.  In such case IPA
> transformations of a function are followed by all the late passes
> working on the same function.
>
> Late IPA passes are unfortunately second class citizens and I would
> strongly recommend not to use them since they do not fit into our
> otherwise robust IPA framework very well.  We could probably provide a
> mechanism that would allow late IPA passes to run all normal IPA
> transformations on a function so they could clearly see what they are
> looking at, but extensive use would slow compilation down so its use
> would be frowned upon at the very least.

So IPA PTA does get_body () on the nodes it wants to analyze and I
thought that triggers any pending IPA transforms?

Richard.

> Martin
>


Re: Where did my function go?

2020-10-20 Thread Martin Jambor
Hi,

On Tue, Oct 20 2020, Richard Biener wrote:
> On Mon, Oct 19, 2020 at 7:52 PM Gary Oblock  wrote:
>>
>> Richard,
>>
>> I guess that will work for me. However, since it
>> was decided to remove an identical function,
>> why weren't the calls to it adjusted to reflect it?
>> If the call wasn't transformed that means it will
>> be mapped at some later time. Is that mapping
>> available to look at? Because using that would
>> also be a potential solution (assuming call
>> graph information exists for the deleted function.)
>
> I'm not sure how the transitional cgraph looks like
> during WPA analysis (which is what we're talking about?),
> but definitely the IL is unmodified in that state.
>
> Maybe Martin has an idea.
>

Exactly, the cgraph_edges is where the correct call information is
stored until the inlining transformation phase calls
cgraph_edge::redirect_call_stmt_to_callee is called on it - inlining is
a special pass in this regard that performs this IPA-infrastructure
function in addition to actual inlining.

In cgraph means the callee itself but also information in
e->callee->clone.param_adjustments which might be interesting for any
struct-reorg-like optimizations (...and in future possibly in other
transformation summaries).

The late IPA passes are in very unfortunate spot here since they run
before the real-IPA transformation phases but after unreachable node
removals and after clone materializations and so can see some but not
all of the changes performed by real IPA passes.  The reason for that is
good cache locality when late IPA passes are either not run at all or
only look at small portion of the compilation unit.  In such case IPA
transformations of a function are followed by all the late passes
working on the same function.

Late IPA passes are unfortunately second class citizens and I would
strongly recommend not to use them since they do not fit into our
otherwise robust IPA framework very well.  We could probably provide a
mechanism that would allow late IPA passes to run all normal IPA
transformations on a function so they could clearly see what they are
looking at, but extensive use would slow compilation down so its use
would be frowned upon at the very least.

Martin



Re: Where did my function go?

2020-10-20 Thread Richard Biener via Gcc
On Mon, Oct 19, 2020 at 7:52 PM Gary Oblock  wrote:
>
> Richard,
>
> I guess that will work for me. However, since it
> was decided to remove an identical function,
> why weren't the calls to it adjusted to reflect it?
> If the call wasn't transformed that means it will
> be mapped at some later time. Is that mapping
> available to look at? Because using that would
> also be a potential solution (assuming call
> graph information exists for the deleted function.)

I'm not sure how the transitional cgraph looks like
during WPA analysis (which is what we're talking about?),
but definitely the IL is unmodified in that state.

Maybe Martin has an idea.

Richard.

> Gary
>
>
>
> 
> From: Richard Biener 
> Sent: Sunday, October 18, 2020 11:28 PM
> To: Gary Oblock 
> Cc: gcc@gcc.gnu.org 
> Subject: Re: Where did my function go?
>
> [EXTERNAL EMAIL NOTICE: This email originated from an external sender. Please 
> be mindful of safe email handling and proprietary information protection 
> practices.]
>
>
> On Fri, Oct 16, 2020 at 9:59 PM Gary Oblock via Gcc  wrote:
> >
> > I have a tiny program composed of a few functions
> > and one of those functions (setupB) has gone missing.
> > Since I need to walk its GIMPLE, this is a problem.
> >
> > The program:
> >
> > -- aux.h -
> > #include "stdlib.h"
> > typedef struct A A_t;
> > typedef struct A B_t;
> > struct A {
> >   int i;
> >   double x;
> > };
> >
> > #define MAX(x,y) ((x)>(y) ? (x) : (y))
> >
> > extern int max1( A_t *, size_t);
> > extern double max2( B_t *, size_t);
> > extern A_t *setupA( size_t);
> > extern B_t *setupB( size_t);
> > -- aux.c 
> > #include "aux.h"
> > #include "stdlib.h"
> >
> > A_t *
> > setupA( size_t size)
> > {
> >   A_t *data = (A_t *)malloc( size * sizeof(A_t));
> >   size_t i;
> >   for( i = 0; i < size; i++ ) {
> > data[i].i = rand();
> > data[i].x = drand48();
> >   }
> >   return data;
> > }
> >
> > B_t *
> > setupB( size_t size)
> > {
> >   B_t *data = (B_t *)malloc( size * sizeof(B_t));
> >   size_t i;
> >   for( i = 0; i < size; i++ ) {
> > data[i].i = rand();
> > data[i].x = drand48();
> >   }
> >   return data;
> > }
> >
> > int
> > max1( A_t *array, size_t len)
> > {
> >   size_t i;
> >   int result = array[0].i;
> >   for( i = 1; i < len; i++  ) {
> > result = MAX( array[i].i, result);
> >   }
> >   return result;
> > }
> >
> > double
> > max2( B_t *array, size_t len)
> > {
> >   size_t i;
> >   double result = array[0].x;
> >   for( i = 1; i < len; i++  ) {
> > result = MAX( array[i].x, result);
> >   }
> >   return result;
> > }
> > -- main.c -
> > #include "stdio.h"
> >
> > A_t *data1;
> >
> > int
> > main(void)
> > {
> >   B_t *data2 = setupB(200);
> >   data1 = setupA(100);
> >
> >   printf("First %d\n" , max1(data1,100));
> >   printf("Second %e\n", max2(data2,200));
> > }
> > 
> >
> > Here is its GIMPLE dump:
> > (for the sole purpose of letting you see
> > with your own eyes that setupB is indeed missing)
> > 
> > Program:
> >   static struct A_t * data1;
> > struct A_t *  (size_t)
> >
> > ;; Function setupA (setupA, funcdef_no=4, decl_uid=4398, cgraph_uid=6, 
> > symbol_order=48) (executed once)
> >
> > setupA (size_t size)
> > {
> >   size_t i;
> >   struct A_t * data;
> >
> >[local count: 118111600]:
> >   _1 = size_8(D) * 16;
> >   data_11 = malloc (_1);
> >   goto ; [100.00%]
> >
> >[local count: 955630225]:
> >   _2 = i_6 * 16;
> >   _3 = data_11 + _2;
> >   _4 = rand ();
> >   _3->i = _4;
> >   _5 = drand48 ();
> >   _3->x = _5;
> >   i_16 = i_6 + 1;
> >
> >[local count: 1073741824]:
> >   # i_6 = PHI <0(2), i_16(3)>
> >   if (i_6 < size_8(D))
> > goto ; [89.00%]
> >   else
> > goto ; [11.00%]
> >
> >[local count: 118111600]:
> >   return data_11;
> >
> > }
> >
> >
> >

Re: Where did my function go?

2020-10-19 Thread Richard Biener via Gcc
On Fri, Oct 16, 2020 at 9:59 PM Gary Oblock via Gcc  wrote:
>
> I have a tiny program composed of a few functions
> and one of those functions (setupB) has gone missing.
> Since I need to walk its GIMPLE, this is a problem.
>
> The program:
>
> -- aux.h -
> #include "stdlib.h"
> typedef struct A A_t;
> typedef struct A B_t;
> struct A {
>   int i;
>   double x;
> };
>
> #define MAX(x,y) ((x)>(y) ? (x) : (y))
>
> extern int max1( A_t *, size_t);
> extern double max2( B_t *, size_t);
> extern A_t *setupA( size_t);
> extern B_t *setupB( size_t);
> -- aux.c 
> #include "aux.h"
> #include "stdlib.h"
>
> A_t *
> setupA( size_t size)
> {
>   A_t *data = (A_t *)malloc( size * sizeof(A_t));
>   size_t i;
>   for( i = 0; i < size; i++ ) {
> data[i].i = rand();
> data[i].x = drand48();
>   }
>   return data;
> }
>
> B_t *
> setupB( size_t size)
> {
>   B_t *data = (B_t *)malloc( size * sizeof(B_t));
>   size_t i;
>   for( i = 0; i < size; i++ ) {
> data[i].i = rand();
> data[i].x = drand48();
>   }
>   return data;
> }
>
> int
> max1( A_t *array, size_t len)
> {
>   size_t i;
>   int result = array[0].i;
>   for( i = 1; i < len; i++  ) {
> result = MAX( array[i].i, result);
>   }
>   return result;
> }
>
> double
> max2( B_t *array, size_t len)
> {
>   size_t i;
>   double result = array[0].x;
>   for( i = 1; i < len; i++  ) {
> result = MAX( array[i].x, result);
>   }
>   return result;
> }
> -- main.c -
> #include "stdio.h"
>
> A_t *data1;
>
> int
> main(void)
> {
>   B_t *data2 = setupB(200);
>   data1 = setupA(100);
>
>   printf("First %d\n" , max1(data1,100));
>   printf("Second %e\n", max2(data2,200));
> }
> 
>
> Here is its GIMPLE dump:
> (for the sole purpose of letting you see
> with your own eyes that setupB is indeed missing)
> 
> Program:
>   static struct A_t * data1;
> struct A_t *  (size_t)
>
> ;; Function setupA (setupA, funcdef_no=4, decl_uid=4398, cgraph_uid=6, 
> symbol_order=48) (executed once)
>
> setupA (size_t size)
> {
>   size_t i;
>   struct A_t * data;
>
>[local count: 118111600]:
>   _1 = size_8(D) * 16;
>   data_11 = malloc (_1);
>   goto ; [100.00%]
>
>[local count: 955630225]:
>   _2 = i_6 * 16;
>   _3 = data_11 + _2;
>   _4 = rand ();
>   _3->i = _4;
>   _5 = drand48 ();
>   _3->x = _5;
>   i_16 = i_6 + 1;
>
>[local count: 1073741824]:
>   # i_6 = PHI <0(2), i_16(3)>
>   if (i_6 < size_8(D))
> goto ; [89.00%]
>   else
> goto ; [11.00%]
>
>[local count: 118111600]:
>   return data_11;
>
> }
>
>
> int  (struct A_t *)
>
> ;; Function max1.constprop (max1.constprop.0, funcdef_no=1, decl_uid=4397, 
> cgraph_uid=5, symbol_order=58) (executed once)
>
> max1.constprop (struct A_t * array)
> {
>   size_t i;
>   int result;
>   size_t len;
>
>[local count: 118111600]:
>
>[local count: 118111600]:
>   result_2 = array_1(D)->i;
>   goto ; [100.00%]
>
>[local count: 955630225]:
>   _4 = i_3 * 16;
>   _5 = array_1(D) + _4;
>   _6 = _5->i;
>   result_8 = MAX_EXPR <_6, result_7>;
>   i_9 = i_3 + 1;
>
>[local count: 1073741824]:
>   # i_3 = PHI <1(2), i_9(3)>
>   # result_7 = PHI 
>   if (i_3 <= 99)
> goto ; [89.00%]
>   else
> goto ; [11.00%]
>
>[local count: 118111600]:
>   # result_10 = PHI 
>   return result_10;
>
> }
>
>
> double  (struct B_t *)
>
> ;; Function max2.constprop (max2.constprop.0, funcdef_no=3, decl_uid=4395, 
> cgraph_uid=3, symbol_order=59) (executed once)
>
> max2.constprop (struct B_t * array)
> {
>   size_t i;
>   double result;
>   size_t len;
>
>[local count: 118111600]:
>
>[local count: 118111600]:
>   result_2 = array_1(D)->x;
>   goto ; [100.00%]
>
>[local count: 955630225]:
>   _4 = i_3 * 16;
>   _5 = array_1(D) + _4;
>   _6 = _5->x;
>   if (_6 > result_7)
> goto ; [50.00%]
>   else
> goto ; [50.00%]
>
>[local count: 477815112]:
>
>[local count: 955630225]:
>   # _10 = PHI 
>   i_8 = i_3 + 1;
>
>[local count: 1073741824]:
>   # i_3 = PHI <1(2), i_8(5)>
>   # result_7 = PHI 
>   if (i_3 <= 199)
> goto ; [89.00%]
>   else
> goto ; [11.00%]
>
>[local count: 118111600]:
>   # result_9 = PHI 
>   return result_9;
>
> }
>
>
> int  (void)
>
> ;; Function main (main, funcdef_no=5, decl_uid=4392, cgraph_uid=1, 
> symbol_order=25) (executed once)
>
> main ()
> {
>   struct B_t * data2;
>
>[local count: 1073741824]:
>   data2_6 = setupB (200);
>   _1 = setupA (100);
>   data1 = _1;
>   _2 = max1 (_1, 100);
>   printf ("First %d\n", _2);
>   _3 = max2 (data2_6, 200);
>   printf ("Second %e\n", _3);
>   return 0;
>
> }
> 
> The pass is invoked at this location in passes.def
>
>   /* Simple IPA passes executed after the regular passes.  In WHOPR mode the
>  passes are executed after partitioning and thus