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!
>>>>>
>>
next prev parent 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).