This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Optimize statements created by if-conversion


Hi,

For the following minloc loop (which I am trying to vectorize):

  for (i = 0; i < N; i++)
    if (arr[i] < limit)
      {
        pos = i + 1;
        limit = arr[i];
      }

if-conversion generates

  # pos_22 = PHI <pos_1(8), 1(3)>
  # i_23 = PHI <prephitmp.8_2(8), 0(3)>
  # limit_24 = PHI <limit_4(8), 1.28e+2(3)>
  limit_10 = arr[i_23];
  pos_11 = i_23 + 1;
  pretmp.7_3 = i_23 + 1;
  pos_1 = [cond_expr] limit_10 >= limit_24 ? pos_22 : pos_11;
  limit_4 = [cond_expr] limit_10 >= limit_24 ? limit_24 : limit_10;
  prephitmp.8_2 = [cond_expr] limit_10 >= limit_24 ? pretmp.7_3 : pos_11;
  if (prephitmp.8_2 < n_9(D))
    goto <bb 8>;
  else
    goto <bb 9>;


For

prephitmp.8_2 = [cond_expr] limit_10 >= limit_24 ? pretmp.7_3 : pos_11;

then and else clauses are equivalent, so

prephitmp.8_2 = pretmp.7_3;

should be enough.


Does the following patch make sense? (Meanwhile, I only tested it with
vectorizer testsuite).

Thanks,
Ira

ChangeLog:

      * tree-if-conv.c (replace_phi_with_cond_gimple_assign_stmt):
      If then and else clauses are equivalent, use one of them as a
      rhs.

Index: tree-if-conv.c
===================================================================
--- tree-if-conv.c      (revision 161484)
+++ tree-if-conv.c      (working copy)
@@ -925,6 +925,8 @@ replace_phi_with_cond_gimple_assign_stmt
   basic_block bb;
   tree rhs;
   tree arg;
+  gimple def_stmt0, def_stmt1;
+  enum tree_code code;

   gcc_assert (gimple_code (phi) == GIMPLE_PHI
              && gimple_phi_num_args (phi) == 2);
@@ -949,9 +951,35 @@ replace_phi_with_cond_gimple_assign_stmt
          arg_1 = gimple_phi_arg_def (phi, 1);
        }

-      /* Build new RHS using selected condition and arguments.  */
-      rhs = build3 (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)),
-                   unshare_expr (cond), arg_0, arg_1);
+      if (TREE_CODE (arg_0) == SSA_NAME && TREE_CODE (arg_1) == SSA_NAME
+          && (def_stmt0 = SSA_NAME_DEF_STMT (arg_0))
+          && (def_stmt1 = SSA_NAME_DEF_STMT (arg_1))
+          && is_gimple_assign (def_stmt0)
+          && is_gimple_assign (def_stmt1)
+          && (code = gimple_assign_rhs_code (def_stmt0))
+             == gimple_assign_rhs_code (def_stmt1)
+          && ((get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS
+               && operand_equal_p (gimple_assign_rhs1 (def_stmt0),
+                                   gimple_assign_rhs1 (def_stmt1), 0))
+              || (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
+                  && operand_equal_p (gimple_assign_rhs1 (def_stmt0),
+                                      gimple_assign_rhs1 (def_stmt1), 0)
+                  && operand_equal_p (gimple_assign_rhs2 (def_stmt0),
+                                      gimple_assign_rhs2 (def_stmt1), 0))
+              || (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS
+                  && operand_equal_p (gimple_assign_rhs1 (def_stmt0),
+                                      gimple_assign_rhs1 (def_stmt1), 0)
+                  && operand_equal_p (gimple_assign_rhs2 (def_stmt0),
+                                      gimple_assign_rhs2 (def_stmt1), 0)
+                  && operand_equal_p (gimple_assign_rhs3 (def_stmt0),
+                                      gimple_assign_rhs3 (def_stmt1),
0))))
+        /* Since then and else parts are equivalent, make RHS to be one of
+           them.  */
+        rhs = arg_0;
+      else
+        /* Build new RHS using selected condition and arguments.  */
+        rhs = build3 (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)),
+                     unshare_expr (cond), arg_0, arg_1);
     }

   new_stmt = gimple_build_assign (PHI_RESULT (phi), rhs);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]