From 1b9191d275f3b600bfb63339cfa291bcceb0edbb Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Fri, 7 Dec 2001 18:49:16 +0000 Subject: [PATCH] extend.texi (Variable Attributes): Document vector_size. 2001-12-07 Aldy Hernandez * doc/extend.texi (Variable Attributes): Document vector_size. * attribs.c (c_common_attribute_table): Add vector_size. (handle_vector_size_attribute): New. (vector_size_helper): New. (decl_attributes): Relayout the decl after calculating attribs. From-SVN: r47764 --- gcc/ChangeLog | 9 +++ gcc/attribs.c | 139 ++++++++++++++++++++++++++++++++++++++++++++ gcc/doc/extend.texi | 42 +++++++++++-- 3 files changed, 184 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 143aa204ab0..04b32b92140 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2001-12-07 Aldy Hernandez + + * doc/extend.texi (Variable Attributes): Document vector_size. + + * attribs.c (c_common_attribute_table): Add vector_size. + (handle_vector_size_attribute): New. + (vector_size_helper): New. + (decl_attributes): Relayout the decl after calculating attribs. + 2001-12-07 Joseph S. Myers * doc/gcc.texi: Don't include install-old.texi. Adjust menu diff --git a/gcc/attribs.c b/gcc/attribs.c index 9322c421106..554591310d9 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -82,6 +82,9 @@ static tree handle_no_limit_stack_attribute PARAMS ((tree *, tree, tree, int, 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[] = @@ -135,6 +138,8 @@ static const struct attribute_spec c_common_attribute_table[] = 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 } }; @@ -363,6 +368,18 @@ decl_attributes (node, attributes, flags) 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) + { + /* Force a recalculation of mode and size. */ + DECL_MODE (*node) = VOIDmode; + DECL_SIZE (*node) = 0; + + layout_decl (*node, 0); + } + if (!no_add_attrs) { tree old_attrs; @@ -1119,6 +1136,128 @@ handle_pure_attribute (node, name, args, flags, no_add_attrs) 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, vector arrays, and + functions returning vectors. For example: + + __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) + || TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == ARRAY_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; +} + +/* HACK. GROSS. This is absolutely disgusting. I wish there was a + better way. + + If we requested a pointer to a vector, build up the pointers that + we stripped off while looking for the inner type. Similarly for + return values from functions. + + 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 (POINTER_TYPE_P (type)) + { + inner = vector_size_helper (TREE_TYPE (type), bottom); + outer = build_pointer_type (inner); + } + else if (TREE_CODE (type) == ARRAY_TYPE) + { + inner = vector_size_helper (TREE_TYPE (type), bottom); + outer = build_array_type (inner, TYPE_VALUES (type)); + } + else if (TREE_CODE (type) == FUNCTION_TYPE) + { + inner = vector_size_helper (TREE_TYPE (type), bottom); + outer = build_function_type (inner, TYPE_VALUES (type)); + } + else + return bottom; + + TREE_READONLY (outer) = TREE_READONLY (type); + TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type); + + return outer; +} + /* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two lists. SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE). diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a6853d8206e..e75a8d600c9 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2794,14 +2794,15 @@ section. 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 +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}, 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}). +@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 @@ -3003,6 +3004,35 @@ 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, +although arrays, pointers, and function return values are allowed in +conjunction with this construct. + +Aggregates with this attribute are invalid, even if they are of 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 even if the size of the structure is the same as the size of +the @code{int}. + @item weak The @code{weak} attribute is described in @xref{Function Attributes}.