aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-analyze.c
diff options
context:
space:
mode:
authorDorit Nuzman <dorit@il.ibm.com>2007-07-12 14:42:08 +0000
committerDorit Nuzman <dorit@gcc.gnu.org>2007-07-12 14:42:08 +0000
commit5b900a4c0ee38a66b04b4ceeecb8b194ddde7e57 (patch)
tree1d606e4397ee32cd9fe29b0165fe91119ff4fbc6 /gcc/tree-vect-analyze.c
parent2df6377e6e01046582d489ae59b5be1371b42d59 (diff)
downloadgcc-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.c103
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;
}
}