This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] fix aliasing for chars in global structures - take II



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]