re PR tree-optimization/68583 (Missed if-conversion)
authorRichard Biener <rguenther@suse.de>
Wed, 9 Dec 2015 08:32:49 +0000 (08:32 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 9 Dec 2015 08:32:49 +0000 (08:32 +0000)
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

gcc/ChangeLog
gcc/tree-if-conv.c

index 7fcec750d072e3c7c6f4f743cfcadb82829d6319..a3813b7cd01b71c2067eedc6706471f3ded98695 100644 (file)
@@ -1,3 +1,21 @@
+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
index f43942ddff0a842e520587e01c2e0e50e6649bd9..573937bf714f89f5d21c04489110326331ecb558 100644 (file)
@@ -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<data_reference_p> 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<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
    (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);