public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Question about the pass_fre about merging if blocks.
@ 2023-10-20 11:47 Hanke Zhang
  2023-10-20 13:33 ` Richard Biener
  0 siblings, 1 reply; 8+ messages in thread
From: Hanke Zhang @ 2023-10-20 11:47 UTC (permalink / raw)
  To: gcc

Hi, I'm trying to make pass_fre work better for me. But I got a
problem. Like the code below:

int glob;

void __attribute__((oninline))
foo() {
  // do nothing meaningful
}

int main() {
  if (glob) {
    foo();
  } else {
    // do something that won't change glob
  }

  if (glob) {
    foo();
  } else {
    // do something that won't change glob
  }
}

I'm trying to merge the two if blocks. And of course it won't work. I
see the code in tree-ssa-structalias.cc, it will do this check:

static bool
pt_solution_includes_1 (struct pt_solution *pt, const_tree decl) {
  // xxxx
  if (pt->nonlocal
      && is_global_var (decl))
    return true;
 // xxxx
}

So the pt->nonlocal will prevent the merge. I would like to ask if I
can make this check less rigid by providing more information about
function foo(). Because obviously the foo function does not change the
value of glob here, but it is caused by the fact that it is noinline.

So if I can prove that foo won't change glob and pass this infomation
to this check, my goal was achieved. Is this possible?

Thanks
Hanke Zhang

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about the pass_fre about merging if blocks.
  2023-10-20 11:47 Question about the pass_fre about merging if blocks Hanke Zhang
@ 2023-10-20 13:33 ` Richard Biener
  2023-10-20 14:33   ` Hanke Zhang
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Biener @ 2023-10-20 13:33 UTC (permalink / raw)
  To: Hanke Zhang; +Cc: gcc

On Fri, Oct 20, 2023 at 1:48 PM Hanke Zhang via Gcc <gcc@gcc.gnu.org> wrote:
>
> Hi, I'm trying to make pass_fre work better for me. But I got a
> problem. Like the code below:
>
> int glob;
>
> void __attribute__((oninline))
> foo() {
>   // do nothing meaningful
> }
>
> int main() {
>   if (glob) {
>     foo();
>   } else {
>     // do something that won't change glob
>   }
>
>   if (glob) {
>     foo();
>   } else {
>     // do something that won't change glob
>   }
> }
>
> I'm trying to merge the two if blocks. And of course it won't work. I
> see the code in tree-ssa-structalias.cc, it will do this check:
>
> static bool
> pt_solution_includes_1 (struct pt_solution *pt, const_tree decl) {
>   // xxxx
>   if (pt->nonlocal
>       && is_global_var (decl))
>     return true;
>  // xxxx
> }
>
> So the pt->nonlocal will prevent the merge. I would like to ask if I
> can make this check less rigid by providing more information about
> function foo(). Because obviously the foo function does not change the
> value of glob here, but it is caused by the fact that it is noinline.
>
> So if I can prove that foo won't change glob and pass this infomation
> to this check, my goal was achieved. Is this possible?

In case 'glob' were static IPA reference has this info and we'd already
use it from call_may_clobber_ref_p.  There's IPA mod-ref which is
a bit more powerful than IPA reference but I think it does not record
this precise info.

Note that the problem with non-static globals is that we do not know
whether they get modified indirectly because they might have their
address take in another TU and that address passed back into the TU.
Usually using LTO helps here and we can promote the decl to hidden
visibility.

Richard.

>
> Thanks
> Hanke Zhang

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about the pass_fre about merging if blocks.
  2023-10-20 13:33 ` Richard Biener
@ 2023-10-20 14:33   ` Hanke Zhang
  2023-10-20 15:26     ` Richard Biener
  0 siblings, 1 reply; 8+ messages in thread
From: Hanke Zhang @ 2023-10-20 14:33 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc

Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 21:33写道:
>
> On Fri, Oct 20, 2023 at 1:48 PM Hanke Zhang via Gcc <gcc@gcc.gnu.org> wrote:
> >
> > Hi, I'm trying to make pass_fre work better for me. But I got a
> > problem. Like the code below:
> >
> > int glob;
> >
> > void __attribute__((oninline))
> > foo() {
> >   // do nothing meaningful
> > }
> >
> > int main() {
> >   if (glob) {
> >     foo();
> >   } else {
> >     // do something that won't change glob
> >   }
> >
> >   if (glob) {
> >     foo();
> >   } else {
> >     // do something that won't change glob
> >   }
> > }
> >
> > I'm trying to merge the two if blocks. And of course it won't work. I
> > see the code in tree-ssa-structalias.cc, it will do this check:
> >
> > static bool
> > pt_solution_includes_1 (struct pt_solution *pt, const_tree decl) {
> >   // xxxx
> >   if (pt->nonlocal
> >       && is_global_var (decl))
> >     return true;
> >  // xxxx
> > }
> >
> > So the pt->nonlocal will prevent the merge. I would like to ask if I
> > can make this check less rigid by providing more information about
> > function foo(). Because obviously the foo function does not change the
> > value of glob here, but it is caused by the fact that it is noinline.
> >
> > So if I can prove that foo won't change glob and pass this infomation
> > to this check, my goal was achieved. Is this possible?
>
> In case 'glob' were static IPA reference has this info and we'd already
> use it from call_may_clobber_ref_p.  There's IPA mod-ref which is
> a bit more powerful than IPA reference but I think it does not record
> this precise info.
>
> Note that the problem with non-static globals is that we do not know
> whether they get modified indirectly because they might have their
> address take in another TU and that address passed back into the TU.
> Usually using LTO helps here and we can promote the decl to hidden
> visibility.

Hi Richard:

Thanks for your replying.

Yeah, I know that. (We do not know whether they get modified
indirectly because they might have their address take in another TU
and that address passed back into the TU.)

But I think in my case, I think I have to let go of some security
concerns. And LTO is enabled already in my case, but that doesn't
help.

So I can understand that the information includes whether Foo uses
glob directly is actually used, but for security reasons, GCC does not
use it as a basis here (pt_solution_includes_1). Right?

So if I want to change the default behavior of GCC, can I use
call_may_clobber_ref_p to check out and make it merge here?

Thanks
Hanke Zhang

>
> Richard.
>
> >
> > Thanks
> > Hanke Zhang

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about the pass_fre about merging if blocks.
  2023-10-20 14:33   ` Hanke Zhang
@ 2023-10-20 15:26     ` Richard Biener
  2023-10-21  8:58       ` Hanke Zhang
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Biener @ 2023-10-20 15:26 UTC (permalink / raw)
  To: Hanke Zhang; +Cc: gcc



> Am 20.10.2023 um 16:33 schrieb Hanke Zhang <hkzhang455@gmail.com>:
> 
> Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 21:33写道:
>> 
>>> On Fri, Oct 20, 2023 at 1:48 PM Hanke Zhang via Gcc <gcc@gcc.gnu.org> wrote:
>>> 
>>> Hi, I'm trying to make pass_fre work better for me. But I got a
>>> problem. Like the code below:
>>> 
>>> int glob;
>>> 
>>> void __attribute__((oninline))
>>> foo() {
>>>  // do nothing meaningful
>>> }
>>> 
>>> int main() {
>>>  if (glob) {
>>>    foo();
>>>  } else {
>>>    // do something that won't change glob
>>>  }
>>> 
>>>  if (glob) {
>>>    foo();
>>>  } else {
>>>    // do something that won't change glob
>>>  }
>>> }
>>> 
>>> I'm trying to merge the two if blocks. And of course it won't work. I
>>> see the code in tree-ssa-structalias.cc, it will do this check:
>>> 
>>> static bool
>>> pt_solution_includes_1 (struct pt_solution *pt, const_tree decl) {
>>>  // xxxx
>>>  if (pt->nonlocal
>>>      && is_global_var (decl))
>>>    return true;
>>> // xxxx
>>> }
>>> 
>>> So the pt->nonlocal will prevent the merge. I would like to ask if I
>>> can make this check less rigid by providing more information about
>>> function foo(). Because obviously the foo function does not change the
>>> value of glob here, but it is caused by the fact that it is noinline.
>>> 
>>> So if I can prove that foo won't change glob and pass this infomation
>>> to this check, my goal was achieved. Is this possible?
>> 
>> In case 'glob' were static IPA reference has this info and we'd already
>> use it from call_may_clobber_ref_p.  There's IPA mod-ref which is
>> a bit more powerful than IPA reference but I think it does not record
>> this precise info.
>> 
>> Note that the problem with non-static globals is that we do not know
>> whether they get modified indirectly because they might have their
>> address take in another TU and that address passed back into the TU.
>> Usually using LTO helps here and we can promote the decl to hidden
>> visibility.
> 
> Hi Richard:
> 
> Thanks for your replying.
> 
> Yeah, I know that. (We do not know whether they get modified
> indirectly because they might have their address take in another TU
> and that address passed back into the TU.)
> 
> But I think in my case, I think I have to let go of some security
> concerns. And LTO is enabled already in my case, but that doesn't
> help.

It’s not security it’s correctness.

> 
> So I can understand that the information includes whether Foo uses
> glob directly is actually used, but for security reasons, GCC does not
> use it as a basis here (pt_solution_includes_1). Right?

I don’t think this function is the correct place for the fix.  I’d instead put it into …

> So if I want to change the default behavior of GCC, can I use
> call_may_clobber_ref_p to check out and

… this function where it would be more targeted.

As said, you are going to miscompile valid code.  Note it should be possible to enhance IPA reference dependent on how foo actually looks like (like if there are no pointer based accesses in it).

Richard.

> make it merge here?
> 
> Thanks
> Hanke Zhang
> 
>> 
>> Richard.
>> 
>>> 
>>> Thanks
>>> Hanke Zhang

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about the pass_fre about merging if blocks.
  2023-10-20 15:26     ` Richard Biener
@ 2023-10-21  8:58       ` Hanke Zhang
  2023-10-21 10:23         ` Richard Biener
  0 siblings, 1 reply; 8+ messages in thread
From: Hanke Zhang @ 2023-10-21  8:58 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc

Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 23:27写道:
>
>
>
> > Am 20.10.2023 um 16:33 schrieb Hanke Zhang <hkzhang455@gmail.com>:
> >
> > Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 21:33写道:
> >>
> >>> On Fri, Oct 20, 2023 at 1:48 PM Hanke Zhang via Gcc <gcc@gcc.gnu.org> wrote:
> >>>
> >>> Hi, I'm trying to make pass_fre work better for me. But I got a
> >>> problem. Like the code below:
> >>>
> >>> int glob;
> >>>
> >>> void __attribute__((oninline))
> >>> foo() {
> >>>  // do nothing meaningful
> >>> }
> >>>
> >>> int main() {
> >>>  if (glob) {
> >>>    foo();
> >>>  } else {
> >>>    // do something that won't change glob
> >>>  }
> >>>
> >>>  if (glob) {
> >>>    foo();
> >>>  } else {
> >>>    // do something that won't change glob
> >>>  }
> >>> }
> >>>
> >>> I'm trying to merge the two if blocks. And of course it won't work. I
> >>> see the code in tree-ssa-structalias.cc, it will do this check:
> >>>
> >>> static bool
> >>> pt_solution_includes_1 (struct pt_solution *pt, const_tree decl) {
> >>>  // xxxx
> >>>  if (pt->nonlocal
> >>>      && is_global_var (decl))
> >>>    return true;
> >>> // xxxx
> >>> }
> >>>
> >>> So the pt->nonlocal will prevent the merge. I would like to ask if I
> >>> can make this check less rigid by providing more information about
> >>> function foo(). Because obviously the foo function does not change the
> >>> value of glob here, but it is caused by the fact that it is noinline.
> >>>
> >>> So if I can prove that foo won't change glob and pass this infomation
> >>> to this check, my goal was achieved. Is this possible?
> >>
> >> In case 'glob' were static IPA reference has this info and we'd already
> >> use it from call_may_clobber_ref_p.  There's IPA mod-ref which is
> >> a bit more powerful than IPA reference but I think it does not record
> >> this precise info.
> >>
> >> Note that the problem with non-static globals is that we do not know
> >> whether they get modified indirectly because they might have their
> >> address take in another TU and that address passed back into the TU.
> >> Usually using LTO helps here and we can promote the decl to hidden
> >> visibility.
> >
> > Hi Richard:
> >
> > Thanks for your replying.
> >
> > Yeah, I know that. (We do not know whether they get modified
> > indirectly because they might have their address take in another TU
> > and that address passed back into the TU.)
> >
> > But I think in my case, I think I have to let go of some security
> > concerns. And LTO is enabled already in my case, but that doesn't
> > help.
>
> It’s not security it’s correctness.
>
> >
> > So I can understand that the information includes whether Foo uses
> > glob directly is actually used, but for security reasons, GCC does not
> > use it as a basis here (pt_solution_includes_1). Right?
>
> I don’t think this function is the correct place for the fix.  I’d instead put it into …
>
> > So if I want to change the default behavior of GCC, can I use
> > call_may_clobber_ref_p to check out and
>
> … this function where it would be more targeted.
>
> As said, you are going to miscompile valid code.  Note it should be possible to enhance IPA reference dependent on how foo actually looks like (like if there are no pointer based accesses in it).

Hi Richard:

Thanks. I understand it now. But I got another problem while handling
this. I create new nodes from existing nodes in my own passes which
are located at all_late_ipa_passes. So when I tried to get the
ipa_reference_optimization_summary in pass_fre, I got nothing because
old nodes were replaced by the new nodes I created before. Is there a
way that I can get the ipa_reference_summay via my new nodes? The main
code of getting ipa_reference_summary is here:

written = ipa_reference_get_written_global (node);

Or is it because I'm replacing nodes in the wrong way?

Thanks
Hanke Zhang

>
> Richard.
>
> > make it merge here?
> >
> > Thanks
> > Hanke Zhang
> >
> >>
> >> Richard.
> >>
> >>>
> >>> Thanks
> >>> Hanke Zhang

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about the pass_fre about merging if blocks.
  2023-10-21  8:58       ` Hanke Zhang
@ 2023-10-21 10:23         ` Richard Biener
  2023-10-21 14:39           ` Hanke Zhang
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Biener @ 2023-10-21 10:23 UTC (permalink / raw)
  To: Hanke Zhang; +Cc: gcc, Jan Hubicka



> Am 21.10.2023 um 10:58 schrieb Hanke Zhang <hkzhang455@gmail.com>:
> 
> Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 23:27写道:
>> 
>> 
>> 
>>>> Am 20.10.2023 um 16:33 schrieb Hanke Zhang <hkzhang455@gmail.com>:
>>> 
>>> Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 21:33写道:
>>>> 
>>>>> On Fri, Oct 20, 2023 at 1:48 PM Hanke Zhang via Gcc <gcc@gcc.gnu.org> wrote:
>>>>> 
>>>>> Hi, I'm trying to make pass_fre work better for me. But I got a
>>>>> problem. Like the code below:
>>>>> 
>>>>> int glob;
>>>>> 
>>>>> void __attribute__((oninline))
>>>>> foo() {
>>>>> // do nothing meaningful
>>>>> }
>>>>> 
>>>>> int main() {
>>>>> if (glob) {
>>>>>   foo();
>>>>> } else {
>>>>>   // do something that won't change glob
>>>>> }
>>>>> 
>>>>> if (glob) {
>>>>>   foo();
>>>>> } else {
>>>>>   // do something that won't change glob
>>>>> }
>>>>> }
>>>>> 
>>>>> I'm trying to merge the two if blocks. And of course it won't work. I
>>>>> see the code in tree-ssa-structalias.cc, it will do this check:
>>>>> 
>>>>> static bool
>>>>> pt_solution_includes_1 (struct pt_solution *pt, const_tree decl) {
>>>>> // xxxx
>>>>> if (pt->nonlocal
>>>>>     && is_global_var (decl))
>>>>>   return true;
>>>>> // xxxx
>>>>> }
>>>>> 
>>>>> So the pt->nonlocal will prevent the merge. I would like to ask if I
>>>>> can make this check less rigid by providing more information about
>>>>> function foo(). Because obviously the foo function does not change the
>>>>> value of glob here, but it is caused by the fact that it is noinline.
>>>>> 
>>>>> So if I can prove that foo won't change glob and pass this infomation
>>>>> to this check, my goal was achieved. Is this possible?
>>>> 
>>>> In case 'glob' were static IPA reference has this info and we'd already
>>>> use it from call_may_clobber_ref_p.  There's IPA mod-ref which is
>>>> a bit more powerful than IPA reference but I think it does not record
>>>> this precise info.
>>>> 
>>>> Note that the problem with non-static globals is that we do not know
>>>> whether they get modified indirectly because they might have their
>>>> address take in another TU and that address passed back into the TU.
>>>> Usually using LTO helps here and we can promote the decl to hidden
>>>> visibility.
>>> 
>>> Hi Richard:
>>> 
>>> Thanks for your replying.
>>> 
>>> Yeah, I know that. (We do not know whether they get modified
>>> indirectly because they might have their address take in another TU
>>> and that address passed back into the TU.)
>>> 
>>> But I think in my case, I think I have to let go of some security
>>> concerns. And LTO is enabled already in my case, but that doesn't
>>> help.
>> 
>> It’s not security it’s correctness.
>> 
>>> 
>>> So I can understand that the information includes whether Foo uses
>>> glob directly is actually used, but for security reasons, GCC does not
>>> use it as a basis here (pt_solution_includes_1). Right?
>> 
>> I don’t think this function is the correct place for the fix.  I’d instead put it into …
>> 
>>> So if I want to change the default behavior of GCC, can I use
>>> call_may_clobber_ref_p to check out and
>> 
>> … this function where it would be more targeted.
>> 
>> As said, you are going to miscompile valid code.  Note it should be possible to enhance IPA reference dependent on how foo actually looks like (like if there are no pointer based accesses in it).
> 
> Hi Richard:
> 
> Thanks. I understand it now. But I got another problem while handling
> this. I create new nodes from existing nodes in my own passes which
> are located at all_late_ipa_passes. So when I tried to get the
> ipa_reference_optimization_summary in pass_fre, I got nothing because
> old nodes were replaced by the new nodes I created before. Is there a
> way that I can get the ipa_reference_summay via my new nodes? The main
> code of getting ipa_reference_summary is here:
> 
> written = ipa_reference_get_written_global (node);
> 
> Or is it because I'm replacing nodes in the wrong way?

Maybe there’s a possibility to create IPA reference info for late introduced clones, Honza might be of help here.  Any reason your pass cannot run during regular IPA processing?  If your clones do not semantically differ you could possibly clone the IPA reference summaries manually.

Richard 

> 
> Thanks
> Hanke Zhang
> 
>> 
>> Richard.
>> 
>>> make it merge here?
>>> 
>>> Thanks
>>> Hanke Zhang
>>> 
>>>> 
>>>> Richard.
>>>> 
>>>>> 
>>>>> Thanks
>>>>> Hanke Zhang

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about the pass_fre about merging if blocks.
  2023-10-21 10:23         ` Richard Biener
@ 2023-10-21 14:39           ` Hanke Zhang
  2023-10-21 16:47             ` Richard Biener
  0 siblings, 1 reply; 8+ messages in thread
From: Hanke Zhang @ 2023-10-21 14:39 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc

Richard Biener <richard.guenther@gmail.com> 于2023年10月21日周六 18:23写道:
>
>
>
> > Am 21.10.2023 um 10:58 schrieb Hanke Zhang <hkzhang455@gmail.com>:
> >
> > Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 23:27写道:
> >>
> >>
> >>
> >>>> Am 20.10.2023 um 16:33 schrieb Hanke Zhang <hkzhang455@gmail.com>:
> >>>
> >>> Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 21:33写道:
> >>>>
> >>>>> On Fri, Oct 20, 2023 at 1:48 PM Hanke Zhang via Gcc <gcc@gcc.gnu.org> wrote:
> >>>>>
> >>>>> Hi, I'm trying to make pass_fre work better for me. But I got a
> >>>>> problem. Like the code below:
> >>>>>
> >>>>> int glob;
> >>>>>
> >>>>> void __attribute__((oninline))
> >>>>> foo() {
> >>>>> // do nothing meaningful
> >>>>> }
> >>>>>
> >>>>> int main() {
> >>>>> if (glob) {
> >>>>>   foo();
> >>>>> } else {
> >>>>>   // do something that won't change glob
> >>>>> }
> >>>>>
> >>>>> if (glob) {
> >>>>>   foo();
> >>>>> } else {
> >>>>>   // do something that won't change glob
> >>>>> }
> >>>>> }
> >>>>>
> >>>>> I'm trying to merge the two if blocks. And of course it won't work. I
> >>>>> see the code in tree-ssa-structalias.cc, it will do this check:
> >>>>>
> >>>>> static bool
> >>>>> pt_solution_includes_1 (struct pt_solution *pt, const_tree decl) {
> >>>>> // xxxx
> >>>>> if (pt->nonlocal
> >>>>>     && is_global_var (decl))
> >>>>>   return true;
> >>>>> // xxxx
> >>>>> }
> >>>>>
> >>>>> So the pt->nonlocal will prevent the merge. I would like to ask if I
> >>>>> can make this check less rigid by providing more information about
> >>>>> function foo(). Because obviously the foo function does not change the
> >>>>> value of glob here, but it is caused by the fact that it is noinline.
> >>>>>
> >>>>> So if I can prove that foo won't change glob and pass this infomation
> >>>>> to this check, my goal was achieved. Is this possible?
> >>>>
> >>>> In case 'glob' were static IPA reference has this info and we'd already
> >>>> use it from call_may_clobber_ref_p.  There's IPA mod-ref which is
> >>>> a bit more powerful than IPA reference but I think it does not record
> >>>> this precise info.
> >>>>
> >>>> Note that the problem with non-static globals is that we do not know
> >>>> whether they get modified indirectly because they might have their
> >>>> address take in another TU and that address passed back into the TU.
> >>>> Usually using LTO helps here and we can promote the decl to hidden
> >>>> visibility.
> >>>
> >>> Hi Richard:
> >>>
> >>> Thanks for your replying.
> >>>
> >>> Yeah, I know that. (We do not know whether they get modified
> >>> indirectly because they might have their address take in another TU
> >>> and that address passed back into the TU.)
> >>>
> >>> But I think in my case, I think I have to let go of some security
> >>> concerns. And LTO is enabled already in my case, but that doesn't
> >>> help.
> >>
> >> It’s not security it’s correctness.
> >>
> >>>
> >>> So I can understand that the information includes whether Foo uses
> >>> glob directly is actually used, but for security reasons, GCC does not
> >>> use it as a basis here (pt_solution_includes_1). Right?
> >>
> >> I don’t think this function is the correct place for the fix.  I’d instead put it into …
> >>
> >>> So if I want to change the default behavior of GCC, can I use
> >>> call_may_clobber_ref_p to check out and
> >>
> >> … this function where it would be more targeted.
> >>
> >> As said, you are going to miscompile valid code.  Note it should be possible to enhance IPA reference dependent on how foo actually looks like (like if there are no pointer based accesses in it).
> >
> > Hi Richard:
> >
> > Thanks. I understand it now. But I got another problem while handling
> > this. I create new nodes from existing nodes in my own passes which
> > are located at all_late_ipa_passes. So when I tried to get the
> > ipa_reference_optimization_summary in pass_fre, I got nothing because
> > old nodes were replaced by the new nodes I created before. Is there a
> > way that I can get the ipa_reference_summay via my new nodes? The main
> > code of getting ipa_reference_summary is here:
> >
> > written = ipa_reference_get_written_global (node);
> >
> > Or is it because I'm replacing nodes in the wrong way?
>
> Maybe there’s a possibility to create IPA reference info for late introduced clones, Honza might be of help here.  Any reason your pass cannot run during regular IPA processing?  If your clones do not semantically differ you could possibly clone the IPA reference summaries manually.

Hi Riichard:

Thanks for your replying again.

I choose to clone the IPA reference summaries manually finally and it
works well. But I find the real problem while doing that. The 'foo' in
my real case is going to change the TU but not for real. Like the code
below:

int glob;
void foo() {
  int tmp = glob;
  glob = 12; //
  // do other things that may use glob
  // ...
  glob = tmp; // glob is back
}

So in this case, the condition below will trap (at: 'bitmap_bit_p
(written, id)'), so I think I have to write another IPA Pass to deal
with the situation and pass the information to the conditions here. Or
is there a better way?

if (node
  && (id = ipa_reference_var_uid (base)) != -1
  && (written = ipa_reference_get_written_global (node))
  && !bitmap_bit_p (written, id))
  return false;

Thanks
Hanke Zhang

>
> Richard
>
> >
> > Thanks
> > Hanke Zhang
> >
> >>
> >> Richard.
> >>
> >>> make it merge here?
> >>>
> >>> Thanks
> >>> Hanke Zhang
> >>>
> >>>>
> >>>> Richard.
> >>>>
> >>>>>
> >>>>> Thanks
> >>>>> Hanke Zhang

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about the pass_fre about merging if blocks.
  2023-10-21 14:39           ` Hanke Zhang
@ 2023-10-21 16:47             ` Richard Biener
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2023-10-21 16:47 UTC (permalink / raw)
  To: Hanke Zhang; +Cc: gcc



> Am 21.10.2023 um 16:39 schrieb Hanke Zhang <hkzhang455@gmail.com>:
> 
> Richard Biener <richard.guenther@gmail.com> 于2023年10月21日周六 18:23写道:
>> 
>> 
>> 
>>>> Am 21.10.2023 um 10:58 schrieb Hanke Zhang <hkzhang455@gmail.com>:
>>> 
>>> Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 23:27写道:
>>>> 
>>>> 
>>>> 
>>>>>> Am 20.10.2023 um 16:33 schrieb Hanke Zhang <hkzhang455@gmail.com>:
>>>>> 
>>>>> Richard Biener <richard.guenther@gmail.com> 于2023年10月20日周五 21:33写道:
>>>>>> 
>>>>>>> On Fri, Oct 20, 2023 at 1:48 PM Hanke Zhang via Gcc <gcc@gcc.gnu.org> wrote:
>>>>>>> 
>>>>>>> Hi, I'm trying to make pass_fre work better for me. But I got a
>>>>>>> problem. Like the code below:
>>>>>>> 
>>>>>>> int glob;
>>>>>>> 
>>>>>>> void __attribute__((oninline))
>>>>>>> foo() {
>>>>>>> // do nothing meaningful
>>>>>>> }
>>>>>>> 
>>>>>>> int main() {
>>>>>>> if (glob) {
>>>>>>>  foo();
>>>>>>> } else {
>>>>>>>  // do something that won't change glob
>>>>>>> }
>>>>>>> 
>>>>>>> if (glob) {
>>>>>>>  foo();
>>>>>>> } else {
>>>>>>>  // do something that won't change glob
>>>>>>> }
>>>>>>> }
>>>>>>> 
>>>>>>> I'm trying to merge the two if blocks. And of course it won't work. I
>>>>>>> see the code in tree-ssa-structalias.cc, it will do this check:
>>>>>>> 
>>>>>>> static bool
>>>>>>> pt_solution_includes_1 (struct pt_solution *pt, const_tree decl) {
>>>>>>> // xxxx
>>>>>>> if (pt->nonlocal
>>>>>>>    && is_global_var (decl))
>>>>>>>  return true;
>>>>>>> // xxxx
>>>>>>> }
>>>>>>> 
>>>>>>> So the pt->nonlocal will prevent the merge. I would like to ask if I
>>>>>>> can make this check less rigid by providing more information about
>>>>>>> function foo(). Because obviously the foo function does not change the
>>>>>>> value of glob here, but it is caused by the fact that it is noinline.
>>>>>>> 
>>>>>>> So if I can prove that foo won't change glob and pass this infomation
>>>>>>> to this check, my goal was achieved. Is this possible?
>>>>>> 
>>>>>> In case 'glob' were static IPA reference has this info and we'd already
>>>>>> use it from call_may_clobber_ref_p.  There's IPA mod-ref which is
>>>>>> a bit more powerful than IPA reference but I think it does not record
>>>>>> this precise info.
>>>>>> 
>>>>>> Note that the problem with non-static globals is that we do not know
>>>>>> whether they get modified indirectly because they might have their
>>>>>> address take in another TU and that address passed back into the TU.
>>>>>> Usually using LTO helps here and we can promote the decl to hidden
>>>>>> visibility.
>>>>> 
>>>>> Hi Richard:
>>>>> 
>>>>> Thanks for your replying.
>>>>> 
>>>>> Yeah, I know that. (We do not know whether they get modified
>>>>> indirectly because they might have their address take in another TU
>>>>> and that address passed back into the TU.)
>>>>> 
>>>>> But I think in my case, I think I have to let go of some security
>>>>> concerns. And LTO is enabled already in my case, but that doesn't
>>>>> help.
>>>> 
>>>> It’s not security it’s correctness.
>>>> 
>>>>> 
>>>>> So I can understand that the information includes whether Foo uses
>>>>> glob directly is actually used, but for security reasons, GCC does not
>>>>> use it as a basis here (pt_solution_includes_1). Right?
>>>> 
>>>> I don’t think this function is the correct place for the fix.  I’d instead put it into …
>>>> 
>>>>> So if I want to change the default behavior of GCC, can I use
>>>>> call_may_clobber_ref_p to check out and
>>>> 
>>>> … this function where it would be more targeted.
>>>> 
>>>> As said, you are going to miscompile valid code.  Note it should be possible to enhance IPA reference dependent on how foo actually looks like (like if there are no pointer based accesses in it).
>>> 
>>> Hi Richard:
>>> 
>>> Thanks. I understand it now. But I got another problem while handling
>>> this. I create new nodes from existing nodes in my own passes which
>>> are located at all_late_ipa_passes. So when I tried to get the
>>> ipa_reference_optimization_summary in pass_fre, I got nothing because
>>> old nodes were replaced by the new nodes I created before. Is there a
>>> way that I can get the ipa_reference_summay via my new nodes? The main
>>> code of getting ipa_reference_summary is here:
>>> 
>>> written = ipa_reference_get_written_global (node);
>>> 
>>> Or is it because I'm replacing nodes in the wrong way?
>> 
>> Maybe there’s a possibility to create IPA reference info for late introduced clones, Honza might be of help here.  Any reason your pass cannot run during regular IPA processing?  If your clones do not semantically differ you could possibly clone the IPA reference summaries manually.
> 
> Hi Riichard:
> 
> Thanks for your replying again.
> 
> I choose to clone the IPA reference summaries manually finally and it
> works well. But I find the real problem while doing that. The 'foo' in
> my real case is going to change the TU but not for real. Like the code
> below:
> 
> int glob;
> void foo() {
>  int tmp = glob;
>  glob = 12; //
>  // do other things that may use glob
>  // ...
>  glob = tmp; // glob is back
> }
> 
> So in this case, the condition below will trap (at: 'bitmap_bit_p
> (written, id)'), so I think I have to write another IPA Pass to deal
> with the situation and pass the information to the conditions here. Or
> is there a better way?

It might be possible to teach IPA reference about this and not record the write.  IIRC there’s a bugreport about a similar situation.

Richard 

> if (node
>  && (id = ipa_reference_var_uid (base)) != -1
>  && (written = ipa_reference_get_written_global (node))
>  && !bitmap_bit_p (written, id))
>  return false;
> 
> Thanks
> Hanke Zhang
> 
>> 
>> Richard
>> 
>>> 
>>> Thanks
>>> Hanke Zhang
>>> 
>>>> 
>>>> Richard.
>>>> 
>>>>> make it merge here?
>>>>> 
>>>>> Thanks
>>>>> Hanke Zhang
>>>>> 
>>>>>> 
>>>>>> Richard.
>>>>>> 
>>>>>>> 
>>>>>>> Thanks
>>>>>>> Hanke Zhang

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-10-21 16:47 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-20 11:47 Question about the pass_fre about merging if blocks Hanke Zhang
2023-10-20 13:33 ` Richard Biener
2023-10-20 14:33   ` Hanke Zhang
2023-10-20 15:26     ` Richard Biener
2023-10-21  8:58       ` Hanke Zhang
2023-10-21 10:23         ` Richard Biener
2023-10-21 14:39           ` Hanke Zhang
2023-10-21 16:47             ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).