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]

[patch] fix char* restrict



It seems that restricted char*s don't work. 
For example the following code:

void
g (char * __restrict__ a, char * __restrict__ b, int n)
{
  int i;
  for (i = 0; i < n; i++){
    a[i] += b[i];
    b[i] += a[i];
  }
}

when compiled with -O2 on SPARC generates: 

g:
        !#PROLOGUE# 0
        !#PROLOGUE# 1
        mov     0, %o3
        mov     %o0, %o5
        cmp     %o3, %o2
        bge     .LL8
        mov     %o1, %o4
        ldub    [%o4+%o3], %o1
.LL9:
        ldub    [%o5+%o3], %o0
        add     %o0, %o1, %o0
        stb     %o0, [%o5+%o3]
        ldub    [%o4+%o3], %o1
        add     %o1, %o0, %o1
        stb     %o1, [%o4+%o3]
        add     %o3, 1, %o3
        cmp     %o3, %o2
        bl,a    .LL9
        ldub    [%o4+%o3], %o1       <- extra load
.LL8:
        retl
        nop

It looks like this is coming from the refence to a[i] being put in
alias set zero by get_alias_set 

alias.c:get_alias_set  calls c-common.c:c_common_get_alias_set 
that returns zero for a char*. 
get_alias_set sees the zero and returns without checking if the "char*"
is a "char* restrict"

A hacky way to fix this is shown below:

*** alias.c.~1.165.~	Sat Feb 16 11:04:35 2002
--- alias.c	Sun Feb 17 11:36:19 2002
***************
*** 465,473 ****
  	 something with this tree before we look at it.  */
        STRIP_NOPS (t);
        set = (*lang_hooks.get_alias_set) (t);
-       if (set != -1)
- 	return set;
  
        /* First see if the actual object referenced is an INDIRECT_REF from a
  	 restrict-qualified pointer or a "void *".  Replace
  	 PLACEHOLDER_EXPRs.  */
--- 465,483 ----
  	 something with this tree before we look at it.  */
        STRIP_NOPS (t);
        set = (*lang_hooks.get_alias_set) (t);
  
+       /* If the returned value is zero, t might be a char*.  Don't
+          return in that case to check if it's a char* restrict
+          bellow. */
+       if (set == 0
+           && TREE_CODE_CLASS (TREE_CODE (t)) == 'r'
+           && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
+           && TYPE_PRECISION (TREE_TYPE (t)) == TYPE_PRECISION (char_type_node))
+         ;
+       else
+         if (set != -1)
+           return set;
+       
        /* First see if the actual object referenced is an INDIRECT_REF from a
  	 restrict-qualified pointer or a "void *".  Replace
  	 PLACEHOLDER_EXPRs.  */


after this the generated code is:

g:
        !#PROLOGUE# 0
        !#PROLOGUE# 1
        mov     0, %o3
        mov     %o0, %o5
        cmp     %o3, %o2
        bge     .LL8
        mov     %o1, %o4
        ldub    [%o4+%o3], %o0
.LL9:
        ldub    [%o5+%o3], %o1
        add     %o1, %o0, %o1
        add     %o0, %o1, %o0
        stb     %o0, [%o4+%o3]
        stb     %o1, [%o5+%o3]
        add     %o3, 1, %o3
        cmp     %o3, %o2
        bl,a    .LL9
        ldub    [%o4+%o3], %o0
.LL8:
        retl
        nop


Can anybody think of a better way of fixing this? 



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