On 23 February 2016 at 22:11, Marek Polacek <[email protected]> wrote: > On Tue, Feb 23, 2016 at 09:49:37PM +0530, Prathamesh Kulkarni wrote: > >> diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c >> index 2b25b45..a6af535 100644 >> --- a/gcc/tree-vectorizer.c >> +++ b/gcc/tree-vectorizer.c >> @@ -794,6 +794,75 @@ make_pass_slp_vectorize (gcc::context *ctxt) >> This should involve global alignment analysis and in the future also >> array padding. */ >> >> +static unsigned get_vec_alignment_for_decl (tree); > > Why the forward decl? Better to topologically sort the functions. The functions get_vec_alignment_for_{record,array}_decl and get_vec_alignment_for_decl() call each other mutually so I suppose I would need to have a forward decl ? > > Also, the functions are missing comments. Thanks, done in this patch.
Thanks,
Prathamesh
>
>> +static unsigned
>> +get_vec_alignment_for_array_decl (tree array_decl)
>> +{
>> + tree type = TREE_TYPE (array_decl);
>> + gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
>> +
>> + tree vectype = get_vectype_for_scalar_type (strip_array_types (type));
>> + return (vectype) ? TYPE_ALIGN (vectype) : 0;
>> +}
>> +
>> +static unsigned
>> +get_vec_alignment_for_record_decl (tree record_decl)
>> +{
>> + tree type = TREE_TYPE (record_decl);
>> + gcc_assert (TREE_CODE (type) == RECORD_TYPE);
>> + unsigned max_align = 0, alignment;
>> + HOST_WIDE_INT offset;
>> +
>> + if (DECL_ARTIFICIAL (record_decl) || TYPE_PACKED (type))
>> + return 0;
>> +
>> + for (tree field = first_field (type);
>> + field != NULL_TREE;
>> + field = DECL_CHAIN (field))
>> + {
>> + /* C++FE puts node "._0" of code TYPE_DECL. skip that. */
>> + if (TREE_CODE (field) != FIELD_DECL)
>> + continue;
>> +
>> + offset = int_byte_position (field);
>> + alignment = get_vec_alignment_for_decl (field);
>> + if (alignment
>> + && (offset % (alignment / BITS_PER_UNIT) == 0)
>> + && (alignment > max_align))
>> + max_align = alignment;
>> + }
>> +
>> + return max_align;
>> +}
>> +
>> +static unsigned
>> +get_vec_alignment_for_decl (tree decl)
>> +{
>> + if (decl == NULL_TREE)
>> + return 0;
>> +
>> + gcc_assert (DECL_P (decl));
>> +
>> + static unsigned alignment = 0;
>> + tree type = TREE_TYPE (decl);
>> +
>> + switch (TREE_CODE (type))
>> + {
>> + case ARRAY_TYPE:
>> + alignment = get_vec_alignment_for_array_decl (decl);
>> + break;
>> + case RECORD_TYPE:
>> + alignment = get_vec_alignment_for_record_decl (decl);
>> + break;
>> + default:
>> + alignment = 0;
>> + break;
>> + }
>> +
>> + return (alignment > DECL_ALIGN (decl)) ? alignment : 0;
>> +}
>> +
>> static unsigned int
>> increase_alignment (void)
>> {
>> @@ -804,23 +873,14 @@ increase_alignment (void)
>> /* Increase the alignment of all global arrays for vectorization. */
>> FOR_EACH_DEFINED_VARIABLE (vnode)
>> {
>> - tree vectype, decl = vnode->decl;
>> - tree t;
>> + tree decl = vnode->decl;
>> unsigned int alignment;
>>
>> - t = TREE_TYPE (decl);
>> - if (TREE_CODE (t) != ARRAY_TYPE)
>> - continue;
>> - vectype = get_vectype_for_scalar_type (strip_array_types (t));
>> - if (!vectype)
>> - continue;
>> - alignment = TYPE_ALIGN (vectype);
>> - if (DECL_ALIGN (decl) >= alignment)
>> - continue;
>> + alignment = get_vec_alignment_for_decl (decl);
>>
>> - if (vect_can_force_dr_alignment_p (decl, alignment))
>> + if (alignment && vect_can_force_dr_alignment_p (decl, alignment))
>> {
>> - vnode->increase_alignment (TYPE_ALIGN (vectype));
>> + vnode->increase_alignment (alignment);
>> dump_printf (MSG_NOTE, "Increasing alignment of decl: ");
>> dump_generic_expr (MSG_NOTE, TDF_SLIM, decl);
>> dump_printf (MSG_NOTE, "\n");
>
>
> Marek
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 2b25b45..d490287 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -794,6 +794,87 @@ make_pass_slp_vectorize (gcc::context *ctxt)
This should involve global alignment analysis and in the future also
array padding. */
+static unsigned get_vec_alignment_for_decl (tree);
+
+/* Return alignment of array's vector type corresponding to scalar type.
+ 0 if no vector type exists. */
+static unsigned
+get_vec_alignment_for_array_decl (tree array_decl)
+{
+ tree type = TREE_TYPE (array_decl);
+ gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+
+ tree vectype = get_vectype_for_scalar_type (strip_array_types (type));
+ return (vectype) ? TYPE_ALIGN (vectype) : 0;
+}
+
+/* Return alignment of field having maximum alignment of vector type
+ corresponding to it's scalar type. For now, we only consider fields whose
+ offset is a multiple of it's vector alignment.
+ 0 if no suitable field is found. */
+static unsigned
+get_vec_alignment_for_record_decl (tree record_decl)
+{
+ tree type = TREE_TYPE (record_decl);
+ gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+ unsigned max_align = 0, alignment;
+ HOST_WIDE_INT offset;
+
+ /* Skip artificial decls like typeinfo decls or if
+ record is packed. */
+ if (DECL_ARTIFICIAL (record_decl) || TYPE_PACKED (type))
+ return 0;
+
+ for (tree field = first_field (type);
+ field != NULL_TREE;
+ field = DECL_CHAIN (field))
+ {
+ /* C++FE puts node "._0" of code TYPE_DECL. skip that. */
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ offset = int_byte_position (field);
+ alignment = get_vec_alignment_for_decl (field);
+ if (alignment
+ && (offset % (alignment / BITS_PER_UNIT) == 0)
+ && (alignment > max_align))
+ max_align = alignment;
+ }
+
+ return max_align;
+}
+
+/* Return alignment of vector type corresponding to decl's scalar type
+ or 0 if it doesn't exist or the vector alignment is lesser than
+ decl's alignment. */
+static unsigned
+get_vec_alignment_for_decl (tree decl)
+{
+ if (decl == NULL_TREE)
+ return 0;
+
+ gcc_assert (DECL_P (decl));
+
+ static unsigned alignment = 0;
+ tree type = TREE_TYPE (decl);
+
+ switch (TREE_CODE (type))
+ {
+ case ARRAY_TYPE:
+ alignment = get_vec_alignment_for_array_decl (decl);
+ break;
+ case RECORD_TYPE:
+ alignment = get_vec_alignment_for_record_decl (decl);
+ break;
+ default:
+ alignment = 0;
+ break;
+ }
+
+ return (alignment > DECL_ALIGN (decl)) ? alignment : 0;
+}
+
+/* Entry point to increase_alignment pass. */
static unsigned int
increase_alignment (void)
{
@@ -804,23 +885,14 @@ increase_alignment (void)
/* Increase the alignment of all global arrays for vectorization. */
FOR_EACH_DEFINED_VARIABLE (vnode)
{
- tree vectype, decl = vnode->decl;
- tree t;
+ tree decl = vnode->decl;
unsigned int alignment;
- t = TREE_TYPE (decl);
- if (TREE_CODE (t) != ARRAY_TYPE)
- continue;
- vectype = get_vectype_for_scalar_type (strip_array_types (t));
- if (!vectype)
- continue;
- alignment = TYPE_ALIGN (vectype);
- if (DECL_ALIGN (decl) >= alignment)
- continue;
-
- if (vect_can_force_dr_alignment_p (decl, alignment))
+ alignment = get_vec_alignment_for_decl (decl);
+
+ if (alignment && vect_can_force_dr_alignment_p (decl, alignment))
{
- vnode->increase_alignment (TYPE_ALIGN (vectype));
+ vnode->increase_alignment (alignment);
dump_printf (MSG_NOTE, "Increasing alignment of decl: ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, decl);
dump_printf (MSG_NOTE, "\n");
ChangeLog
Description: Binary data
