gimple-fold.c (has_use_on_stmt): New function.
authorRichard Biener <rguenther@suse.de>
Wed, 29 Jul 2015 07:48:10 +0000 (07:48 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 29 Jul 2015 07:48:10 +0000 (07:48 +0000)
2015-07-29  Richard Biener  <rguenther@suse.de>

* gimple-fold.c (has_use_on_stmt): New function.
(replace_stmt_with_simplification): Use it to allow
abnormals originally referenced in the stmt.
(fold_stmt_1): Canonicalize operand order.

From-SVN: r226339

gcc/ChangeLog
gcc/gimple-fold.c

index c3f78dd21d102e56e565ed1cc52c642fddfdc1be..e3ed02b100716cfecc024ba3162efdb73d9cf720 100644 (file)
@@ -1,3 +1,10 @@
+2015-07-29  Richard Biener  <rguenther@suse.de>
+
+       * gimple-fold.c (has_use_on_stmt): New function.
+       (replace_stmt_with_simplification): Use it to allow
+       abnormals originally referenced in the stmt.
+       (fold_stmt_1): Canonicalize operand order.
+
 2015-07-28  David Sherwood  <david.sherwood@arm.com>
 
        * config/arm/arm.c (neon_element_bits, neon_valid_immediate): Call
index 64f27917e6152c763294d401ed9d6a877b57e73f..68a4a9f5f45e8120a4095b33c79b96b50f5e1517 100644 (file)
@@ -3307,6 +3307,19 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
 }
 
 
+/* Return true whether NAME has a use on STMT.  */
+
+static bool
+has_use_on_stmt (tree name, gimple stmt)
+{
+  imm_use_iterator iter;
+  use_operand_p use_p;
+  FOR_EACH_IMM_USE_FAST (use_p, iter, name)
+    if (USE_STMT (use_p) == stmt)
+      return true;
+  return false;
+}
+
 /* Worker for fold_stmt_1 dispatch to pattern based folding with
    gimple_simplify.
 
@@ -3322,15 +3335,20 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
   gimple stmt = gsi_stmt (*gsi);
 
   /* Play safe and do not allow abnormals to be mentioned in
-     newly created statements.  See also maybe_push_res_to_seq.  */
+     newly created statements.  See also maybe_push_res_to_seq.
+     As an exception allow such uses if there was a use of the
+     same SSA name on the old stmt.  */
   if ((TREE_CODE (ops[0]) == SSA_NAME
-       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
+       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0])
+       && !has_use_on_stmt (ops[0], stmt))
       || (ops[1]
          && TREE_CODE (ops[1]) == SSA_NAME
-         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
+         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1])
+         && !has_use_on_stmt (ops[1], stmt))
       || (ops[2]
          && TREE_CODE (ops[2]) == SSA_NAME
-         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
+         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])
+         && !has_use_on_stmt (ops[2], stmt)))
     return false;
 
   if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
@@ -3531,7 +3549,8 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
      after propagation.
      ???  This shouldn't be done in generic folding but in the
      propagation helpers which also know whether an address was
-     propagated.  */
+     propagated.
+     Also canonicalize operand order.  */
   switch (gimple_code (stmt))
     {
     case GIMPLE_ASSIGN:
@@ -3547,6 +3566,27 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
              && maybe_canonicalize_mem_ref_addr (lhs))
            changed = true;
        }
+      else
+       {
+         /* Canonicalize operand order.  */
+         enum tree_code code = gimple_assign_rhs_code (stmt);
+         if (TREE_CODE_CLASS (code) == tcc_comparison
+             || commutative_tree_code (code)
+             || commutative_ternary_tree_code (code))
+           {
+             tree rhs1 = gimple_assign_rhs1 (stmt);
+             tree rhs2 = gimple_assign_rhs2 (stmt);
+             if (tree_swap_operands_p (rhs1, rhs2, false))
+               {
+                 gimple_assign_set_rhs1 (stmt, rhs2);
+                 gimple_assign_set_rhs2 (stmt, rhs1);
+                 if (TREE_CODE_CLASS (code) == tcc_comparison)
+                   gimple_assign_set_rhs_code (stmt,
+                                               swap_tree_comparison (code));
+                 changed = true;
+               }
+           }
+       }
       break;
     case GIMPLE_CALL:
       {
@@ -3597,6 +3637,21 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
            changed = true;
        }
       break;
+    case GIMPLE_COND:
+      {
+       /* Canonicalize operand order.  */
+       tree lhs = gimple_cond_lhs (stmt);
+       tree rhs = gimple_cond_rhs (stmt);
+       if (tree_swap_operands_p (lhs, rhs, false))
+         {
+           gcond *gc = as_a <gcond *> (stmt);
+           gimple_cond_set_lhs (gc, rhs);
+           gimple_cond_set_rhs (gc, lhs);
+           gimple_cond_set_code (gc,
+                                 swap_tree_comparison (gimple_cond_code (gc)));
+           changed = true;
+         }
+      }
     default:;
     }