This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] fix aliasing for chars in global structures - take II
- From: Dan Nicolaescu <dann at godzilla dot ICS dot UCI dot EDU>
- To: "Joseph S. Myers" <jsm28 at cam dot ac dot uk>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 22 Mar 2002 09:21:43 -0800
- Subject: Re: [PATCH] fix aliasing for chars in global structures - take II
- References: <Pine.LNX.4.33.0203202205500.12199-100000@kern.srcf.societies.cam.ac.uk>
I wrote:
> It looks like the guys on comp.std.c aggree that this is optimization
> is OK.
This was just a note to self, was not meant to appear in my
message. The question I asked on comp.std.c is not really related to
this patch (look at the third example), I appologize for the
confusion.
I order to get things cleared up, let's look again at what this patch does.
Currently references to a "char" member of a structure are put in
alias set zero, ie like they are a char*.
The effect of this is shown in the examples below: a store to
ps1->f1 is beleived to alias the value in ps1, ps2 and ps3
struct first { char a; char f1; double d;};
struct second { char b; int f2; int f3;};
struct third { short m; char f3;};
struct first *ps1;
struct second *ps2;
struct third *ps3;
void
g1 (void)
{
ps1->f1++;
ps2->f2++;
ps1->f1++;
ps2->f2++;
}
SPARC assembly (with gcc -O2):
before the patch: after the patch:
g1: g1:
sethi %hi(ps1), %o4 sethi %hi(ps1), %o0
ld [%o4+%lo(ps1)], %o1 sethi %hi(ps2), %o1
sethi %hi(ps2), %o5 ld [%o0+%lo(ps1)], %o3
ldub [%o1+1], %o0 ld [%o1+%lo(ps2)], %o2
add %o0, 1, %o0 ldub [%o3+1], %o0
stb %o0, [%o1+1] ld [%o2+4], %o1
ld [%o5+%lo(ps2)], %o2 add %o0, 2, %o0
ld [%o2+4], %o1 add %o1, 2, %o1
ld [%o4+%lo(ps1)], %o3 stb %o0, [%o3+1]
add %o1, 1, %o1 retl
st %o1, [%o2+4] st %o1, [%o2+4]
ldub [%o3+1], %o0
add %o0, 1, %o0
stb %o0, [%o3+1]
ld [%o5+%lo(ps2)], %o1
ld [%o1+4], %o0
add %o0, 1, %o0
retl
st %o0, [%o1+4]
here after each store to ps1->f1 the values of ps1, ps2 and ps2->f2 are
loaded again.
void
g2 (void)
{
ps1->f1++;
ps1->f1++;
ps1->f1++;
ps1->f1++;
}
g2: g2:
sethi %hi(ps1), %o3 sethi %hi(ps1), %o0
ld [%o3+%lo(ps1)], %o1 ld [%o0+%lo(ps1)], %o2
ldub [%o1+1], %o0 ldub [%o2+1], %o1
add %o0, 1, %o0 add %o1, 4, %o1
stb %o0, [%o1+1] retl
ld [%o3+%lo(ps1)], %o2 stb %o1, [%o2+1]
ldub [%o2+1], %o0
add %o0, 1, %o0
stb %o0, [%o2+1]
ld [%o3+%lo(ps1)], %o1
ldub [%o1+1], %o0
add %o0, 1, %o0
stb %o0, [%o1+1]
ld [%o3+%lo(ps1)], %o2
ldub [%o2+1], %o0
add %o0, 1, %o0
retl
stb %o0, [%o2+1]
here the store to ps1->f1 is assumed to alias ps1, so everything is
reloaded after a store.
void
g3 (void)
{
ps1->f1++;
ps3->f3++;
ps1->f1++;
ps3->f3++;
}
g3: g3:
sethi %hi(ps1), %o3 sethi %hi(ps1), %o0
ld [%o3+%lo(ps1)], %o2 ld [%o0+%lo(ps1)], %o2
sethi %hi(ps3), %o4 ldub [%o2+1], %o1
ldub [%o2+1], %o0 sethi %hi(ps3), %o0
add %o0, 1, %o0 ld [%o0+%lo(ps3)], %o3
stb %o0, [%o2+1] add %o1, 1, %o1
ld [%o4+%lo(ps3)], %o1 stb %o1, [%o2+1]
ldub [%o1+2], %o0 ldub [%o3+2], %o0
add %o0, 1, %o0 add %o0, 1, %o0
stb %o0, [%o1+2] stb %o0, [%o3+2]
ld [%o3+%lo(ps1)], %o2 ldub [%o2+1], %o1
ldub [%o2+1], %o0 add %o1, 1, %o1
add %o0, 1, %o0 stb %o1, [%o2+1]
stb %o0, [%o2+1] ldub [%o3+2], %o0
ld [%o4+%lo(ps3)], %o1 add %o0, 1, %o0
ldub [%o1+2], %o0 retl
add %o0, 1, %o0 stb %o0, [%o3+2]
retl
stb %o0, [%o1+2]
here ps1->f1 and ps3->f3 are assumed to alias ps1 and ps3.
Note that in the new code ps1->f1 and ps3->f3 are still assumed to
alias each other.
Hope things are a little bit more clear now and the patch can be
reviewed...
Thanks.
--dan