This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] COMPONENT_REFs referring to non-aliasing structures don't alias
- From: Dan Nicolaescu <dann at godzilla dot ICS dot UCI dot EDU>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Kenner <kenner at vlsi1 dot ultra dot nyu dot edu>
- Date: Thu, 07 Mar 2002 11:30:59 -0800
- Subject: [patch] COMPONENT_REFs referring to non-aliasing structures don't alias
The following code:
struct first
{
double d;
int f1;
};
struct second
{
int f2;
short a;
};
void
g0 (struct second s2, struct first s1)
{
s1.f1++;
s2.f2++;
s1.f1++;
}
void
g1 (struct second *s2, struct first *s1)
{
s1->f1++;
s2->f2++;
s1->f1++;
}
compiled with -O2 on sparc-sun-solaris2.7 produces:
g0:
!#PROLOGUE# 0
save %sp, -112, %sp
!#PROLOGUE# 1
ld [%i1+8], %i3
add %i3, 1, %i3
st %i3, [%i1+8]
ld [%i0], %i2
add %i2, 1, %i2
st %i2, [%i0]
ld [%i1+8], %i0 <= extra load
add %i0, 1, %i0
st %i0, [%i1+8]
ret
restore
g1:
!#PROLOGUE# 0
save %sp, -112, %sp
!#PROLOGUE# 1
ld [%i1+8], %i3
add %i3, 1, %i3
st %i3, [%i1+8]
ld [%i0], %i2
add %i2, 1, %i2
st %i2, [%i0]
ld [%i1+8], %i0 <= extra load
add %i0, 1, %i0
st %i0, [%i1+8]
ret
restore
As "struct first" and "struct second" cannot alias, s1.f1 and s2.f2
cannot alias either.
GCC currently has enough information to determine that "struct first"
and "struct second" don't alias, it's just not using it.
The attached patch fixes that. GCC now generates:
g0:
!#PROLOGUE# 0
save %sp, -112, %sp
!#PROLOGUE# 1
ld [%i1+8], %i3
ld [%i0], %i2
add %i3, 2, %i3
add %i2, 1, %i2
st %i2, [%i0]
st %i3, [%i1+8]
ret
restore
g1:
!#PROLOGUE# 0
save %sp, -112, %sp
!#PROLOGUE# 1
ld [%i1+8], %i3
ld [%i0], %i2
add %i3, 2, %i3
add %i2, 1, %i2
st %i2, [%i0]
st %i3, [%i1+8]
ret
restore
after the patch the stripped cc1 binary is slightly smaller:
-rwx------ 1 dann amrm 3227972 Mar 7 10:33 cc1-new*
-rwx------ 1 dann amrm 3230356 Mar 7 10:33 cc1-old*
Comments?
Should the new code go in nonoverlapping_component_refs_p ?
2002-03-07 Dan Nicolaescu <dann@ics.uci.edu>
* alias.c (nonoverlapping_memrefs_p): COMPONENT_REFs
referring to non-aliasing structures don't overlap.
*** alias.c.~1.166.~ Tue Mar 5 23:56:32 2002
--- alias.c Thu Mar 7 11:17:23 2002
*************** nonoverlapping_memrefs_p (x, y)
*** 1913,1921 ****
/* If both are field references, we may be able to determine something. */
if (TREE_CODE (exprx) == COMPONENT_REF
! && TREE_CODE (expry) == COMPONENT_REF
! && nonoverlapping_component_refs_p (exprx, expry))
! return 1;
/* If the field reference test failed, look at the DECLs involved. */
moffsetx = MEM_OFFSET (x);
--- 1923,1946 ----
/* If both are field references, we may be able to determine something. */
if (TREE_CODE (exprx) == COMPONENT_REF
! && TREE_CODE (expry) == COMPONENT_REF)
! {
! if (nonoverlapping_component_refs_p (exprx, expry))
! return 1;
! else
! {
! /* Component refs that belong to structures that are known
! not to alias, don't alias. */
! tree declx = DECL_CONTEXT (TREE_OPERAND (exprx, 1));
! tree decly = DECL_CONTEXT (TREE_OPERAND (expry, 1));
! if (declx != NULL && decly != NULL
! && TREE_CODE (declx) == RECORD_TYPE
! && TREE_CODE (decly) == RECORD_TYPE
! && ! alias_sets_conflict_p (get_alias_set (declx),
! get_alias_set (decly)))
! return 1;
! }
! }
/* If the field reference test failed, look at the DECLs involved. */
moffsetx = MEM_OFFSET (x);