On 23 February 2016 at 22:11, Marek Polacek <pola...@redhat.com> 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