Damn. I just sent this mail and found this comment in
gimple-ssa-pta-constraints.cc:create_variable_info_for_1:
3357 /* Collect field information. */
3358 if (use_field_sensitive
3359 && var_can_have_subvars (decl)
3360 /* ??? Force us to not use subfields for globals in IPA mode.
3361 Else we'd have to parse arbitrary initializers. */
So that would explain why I couldn't see separate varinfos for fields. Indeed,
if compile the testcase from my previous mail and dump early PTA (ealias), I
see
a.0+64 = &x
a.64+64 = &y
Now that I know about this, I think I'll be able to find answer to question 1.
Filip
On Tue 2026-09-01 11:09:40, Filip Kastl wrote:
> Hi.
>
> (by aggregates, I will mean C structs and arrays and similar constructs that
> aggregate data from other languages that GCC compiles)
>
> The first question:
> -------------------
>
> I'm trying to understand the IPA PTA code related to shadow vars. In the code
> snippet from tree-ssa-structalias.cc:ipa_pta_execute() below, why do we need
> the second 'for' loop over vi_next()? Are the varinfos that represent fields
> of a global aggregate variable not is_global_var = true? If they were
> is_global_var = true, then the for loop would be redundant, right? (the outer
> for loop would suffice to visit all the varinfos we need to visit)
>
> 1876 /* Now post-process solutions to handle locals from different
> 1877 runtime instantiations coming in through recursive invocations. */
> 1878 unsigned shadow_var_cnt = 0;
> 1879 for (unsigned i = 1; i < varmap.length (); ++i)
> 1880 {
> 1881 varinfo_t fi = get_varinfo (i);
> 1882 if (fi->is_fn_info
> 1883 && fi->decl)
> 1884 /* Automatic variables pointed to by their containing functions
> 1885 parameters need this treatment. */
> 1886 for (varinfo_t ai = first_vi_for_offset (fi, fi_parm_base);
> 1887 ai; ai = vi_next (ai))
> 1888 {
> 1889 varinfo_t vi = get_varinfo (var_rep[ai->id]);
> 1890 bitmap_iterator bi;
> 1891 unsigned j;
> 1892 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
> 1893 {
> 1894 varinfo_t pt = get_varinfo (j);
> 1895 if (pt->shadow_var_uid == 0
> 1896 && pt->decl
> 1897 && auto_var_in_fn_p (pt->decl, fi->decl))
> 1898 {
> 1899 pt->shadow_var_uid = allocate_decl_uid ();
> 1900 shadow_var_cnt++;
> 1901 }
> 1902 }
> 1903 }
> 1904 /* As well as global variables which are another way of passing
> 1905 arguments to recursive invocations. */
> 1906 else if (fi->is_global_var)
> 1907 {
> 1908 for (varinfo_t ai = fi; ai; ai = vi_next (ai))
> 1909 {
> 1910 varinfo_t vi = get_varinfo (var_rep[ai->id]);
> 1911 bitmap_iterator bi;
> 1912 unsigned j;
> 1913 EXECUTE_IF_SET_IN_BITMAP (vi->solution, 0, j, bi)
> 1914 {
> 1915 varinfo_t pt = get_varinfo (j);
> 1916 if (pt->shadow_var_uid == 0
> 1917 && pt->decl
> 1918 && auto_var_p (pt->decl))
> 1919 {
> 1920 pt->shadow_var_uid = allocate_decl_uid ();
> 1921 shadow_var_cnt++;
> 1922 }
> 1923 }
> 1924 }
> 1925 }
> 1926 }
>
> The second question:
> --------------------
>
> I've tried to find the answer to my first question by inspecting how GCC
> represents global aggregate variables in a debugger / look at IPA PTA dumps.
> But this confused me even more because GCC seems to represent the whole
> aggregate with a single varinfo. Like here for example:
>
> struct A {
> int *p;
> int *q;
> } a;
>
> int x;
> int y;
>
> void bar()
> {
> a.p = &x;
> a.q = &y;
> }
>
> int foo()
> {
> return (int) a.p + (int) a.q;
> }
>
> ->
>
> from ipa pta dump:
> a = &x
> a = &y
>
> I would instead expect
> a.p = &x
> a.q = &y
>
> Does GCC's PTA ever represent fields of global aggregate variables as separate
> varinfos? If it does, is there a simple testcase that shows it?
>
> Thanks,
> Filip Kastl