[Bug ipa/68871] New: fipa-pta tracks function-level nonlocal
vries at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sat Dec 12 09:48:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68871
Bug ID: 68871
Summary: fipa-pta tracks function-level nonlocal
Product: gcc
Version: 6.0
Status: UNCONFIRMED
Severity: enhancement
Priority: P3
Component: ipa
Assignee: unassigned at gcc dot gnu.org
Reporter: vries at gcc dot gnu.org
Target Milestone: ---
I. one function, ealias
Consider testcase ealias.c:
...
void
foo (int *a)
{
int b;
int *c = a;
int *d = &b;
*c = 1;
*d = 2;
*c = *c + 1;
}
...
compiled with
...
$ gcc ealias.c -O2 -S -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre
...
At ealias, we have:
...
intD.6 bD.1758;
# PT = nonlocal
c_2 = a_1(D);
# PT = { D.1758 }
d_3 = &bD.1758;
...
So:
- c_2 points-to something nonlocal, and
- d_3 points to local b.
This allows disambiguation of the store '*d = 2' with the load in '*c = *c +
1', and dse removes the store:
...
Deleted dead store *d_3 = 2;
...
II. two functions, ealias
Now, consider example ealias-2.c:
...
static void __attribute__((noinline, noclone))
bar (int *c, int *d)
{
*c = 1;
*d = 2;
*c = *c + 1;
}
void
foo (int *a)
{
int b;
bar (a, &b);
}
...
When compiled at -O2, at ealias we have (using the patch at
https://gcc.gnu.org/ml/gcc-patches/2015-12/msg01282.html to get ssa-name info
for default defs):
...
__attribute__((noclone, noinline))
bar (intD.6 * cD.1755, intD.6 * dD.1756)
# PT = nonlocal
# DEFAULT_DEF c_2(D)
# PT = nonlocal
# DEFAULT_DEF d_4(D)
...
So both pointers point to a non-local, and cannot be disambiguated.
III. two functions, fipa-pta
Now, consider example ipa-pta.c (the same as ealias-2.c, but with &b assigned
to a pointer, to expose the points-to info).
...
static void __attribute__((noinline, noclone))
bar (int *c, int *d)
{
*c = 1;
*d = 2;
*c = *c + 1;
}
void
foo (int *a)
{
int b;
int *bp = &b;
bar (a, bp);
}
...
When compiled at -O2 -fipa-pta-fno-tree-ccp -fno-tree-forwprop -fno-tree-fre
-fno-tree-pre, at pta we have:
...
__attribute__((noclone, noinline))
bar (intD.6 * cD.1755, intD.6 * dD.1756)
# PT = nonlocal
# DEFAULT_DEF c_2(D)
# PT = { D.1762 } (nonlocal)
# ALIGN = 4, MISALIGN = 0
# DEFAULT_DEF d_4(D)
...
c_2 points to a nonlocal.
d_4 points to D.1762, which is b in foo:
...
foo (intD.6 * aD.1759)
# PT = nonlocal
# DEFAULT_DEF a_2(D)
{
intD.6 bD.1762;
...
The disambiguation of the memory references relative to the two pointers does
not take place, because:
- b is nonlocal in bar, and
- the nonlocal of c_2 refers to nonlocal to bar.
Still:
- c_2 has the same value as a_3, which is nonlocal to foo, and
- d_2 has the same value as bp_1, which is local to foo
as we can see here:
...
foo (intD.6 * aD.1759)
# PT = nonlocal
# DEFAULT_DEF a_3(D)
{
intD.6 * bpD.1763;
intD.6 bD.1762;
# PT = { D.1762 }
bp_1 = &bD.1762;
...
So it seems the information to make the disambiguation is there in principle.
A more precise analysis could give something along the lines of:
...
__attribute__((noclone, noinline))
bar (intD.6 * cD.1755, intD.6 * dD.1756)
# PT = nonlocal(bar, foo)
# DEFAULT_DEF c_2(D)
# PT = { D.1762 } (local(foo))
# ALIGN = 4, MISALIGN = 0
# DEFAULT_DEF d_4(D)
...
And we could disambiguate c_2 and d_4 because:
- c_2 is nonlocal(foo), and
- d_4 is local(foo).
More information about the Gcc-bugs
mailing list