diff options
author | Dorit Nuzman <dorit@il.ibm.com> | 2007-07-12 14:42:08 +0000 |
---|---|---|
committer | Dorit Nuzman <dorit@gcc.gnu.org> | 2007-07-12 14:42:08 +0000 |
commit | 5b900a4c0ee38a66b04b4ceeecb8b194ddde7e57 (patch) | |
tree | 1d606e4397ee32cd9fe29b0165fe91119ff4fbc6 /gcc/tree-vect-analyze.c | |
parent | 2df6377e6e01046582d489ae59b5be1371b42d59 (diff) | |
download | gcc-5b900a4c0ee38a66b04b4ceeecb8b194ddde7e57.zip gcc-5b900a4c0ee38a66b04b4ceeecb8b194ddde7e57.tar.gz gcc-5b900a4c0ee38a66b04b4ceeecb8b194ddde7e57.tar.bz2 |
re PR target/25413 (wrong alignment or incorrect address computation in vectorized code on Pentium 4 SSE)
2007-07-12 Dorit Nuzman <dorit@il.ibm.com>
Devang Patel <dpatel@apple.com>
PR tree-optimization/25413
* targhooks.c (default_builtin_vector_alignment_reachable): New.
* targhooks.h (default_builtin_vector_alignment_reachable): New.
* tree.h (contains_packed_reference): New.
* expr.c (contains_packed_reference): New.
* tree-vect-analyze.c (vector_alignment_reachable_p): New.
(vect_enhance_data_refs_alignment): Call
vector_alignment_reachable_p.
* target.h (vector_alignment_reachable): New builtin.
* target-def.h (TARGET_VECTOR_ALIGNMENT_REACHABLE): New.
* config/rs6000/rs6000.c (rs6000_vector_alignment_reachable): New.
(TARGET_VECTOR_ALIGNMENT_REACHABLE): Define.
Co-Authored-By: Devang Patel <dpatel@apple.com>
From-SVN: r126591
Diffstat (limited to 'gcc/tree-vect-analyze.c')
-rw-r--r-- | gcc/tree-vect-analyze.c | 103 |
1 files changed, 76 insertions, 27 deletions
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c index 2b8f318..317e334 100644 --- a/gcc/tree-vect-analyze.c +++ b/gcc/tree-vect-analyze.c @@ -25,6 +25,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "tm.h" #include "ggc.h" #include "tree.h" +#include "target.h" #include "basic-block.h" #include "diagnostic.h" #include "tree-flow.h" @@ -1379,6 +1380,76 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo) } +/* Function vector_alignment_reachable_p + + Return true if vector alignment for DR is reachable by peeling + a few loop iterations. Return false otherwise. */ + +static bool +vector_alignment_reachable_p (struct data_reference *dr) +{ + tree stmt = DR_STMT (dr); + stmt_vec_info stmt_info = vinfo_for_stmt (stmt); + tree vectype = STMT_VINFO_VECTYPE (stmt_info); + + if (DR_GROUP_FIRST_DR (stmt_info)) + { + /* For interleaved access we peel only if number of iterations in + the prolog loop ({VF - misalignment}), is a multiple of the + number of the interleaved accesses. */ + int elem_size, mis_in_elements; + int nelements = TYPE_VECTOR_SUBPARTS (vectype); + + /* FORNOW: handle only known alignment. */ + if (!known_alignment_for_access_p (dr)) + return false; + + elem_size = UNITS_PER_SIMD_WORD / nelements; + mis_in_elements = DR_MISALIGNMENT (dr) / elem_size; + + if ((nelements - mis_in_elements) % DR_GROUP_SIZE (stmt_info)) + return false; + } + + /* If misalignment is known at the compile time then allow peeling + only if natural alignment is reachable through peeling. */ + if (known_alignment_for_access_p (dr) && !aligned_access_p (dr)) + { + HOST_WIDE_INT elmsize = + int_cst_value (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, "data size =" HOST_WIDE_INT_PRINT_DEC, elmsize); + fprintf (vect_dump, ". misalignment = %d. ", DR_MISALIGNMENT (dr)); + } + if (DR_MISALIGNMENT (dr) % elmsize) + { + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "data size does not divide the misalignment.\n"); + return false; + } + } + + if (!known_alignment_for_access_p (dr)) + { + tree type = (TREE_TYPE (DR_REF (dr))); + tree ba = DR_BASE_OBJECT (dr); + bool is_packed = false; + + if (ba) + is_packed = contains_packed_reference (ba); + + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "Unknown misalignment, is_packed = %d",is_packed); + if (targetm.vectorize.vector_alignment_reachable (type, is_packed)) + return true; + else + return false; + } + + return true; +} + /* Function vect_enhance_data_refs_alignment This pass will use loop versioning and loop peeling in order to enhance @@ -1540,33 +1611,11 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) if (!DR_IS_READ (dr) && !aligned_access_p (dr)) { - if (DR_GROUP_FIRST_DR (stmt_info)) - { - /* For interleaved access we peel only if number of iterations in - the prolog loop ({VF - misalignment}), is a multiple of the - number of the interleaved accesses. */ - int elem_size, mis_in_elements; - tree vectype = STMT_VINFO_VECTYPE (stmt_info); - int nelements = TYPE_VECTOR_SUBPARTS (vectype); - - /* FORNOW: handle only known alignment. */ - if (!known_alignment_for_access_p (dr)) - { - do_peeling = false; - break; - } - - elem_size = UNITS_PER_SIMD_WORD / nelements; - mis_in_elements = DR_MISALIGNMENT (dr) / elem_size; - - if ((nelements - mis_in_elements) % DR_GROUP_SIZE (stmt_info)) - { - do_peeling = false; - break; - } - } - dr0 = dr; - do_peeling = true; + do_peeling = vector_alignment_reachable_p (dr); + if (do_peeling) + dr0 = dr; + if (!do_peeling && vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "vector alignment may not be reachable"); break; } } |