tree-vectorizer.c (get_vec_alignment_for_decl): New static function.
2016-05-20 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> * tree-vectorizer.c (get_vec_alignment_for_decl): New static function. (get_vec_alignment_for_array_decl): Likewise. (get_vec_alignment_for_record_decl): Likewise. (increase_alignment::execute): Move code to find alignment to get_vec_alignment_for_array_decl and call get_vec_alignment_for_decl. (type_align_map): New hash_map. testsuite/ * gcc.dg/vect/section-anchors-vect-70.c: New test-case. * gcc.dg/vect/section-anchors-vect-71.c: Likewise. * gcc.dg/vect/section-anchors-vect-72.c: Likewise. From-SVN: r236502
This commit is contained in:
parent
483c642948
commit
550fa09318
|
@ -1,3 +1,12 @@
|
||||||
|
2016-05-20 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
|
||||||
|
|
||||||
|
* tree-vectorizer.c (get_vec_alignment_for_decl): New static function.
|
||||||
|
(get_vec_alignment_for_array_decl): Likewise.
|
||||||
|
(get_vec_alignment_for_record_decl): Likewise.
|
||||||
|
(increase_alignment::execute): Move code to find alignment to
|
||||||
|
get_vec_alignment_for_array_decl and call get_vec_alignment_for_decl.
|
||||||
|
(type_align_map): New hash_map.
|
||||||
|
|
||||||
2016-05-20 Richard Guenther <rguenther@suse.de>
|
2016-05-20 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
PR tree-optimization/29756
|
PR tree-optimization/29756
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2016-05-20 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
|
||||||
|
|
||||||
|
* gcc.dg/vect/section-anchors-vect-70.c: New test-case.
|
||||||
|
* gcc.dg/vect/section-anchors-vect-71.c: Likewise.
|
||||||
|
* gcc.dg/vect/section-anchors-vect-72.c: Likewise.
|
||||||
|
|
||||||
2016-05-20 Richard Guenther <rguenther@suse.de>
|
2016-05-20 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
PR tree-optimization/29756
|
PR tree-optimization/29756
|
||||||
|
|
|
@ -794,38 +794,142 @@ make_pass_slp_vectorize (gcc::context *ctxt)
|
||||||
This should involve global alignment analysis and in the future also
|
This should involve global alignment analysis and in the future also
|
||||||
array padding. */
|
array padding. */
|
||||||
|
|
||||||
|
static unsigned get_vec_alignment_for_type (tree);
|
||||||
|
static hash_map<tree, unsigned> *type_align_map;
|
||||||
|
|
||||||
|
/* Return alignment of array's vector type corresponding to scalar type.
|
||||||
|
0 if no vector type exists. */
|
||||||
|
static unsigned
|
||||||
|
get_vec_alignment_for_array_type (tree type)
|
||||||
|
{
|
||||||
|
gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
|
||||||
|
|
||||||
|
tree vectype = get_vectype_for_scalar_type (strip_array_types (type));
|
||||||
|
if (!vectype
|
||||||
|
|| !TYPE_SIZE (type)
|
||||||
|
|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
|
||||||
|
|| tree_int_cst_lt (TYPE_SIZE (type), TYPE_SIZE (vectype)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return TYPE_ALIGN (vectype);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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_type (tree type)
|
||||||
|
{
|
||||||
|
gcc_assert (TREE_CODE (type) == RECORD_TYPE);
|
||||||
|
|
||||||
|
unsigned max_align = 0, alignment;
|
||||||
|
HOST_WIDE_INT offset;
|
||||||
|
tree offset_tree;
|
||||||
|
|
||||||
|
if (TYPE_PACKED (type))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
unsigned *slot = type_align_map->get (type);
|
||||||
|
if (slot)
|
||||||
|
return *slot;
|
||||||
|
|
||||||
|
for (tree field = first_field (type);
|
||||||
|
field != NULL_TREE;
|
||||||
|
field = DECL_CHAIN (field))
|
||||||
|
{
|
||||||
|
/* Skip if not FIELD_DECL or if alignment is set by user. */
|
||||||
|
if (TREE_CODE (field) != FIELD_DECL
|
||||||
|
|| DECL_USER_ALIGN (field)
|
||||||
|
|| DECL_ARTIFICIAL (field))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* We don't need to process the type further if offset is variable,
|
||||||
|
since the offsets of remaining members will also be variable. */
|
||||||
|
if (TREE_CODE (DECL_FIELD_OFFSET (field)) != INTEGER_CST
|
||||||
|
|| TREE_CODE (DECL_FIELD_BIT_OFFSET (field)) != INTEGER_CST)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Similarly stop processing the type if offset_tree
|
||||||
|
does not fit in unsigned HOST_WIDE_INT. */
|
||||||
|
offset_tree = bit_position (field);
|
||||||
|
if (!tree_fits_uhwi_p (offset_tree))
|
||||||
|
break;
|
||||||
|
|
||||||
|
offset = tree_to_uhwi (offset_tree);
|
||||||
|
alignment = get_vec_alignment_for_type (TREE_TYPE (field));
|
||||||
|
|
||||||
|
/* Get maximum alignment of vectorized field/array among those members
|
||||||
|
whose offset is multiple of the vector alignment. */
|
||||||
|
if (alignment
|
||||||
|
&& (offset % alignment == 0)
|
||||||
|
&& (alignment > max_align))
|
||||||
|
max_align = alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_align_map->put (type, max_align);
|
||||||
|
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_type (tree type)
|
||||||
|
{
|
||||||
|
if (type == NULL_TREE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
gcc_assert (TYPE_P (type));
|
||||||
|
|
||||||
|
static unsigned alignment = 0;
|
||||||
|
switch (TREE_CODE (type))
|
||||||
|
{
|
||||||
|
case ARRAY_TYPE:
|
||||||
|
alignment = get_vec_alignment_for_array_type (type);
|
||||||
|
break;
|
||||||
|
case RECORD_TYPE:
|
||||||
|
alignment = get_vec_alignment_for_record_type (type);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
alignment = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (alignment > TYPE_ALIGN (type)) ? alignment : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entry point to increase_alignment pass. */
|
||||||
static unsigned int
|
static unsigned int
|
||||||
increase_alignment (void)
|
increase_alignment (void)
|
||||||
{
|
{
|
||||||
varpool_node *vnode;
|
varpool_node *vnode;
|
||||||
|
|
||||||
vect_location = UNKNOWN_LOCATION;
|
vect_location = UNKNOWN_LOCATION;
|
||||||
|
type_align_map = new hash_map<tree, unsigned>;
|
||||||
|
|
||||||
/* Increase the alignment of all global arrays for vectorization. */
|
/* Increase the alignment of all global arrays for vectorization. */
|
||||||
FOR_EACH_DEFINED_VARIABLE (vnode)
|
FOR_EACH_DEFINED_VARIABLE (vnode)
|
||||||
{
|
{
|
||||||
tree vectype, decl = vnode->decl;
|
tree decl = vnode->decl;
|
||||||
tree t;
|
|
||||||
unsigned int alignment;
|
unsigned int alignment;
|
||||||
|
|
||||||
t = TREE_TYPE (decl);
|
if ((decl_in_symtab_p (decl)
|
||||||
if (TREE_CODE (t) != ARRAY_TYPE)
|
&& !symtab_node::get (decl)->can_increase_alignment_p ())
|
||||||
continue;
|
|| DECL_USER_ALIGN (decl) || DECL_ARTIFICIAL (decl))
|
||||||
vectype = get_vectype_for_scalar_type (strip_array_types (t));
|
continue;
|
||||||
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_type (TREE_TYPE (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_printf (MSG_NOTE, "Increasing alignment of decl: ");
|
||||||
dump_generic_expr (MSG_NOTE, TDF_SLIM, decl);
|
dump_generic_expr (MSG_NOTE, TDF_SLIM, decl);
|
||||||
dump_printf (MSG_NOTE, "\n");
|
dump_printf (MSG_NOTE, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete type_align_map;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue