patch: vector_size attribute

Aldy Hernandez aldyh@redhat.com
Wed Dec 5 18:12:00 GMT 2001


On Wed, 2001-12-05 at 12:18, Joseph S. Myers wrote:
> On 5 Dec 2001, Aldy Hernandez wrote:
> 
> > everyone's suggestions taken.
> 
> Do pointers to vectors (vector int *foo) work with this patch?  If so,
> there should be tests for them.

yes, fixed the testcase.

i found a couple things broken while adding support for vector pointers,
and richard pointed out a few more.

in the case where we have:

	#define vector __attribute__((vector_size(16))) 
	vector short **foo;

we need to traverse and find the type being modified (short).  then, we
need to build back the pointers.  this is icky, i know.

there's a new change in change_attributes() to re-layout the decl after
we've changed the type-- since a change to the type might need a change
in the decl (particularly the mode).

and finally, there's a change to stor-layout.c: layout_decl wouldn't
reset the mode unless it was VOIDmode.  i believe the mode should be set
regardless-- we have nothing to loose.  i *think* this is the right
approach for layout_decl, let me know...

the problem was that in the above code snippet, foo still maintained an
HI mode instead of an V8HI mode.

and that's all...


2001-12-05  Aldy Hernandez  <aldyh@redhat.com>

	* stor-layout.c (layout_decl): Reset the decl's mode.

	* extend.texi (Variable Attributes): Document vector_size.

	* gcc.dg/altivec-2.c: New.

	* attribs.c (c_common_attribute_table): Add vector_size.
	(handle_vector_size_attribute): New.
	(vector_size_helper): New.

Index: attribs.c
===================================================================
RCS file: /cvs/uberbaum/gcc/attribs.c,v
retrieving revision 1.4
diff -c -p -r1.4 attribs.c
*** attribs.c	2001/11/04 02:51:21	1.4
--- attribs.c	2001/12/06 02:08:00
*************** static tree handle_no_limit_stack_attrib
*** 84,89 ****
--- 84,92 ----
  						     bool *));
  static tree handle_pure_attribute	PARAMS ((tree *, tree, tree, int,
  						 bool *));
+ static tree handle_vector_size_attribute PARAMS ((tree *, tree, tree, int,
+ 						  bool *));
+ static tree vector_size_helper PARAMS ((tree, tree));
  
  /* Table of machine-independent attributes common to all C-like languages.  */
  static const struct attribute_spec c_common_attribute_table[] =
*************** static const struct attribute_spec c_com
*** 139,144 ****
--- 142,149 ----
  			      handle_no_limit_stack_attribute },
    { "pure",                   0, 0, true,  false, false,
  			      handle_pure_attribute },
+   { "vector_size",	      1, 1, false, true, false,
+ 			      handle_vector_size_attribute },
    { NULL,                     0, 0, false, false, false, NULL }
  };
  
*************** decl_attributes (node, attributes, flags
*** 367,372 ****
--- 372,383 ----
  	returned_attrs = chainon ((*spec->handler) (anode, name, args,
  						    flags, &no_add_attrs),
  				  returned_attrs);
+ 
+       /* Layout the decl in case anything changed.  */
+       if (spec->type_required && DECL_P (*node)
+ 	  && TREE_CODE (*node) == VAR_DECL)
+ 	layout_decl (*node, 0);
+ 
        if (!no_add_attrs)
  	{
  	  tree old_attrs;
*************** handle_pure_attribute (node, name, args,
*** 1154,1159 ****
--- 1165,1274 ----
      }
  
    return NULL_TREE;
+ }
+ 
+ /* Handle a "vector_size" attribute; arguments as in
+    struct attribute_spec.handler.  */
+ 
+ static tree
+ handle_vector_size_attribute (node, name, args, flags, no_add_attrs)
+      tree *node;
+      tree name;
+      tree args;
+      int flags ATTRIBUTE_UNUSED;
+      bool *no_add_attrs;
+ {
+   unsigned int vecsize, nunits;
+   enum machine_mode mode, orig_mode, new_mode;
+   tree type = *node, new_type;
+ 
+   *no_add_attrs = true;
+ 
+   if (TREE_CODE (TREE_VALUE (args)) != INTEGER_CST)
+     {
+       warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+       return NULL_TREE;
+     }
+ 
+   /* Get the vector size (in bytes).  */
+   vecsize = TREE_INT_CST_LOW (TREE_VALUE (args));
+ 
+   /* We need to provide for vector pointers like:
+ 
+        __attribute__((vector_size(16))) short *foo;
+ 
+      In this case, the mode is SI, but the type being modified is
+      HI, so we need to look further.  */
+   
+   while (POINTER_TYPE_P (type))
+     type = TREE_TYPE (type);
+ 
+   /* Get the mode of the type being modified.  */
+   orig_mode = TYPE_MODE (type);
+ 
+   if (TREE_CODE (type) == RECORD_TYPE ||
+       (GET_MODE_CLASS (orig_mode) != MODE_FLOAT
+        && GET_MODE_CLASS (orig_mode) != MODE_INT))
+     {
+       error ("invalid vector type for attribute `%s'",
+ 	     IDENTIFIER_POINTER (name));
+       return NULL_TREE;
+     }
+ 
+   /* Calculate how many units fit in the vector.  */
+   nunits = vecsize / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
+ 
+   /* Find a suitably sized vector.  */
+   new_mode = VOIDmode;
+   for (mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_mode) == MODE_INT
+ 					? MODE_VECTOR_INT
+ 					: MODE_VECTOR_FLOAT);
+        mode != VOIDmode;
+        mode = GET_MODE_WIDER_MODE (mode))
+     if (vecsize == GET_MODE_SIZE (mode)	&& nunits == GET_MODE_NUNITS (mode))
+       {
+ 	new_mode = mode;
+ 	break;
+       }
+ 
+   if (new_mode == VOIDmode)
+     error ("no vector mode with the size and type specified could be found");
+   else
+     {
+       new_type = type_for_mode (new_mode, TREE_UNSIGNED (type));
+       if (!new_type)
+ 	error ("no vector mode with the size and type specified could be found");
+       else
+ 	/* Build back pointers if needed.  */
+ 	*node = vector_size_helper (*node, new_type);
+     }
+     
+   return NULL_TREE;
+ }
+ 
+ /* If we requested a pointer to a vector, build up the pointers that
+    we stripped off while looking for the inner type.
+ 
+    The argument "type" is the top of the chain, and "bottom" is the
+    new type which we will point to.  */
+ 
+ static tree
+ vector_size_helper (type, bottom)
+      tree type, bottom;
+ {
+   tree inner, outer;
+ 
+   if (TREE_CODE (type) == POINTER_TYPE)
+     {
+       inner = vector_size_helper (TREE_TYPE (type), bottom);
+       outer = build_pointer_type (inner);
+       TREE_READONLY (outer) = TREE_READONLY (type);
+       TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
+ 
+       return outer;
+     }
+   else
+     return bottom;
  }
  
  /* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
Index: stor-layout.c
===================================================================
RCS file: /cvs/uberbaum/gcc/stor-layout.c,v
retrieving revision 1.113
diff -c -p -r1.113 stor-layout.c
*** stor-layout.c	2001/12/03 15:22:47	1.113
--- stor-layout.c	2001/12/06 02:08:01
*************** layout_decl (decl, known_align)
*** 358,365 ****
       don't set it again since we can be called twice for FIELD_DECLs.  */
  
    TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
!   if (DECL_MODE (decl) == VOIDmode)
!     DECL_MODE (decl) = TYPE_MODE (type);
  
    if (DECL_SIZE (decl) == 0)
      {
--- 358,364 ----
       don't set it again since we can be called twice for FIELD_DECLs.  */
  
    TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
!   DECL_MODE (decl) = TYPE_MODE (type);
  
    if (DECL_SIZE (decl) == 0)
      {
Index: testsuite/gcc.dg/altivec-2.c
===================================================================
RCS file: altivec-2.c
diff -N altivec-2.c
*** /dev/null	Tue May  5 13:32:27 1998
--- altivec-2.c	Wed Dec  5 18:08:01 2001
***************
*** 0 ****
--- 1,23 ----
+ /* { dg-do compile { target powerpc-*-* } } */
+ /* { dg-options "-maltivec" } */
+ 
+ /* Program to test the vector_size attribute.  This needs to run on a
+    target that has vectors, so use AltiVec.  */
+ 
+ #define vector __attribute__((vector_size(16)))
+ 
+ vector int foobar;
+ 
+ /* Only floats and integrals allowed.  We don't care if they map to SIs.  */
+ struct X { int frances; };
+ vector struct X hotdog;	/* { dg-bogus "invalid vector type" "case 1" } */
+ 
+ /* We don't have a V2DF.  */
+ vector double x;	/* { dg-bogus "no vector mode" "case 2" } */
+ 
+ vector short *shoe, polish;
+ 
+ code ()
+ {
+   *shoe = polish;
+ }
Index: doc/extend.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/extend.texi,v
retrieving revision 1.37
diff -c -p -r1.37 extend.texi
*** extend.texi	2001/11/18 03:30:55	1.37
--- extend.texi	2001/12/06 02:08:01
*************** section.
*** 2826,2839 ****
  
  The keyword @code{__attribute__} allows you to specify special
  attributes of variables or structure fields.  This keyword is followed
! by an attribute specification inside double parentheses.  Eight
  attributes are currently defined for variables: @code{aligned},
  @code{mode}, @code{nocommon}, @code{packed}, @code{section},
! @code{transparent_union}, @code{unused}, and @code{weak}.  Some other
! attributes are defined for variables on particular target systems.  Other
! attributes are available for functions (@pxref{Function Attributes}) and
! for types (@pxref{Type Attributes}).  Other front ends might define more
! attributes (@pxref{C++ Extensions,,Extensions to the C++ Language}).
  
  You may also specify attributes with @samp{__} preceding and following
  each keyword.  This allows you to use them in header files without
--- 2826,2840 ----
  
  The keyword @code{__attribute__} allows you to specify special
  attributes of variables or structure fields.  This keyword is followed
! by an attribute specification inside double parentheses.  Nine
  attributes are currently defined for variables: @code{aligned},
  @code{mode}, @code{nocommon}, @code{packed}, @code{section},
! @code{transparent_union}, @code{unused}, @code{vector_size}, and
! @code{weak}.  Some other attributes are defined for variables on
! particular target systems.  Other attributes are available for functions
! (@pxref{Function Attributes}) and for types (@pxref{Type Attributes}).
! Other front ends might define more attributes (@pxref{C++
! Extensions,,Extensions to the C++ Language}).
  
  You may also specify attributes with @samp{__} preceding and following
  each keyword.  This allows you to use them in header files without
*************** applies to all function parameters with 
*** 3034,3039 ****
--- 3035,3065 ----
  This attribute, attached to a variable, means that the variable is meant
  to be possibly unused.  GCC will not produce a warning for this
  variable.
+ 
+ @item vector_size (@var{bytes})
+ This attribute specifies the vector size for the variable, measured in
+ bytes.  For example, the declaration:
+ 
+ @smallexample
+ int foo __attribute__ ((vector_size (16)));
+ @end smallexample
+ 
+ @noindent
+ causes the compiler to set the mode for @code{foo}, to be 16 bytes,
+ divided into @code{int} sized units.  Assuming a 32-bit int (a vector of
+ 4 units of 4 bytes), the corresponding mode of @code{foo} will be V4SI@.
+ 
+ This attribute is only applicable to integral and float scalars.
+ Aggregates with this attribute are invalid, even if they are the same
+ size as a corresponding scalar.  For example, the declaration:
+ 
+ @smallexample
+ struct S { int a; };
+ struct S  __attribute__ ((vector_size (16))) foo;
+ @end smallexample
+ 
+ @noindent
+ is invalid.
  
  @item weak
  The @code{weak} attribute is described in @xref{Function Attributes}.



More information about the Gcc-patches mailing list