aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-data-refs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r--gcc/tree-vect-data-refs.c94
1 files changed, 65 insertions, 29 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 5f08cdf..8d9acd8 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -819,7 +819,7 @@ vect_record_base_alignments (vec_info *vinfo)
/* Return the target alignment for the vectorized form of DR_INFO. */
-static unsigned int
+static poly_uint64
vect_calculate_target_alignment (dr_vec_info *dr_info)
{
tree vectype = STMT_VINFO_VECTYPE (dr_info->stmt);
@@ -862,10 +862,14 @@ vect_compute_data_ref_alignment (dr_vec_info *dr_info)
innermost_loop_behavior *drb = vect_dr_behavior (dr_info);
bool step_preserves_misalignment_p;
- unsigned HOST_WIDE_INT vector_alignment
- = vect_calculate_target_alignment (dr_info) / BITS_PER_UNIT;
+ poly_uint64 vector_alignment
+ = exact_div (vect_calculate_target_alignment (dr_info), BITS_PER_UNIT);
DR_TARGET_ALIGNMENT (dr_info) = vector_alignment;
+ unsigned HOST_WIDE_INT vect_align_c;
+ if (!vector_alignment.is_constant (&vect_align_c))
+ return;
+
/* No step for BB vectorization. */
if (!loop)
{
@@ -882,7 +886,7 @@ vect_compute_data_ref_alignment (dr_vec_info *dr_info)
else if (nested_in_vect_loop_p (loop, stmt_info))
{
step_preserves_misalignment_p
- = (DR_STEP_ALIGNMENT (dr_info->dr) % vector_alignment) == 0;
+ = (DR_STEP_ALIGNMENT (dr_info->dr) % vect_align_c) == 0;
if (dump_enabled_p ())
{
@@ -904,7 +908,7 @@ vect_compute_data_ref_alignment (dr_vec_info *dr_info)
{
poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
step_preserves_misalignment_p
- = multiple_p (DR_STEP_ALIGNMENT (dr_info->dr) * vf, vector_alignment);
+ = multiple_p (DR_STEP_ALIGNMENT (dr_info->dr) * vf, vect_align_c);
if (!step_preserves_misalignment_p && dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -923,7 +927,7 @@ vect_compute_data_ref_alignment (dr_vec_info *dr_info)
base_misalignment = (*entry)->base_misalignment;
}
- if (drb->offset_alignment < vector_alignment
+ if (drb->offset_alignment < vect_align_c
|| !step_preserves_misalignment_p
/* We need to know whether the step wrt the vectorized loop is
negative when computing the starting misalignment below. */
@@ -935,13 +939,13 @@ vect_compute_data_ref_alignment (dr_vec_info *dr_info)
return;
}
- if (base_alignment < vector_alignment)
+ if (base_alignment < vect_align_c)
{
unsigned int max_alignment;
tree base = get_base_for_alignment (drb->base_address, &max_alignment);
- if (max_alignment < vector_alignment
+ if (max_alignment < vect_align_c
|| !vect_can_force_dr_alignment_p (base,
- vector_alignment * BITS_PER_UNIT))
+ vect_align_c * BITS_PER_UNIT))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
@@ -972,8 +976,7 @@ vect_compute_data_ref_alignment (dr_vec_info *dr_info)
* TREE_INT_CST_LOW (drb->step));
unsigned int const_misalignment;
- if (!known_misalignment (misalignment, vector_alignment,
- &const_misalignment))
+ if (!known_misalignment (misalignment, vect_align_c, &const_misalignment))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -1027,12 +1030,14 @@ vect_update_misalignment_for_peel (dr_vec_info *dr_info,
return;
}
- if (known_alignment_for_access_p (dr_info)
+ unsigned HOST_WIDE_INT alignment;
+ if (DR_TARGET_ALIGNMENT (dr_info).is_constant (&alignment)
+ && known_alignment_for_access_p (dr_info)
&& known_alignment_for_access_p (dr_peel_info))
{
int misal = DR_MISALIGNMENT (dr_info);
misal += npeel * TREE_INT_CST_LOW (DR_STEP (dr_info->dr));
- misal &= DR_TARGET_ALIGNMENT (dr_info) - 1;
+ misal &= alignment - 1;
SET_DR_MISALIGNMENT (dr_info, misal);
return;
}
@@ -1676,7 +1681,12 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
size_zero_node) < 0;
vectype = STMT_VINFO_VECTYPE (stmt_info);
- unsigned int target_align = DR_TARGET_ALIGNMENT (dr_info);
+ /* If known_alignment_for_access_p then we have set
+ DR_MISALIGNMENT which is only done if we know it at compiler
+ time, so it is safe to assume target alignment is constant.
+ */
+ unsigned int target_align =
+ DR_TARGET_ALIGNMENT (dr_info).to_constant ();
unsigned int dr_size = vect_get_scalar_dr_size (dr_info);
mis = (negative
? DR_MISALIGNMENT (dr_info)
@@ -1953,7 +1963,12 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
mis = (negative
? DR_MISALIGNMENT (dr0_info)
: -DR_MISALIGNMENT (dr0_info));
- unsigned int target_align = DR_TARGET_ALIGNMENT (dr0_info);
+ /* If known_alignment_for_access_p then we have set
+ DR_MISALIGNMENT which is only done if we know it at compiler
+ time, so it is safe to assume target alignment is constant.
+ */
+ unsigned int target_align =
+ DR_TARGET_ALIGNMENT (dr0_info).to_constant ();
npeel = ((mis & (target_align - 1))
/ vect_get_scalar_dr_size (dr0_info));
}
@@ -1993,9 +2008,19 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
unsigned max_peel = npeel;
if (max_peel == 0)
{
- unsigned int target_align = DR_TARGET_ALIGNMENT (dr0_info);
- max_peel = (target_align
- / vect_get_scalar_dr_size (dr0_info) - 1);
+ poly_uint64 target_align = DR_TARGET_ALIGNMENT (dr0_info);
+ unsigned HOST_WIDE_INT target_align_c;
+ if (target_align.is_constant (&target_align_c))
+ max_peel =
+ target_align_c / vect_get_scalar_dr_size (dr0_info) - 1;
+ else
+ {
+ do_peeling = false;
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Disable peeling, max peels set and vector"
+ " alignment unknown\n");
+ }
}
if (max_peel > max_allowed_peel)
{
@@ -2234,11 +2259,18 @@ vect_find_same_alignment_drs (vec_info *vinfo, data_dependence_relation *ddr)
if (maybe_ne (diff, 0))
{
/* Get the wider of the two alignments. */
- unsigned int align_a = (vect_calculate_target_alignment (dr_info_a)
- / BITS_PER_UNIT);
- unsigned int align_b = (vect_calculate_target_alignment (dr_info_b)
- / BITS_PER_UNIT);
- unsigned int max_align = MAX (align_a, align_b);
+ poly_uint64 align_a =
+ exact_div (vect_calculate_target_alignment (dr_info_a),
+ BITS_PER_UNIT);
+ poly_uint64 align_b =
+ exact_div (vect_calculate_target_alignment (dr_info_b),
+ BITS_PER_UNIT);
+ unsigned HOST_WIDE_INT align_a_c, align_b_c;
+ if (!align_a.is_constant (&align_a_c)
+ || !align_b.is_constant (&align_b_c))
+ return;
+
+ unsigned HOST_WIDE_INT max_align = MAX (align_a_c, align_b_c);
/* Require the gap to be a multiple of the larger vector alignment. */
if (!multiple_p (diff, max_align))
@@ -4357,7 +4389,8 @@ vect_duplicate_ssa_name_ptr_info (tree name, dr_vec_info *dr_info)
mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (name));
else
set_ptr_info_alignment (SSA_NAME_PTR_INFO (name),
- DR_TARGET_ALIGNMENT (dr_info), misalign);
+ known_alignment (DR_TARGET_ALIGNMENT (dr_info)),
+ misalign);
}
/* Function vect_create_addr_base_for_vector_ref.
@@ -5401,10 +5434,13 @@ vect_setup_realignment (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
new_temp = copy_ssa_name (ptr);
else
new_temp = make_ssa_name (TREE_TYPE (ptr));
- unsigned int align = DR_TARGET_ALIGNMENT (dr_info);
+ poly_uint64 align = DR_TARGET_ALIGNMENT (dr_info);
+ tree type = TREE_TYPE (ptr);
new_stmt = gimple_build_assign
(new_temp, BIT_AND_EXPR, ptr,
- build_int_cst (TREE_TYPE (ptr), -(HOST_WIDE_INT) align));
+ fold_build2 (MINUS_EXPR, type,
+ build_int_cst (type, 0),
+ build_int_cst (type, align)));
new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
gcc_assert (!new_bb);
data_ref
@@ -6287,7 +6323,7 @@ vect_record_grouped_load_vectors (stmt_vec_info stmt_info,
on ALIGNMENT bit boundary. */
bool
-vect_can_force_dr_alignment_p (const_tree decl, unsigned int alignment)
+vect_can_force_dr_alignment_p (const_tree decl, poly_uint64 alignment)
{
if (!VAR_P (decl))
return false;
@@ -6297,9 +6333,9 @@ vect_can_force_dr_alignment_p (const_tree decl, unsigned int alignment)
return false;
if (TREE_STATIC (decl))
- return (alignment <= MAX_OFILE_ALIGNMENT);
+ return (known_le (alignment, MAX_OFILE_ALIGNMENT));
else
- return (alignment <= MAX_STACK_ALIGNMENT);
+ return (known_le (alignment, (unsigned HOST_WIDE_INT) MAX_STACK_ALIGNMENT));
}