Re: Where did my function go?
> 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?
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?
>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?
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?
> > 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?
> 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?
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?
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?
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?
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