> Am 21.10.2023 um 16:39 schrieb Hanke Zhang <hkzhang...@gmail.com>:
>
> Richard Biener <richard.guent...@gmail.com> 于2023年10月21日周六 18:23写道:
>>
>>
>>
>>>> Am 21.10.2023 um 10:58 schrieb Hanke Zhang <hkzhang...@gmail.com>:
>>>
>>> Richard Biener <richard.guent...@gmail.com> 于2023年10月20日周五 23:27写道:
>>>>
>>>>
>>>>
>>>>>> Am 20.10.2023 um 16:33 schrieb Hanke Zhang <hkzhang...@gmail.com>:
>>>>>
>>>>> Richard Biener <richard.guent...@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