From f702e7d43f2aec71640d0db7ecf1543ba75f37c3 Mon Sep 17 00:00:00 2001
From: Richard Sandiford <richard.sandiford@linaro.org>
Date: Fri, 22 Sep 2017 16:44:29 +0000
Subject: Let the target choose a vectorisation alignment

The vectoriser aligned vectors to TYPE_ALIGN unconditionally, although
there was also a hard-coded assumption that this was equal to the type
size.  This was inconvenient for SVE for two reasons:

- When compiling for a specific power-of-2 SVE vector length, we might
  want to align to a full vector.  However, the TYPE_ALIGN is governed
  by the ABI alignment, which is 128 bits regardless of size.

- For vector-length-agnostic code it doesn't usually make sense to align,
  since the runtime vector length might not be a power of two.  Even for
  power of two sizes, there's no guarantee that aligning to the previous
  16 bytes will be an improveent.

This patch therefore adds a target hook to control the preferred
vectoriser (as opposed to ABI) alignment.

2017-09-22  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* target.def (preferred_vector_alignment): New hook.
	* doc/tm.texi.in (TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT): New
	hook.
	* doc/tm.texi: Regenerate.
	* targhooks.h (default_preferred_vector_alignment): Declare.
	* targhooks.c (default_preferred_vector_alignment): New function.
	* tree-vectorizer.h (dataref_aux): Add a target_alignment field.
	Expand commentary.
	(DR_TARGET_ALIGNMENT): New macro.
	(aligned_access_p): Update commentary.
	(vect_known_alignment_in_bytes): New function.
	* tree-vect-data-refs.c (vect_calculate_required_alignment): New
	function.
	(vect_compute_data_ref_alignment): Set DR_TARGET_ALIGNMENT.
	Calculate the misalignment based on the target alignment rather than
	the vector size.
	(vect_update_misalignment_for_peel): Use DR_TARGET_ALIGMENT
	rather than TYPE_ALIGN / BITS_PER_UNIT to update the misalignment.
	(vect_enhance_data_refs_alignment): Mask the byte misalignment with
	the target alignment, rather than masking the element misalignment
	with the number of elements in a vector.  Also use the target
	alignment when calculating the maximum number of peels.
	(vect_find_same_alignment_drs): Use vect_calculate_required_alignment
	instead of TYPE_ALIGN_UNIT.
	(vect_duplicate_ssa_name_ptr_info): Remove stmt_info parameter.
	Measure DR_MISALIGNMENT relative to DR_TARGET_ALIGNMENT.
	(vect_create_addr_base_for_vector_ref): Update call accordingly.
	(vect_create_data_ref_ptr): Likewise.
	(vect_setup_realignment): Realign by ANDing with
	-DR_TARGET_MISALIGNMENT.
	* tree-vect-loop-manip.c (vect_gen_prolog_loop_niters): Calculate
	the number of peels based on DR_TARGET_ALIGNMENT.
	* tree-vect-stmts.c (get_group_load_store_type): Compare the gap
	with the guaranteed alignment boundary when deciding whether
	overrun is OK.
	(vectorizable_mask_load_store): Interpret DR_MISALIGNMENT
	relative to DR_TARGET_ALIGNMENT instead of TYPE_ALIGN_UNIT.
	(ensure_base_align): Remove stmt_info parameter.  Get the
	target base alignment from DR_TARGET_ALIGNMENT.
	(vectorizable_store): Update call accordingly.   Interpret
	DR_MISALIGNMENT relative to DR_TARGET_ALIGNMENT instead of
	TYPE_ALIGN_UNIT.
	(vectorizable_load): Likewise.

gcc/testsuite/
	* gcc.dg/vect/vect-outer-3a.c: Adjust dump scan for new wording
	of alignment message.
	* gcc.dg/vect/vect-outer-3a-big-array.c: Likewise.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r253101
---
 gcc/target.def | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

(limited to 'gcc/target.def')

diff --git a/gcc/target.def b/gcc/target.def
index ae22d7a..9e5ddc0 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1820,6 +1820,20 @@ misalignment value (@var{misalign}).",
  int, (enum vect_cost_for_stmt type_of_cost, tree vectype, int misalign),
  default_builtin_vectorization_cost)
 
+DEFHOOK
+(preferred_vector_alignment,
+ "This hook returns the preferred alignment in bits for accesses to\n\
+vectors of type @var{type} in vectorized code.  This might be less than\n\
+or greater than the ABI-defined value returned by\n\
+@code{TARGET_VECTOR_ALIGNMENT}.  It can be equal to the alignment of\n\
+a single element, in which case the vectorizer will not try to optimize\n\
+for alignment.\n\
+\n\
+The default hook returns @code{TYPE_ALIGN (@var{type})}, which is\n\
+correct for most targets.",
+ HOST_WIDE_INT, (const_tree type),
+ default_preferred_vector_alignment)
+
 /* Return true if vector alignment is reachable (by peeling N
    iterations) for the given scalar type.  */
 DEFHOOK
-- 
cgit v1.1

