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]

[RFC] a char* that doesn't alias everything



The C standards specify that a char* should alias everything.
Sometimes this is quite undesirable. 

So here is an implementation of an attribute that only applies to
"char" types and allows char* to not alias all other objects.

Then name of the attribute could surely be improved...

Is an attribute the way to go about implementing this? 
Or it should be a compiler built-in type?  Comments? 


For example:

typedef char __attribute__((__char_no_alias_everything__)) char_no_a;

char_no_a*  cnoarr;
char *carr;
int *iarr;

int
f (int val)
{
  int i;
  for (i = 0; i < val; i++) {
    iarr[i]++;
    cnoarr[i]++;
    iarr[i]++;
  }

}

int
g (int val)
{
  int i;
  for (i = 0; i < val; i++) {
    iarr[i]++;
    carr[i]++;
    iarr[i]++;
  }

}

The SPARC assembly for the loops in the 2 functions is: 

f()                                      g()
.LL5:                              .LL13:                                      
        ldub    [%o4+%o3], %o0             ld      [%g1+%lo(iarr)], %i4
        sll     %o3, 2, %o2                sll     %i5, 2, %i2
        ld      [%o5+%o2], %o1             ld      [%i4+%i2], %i1
        add     %o0, 1, %o0                ld      [%o7+%lo(carr)], %i3
        stb     %o0, [%o4+%o3]             add     %i1, 1, %i1
        add     %o1, 2, %o1                st      %i1, [%i4+%i2]
        add     %o3, 1, %o3                ldub    [%i3+%i5], %i0
        cmp     %o3, %g1                   add     %i0, 1, %i0
        bl      .LL5                       stb     %i0, [%i3+%i5]
        st      %o1, [%o5+%o2]             ld      [%g1+%lo(iarr)], %i1
                                           add     %i5, 1, %i5
                                           ld      [%i1+%i2], %i0
                                           cmp     %i5, %o0
                                           add     %i0, 1, %i0
                                           bl      .LL13
                                           st      %i0, [%i1+%i2]


A testcase: (I don't know how to integrate it in the testsuite)

typedef char __attribute__((__char_no_alias_everything__)) char_no_a;
unsigned int x = 0xdeadbeef;
char_no_a *noint = (char_no_a*) &x;

unsigned short s = 0xbeef;
char_no_a *noshort = (char_no_a*) &s;

_Bool b = (_Bool)1;
char_no_a *nobool = (char_no_a*) &b;


char_no_a cnoa = 'c';
char_no_a *cnoap = &cnoa;

char c = 'd';
char_no_a *cnoap1 = (char_no_a*) &c;

char_no_a cnoa1 = 'e';
char *cp = (char*) &cnoa1;


int
main (void)
{

  /* test that the `char_no_alias_everything' attribute works */
  noint[1] = 0;
  if (x != 0xdeadbeef)
    abort ();

  *noshort = 0;
  if (s != 0xbeef)
    abort ();

  *nobool = 0;
  if (!b)
    abort ();

  /* test that a `char_no_alias_everything' pointer aliases
     a `char_no_alias_everything' char */

  *cnoap = 'b';
  if (cnoa == 'c')
    abort ();

  /* test that a `char_no_alias_everything' pointer doesn't alias char
  */
  *cnoap1 = 'b';
  if (c != 'd')
    abort ();

  /* test that a char*  aliases a `char_no_alias_everything' char */
  *cp = 'b';
  if (cnoa1 == 'e')
    abort ();

  exit (0);
}



The patch: (no docs for now)

2002-01-27 Dan Nicolaescu  <dann@ics.uci.edu>

        * gcc/attribs.c (c_common_attribute_table): Add
        "char_no_alias_everything".
        (handle_char_no_alias_everything_attribute): New function.
        * gcc/c-common.c (c_common_get_alias_set): Don't put a char
        with the
        "char_no_alias_everything" in the alias set zero.

*** c-common.c.~1.287.~	Fri Jan 25 09:37:21 2002
--- c-common.c	Sun Jan 27 12:08:49 2002
***************
*** 2236,2242 ****
       anything.  Note that all references need do this.  */
    if (TREE_CODE_CLASS (TREE_CODE (t)) == 'r'
        && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
!       && TYPE_PRECISION (TREE_TYPE (t)) == TYPE_PRECISION (char_type_node))
      return 0;
  
    /* That's all the expressions we handle specially.  */
--- 2236,2245 ----
       anything.  Note that all references need do this.  */
    if (TREE_CODE_CLASS (TREE_CODE (t)) == 'r'
        && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
!       && TYPE_PRECISION (TREE_TYPE (t)) == TYPE_PRECISION (char_type_node)
!       && ! (! TYPE_P(t) && (lookup_attribute ("char_no_alias_everything",
!                                               TYPE_ATTRIBUTES (TREE_TYPE (t)))
!                            != NULL_TREE)))
      return 0;
  
    /* That's all the expressions we handle specially.  */
*** attribs.c.~1.11.~	Fri Jan 25 09:37:21 2002
--- attribs.c	Sun Jan 27 13:28:08 2002
***************
*** 82,87 ****
--- 82,89 ----
  						     bool *));
  static tree handle_pure_attribute	PARAMS ((tree *, tree, tree, int,
  						 bool *));
+ static tree handle_char_no_alias_everything_attribute PARAMS ((tree *, tree, tree, int,
+                                                     bool *));
  static tree handle_deprecated_attribute	PARAMS ((tree *, tree, tree, int,
  						 bool *));
  static tree handle_vector_size_attribute PARAMS ((tree *, tree, tree, int,
***************
*** 142,149 ****
--- 144,154 ----
  			      handle_pure_attribute },
    { "deprecated",             0, 0, false, false, false,
  			      handle_deprecated_attribute },
+   { "char_no_alias_everything", 0, 0, false, true,  false,
+                               handle_char_no_alias_everything_attribute },
    { "vector_size",	      1, 1, false, true, false,
  			      handle_vector_size_attribute },
+   
    { NULL,                     0, 0, false, false, false, NULL }
  };
  
***************
*** 1202,1207 ****
--- 1207,1236 ----
  
    return NULL_TREE;
  }
+ 
+ /* Handle a "char_no_alias_everything" attribute; arguments as in
+    struct attribute_spec.handler.  */
+    
+ static tree
+ handle_char_no_alias_everything_attribute (node, name, args, flags, no_add_attrs)
+      tree *node;
+      tree name;
+      tree args ATTRIBUTE_UNUSED;
+      int flags ATTRIBUTE_UNUSED;
+      bool *no_add_attrs;
+ {
+   /* the "char_no_alias_everything" attribute applies only to chars */
+   if (! ((TREE_CODE (*node) == INTEGER_TYPE)
+          && (TYPE_PRECISION (*node) == TYPE_PRECISION (char_type_node))))
+     {
+       *no_add_attrs = true;
+       warning ("`%s' attribute ignored", 
+                IDENTIFIER_POINTER (name));
+     }
+ 
+   return NULL_TREE;
+ }
+ 
  
  /* Handle a "vector_size" attribute; arguments as in
     struct attribute_spec.handler.  */


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