From: Ulrich Weigand Date: Mon, 30 Jul 2012 14:39:32 +0000 (+0000) Subject: target.def (vector_alignment): New target hook. X-Git-Tag: upstream/12.2.0~75024 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5aea1e76a80c9c5770692ece18100b9383cbab3a;p=platform%2Fupstream%2Fgcc.git target.def (vector_alignment): New target hook. ChangeLog: * target.def (vector_alignment): New target hook. * doc/tm.texi.in (TARGET_VECTOR_ALIGNMENT): Document new hook. * doc/tm.texi: Regenerate. * targhooks.c (default_vector_alignment): New function. * targhooks.h (default_vector_alignment): Add prototype. * stor-layout.c (layout_type): Use targetm.vector_alignment. * config/arm/arm.c (arm_vector_alignment): New function. (TARGET_VECTOR_ALIGNMENT): Define. * tree-vect-data-refs.c (vect_update_misalignment_for_peel): Use vector type alignment instead of size. * tree-vect-loop-manip.c (vect_do_peeling_for_loop_bound): Use element type size directly instead of computing it from alignment. Fix variable naming and comment. testsuite/ChangeLog: * lib/target-supports.exp (check_effective_target_vect_natural_alignment): New function. * gcc.dg/align-2.c: Only run on targets with natural alignment of vector types. * gcc.dg/vect/slp-25.c: Adjust tests for targets without natural alignment of vector types. Co-Authored-By: Richard Earnshaw From-SVN: r189974 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f73410d..2b5385f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2012-07-30 Ulrich Weigand + Richard Earnshaw + + * target.def (vector_alignment): New target hook. + * doc/tm.texi.in (TARGET_VECTOR_ALIGNMENT): Document new hook. + * doc/tm.texi: Regenerate. + * targhooks.c (default_vector_alignment): New function. + * targhooks.h (default_vector_alignment): Add prototype. + * stor-layout.c (layout_type): Use targetm.vector_alignment. + * config/arm/arm.c (arm_vector_alignment): New function. + (TARGET_VECTOR_ALIGNMENT): Define. + + * tree-vect-data-refs.c (vect_update_misalignment_for_peel): Use + vector type alignment instead of size. + * tree-vect-loop-manip.c (vect_do_peeling_for_loop_bound): Use + element type size directly instead of computing it from alignment. + Fix variable naming and comment. + 2012-07-30 Kirill Yukhin Michael Zolotukhin diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 1f3f9b3..701ab4c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -255,6 +255,7 @@ static bool arm_array_mode_supported_p (enum machine_mode, unsigned HOST_WIDE_INT); static enum machine_mode arm_preferred_simd_mode (enum machine_mode); static bool arm_class_likely_spilled_p (reg_class_t); +static HOST_WIDE_INT arm_vector_alignment (const_tree type); static bool arm_vector_alignment_reachable (const_tree type, bool is_packed); static bool arm_builtin_support_vector_misalignment (enum machine_mode mode, const_tree type, @@ -606,6 +607,9 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_CLASS_LIKELY_SPILLED_P #define TARGET_CLASS_LIKELY_SPILLED_P arm_class_likely_spilled_p +#undef TARGET_VECTOR_ALIGNMENT +#define TARGET_VECTOR_ALIGNMENT arm_vector_alignment + #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE \ arm_vector_alignment_reachable @@ -25063,6 +25067,18 @@ arm_have_conditional_execution (void) return !TARGET_THUMB1; } +/* The AAPCS sets the maximum alignment of a vector to 64 bits. */ +static HOST_WIDE_INT +arm_vector_alignment (const_tree type) +{ + HOST_WIDE_INT align = tree_low_cst (TYPE_SIZE (type), 0); + + if (TARGET_AAPCS_BASED) + align = MIN (align, 64); + + return align; +} + static unsigned int arm_autovectorize_vector_sizes (void) { diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index b419a71..0f8d43a 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1107,6 +1107,14 @@ make it all fit in fewer cache lines. If the value of this macro has a type, it should be an unsigned type. @end defmac +@deftypefn {Target Hook} HOST_WIDE_INT TARGET_VECTOR_ALIGNMENT (const_tree @var{type}) +This hook can be used to define the alignment for a vector of type +@var{type}, in order to comply with a platform ABI. The default is to +require natural alignment for vector types. The alignment returned by +this hook must be a power-of-two multiple of the default alignment of +the vector element type. +@end deftypefn + @defmac STACK_SLOT_ALIGNMENT (@var{type}, @var{mode}, @var{basic-align}) If defined, a C expression to compute the alignment for stack slot. @var{type} is the data type, @var{mode} is the widest mode available, diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 3f2ef1e..8deaf69 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -1091,6 +1091,8 @@ make it all fit in fewer cache lines. If the value of this macro has a type, it should be an unsigned type. @end defmac +@hook TARGET_VECTOR_ALIGNMENT + @defmac STACK_SLOT_ALIGNMENT (@var{type}, @var{mode}, @var{basic-align}) If defined, a C expression to compute the alignment for stack slot. @var{type} is the data type, @var{mode} is the widest mode available, diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 0d3d5d2..ddec141 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -2131,9 +2131,17 @@ layout_type (tree type) TYPE_SIZE (type) = int_const_binop (MULT_EXPR, TYPE_SIZE (innertype), bitsize_int (nunits)); - /* Always naturally align vectors. This prevents ABI changes - depending on whether or not native vector modes are supported. */ - TYPE_ALIGN (type) = tree_low_cst (TYPE_SIZE (type), 0); + /* For vector types, we do not default to the mode's alignment. + Instead, query a target hook, defaulting to natural alignment. + This prevents ABI changes depending on whether or not native + vector modes are supported. */ + TYPE_ALIGN (type) = targetm.vector_alignment (type); + + /* However, if the underlying mode requires a bigger alignment than + what the target hook provides, we cannot use the mode. For now, + simply reject that case. */ + gcc_assert (TYPE_ALIGN (type) + >= GET_MODE_ALIGNMENT (TYPE_MODE (type))); break; } diff --git a/gcc/target.def b/gcc/target.def index bdbf68e..5ac6d48 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -1664,6 +1664,16 @@ DEFHOOK bool, (enum machine_mode mode), hook_bool_mode_false) +DEFHOOK +(vector_alignment, + "This hook can be used to define the alignment for a vector of type\n\ +@var{type}, in order to comply with a platform ABI. The default is to\n\ +require natural alignment for vector types. The alignment returned by\n\ +this hook must be a power-of-two multiple of the default alignment of\n\ +the vector element type.", + HOST_WIDE_INT, (const_tree type), + default_vector_alignment) + /* True if we should try to use a scalar mode to represent an array, overriding the usual MAX_FIXED_MODE limit. */ DEFHOOK diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 8993659..1703aad 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -945,6 +945,13 @@ tree default_mangle_decl_assembler_name (tree decl ATTRIBUTE_UNUSED, return id; } +/* Default to natural alignment for vector types. */ +HOST_WIDE_INT +default_vector_alignment (const_tree type) +{ + return tree_low_cst (TYPE_SIZE (type), 0); +} + bool default_builtin_vector_alignment_reachable (const_tree type, bool is_packed) { diff --git a/gcc/targhooks.h b/gcc/targhooks.h index f6e03e7..f1cc403 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -83,6 +83,8 @@ extern int default_builtin_vectorization_cost (enum vect_cost_for_stmt, tree, in extern tree default_builtin_reciprocal (unsigned int, bool, bool); +extern HOST_WIDE_INT default_vector_alignment (const_tree); + extern bool default_builtin_vector_alignment_reachable (const_tree, bool); extern bool default_builtin_support_vector_misalignment (enum machine_mode mode, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f593cf0..442aa3f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2012-07-30 Ulrich Weigand + + * lib/target-supports.exp + (check_effective_target_vect_natural_alignment): New function. + * gcc.dg/align-2.c: Only run on targets with natural alignment + of vector types. + * gcc.dg/vect/slp-25.c: Adjust tests for targets without natural + alignment of vector types. + 2012-07-30 Kirill Yukhin Michael Zolotukhin diff --git a/gcc/testsuite/gcc.dg/align-2.c b/gcc/testsuite/gcc.dg/align-2.c index f5c00fd..2001a15 100644 --- a/gcc/testsuite/gcc.dg/align-2.c +++ b/gcc/testsuite/gcc.dg/align-2.c @@ -1,5 +1,5 @@ /* PR 17962 */ -/* { dg-do compile } */ +/* { dg-do compile { target vect_natural_alignment } } */ /* { dg-options "" } */ typedef float v4 __attribute__((vector_size(sizeof(float)*4))); diff --git a/gcc/testsuite/gcc.dg/vect/slp-25.c b/gcc/testsuite/gcc.dg/vect/slp-25.c index 0dec2f1..e5e5e3b 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-25.c +++ b/gcc/testsuite/gcc.dg/vect/slp-25.c @@ -56,5 +56,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { vect_no_align || { ! vect_natural_alignment } } } } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 6640ef2..0dc5815 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3387,6 +3387,26 @@ proc check_effective_target_natural_alignment_64 { } { return $et_natural_alignment_64_saved } +# Return 1 if all vector types are naturally aligned (aligned to their +# type-size), 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_natural_alignment { } { + global et_vect_natural_alignment + + if [info exists et_vect_natural_alignment_saved] { + verbose "check_effective_target_vect_natural_alignment: using cached result" 2 + } else { + set et_vect_natural_alignment_saved 1 + if { [check_effective_target_arm_eabi] } { + set et_vect_natural_alignment_saved 0 + } + } + verbose "check_effective_target_vect_natural_alignment: returning $et_vect_natural_alignment_saved" 2 + return $et_vect_natural_alignment_saved +} + # Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise. # # This won't change for different subtargets so cache the result. diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 81a9521..fe6e40e 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -1059,7 +1059,7 @@ vect_update_misalignment_for_peel (struct data_reference *dr, int misal = DR_MISALIGNMENT (dr); tree vectype = STMT_VINFO_VECTYPE (stmt_info); misal += negative ? -npeel * dr_size : npeel * dr_size; - misal &= GET_MODE_SIZE (TYPE_MODE (vectype)) - 1; + misal &= (TYPE_ALIGN (vectype) / BITS_PER_UNIT) - 1; SET_DR_MISALIGNMENT (dr, misal); return; } diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index d7d9f25..0008116 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -1937,7 +1937,7 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio, If the misalignment of DR is known at compile time: addr_mis = int mis = DR_MISALIGNMENT (dr); Else, compute address misalignment in bytes: - addr_mis = addr & (vectype_size - 1) + addr_mis = addr & (vectype_align - 1) prolog_niters = min (LOOP_NITERS, ((VF - addr_mis/elem_size)&(VF-1))/step) @@ -1991,9 +1991,10 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) tree start_addr = vect_create_addr_base_for_vector_ref (dr_stmt, &new_stmts, offset, loop); tree type = unsigned_type_for (TREE_TYPE (start_addr)); - tree vectype_size_minus_1 = build_int_cst (type, vectype_align - 1); - tree elem_size_log = - build_int_cst (type, exact_log2 (vectype_align/nelements)); + tree vectype_align_minus_1 = build_int_cst (type, vectype_align - 1); + HOST_WIDE_INT elem_size = + int_cst_value (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); + tree elem_size_log = build_int_cst (type, exact_log2 (elem_size)); tree nelements_minus_1 = build_int_cst (type, nelements - 1); tree nelements_tree = build_int_cst (type, nelements); tree byte_misalign; @@ -2002,10 +2003,10 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters) new_bb = gsi_insert_seq_on_edge_immediate (pe, new_stmts); gcc_assert (!new_bb); - /* Create: byte_misalign = addr & (vectype_size - 1) */ + /* Create: byte_misalign = addr & (vectype_align - 1) */ byte_misalign = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, start_addr), - vectype_size_minus_1); + vectype_align_minus_1); /* Create: elem_misalign = byte_misalign / element_size */ elem_misalign =