public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Erick Ochoa <erick.ochoa@theobroma-systems.com>
To: Richard Biener <richard.guenther@gmail.com>, gcc@gcc.gnu.org
Cc: "Philipp Tomsich" <philipp.tomsich@theobroma-systems.com>,
	"Christoph Müllner" <christoph.muellner@theobroma-systems.com>
Subject: Re: Do all global structure variables escape in IPA-PTA?
Date: Wed, 26 Aug 2020 11:46:03 +0200	[thread overview]
Message-ID: <0410d1bb-33d0-4491-74f6-4ba59dd8c0d0@theobroma-systems.com> (raw)
In-Reply-To: <7832399a-ead9-37a8-397e-af4d376af5ed@theobroma-systems.com>



On 26/08/2020 10:36, Erick Ochoa wrote:
> 
> 
> On 25/08/2020 22:03, Richard Biener wrote:
>> On August 25, 2020 6:36:19 PM GMT+02:00, Erick Ochoa 
>> <erick.ochoa@theobroma-systems.com> wrote:
>>>
>>>
>>> On 25/08/2020 17:19, Erick Ochoa wrote:
>>>>
>>>>
>>>> On 25/08/2020 17:10, Richard Biener wrote:
>>>>> On August 25, 2020 3:09:13 PM GMT+02:00, Erick Ochoa
>>>>> <erick.ochoa@theobroma-systems.com> wrote:
>>>>>> Hi,
>>>>>>
>>>>>> I'm trying to understand how the escape analysis in IPA-PTA works.
>>> I
>>>>>> was
>>>>>> testing a hypothesis where if a structure contains an array of
>>>>>> characters and this array of characters is passed to fopen, the
>>>>>> structure and all subfields will escape.
>>>>>>
>>>>>> To do this, I made a program that has a global structure variable
>>> foo2
>>>>>> that is has a field passed as an argument to fopen. I also made
>>> another
>>>>>>
>>>>>> variable foo whose array is initialized by the result of rand.
>>>>>>
>>>>>> However, after compiling this program with -flto
>>> -flto-partition=none
>>>>>> -fipa -fdump-ipa-pta -fdump-tree-all-all -Ofast (gcc --version
>>> 10.2.0)
>>>>>>
>>>>>> E.g.
>>>>>>
>>>>>> #include <stdio.h>
>>>>>> #include <math.h>
>>>>>> #include <string.h>
>>>>>>
>>>>>> struct foo_t {
>>>>>>     char buffer1[100];
>>>>>>     char buffer2[100];
>>>>>> };
>>>>>>
>>>>>> struct foo_t foo;
>>>>>> struct foo_t foo2;
>>>>>>
>>>>>> int
>>>>>> main(int argc, char** argv)
>>>>>> {
>>>>>>
>>>>>>     fopen(foo2.buffer1, "r");
>>>>>>     for (int i = 0; i < 100; i++)
>>>>>>     {
>>>>>>       foo.buffer1[i] = rand();
>>>>>>     }
>>>>>>     int i = rand();
>>>>>>     int retval = foo.buffer1[i % 100];
>>>>>>     return retval;
>>>>>> }
>>>>>>
>>>>>> I see the PTA dump state the following:
>>>>>>
>>>>>> ESCAPED = { STRING ESCAPED NONLOCAL foo2 }
>>>>>> foo = { ESCAPED NONLOCAL }
>>>>>> foo2 = { ESCAPED NONLOCAL }
>>>>>>
>>>>>> which I understand as
>>>>>> * something externally visible might point to foo2
>>>>>> * foo2 might point to something externally visible
>>>>>> * foo might point to something externally visible
>>>>>
>>>>> Yes. So it's exactly as your hypothesis.
>>>>>
>>>>>> I have seen that global variables are stored in the .gnu.lto_.decls
>>> LTO
>>>>>>
>>>>>> file section. In the passes I have worked on I have ignored global
>>>>>> variables. But can foo and foo2 be marked as escaping because the
>>>>>> declarations are not streamed in yet? Or is there another reason I
>>> am
>>>>>> not seeing? I am aware of aware of the several TODOs at the
>>> beginning
>>>>>> of
>>>>>> gcc/tree-ssa-structalias.c but I am unsure if they contribute to
>>> these
>>>>>> variables being marked as escaping. (Maybe TODO 1 and TODO 2?)
>>>>>
>>>>> Not sure what the problem is. Foo2 escapes because it's address is
>>>>> passed to a function.
>>>>>
>>>>
>>>> foo2 is not the problem, it is foo. foo is not passed to a function
>>> and
>>>> it is also escaping.
>>>
>>>
>>> Sorry, I meant: foo might point to something which is externally
>>> visible. Which I don't think is the case in the program. I understand
>>> this might be due to the imprecision in the escape-analysis and what
>>> I'm
>>> trying to find out is the source of imprecision.
>>
>> Foo is exported and thus all function calls can store to it making it 
>> point to escaped and nonlocal variables.
> 
> Hi Richard,
> 
> I'm still not sure why foo can point to escaped and nonlocal variables.
> 
> My understanding is that ipa-visibility can mark variables and functions 
> as not externally visible. Which I think is equivalent to excluding 
> these symbols from the export table. I have printed the results of 
> vnode->externally_visible and vnode->externally_visible_p() of foo and 
> foo2 and both predicates return 0. (This is in a pass just before 
> IPA-PTA). I think this means that both variables are not exported. 
> IPA-PTA still says that foo can point to escaped memory.
> 
> ESCAPED = { NULL STRING ESCAPED NONLOCAL foo2 } // correct
> foo = { ESCAPED NONLOCAL } same as _4 // my question
> foo2 = { ESCAPED NONLOCAL } // correct
> 
> I then later declared foo as static. Which I think should mark the 
> variable for internal linkage only. IPA-PTA still says that foo can 
> point to escaped memory.
> 
> I also used the -fwhole-program flag and IPA-PTA still says that foo can 
> point to escaped memory.
> 
> Am I failing to specify that foo must *not* be exported? Or IPA-PTA does 
> not considering the visibility of symbols? Or there is something else 
> I'm missing?

Hi Richard,

I think the reason why the global variables escape is because probably 
is_ipa_escape_point is not being used in all the places. According to 
the comments in tree-ssa-structalias.c

    The is_global_var bit which marks escape points is overly conservative
    in IPA mode.  Split it to is_escape_point and is_global_var - only
    externally visible globals are escape points in IPA mode.
    There is now is_ipa_escape_point but this is only used in a few
    selected places.

I had read this before, but the test I had made originally tested to see 
if a subfield escapes the whole global structure also escapes. I think 
there's another comment in tree-ssa-structalias.c that comments on this:

       /* ???  Force us to not use subfields for globals in IPA mode.
          Else we'd have to parse arbitrary initializers.  */

Thanks!


> 
> Thanks!
> 
>>
>> Richard.
>>
>>>>
>>>>> ?
>>>>>
>>>>> Richard.
>>>>>
>>>>>> Just FYI, I've been reading:
>>>>>> * Structure Aliasing in GCC
>>>>>> * Gimple Alias Improvements for GCC 4.5
>>>>>> * Memory SSA - A Unified Approach for Sparsely Representing Memory
>>>>>> Operations
>>>>>>
>>>>>> Thanks, I appreciate all help!
>>>>>
>>

  reply	other threads:[~2020-08-26  9:45 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-25 13:09 Erick Ochoa
2020-08-25 15:10 ` Richard Biener
2020-08-25 15:19   ` Erick Ochoa
2020-08-25 16:36     ` Erick Ochoa
2020-08-25 20:03       ` Richard Biener
2020-08-26  8:36         ` Erick Ochoa
2020-08-26  9:46           ` Erick Ochoa [this message]
2020-08-26 11:14             ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0410d1bb-33d0-4491-74f6-4ba59dd8c0d0@theobroma-systems.com \
    --to=erick.ochoa@theobroma-systems.com \
    --cc=christoph.muellner@theobroma-systems.com \
    --cc=gcc@gcc.gnu.org \
    --cc=philipp.tomsich@theobroma-systems.com \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).