summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-26 06:39:27 +0000
committerirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-26 06:39:27 +0000
commit6ea6a380355ec8324844a76243c61db77eab2b8b (patch)
tree127816de355ad6eada440e245b181155ca6791c6 /gcc
parent3ba0ce4759c71b0e9a0e516072a0cadcfe098765 (diff)
downloadgcc-6ea6a380355ec8324844a76243c61db77eab2b8b.tar.gz
* tree-vectorizer.h (struct _stmt_vec_info): Add new field to
determine if the statement is vectorizable, and a macro to access it. * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Skip statements that can't be vectorized. If the analysis fails, mark the statement as unvectorizable if vectorizing basic block. (vect_compute_data_refs_alignment): Likewise. (vect_verify_datarefs_alignment): Skip statements marked as unvectorizable. Add print. (vect_analyze_group_access): Skip statements that can't be vectorized. If the analysis fails, mark the statement as unvectorizable if vectorizing basic block. (vect_analyze_data_ref_accesses, vect_analyze_data_refs): Likewise. * tree-vect-stmts.c (vectorizable_store): Fix the number of generated stmts for SLP. (new_stmt_vec_info): Initialize the new field. * tree-vect-slp.c (vect_build_slp_tree): Fail to vectorize statements marked as unvectorizable. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158719 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-23.c54
-rw-r--r--gcc/tree-vect-data-refs.c91
-rw-r--r--gcc/tree-vect-slp.c13
-rw-r--r--gcc/tree-vect-stmts.c16
-rw-r--r--gcc/tree-vectorizer.h5
7 files changed, 189 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a6fd13b1782..3b4ed3c2f2b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,26 @@
+2010-04-26 Ira Rosen <irar@il.ibm.com>
+
+ * tree-vectorizer.h (struct _stmt_vec_info): Add new field to
+ determine if the statement is vectorizable, and a macro to
+ access it.
+ * tree-vect-data-refs.c (vect_analyze_data_ref_dependence):
+ Skip statements that can't be vectorized. If the analysis
+ fails, mark the statement as unvectorizable if vectorizing
+ basic block.
+ (vect_compute_data_refs_alignment): Likewise.
+ (vect_verify_datarefs_alignment): Skip statements marked as
+ unvectorizable. Add print.
+ (vect_analyze_group_access): Skip statements that can't be
+ vectorized. If the analysis fails, mark the statement as
+ unvectorizable if vectorizing basic block.
+ (vect_analyze_data_ref_accesses, vect_analyze_data_refs):
+ Likewise.
+ * tree-vect-stmts.c (vectorizable_store): Fix the number of
+ generated stmts for SLP.
+ (new_stmt_vec_info): Initialize the new field.
+ * tree-vect-slp.c (vect_build_slp_tree): Fail to vectorize
+ statements marked as unvectorizable.
+
2010-04-25 Joseph Myers <joseph@codesourcery.com>
* c-common.c (flag_isoc1x): New.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index add87e8fac4..badf9107c51 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-26 Ira Rosen <irar@il.ibm.com>
+
+ * gcc.dg/vect/bb-slp-23.c: New test.
+
2010-04-25 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/c90-float-1.c: Also test that C1X macros are not defined.
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
new file mode 100644
index 00000000000..640d81a2560
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
@@ -0,0 +1,54 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+int a[N], b[N];
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ /* This statement is ignored in vectorization of this basic block. */
+ a[x] = b [y];
+
+ a0 = in[0] + 23;
+ a1 = in[1] + 142;
+ a2 = in[2] + 2;
+ a3 = in[3] + 31;
+
+ out[0] = a0 * x;
+ out[1] = a1 * y;
+ out[2] = a2 * x;
+ out[3] = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index ba537a062ef..cf2ac21fca2 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -503,6 +503,11 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
lambda_vector dist_v;
unsigned int loop_depth;
+ /* Don't bother to analyze statements marked as unvectorizable. */
+ if (!STMT_VINFO_VECTORIZABLE (stmtinfo_a)
+ || !STMT_VINFO_VECTORIZABLE (stmtinfo_b))
+ return false;
+
if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
{
/* Independent data accesses. */
@@ -546,7 +551,11 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
}
- return true;
+ /* Mark the statements as unvectorizable. */
+ STMT_VINFO_VECTORIZABLE (stmtinfo_a) = false;
+ STMT_VINFO_VECTORIZABLE (stmtinfo_b) = false;
+
+ return false;
}
/* Versioning for alias is not yet supported for basic block SLP, and
@@ -851,8 +860,18 @@ vect_compute_data_refs_alignment (loop_vec_info loop_vinfo,
datarefs = BB_VINFO_DATAREFS (bb_vinfo);
for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
- if (!vect_compute_data_ref_alignment (dr))
- return false;
+ if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr)))
+ && !vect_compute_data_ref_alignment (dr))
+ {
+ if (bb_vinfo)
+ {
+ /* Mark unsupported statement as unvectorizable. */
+ STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
+ continue;
+ }
+ else
+ return false;
+ }
return true;
}
@@ -939,9 +958,11 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
- /* For interleaving, only the alignment of the first access matters. */
- if (STMT_VINFO_STRIDED_ACCESS (stmt_info)
- && DR_GROUP_FIRST_DR (stmt_info) != stmt)
+ /* For interleaving, only the alignment of the first access matters.
+ Skip statements marked as not vectorizable. */
+ if ((STMT_VINFO_STRIDED_ACCESS (stmt_info)
+ && DR_GROUP_FIRST_DR (stmt_info) != stmt)
+ || !STMT_VINFO_VECTORIZABLE (stmt_info))
continue;
supportable_dr_alignment = vect_supportable_dr_alignment (dr);
@@ -955,6 +976,8 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
else
fprintf (vect_dump,
"not vectorized: unsupported unaligned store.");
+
+ print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
}
return false;
}
@@ -1564,8 +1587,20 @@ vect_analyze_group_access (struct data_reference *dr)
}
return true;
}
+
if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "not consecutive access");
+ {
+ fprintf (vect_dump, "not consecutive access ");
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ }
+
+ if (bb_vinfo)
+ {
+ /* Mark the statement as unvectorizable. */
+ STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
+ return true;
+ }
+
return false;
}
@@ -1836,11 +1871,20 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
datarefs = BB_VINFO_DATAREFS (bb_vinfo);
for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
- if (!vect_analyze_data_ref_access (dr))
+ if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr)))
+ && !vect_analyze_data_ref_access (dr))
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
fprintf (vect_dump, "not vectorized: complicated access pattern.");
- return false;
+
+ if (bb_vinfo)
+ {
+ /* Mark the statement as not vectorizable. */
+ STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
+ continue;
+ }
+ else
+ return false;
}
return true;
@@ -2013,7 +2057,15 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
fprintf (vect_dump, "not vectorized: data ref analysis failed ");
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
- return false;
+
+ if (bb_vinfo)
+ {
+ /* Mark the statement as not vectorizable. */
+ STMT_VINFO_VECTORIZABLE (stmt_info) = false;
+ continue;
+ }
+ else
+ return false;
}
if (TREE_CODE (DR_BASE_ADDRESS (dr)) == INTEGER_CST)
@@ -2021,7 +2073,14 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
fprintf (vect_dump, "not vectorized: base addr of dr is a "
"constant");
- return false;
+ if (bb_vinfo)
+ {
+ /* Mark the statement as not vectorizable. */
+ STMT_VINFO_VECTORIZABLE (stmt_info) = false;
+ continue;
+ }
+ else
+ return false;
}
base = unshare_expr (DR_BASE_ADDRESS (dr));
@@ -2163,7 +2222,15 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
fprintf (vect_dump, " scalar_type: ");
print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
}
- return false;
+
+ if (bb_vinfo)
+ {
+ /* Mark the statement as not vectorizable. */
+ STMT_VINFO_VECTORIZABLE (stmt_info) = false;
+ continue;
+ }
+ else
+ return false;
}
/* Adjust the minimal vectorization factor according to the
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 6949ebdf873..f313294bd29 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -344,6 +344,19 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
+ /* Fail to vectorize statements marked as unvectorizable. */
+ if (!STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)))
+ {
+ if (vect_print_dump_info (REPORT_SLP))
+ {
+ fprintf (vect_dump,
+ "Build SLP failed: unvectorizable statement ");
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ }
+
+ return false;
+ }
+
lhs = gimple_get_lhs (stmt);
if (lhs == NULL_TREE)
{
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 988749b792f..0dabb6a365b 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -3031,12 +3031,17 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
}
if (slp)
- strided_store = false;
-
- /* VEC_NUM is the number of vect stmts to be created for this group. */
- if (slp)
- vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
+ {
+ strided_store = false;
+ /* VEC_NUM is the number of vect stmts to be created for this
+ group. */
+ vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
+ first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0);
+ first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
+ }
else
+ /* VEC_NUM is the number of vect stmts to be created for this
+ group. */
vec_num = group_size;
}
else
@@ -4327,6 +4332,7 @@ new_stmt_vec_info (gimple stmt, loop_vec_info loop_vinfo,
STMT_VINFO_LIVE_P (res) = false;
STMT_VINFO_VECTYPE (res) = NULL;
STMT_VINFO_VEC_STMT (res) = NULL;
+ STMT_VINFO_VECTORIZABLE (res) = true;
STMT_VINFO_IN_PATTERN_P (res) = false;
STMT_VINFO_RELATED_STMT (res) = NULL;
STMT_VINFO_DATA_REF (res) = NULL;
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index bd43a4bc173..c80c34529e4 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -489,6 +489,10 @@ typedef struct _stmt_vec_info {
/* The bb_vec_info with respect to which STMT is vectorized. */
bb_vec_info bb_vinfo;
+
+ /* Is this statement vectorizable or should it be skipped in (partial)
+ vectorization. */
+ bool vectorizable;
} *stmt_vec_info;
/* Access Functions. */
@@ -500,6 +504,7 @@ typedef struct _stmt_vec_info {
#define STMT_VINFO_LIVE_P(S) (S)->live
#define STMT_VINFO_VECTYPE(S) (S)->vectype
#define STMT_VINFO_VEC_STMT(S) (S)->vectorized_stmt
+#define STMT_VINFO_VECTORIZABLE(S) (S)->vectorizable
#define STMT_VINFO_DATA_REF(S) (S)->data_ref_info
#define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address