aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-03-18 10:25:42 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-03-18 10:25:42 +0000
commitfcac74a177b6c86bf70320aae7145f3b79e54739 (patch)
treed1488179bfed051c219f22ecde86646c070342c7 /gcc
parentad6fdc197621e1f48d72df91f021c187949ba6c2 (diff)
downloadgcc-fcac74a177b6c86bf70320aae7145f3b79e54739.zip
gcc-fcac74a177b6c86bf70320aae7145f3b79e54739.tar.gz
gcc-fcac74a177b6c86bf70320aae7145f3b79e54739.tar.bz2
tree-data-ref.h (find_data_references_in_loop): Declare.
2013-03-18 Richard Biener <rguenther@suse.de> * tree-data-ref.h (find_data_references_in_loop): Declare. * tree-data-ref.c (get_references_in_stmt): Use a stack vector pre-allocated in the callers. (find_data_references_in_stmt): Adjust. (graphite_find_data_references_in_stmt): Likewise. (create_rdg_vertices): Likewise. (find_data_references_in_loop): Export. * tree-vect-data-refs.c (vect_analyze_data_ref_dependences): Compute dependences here... (vect_analyze_data_refs): ...not here. When we encounter a non-vectorizable data reference in basic-block vectorization truncate the data reference vector. Do not bother to fixup data-dependence information for gather loads. * tree-vect-slp.c (vect_slp_analyze_bb_1): Check the number of data references, as reported. From-SVN: r196775
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/tree-data-ref.c23
-rw-r--r--gcc/tree-data-ref.h1
-rw-r--r--gcc/tree-vect-data-refs.c168
-rw-r--r--gcc/tree-vect-slp.c4
5 files changed, 73 insertions, 141 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 385821f..4d9203f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,23 @@
2013-03-18 Richard Biener <rguenther@suse.de>
+ * tree-data-ref.h (find_data_references_in_loop): Declare.
+ * tree-data-ref.c (get_references_in_stmt): Use a stack
+ vector pre-allocated in the callers.
+ (find_data_references_in_stmt): Adjust.
+ (graphite_find_data_references_in_stmt): Likewise.
+ (create_rdg_vertices): Likewise.
+ (find_data_references_in_loop): Export.
+ * tree-vect-data-refs.c (vect_analyze_data_ref_dependences):
+ Compute dependences here...
+ (vect_analyze_data_refs): ...not here. When we encounter
+ a non-vectorizable data reference in basic-block vectorization
+ truncate the data reference vector. Do not bother to
+ fixup data-dependence information for gather loads.
+ * tree-vect-slp.c (vect_slp_analyze_bb_1): Check the number
+ of data references, as reported.
+
+2013-03-18 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/3713
* tree-ssa-sccvn.c (visit_copy): Simplify. Always propagate
has_constants and expr.
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index ebb7f30..a387d82 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -4257,11 +4257,11 @@ compute_all_dependences (vec<data_reference_p> datarefs,
typedef struct data_ref_loc_d
{
- /* Position of the memory reference. */
- tree *pos;
+ /* Position of the memory reference. */
+ tree *pos;
- /* True if the memory reference is read. */
- bool is_read;
+ /* True if the memory reference is read. */
+ bool is_read;
} data_ref_loc;
@@ -4269,15 +4269,13 @@ typedef struct data_ref_loc_d
true if STMT clobbers memory, false otherwise. */
static bool
-get_references_in_stmt (gimple stmt, vec<data_ref_loc> *references)
+get_references_in_stmt (gimple stmt, vec<data_ref_loc, va_stack> *references)
{
bool clobbers_memory = false;
data_ref_loc ref;
tree *op0, *op1;
enum gimple_code stmt_code = gimple_code (stmt);
- references->create (0);
-
/* ASM_EXPR and CALL_EXPR may embed arbitrary side effects.
As we cannot model data-references to not spelled out
accesses give up if they may occur. */
@@ -4348,11 +4346,12 @@ find_data_references_in_stmt (struct loop *nest, gimple stmt,
vec<data_reference_p> *datarefs)
{
unsigned i;
- vec<data_ref_loc> references;
+ vec<data_ref_loc, va_stack> references;
data_ref_loc *ref;
bool ret = true;
data_reference_p dr;
+ vec_stack_alloc (data_ref_loc, references, 2);
if (get_references_in_stmt (stmt, &references))
{
references.release ();
@@ -4381,11 +4380,12 @@ graphite_find_data_references_in_stmt (loop_p nest, loop_p loop, gimple stmt,
vec<data_reference_p> *datarefs)
{
unsigned i;
- vec<data_ref_loc> references;
+ vec<data_ref_loc, va_stack> references;
data_ref_loc *ref;
bool ret = true;
data_reference_p dr;
+ vec_stack_alloc (data_ref_loc, references, 2);
if (get_references_in_stmt (stmt, &references))
{
references.release ();
@@ -4437,7 +4437,7 @@ find_data_references_in_bb (struct loop *loop, basic_block bb,
TODO: This function should be made smarter so that it can handle address
arithmetic as if they were array accesses, etc. */
-static tree
+tree
find_data_references_in_loop (struct loop *loop,
vec<data_reference_p> *datarefs)
{
@@ -5005,7 +5005,7 @@ create_rdg_vertices (struct graph *rdg, vec<gimple> stmts, loop_p loop)
FOR_EACH_VEC_ELT (stmts, i, stmt)
{
- vec<data_ref_loc> references;
+ vec<data_ref_loc, va_stack> references;
data_ref_loc *ref;
struct vertex *v = &(rdg->vertices[i]);
@@ -5020,6 +5020,7 @@ create_rdg_vertices (struct graph *rdg, vec<gimple> stmts, loop_p loop)
if (gimple_code (stmt) == GIMPLE_PHI)
continue;
+ vec_stack_alloc (data_ref_loc, references, 2);
get_references_in_stmt (stmt, &references);
FOR_EACH_VEC_ELT (references, j, ref)
{
diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
index 93a75f2..c5d3e86 100644
--- a/gcc/tree-data-ref.h
+++ b/gcc/tree-data-ref.h
@@ -382,6 +382,7 @@ extern bool find_data_references_in_stmt (struct loop *, gimple,
vec<data_reference_p> *);
extern bool graphite_find_data_references_in_stmt (loop_p, loop_p, gimple,
vec<data_reference_p> *);
+tree find_data_references_in_loop (struct loop *, vec<data_reference_p> *);
struct data_reference *create_data_ref (loop_p, loop_p, tree, gimple, bool);
extern bool find_loop_nest (struct loop *, vec<loop_p> *);
extern struct data_dependence_relation *initialize_data_dependence_relation
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index fdb73c3..49216f4 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -798,9 +798,21 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo,
dump_printf_loc (MSG_NOTE, vect_location,
"=== vect_analyze_dependences ===");
if (loop_vinfo)
- ddrs = LOOP_VINFO_DDRS (loop_vinfo);
+ {
+ if (!compute_all_dependences (LOOP_VINFO_DATAREFS (loop_vinfo),
+ &LOOP_VINFO_DDRS (loop_vinfo),
+ LOOP_VINFO_LOOP_NEST (loop_vinfo), true))
+ return false;
+ ddrs = LOOP_VINFO_DDRS (loop_vinfo);
+ }
else
- ddrs = BB_VINFO_DDRS (bb_vinfo);
+ {
+ if (!compute_all_dependences (BB_VINFO_DATAREFS (bb_vinfo),
+ &BB_VINFO_DDRS (bb_vinfo),
+ vNULL, true))
+ return false;
+ ddrs = BB_VINFO_DDRS (bb_vinfo);
+ }
FOR_EACH_VEC_ELT (ddrs, i, ddr)
if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, max_vf))
@@ -2941,7 +2953,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
vec<data_reference_p> datarefs;
struct data_reference *dr;
tree scalar_type;
- bool res, stop_bb_analysis = false;
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
@@ -2950,13 +2961,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (loop_vinfo)
{
loop = LOOP_VINFO_LOOP (loop_vinfo);
- res = compute_data_dependences_for_loop
- (loop, true,
- &LOOP_VINFO_LOOP_NEST (loop_vinfo),
- &LOOP_VINFO_DATAREFS (loop_vinfo),
- &LOOP_VINFO_DDRS (loop_vinfo));
-
- if (!res)
+ if (!find_loop_nest (loop, &LOOP_VINFO_LOOP_NEST (loop_vinfo))
+ || find_data_references_in_loop
+ (loop, &LOOP_VINFO_DATAREFS (loop_vinfo)))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -2987,17 +2994,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
break;
}
}
- if (!compute_all_dependences (BB_VINFO_DATAREFS (bb_vinfo),
- &BB_VINFO_DDRS (bb_vinfo),
- vNULL, true))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: basic block contains function"
- " calls or data references that cannot be"
- " analyzed");
- return false;
- }
datarefs = BB_VINFO_DATAREFS (bb_vinfo);
}
@@ -3024,12 +3020,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
stmt = DR_STMT (dr);
stmt_info = vinfo_for_stmt (stmt);
- if (stop_bb_analysis)
- {
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- continue;
- }
-
/* Check that analysis of the data-ref succeeded. */
if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
|| !DR_STEP (dr))
@@ -3070,11 +3060,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
}
if (bb_vinfo)
- {
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- stop_bb_analysis = true;
- continue;
- }
+ break;
return false;
}
@@ -3088,11 +3074,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
"constant");
if (bb_vinfo)
- {
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- stop_bb_analysis = true;
- continue;
- }
+ break;
if (gather)
free_data_ref (dr);
@@ -3109,11 +3091,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
}
if (bb_vinfo)
- {
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- stop_bb_analysis = true;
- continue;
- }
+ break;
return false;
}
@@ -3129,11 +3107,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
}
if (bb_vinfo)
- {
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- stop_bb_analysis = true;
- continue;
- }
+ break;
if (gather)
free_data_ref (dr);
@@ -3152,11 +3126,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
}
if (bb_vinfo)
- {
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- stop_bb_analysis = true;
- continue;
- }
+ break;
if (gather)
free_data_ref (dr);
@@ -3177,11 +3147,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
}
if (bb_vinfo)
- {
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- stop_bb_analysis = true;
- continue;
- }
+ break;
if (gather)
free_data_ref (dr);
@@ -3316,11 +3282,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
}
if (bb_vinfo)
- {
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- stop_bb_analysis = true;
- continue;
- }
+ break;
if (gather)
free_data_ref (dr);
@@ -3346,12 +3308,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
}
if (bb_vinfo)
- {
- /* Mark the statement as not vectorizable. */
- STMT_VINFO_VECTORIZABLE (stmt_info) = false;
- stop_bb_analysis = true;
- continue;
- }
+ break;
if (gather)
{
@@ -3369,14 +3326,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (gather)
{
- unsigned int j, k, n;
- struct data_reference *olddr
- = datarefs[i];
- vec<ddr_p> ddrs = LOOP_VINFO_DDRS (loop_vinfo);
- struct data_dependence_relation *ddr, *newddr;
- bool bad = false;
tree off;
- vec<loop_p> nest = LOOP_VINFO_LOOP_NEST (loop_vinfo);
gather = 0 != vect_check_gather (stmt, loop_vinfo, NULL, &off, NULL);
if (gather
@@ -3396,59 +3346,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
return false;
}
- n = datarefs.length () - 1;
- for (j = 0, k = i - 1; j < i; j++)
- {
- ddr = ddrs[k];
- gcc_assert (DDR_B (ddr) == olddr);
- newddr = initialize_data_dependence_relation (DDR_A (ddr), dr,
- nest);
- ddrs[k] = newddr;
- free_dependence_relation (ddr);
- if (!bad
- && DR_IS_WRITE (DDR_A (newddr))
- && DDR_ARE_DEPENDENT (newddr) != chrec_known)
- bad = true;
- k += --n;
- }
-
- k++;
- n = k + datarefs.length () - i - 1;
- for (; k < n; k++)
- {
- ddr = ddrs[k];
- gcc_assert (DDR_A (ddr) == olddr);
- newddr = initialize_data_dependence_relation (dr, DDR_B (ddr),
- nest);
- ddrs[k] = newddr;
- free_dependence_relation (ddr);
- if (!bad
- && DR_IS_WRITE (DDR_B (newddr))
- && DDR_ARE_DEPENDENT (newddr) != chrec_known)
- bad = true;
- }
-
- k = ddrs.length ()
- - datarefs.length () + i;
- ddr = ddrs[k];
- gcc_assert (DDR_A (ddr) == olddr && DDR_B (ddr) == olddr);
- newddr = initialize_data_dependence_relation (dr, dr, nest);
- ddrs[k] = newddr;
- free_dependence_relation (ddr);
datarefs[i] = dr;
-
- if (bad)
- {
- if (dump_enabled_p ())
- {
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: data dependence conflict"
- " prevents gather load");
- dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
- }
- return false;
- }
-
STMT_VINFO_GATHER_P (stmt_info) = true;
}
else if (loop_vinfo
@@ -3472,6 +3370,22 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
}
}
+ /* If we stopped analysis at the first dataref we could not analyze
+ when trying to vectorize a basic-block mark the rest of the datarefs
+ as not vectorizable and truncate the vector of datarefs. That
+ avoids spending useless time in analyzing their dependence. */
+ if (i != datarefs.length ())
+ {
+ gcc_assert (bb_vinfo != NULL);
+ for (unsigned j = i; j < datarefs.length (); ++j)
+ {
+ data_reference_p dr = datarefs[j];
+ STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
+ free_data_ref (dr);
+ }
+ datarefs.truncate (i);
+ }
+
return true;
}
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index e184326..8567eac 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2078,7 +2078,6 @@ static bb_vec_info
vect_slp_analyze_bb_1 (basic_block bb)
{
bb_vec_info bb_vinfo;
- vec<ddr_p> ddrs;
vec<slp_instance> slp_instances;
slp_instance instance;
int i;
@@ -2100,8 +2099,7 @@ vect_slp_analyze_bb_1 (basic_block bb)
return NULL;
}
- ddrs = BB_VINFO_DDRS (bb_vinfo);
- if (!ddrs.length ())
+ if (BB_VINFO_DATAREFS (bb_vinfo).length () < 2)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,