Commit 27312bf2 by Richard Biener Committed by Richard Biener

tree-ssa-alias.h (refs_may_alias_p): Add tbaa_p bool parameter, defaulted to true.

2018-05-25  Richard Biener  <rguenther@suse.de>

	* tree-ssa-alias.h (refs_may_alias_p): Add tbaa_p bool parameter,
	defaulted to true.
	(ref_maybe_used_by_stmt_p): Likewise.
	(stmt_may_clobber_ref_p): Likewise.
	(stmt_may_clobber_ref_p_1): Likewise.
	* tree-ssa-alias.c (refs_may_alias_p): Add tbaa_p bool parameter
	and pass it along.
	(ref_maybe_used_by_stmt_p): Likewise.
	(stmt_may_clobber_ref_p): Likewise.
	(stmt_may_clobber_ref_p_1): Likewise.
	* tree-vect-data-refs.c (vect_slp_analyze_node_dependences): Use
	the alias oracle to disambiguate DRs with stmts DR analysis
	couldn't handle.
	(vect_analyze_data_refs): Do not give up on not analyzable
	DRs for BB vectorization.  Remove code truncating the dataref
	vector.

From-SVN: r260757
parent b55f342b
2018-05-25 Richard Biener <rguenther@suse.de>
* tree-ssa-alias.h (refs_may_alias_p): Add tbaa_p bool parameter,
defaulted to true.
(ref_maybe_used_by_stmt_p): Likewise.
(stmt_may_clobber_ref_p): Likewise.
(stmt_may_clobber_ref_p_1): Likewise.
* tree-ssa-alias.c (refs_may_alias_p): Add tbaa_p bool parameter
and pass it along.
(ref_maybe_used_by_stmt_p): Likewise.
(stmt_may_clobber_ref_p): Likewise.
(stmt_may_clobber_ref_p_1): Likewise.
* tree-vect-data-refs.c (vect_slp_analyze_node_dependences): Use
the alias oracle to disambiguate DRs with stmts DR analysis
couldn't handle.
(vect_analyze_data_refs): Do not give up on not analyzable
DRs for BB vectorization. Remove code truncating the dataref
vector.
2018-05-25 Jakub Jelinek <jakub@redhat.com> 2018-05-25 Jakub Jelinek <jakub@redhat.com>
PR target/85832 PR target/85832
......
...@@ -1509,21 +1509,21 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) ...@@ -1509,21 +1509,21 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
} }
static bool static bool
refs_may_alias_p (tree ref1, ao_ref *ref2) refs_may_alias_p (tree ref1, ao_ref *ref2, bool tbaa_p)
{ {
ao_ref r1; ao_ref r1;
ao_ref_init (&r1, ref1); ao_ref_init (&r1, ref1);
return refs_may_alias_p_1 (&r1, ref2, true); return refs_may_alias_p_1 (&r1, ref2, tbaa_p);
} }
bool bool
refs_may_alias_p (tree ref1, tree ref2) refs_may_alias_p (tree ref1, tree ref2, bool tbaa_p)
{ {
ao_ref r1, r2; ao_ref r1, r2;
bool res; bool res;
ao_ref_init (&r1, ref1); ao_ref_init (&r1, ref1);
ao_ref_init (&r2, ref2); ao_ref_init (&r2, ref2);
res = refs_may_alias_p_1 (&r1, &r2, true); res = refs_may_alias_p_1 (&r1, &r2, tbaa_p);
if (res) if (res)
++alias_stats.refs_may_alias_p_may_alias; ++alias_stats.refs_may_alias_p_may_alias;
else else
...@@ -1559,7 +1559,7 @@ refs_output_dependent_p (tree store1, tree store2) ...@@ -1559,7 +1559,7 @@ refs_output_dependent_p (tree store1, tree store2)
otherwise return false. */ otherwise return false. */
static bool static bool
ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *ref) ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *ref, bool tbaa_p)
{ {
tree base, callee; tree base, callee;
unsigned i; unsigned i;
...@@ -1860,7 +1860,7 @@ process_args: ...@@ -1860,7 +1860,7 @@ process_args:
{ {
ao_ref r; ao_ref r;
ao_ref_init (&r, op); ao_ref_init (&r, op);
if (refs_may_alias_p_1 (&r, ref, true)) if (refs_may_alias_p_1 (&r, ref, tbaa_p))
return true; return true;
} }
} }
...@@ -1869,10 +1869,10 @@ process_args: ...@@ -1869,10 +1869,10 @@ process_args:
} }
static bool static bool
ref_maybe_used_by_call_p (gcall *call, ao_ref *ref) ref_maybe_used_by_call_p (gcall *call, ao_ref *ref, bool tbaa_p)
{ {
bool res; bool res;
res = ref_maybe_used_by_call_p_1 (call, ref); res = ref_maybe_used_by_call_p_1 (call, ref, tbaa_p);
if (res) if (res)
++alias_stats.ref_maybe_used_by_call_p_may_alias; ++alias_stats.ref_maybe_used_by_call_p_may_alias;
else else
...@@ -1885,7 +1885,7 @@ ref_maybe_used_by_call_p (gcall *call, ao_ref *ref) ...@@ -1885,7 +1885,7 @@ ref_maybe_used_by_call_p (gcall *call, ao_ref *ref)
true, otherwise return false. */ true, otherwise return false. */
bool bool
ref_maybe_used_by_stmt_p (gimple *stmt, ao_ref *ref) ref_maybe_used_by_stmt_p (gimple *stmt, ao_ref *ref, bool tbaa_p)
{ {
if (is_gimple_assign (stmt)) if (is_gimple_assign (stmt))
{ {
...@@ -1901,17 +1901,17 @@ ref_maybe_used_by_stmt_p (gimple *stmt, ao_ref *ref) ...@@ -1901,17 +1901,17 @@ ref_maybe_used_by_stmt_p (gimple *stmt, ao_ref *ref)
|| gimple_assign_rhs_code (stmt) == CONSTRUCTOR) || gimple_assign_rhs_code (stmt) == CONSTRUCTOR)
return false; return false;
return refs_may_alias_p (rhs, ref); return refs_may_alias_p (rhs, ref, tbaa_p);
} }
else if (is_gimple_call (stmt)) else if (is_gimple_call (stmt))
return ref_maybe_used_by_call_p (as_a <gcall *> (stmt), ref); return ref_maybe_used_by_call_p (as_a <gcall *> (stmt), ref, tbaa_p);
else if (greturn *return_stmt = dyn_cast <greturn *> (stmt)) else if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
{ {
tree retval = gimple_return_retval (return_stmt); tree retval = gimple_return_retval (return_stmt);
if (retval if (retval
&& TREE_CODE (retval) != SSA_NAME && TREE_CODE (retval) != SSA_NAME
&& !is_gimple_min_invariant (retval) && !is_gimple_min_invariant (retval)
&& refs_may_alias_p (retval, ref)) && refs_may_alias_p (retval, ref, tbaa_p))
return true; return true;
/* If ref escapes the function then the return acts as a use. */ /* If ref escapes the function then the return acts as a use. */
tree base = ao_ref_base (ref); tree base = ao_ref_base (ref);
...@@ -1929,11 +1929,11 @@ ref_maybe_used_by_stmt_p (gimple *stmt, ao_ref *ref) ...@@ -1929,11 +1929,11 @@ ref_maybe_used_by_stmt_p (gimple *stmt, ao_ref *ref)
} }
bool bool
ref_maybe_used_by_stmt_p (gimple *stmt, tree ref) ref_maybe_used_by_stmt_p (gimple *stmt, tree ref, bool tbaa_p)
{ {
ao_ref r; ao_ref r;
ao_ref_init (&r, ref); ao_ref_init (&r, ref);
return ref_maybe_used_by_stmt_p (stmt, &r); return ref_maybe_used_by_stmt_p (stmt, &r, tbaa_p);
} }
/* If the call in statement CALL may clobber the memory reference REF /* If the call in statement CALL may clobber the memory reference REF
...@@ -2245,7 +2245,7 @@ call_may_clobber_ref_p (gcall *call, tree ref) ...@@ -2245,7 +2245,7 @@ call_may_clobber_ref_p (gcall *call, tree ref)
otherwise return false. */ otherwise return false. */
bool bool
stmt_may_clobber_ref_p_1 (gimple *stmt, ao_ref *ref) stmt_may_clobber_ref_p_1 (gimple *stmt, ao_ref *ref, bool tbaa_p)
{ {
if (is_gimple_call (stmt)) if (is_gimple_call (stmt))
{ {
...@@ -2255,7 +2255,7 @@ stmt_may_clobber_ref_p_1 (gimple *stmt, ao_ref *ref) ...@@ -2255,7 +2255,7 @@ stmt_may_clobber_ref_p_1 (gimple *stmt, ao_ref *ref)
{ {
ao_ref r; ao_ref r;
ao_ref_init (&r, lhs); ao_ref_init (&r, lhs);
if (refs_may_alias_p_1 (ref, &r, true)) if (refs_may_alias_p_1 (ref, &r, tbaa_p))
return true; return true;
} }
...@@ -2268,7 +2268,7 @@ stmt_may_clobber_ref_p_1 (gimple *stmt, ao_ref *ref) ...@@ -2268,7 +2268,7 @@ stmt_may_clobber_ref_p_1 (gimple *stmt, ao_ref *ref)
{ {
ao_ref r; ao_ref r;
ao_ref_init (&r, lhs); ao_ref_init (&r, lhs);
return refs_may_alias_p_1 (ref, &r, true); return refs_may_alias_p_1 (ref, &r, tbaa_p);
} }
} }
else if (gimple_code (stmt) == GIMPLE_ASM) else if (gimple_code (stmt) == GIMPLE_ASM)
...@@ -2278,11 +2278,11 @@ stmt_may_clobber_ref_p_1 (gimple *stmt, ao_ref *ref) ...@@ -2278,11 +2278,11 @@ stmt_may_clobber_ref_p_1 (gimple *stmt, ao_ref *ref)
} }
bool bool
stmt_may_clobber_ref_p (gimple *stmt, tree ref) stmt_may_clobber_ref_p (gimple *stmt, tree ref, bool tbaa_p)
{ {
ao_ref r; ao_ref r;
ao_ref_init (&r, ref); ao_ref_init (&r, ref);
return stmt_may_clobber_ref_p_1 (stmt, &r); return stmt_may_clobber_ref_p_1 (stmt, &r, tbaa_p);
} }
/* Return true if store1 and store2 described by corresponding tuples /* Return true if store1 and store2 described by corresponding tuples
......
...@@ -118,15 +118,15 @@ extern bool ptr_derefs_may_alias_p (tree, tree); ...@@ -118,15 +118,15 @@ extern bool ptr_derefs_may_alias_p (tree, tree);
extern bool ptrs_compare_unequal (tree, tree); extern bool ptrs_compare_unequal (tree, tree);
extern bool ref_may_alias_global_p (tree); extern bool ref_may_alias_global_p (tree);
extern bool ref_may_alias_global_p (ao_ref *); extern bool ref_may_alias_global_p (ao_ref *);
extern bool refs_may_alias_p (tree, tree); extern bool refs_may_alias_p (tree, tree, bool = true);
extern bool refs_may_alias_p_1 (ao_ref *, ao_ref *, bool); extern bool refs_may_alias_p_1 (ao_ref *, ao_ref *, bool);
extern bool refs_anti_dependent_p (tree, tree); extern bool refs_anti_dependent_p (tree, tree);
extern bool refs_output_dependent_p (tree, tree); extern bool refs_output_dependent_p (tree, tree);
extern bool ref_maybe_used_by_stmt_p (gimple *, tree); extern bool ref_maybe_used_by_stmt_p (gimple *, tree, bool = true);
extern bool ref_maybe_used_by_stmt_p (gimple *, ao_ref *); extern bool ref_maybe_used_by_stmt_p (gimple *, ao_ref *, bool = true);
extern bool stmt_may_clobber_global_p (gimple *); extern bool stmt_may_clobber_global_p (gimple *);
extern bool stmt_may_clobber_ref_p (gimple *, tree); extern bool stmt_may_clobber_ref_p (gimple *, tree, bool = true);
extern bool stmt_may_clobber_ref_p_1 (gimple *, ao_ref *); extern bool stmt_may_clobber_ref_p_1 (gimple *, ao_ref *, bool = true);
extern bool call_may_clobber_ref_p (gcall *, tree); extern bool call_may_clobber_ref_p (gcall *, tree);
extern bool call_may_clobber_ref_p_1 (gcall *, ao_ref *); extern bool call_may_clobber_ref_p_1 (gcall *, ao_ref *);
extern bool stmt_kills_ref_p (gimple *, tree); extern bool stmt_kills_ref_p (gimple *, tree);
......
...@@ -664,6 +664,8 @@ vect_slp_analyze_node_dependences (slp_instance instance, slp_tree node, ...@@ -664,6 +664,8 @@ vect_slp_analyze_node_dependences (slp_instance instance, slp_tree node,
if (access == last_access) if (access == last_access)
continue; continue;
data_reference *dr_a = STMT_VINFO_DATA_REF (vinfo_for_stmt (access)); data_reference *dr_a = STMT_VINFO_DATA_REF (vinfo_for_stmt (access));
ao_ref ref;
bool ref_initialized_p = false;
for (gimple_stmt_iterator gsi = gsi_for_stmt (access); for (gimple_stmt_iterator gsi = gsi_for_stmt (access);
gsi_stmt (gsi) != last_access; gsi_next (&gsi)) gsi_stmt (gsi) != last_access; gsi_next (&gsi))
{ {
...@@ -673,12 +675,19 @@ vect_slp_analyze_node_dependences (slp_instance instance, slp_tree node, ...@@ -673,12 +675,19 @@ vect_slp_analyze_node_dependences (slp_instance instance, slp_tree node,
continue; continue;
/* If we couldn't record a (single) data reference for this /* If we couldn't record a (single) data reference for this
stmt we have to give up. */ stmt we have to resort to the alias oracle. */
/* ??? Here and below if dependence analysis fails we can resort
to the alias oracle which can handle more kinds of stmts. */
data_reference *dr_b = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)); data_reference *dr_b = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt));
if (!dr_b) if (!dr_b)
return false; {
/* We are moving a store or sinking a load - this means
we cannot use TBAA for disambiguation. */
if (!ref_initialized_p)
ao_ref_init (&ref, DR_REF (dr_a));
if (stmt_may_clobber_ref_p_1 (stmt, &ref, false)
|| ref_maybe_used_by_stmt_p (stmt, &ref, false))
return false;
continue;
}
bool dependent = false; bool dependent = false;
/* If we run into a store of this same instance (we've just /* If we run into a store of this same instance (we've just
...@@ -4183,10 +4192,13 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4183,10 +4192,13 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
"failed "); "failed ");
dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
} }
if (is_a <bb_vec_info> (vinfo)) if (is_a <bb_vec_info> (vinfo))
break; {
/* In BB vectorization the ref can still participate
in dependence analysis, we just can't vectorize it. */
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
continue;
}
return false; return false;
} }
} }
...@@ -4379,21 +4391,9 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf) ...@@ -4379,21 +4391,9 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf)
} }
} }
/* If we stopped analysis at the first dataref we could not analyze /* We used to stop processing and prune the list here. Verify we no
when trying to vectorize a basic-block mark the rest of the datarefs longer need to. */
as not vectorizable and truncate the vector of datarefs. That gcc_assert (i == datarefs.length ());
avoids spending useless time in analyzing their dependence. */
if (i != datarefs.length ())
{
gcc_assert (is_a <bb_vec_info> (vinfo));
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; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment