Commit db9be04e by Richard Biener Committed by Richard Biener

re PR tree-optimization/68583 (Missed if-conversion)

2015-12-09  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/68583
	* tree-if-conv.c (ifc_dr): Make flags bool, add w_unconditionally
	flag and rename predicates to w_predicate, rw_predicate and
	base_w_predicate.
	(DR_WRITTEN_AT_LEAST_ONCE): Rename to ...
	(DR_BASE_W_UNCONDITIONALLY): ... this.
	(DR_W_UNCONDITIONALLY): Add.
	(hash_memrefs_baserefs_and_store_DRs_read): Adjust.  Compute
	unconditionally written separately from read or written.
	(ifcvt_memrefs_wont_trap): Properly treat reads.
	(ifcvt_could_trap_p): Inline ...
	(if_convertible_gimple_assign_stmt_p): ... here.  Refactor
	to avoid code duplication.
	(if_convertible_loop_p_1): Adjust and properly initialize
	predicates.

From-SVN: r231444
parent 34cd48e5
2015-12-09 Richard Biener <rguenther@suse.de> 2015-12-09 Richard Biener <rguenther@suse.de>
PR tree-optimization/68583
* tree-if-conv.c (ifc_dr): Make flags bool, add w_unconditionally
flag and rename predicates to w_predicate, rw_predicate and
base_w_predicate.
(DR_WRITTEN_AT_LEAST_ONCE): Rename to ...
(DR_BASE_W_UNCONDITIONALLY): ... this.
(DR_W_UNCONDITIONALLY): Add.
(hash_memrefs_baserefs_and_store_DRs_read): Adjust. Compute
unconditionally written separately from read or written.
(ifcvt_memrefs_wont_trap): Properly treat reads.
(ifcvt_could_trap_p): Inline ...
(if_convertible_gimple_assign_stmt_p): ... here. Refactor
to avoid code duplication.
(if_convertible_loop_p_1): Adjust and properly initialize
predicates.
2015-12-09 Richard Biener <rguenther@suse.de>
* tree-vect-stmts.c (vectorizable_load): Set new vinfo only * tree-vect-stmts.c (vectorizable_load): Set new vinfo only
if it was not yet set. if it was not yet set.
* tree-vectorizer.h (set_vinfo_for_stmt): Assert we don't * tree-vectorizer.h (set_vinfo_for_stmt): Assert we don't
...@@ -582,20 +582,19 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi, ...@@ -582,20 +582,19 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi,
each DR->aux field. */ each DR->aux field. */
struct ifc_dr { struct ifc_dr {
/* -1 when not initialized, 0 when false, 1 when true. */ bool rw_unconditionally;
int written_at_least_once; bool w_unconditionally;
bool written_at_least_once;
/* -1 when not initialized, 0 when false, 1 when true. */ tree rw_predicate;
int rw_unconditionally; tree w_predicate;
tree base_w_predicate;
tree predicate;
tree base_predicate;
}; };
#define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux) #define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux)
#define DR_WRITTEN_AT_LEAST_ONCE(DR) (IFC_DR (DR)->written_at_least_once) #define DR_BASE_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->written_at_least_once)
#define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally) #define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally)
#define DR_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->w_unconditionally)
/* Iterates over DR's and stores refs, DR and base refs, DR pairs in /* Iterates over DR's and stores refs, DR and base refs, DR pairs in
HASH tables. While storing them in HASH table, it checks if the HASH tables. While storing them in HASH table, it checks if the
...@@ -623,38 +622,33 @@ hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a) ...@@ -623,38 +622,33 @@ hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a)
ref = TREE_OPERAND (ref, 0); ref = TREE_OPERAND (ref, 0);
master_dr = &ref_DR_map->get_or_insert (ref, &exist1); master_dr = &ref_DR_map->get_or_insert (ref, &exist1);
if (!exist1) if (!exist1)
*master_dr = a;
if (DR_IS_WRITE (a))
{ {
IFC_DR (a)->predicate = ca; IFC_DR (*master_dr)->w_predicate
*master_dr = a; = fold_or_predicates (UNKNOWN_LOCATION, ca,
IFC_DR (*master_dr)->w_predicate);
if (is_true_predicate (IFC_DR (*master_dr)->w_predicate))
DR_W_UNCONDITIONALLY (*master_dr) = true;
} }
else IFC_DR (*master_dr)->rw_predicate
IFC_DR (*master_dr)->predicate = fold_or_predicates (UNKNOWN_LOCATION, ca,
= fold_or_predicates IFC_DR (*master_dr)->rw_predicate);
(EXPR_LOCATION (IFC_DR (*master_dr)->predicate), if (is_true_predicate (IFC_DR (*master_dr)->rw_predicate))
ca, IFC_DR (*master_dr)->predicate); DR_RW_UNCONDITIONALLY (*master_dr) = true;
if (is_true_predicate (IFC_DR (*master_dr)->predicate))
DR_RW_UNCONDITIONALLY (*master_dr) = 1;
if (DR_IS_WRITE (a)) if (DR_IS_WRITE (a))
{ {
base_master_dr = &baseref_DR_map->get_or_insert (base_ref, &exist2); base_master_dr = &baseref_DR_map->get_or_insert (base_ref, &exist2);
if (!exist2) if (!exist2)
{ *base_master_dr = a;
IFC_DR (a)->base_predicate = ca; IFC_DR (*base_master_dr)->base_w_predicate
*base_master_dr = a; = fold_or_predicates (UNKNOWN_LOCATION, ca,
} IFC_DR (*base_master_dr)->base_w_predicate);
else if (is_true_predicate (IFC_DR (*base_master_dr)->base_w_predicate))
IFC_DR (*base_master_dr)->base_predicate DR_BASE_W_UNCONDITIONALLY (*base_master_dr) = true;
= fold_or_predicates
(EXPR_LOCATION (IFC_DR (*base_master_dr)->base_predicate),
ca, IFC_DR (*base_master_dr)->base_predicate);
if (is_true_predicate (IFC_DR (*base_master_dr)->base_predicate))
DR_WRITTEN_AT_LEAST_ONCE (*base_master_dr) = 1;
} }
} }
...@@ -704,39 +698,36 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs) ...@@ -704,39 +698,36 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
gcc_assert (master_dr != NULL); gcc_assert (master_dr != NULL);
if (DR_RW_UNCONDITIONALLY (*master_dr) == 1) /* If a is unconditionally written to it doesn't trap. */
if (DR_W_UNCONDITIONALLY (*master_dr))
return true;
/* If a is unconditionally accessed then ... */
if (DR_RW_UNCONDITIONALLY (*master_dr))
{ {
/* an unconditional read won't trap. */
if (DR_IS_READ (a))
return true;
/* an unconditionaly write won't trap if the base is written
to unconditionally. */
if (base_master_dr if (base_master_dr
&& DR_WRITTEN_AT_LEAST_ONCE (*base_master_dr) == 1) && DR_BASE_W_UNCONDITIONALLY (*base_master_dr))
return true; return true;
else else
{ {
/* or the base is know to be not readonly. */
tree base_tree = get_base_address (DR_REF (a)); tree base_tree = get_base_address (DR_REF (a));
if (DECL_P (base_tree) if (DECL_P (base_tree)
&& decl_binds_to_current_def_p (base_tree) && decl_binds_to_current_def_p (base_tree)
&& flag_tree_loop_if_convert_stores && flag_tree_loop_if_convert_stores
&& !TREE_READONLY (base_tree)) && !TREE_READONLY (base_tree))
return true; return true;
} }
} }
return false; return false;
} }
/* Wrapper around gimple_could_trap_p refined for the needs of the
if-conversion. Try to prove that the memory accesses of STMT could
not trap in the innermost loop containing STMT. */
static bool
ifcvt_could_trap_p (gimple *stmt, vec<data_reference_p> refs)
{
if (gimple_vuse (stmt)
&& !gimple_could_trap_p_1 (stmt, false, false)
&& ifcvt_memrefs_wont_trap (stmt, refs))
return false;
return gimple_could_trap_p (stmt);
}
/* Return true if STMT could be converted into a masked load or store /* Return true if STMT could be converted into a masked load or store
(conditional load or store based on a mask computed from bb predicate). */ (conditional load or store based on a mask computed from bb predicate). */
...@@ -828,24 +819,10 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt, ...@@ -828,24 +819,10 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt,
we can perform loop versioning. */ we can perform loop versioning. */
gimple_set_plf (stmt, GF_PLF_2, false); gimple_set_plf (stmt, GF_PLF_2, false);
if (flag_tree_loop_if_convert_stores) if ((! gimple_vuse (stmt)
{ || gimple_could_trap_p_1 (stmt, false, false)
if (ifcvt_could_trap_p (stmt, refs)) || ! ifcvt_memrefs_wont_trap (stmt, refs))
{ && gimple_could_trap_p (stmt))
if (ifcvt_can_use_mask_load_store (stmt))
{
gimple_set_plf (stmt, GF_PLF_2, true);
*any_mask_load_store = true;
return true;
}
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "tree could trap...\n");
return false;
}
return true;
}
if (ifcvt_could_trap_p (stmt, refs))
{ {
if (ifcvt_can_use_mask_load_store (stmt)) if (ifcvt_can_use_mask_load_store (stmt))
{ {
...@@ -858,6 +835,9 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt, ...@@ -858,6 +835,9 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt,
return false; return false;
} }
if (flag_tree_loop_if_convert_stores)
return true;
bb = gimple_bb (stmt); bb = gimple_bb (stmt);
if (TREE_CODE (lhs) != SSA_NAME if (TREE_CODE (lhs) != SSA_NAME
...@@ -1279,8 +1259,12 @@ if_convertible_loop_p_1 (struct loop *loop, ...@@ -1279,8 +1259,12 @@ if_convertible_loop_p_1 (struct loop *loop,
for (i = 0; refs->iterate (i, &dr); i++) for (i = 0; refs->iterate (i, &dr); i++)
{ {
dr->aux = XNEW (struct ifc_dr); dr->aux = XNEW (struct ifc_dr);
DR_WRITTEN_AT_LEAST_ONCE (dr) = -1; DR_BASE_W_UNCONDITIONALLY (dr) = false;
DR_RW_UNCONDITIONALLY (dr) = -1; DR_RW_UNCONDITIONALLY (dr) = false;
DR_W_UNCONDITIONALLY (dr) = false;
IFC_DR (dr)->rw_predicate = boolean_false_node;
IFC_DR (dr)->w_predicate = boolean_false_node;
IFC_DR (dr)->base_w_predicate = boolean_false_node;
if (gimple_uid (DR_STMT (dr)) == 0) if (gimple_uid (DR_STMT (dr)) == 0)
gimple_set_uid (DR_STMT (dr), i + 1); gimple_set_uid (DR_STMT (dr), i + 1);
hash_memrefs_baserefs_and_store_DRs_read_written_info (dr); hash_memrefs_baserefs_and_store_DRs_read_written_info (dr);
......
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