From: Richard Biener Date: Wed, 9 Dec 2015 08:32:49 +0000 (+0000) Subject: re PR tree-optimization/68583 (Missed if-conversion) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=db9be04ed89e3aa82d113775d7a12699904d9735;p=gcc.git re PR tree-optimization/68583 (Missed if-conversion) 2015-12-09 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7fcec750d07..a3813b7cd01 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2015-12-09 Richard Biener + + 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 * tree-vect-stmts.c (vectorizable_load): Set new vinfo only diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index f43942ddff0..573937bf714 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -582,20 +582,19 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi, each DR->aux field. */ struct ifc_dr { - /* -1 when not initialized, 0 when false, 1 when true. */ - int written_at_least_once; + bool rw_unconditionally; + bool w_unconditionally; + bool written_at_least_once; - /* -1 when not initialized, 0 when false, 1 when true. */ - int rw_unconditionally; - - tree predicate; - - tree base_predicate; + tree rw_predicate; + tree w_predicate; + tree base_w_predicate; }; #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_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->w_unconditionally) /* 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 @@ -623,38 +622,33 @@ hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a) ref = TREE_OPERAND (ref, 0); master_dr = &ref_DR_map->get_or_insert (ref, &exist1); - if (!exist1) + *master_dr = a; + + if (DR_IS_WRITE (a)) { - IFC_DR (a)->predicate = ca; - *master_dr = a; + IFC_DR (*master_dr)->w_predicate + = 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)->predicate - = fold_or_predicates - (EXPR_LOCATION (IFC_DR (*master_dr)->predicate), - ca, IFC_DR (*master_dr)->predicate); - - if (is_true_predicate (IFC_DR (*master_dr)->predicate)) - DR_RW_UNCONDITIONALLY (*master_dr) = 1; + IFC_DR (*master_dr)->rw_predicate + = fold_or_predicates (UNKNOWN_LOCATION, ca, + IFC_DR (*master_dr)->rw_predicate); + if (is_true_predicate (IFC_DR (*master_dr)->rw_predicate)) + DR_RW_UNCONDITIONALLY (*master_dr) = true; if (DR_IS_WRITE (a)) { base_master_dr = &baseref_DR_map->get_or_insert (base_ref, &exist2); - if (!exist2) - { - IFC_DR (a)->base_predicate = ca; - *base_master_dr = a; - } - else - IFC_DR (*base_master_dr)->base_predicate - = 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; + *base_master_dr = a; + IFC_DR (*base_master_dr)->base_w_predicate + = fold_or_predicates (UNKNOWN_LOCATION, ca, + IFC_DR (*base_master_dr)->base_w_predicate); + if (is_true_predicate (IFC_DR (*base_master_dr)->base_w_predicate)) + DR_BASE_W_UNCONDITIONALLY (*base_master_dr) = true; } } @@ -704,39 +698,36 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec drs) 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 - && DR_WRITTEN_AT_LEAST_ONCE (*base_master_dr) == 1) + && DR_BASE_W_UNCONDITIONALLY (*base_master_dr)) return true; else { + /* or the base is know to be not readonly. */ tree base_tree = get_base_address (DR_REF (a)); if (DECL_P (base_tree) && decl_binds_to_current_def_p (base_tree) && flag_tree_loop_if_convert_stores && !TREE_READONLY (base_tree)) - return true; + return true; } } 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 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 (conditional load or store based on a mask computed from bb predicate). */ @@ -828,24 +819,10 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt, we can perform loop versioning. */ gimple_set_plf (stmt, GF_PLF_2, false); - if (flag_tree_loop_if_convert_stores) - { - if (ifcvt_could_trap_p (stmt, refs)) - { - 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 ((! gimple_vuse (stmt) + || gimple_could_trap_p_1 (stmt, false, false) + || ! ifcvt_memrefs_wont_trap (stmt, refs)) + && gimple_could_trap_p (stmt)) { if (ifcvt_can_use_mask_load_store (stmt)) { @@ -858,6 +835,9 @@ if_convertible_gimple_assign_stmt_p (gimple *stmt, return false; } + if (flag_tree_loop_if_convert_stores) + return true; + bb = gimple_bb (stmt); if (TREE_CODE (lhs) != SSA_NAME @@ -1279,8 +1259,12 @@ if_convertible_loop_p_1 (struct loop *loop, for (i = 0; refs->iterate (i, &dr); i++) { dr->aux = XNEW (struct ifc_dr); - DR_WRITTEN_AT_LEAST_ONCE (dr) = -1; - DR_RW_UNCONDITIONALLY (dr) = -1; + DR_BASE_W_UNCONDITIONALLY (dr) = false; + 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) gimple_set_uid (DR_STMT (dr), i + 1); hash_memrefs_baserefs_and_store_DRs_read_written_info (dr);