diff options
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 94 |
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)); } |