On Tue, 1 Sep 2026, 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))
Yes, I think this loop is redundant - the outer iteration over varmap
should already walk over all subfields and subfields should have
->is_global_var set.
> 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?
/* Collect field information. */
if (use_field_sensitive
&& var_can_have_subvars (decl)
/* ??? Force us to not use subfields for globals in IPA mode.
Else we'd have to parse arbitrary initializers. */
&& !(in_ipa_mode
&& is_global_var (decl)))
so no, due to limits in how we parse global CTORs (-> meaning we
could check here, if there _is_ a CTOR and/or if we can parse it),
we are refraining from this due to correctness issues. Consider
struct S s = { { .ptr = &a }, [7] = &b };
we have no code to walk CTOR elements and figure the PTA subvariable(s)
an initialization overlaps with. Instead we do the very simple
thing,
for-each-CTOR-eleemnt
generate VAR = element constaint
See
/* In IPA mode parse the initializer and generate proper constraints
for it. */
else
{
varpool_node *vnode = varpool_node::get (decl);
...
Richard.
> Thanks,
> Filip Kastl
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)