This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] fix char* restrict
- From: Dan Nicolaescu <dann at godzilla dot ICS dot UCI dot EDU>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 06 Mar 2002 12:08:59 -0800
- Subject: [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?