genmatch.c (commutative_tree_code, [...]): Copy from tree.c
authorRichard Biener <rguenther@suse.de>
Fri, 3 Jul 2015 13:46:34 +0000 (13:46 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 3 Jul 2015 13:46:34 +0000 (13:46 +0000)
2015-07-03  Richard Biener  <rguenther@suse.de>

* genmatch.c (commutative_tree_code, commutative_ternary_tree_code):
Copy from tree.c
(dt_operand::gen_gimple_expr): After valueizing operands
re-canonicalize operand order for commutative tree codes.

From-SVN: r225378

gcc/ChangeLog
gcc/genmatch.c

index 0335921..1b60027 100644 (file)
@@ -1,3 +1,10 @@
+2015-07-03  Richard Biener  <rguenther@suse.de>
+
+       * genmatch.c (commutative_tree_code, commutative_ternary_tree_code):
+       Copy from tree.c
+       (dt_operand::gen_gimple_expr): After valueizing operands
+       re-canonicalize operand order for commutative tree codes.
+
 2015-07-03  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/66746.
index 6f8cea9..7ee6fb5 100644 (file)
@@ -175,6 +175,62 @@ END_BUILTINS
 };
 #undef DEF_BUILTIN
 
+/* Return true if CODE represents a commutative tree code.  Otherwise
+   return false.  */
+bool
+commutative_tree_code (enum tree_code code)
+{
+  switch (code)
+    {
+    case PLUS_EXPR:
+    case MULT_EXPR:
+    case MULT_HIGHPART_EXPR:
+    case MIN_EXPR:
+    case MAX_EXPR:
+    case BIT_IOR_EXPR:
+    case BIT_XOR_EXPR:
+    case BIT_AND_EXPR:
+    case NE_EXPR:
+    case EQ_EXPR:
+    case UNORDERED_EXPR:
+    case ORDERED_EXPR:
+    case UNEQ_EXPR:
+    case LTGT_EXPR:
+    case TRUTH_AND_EXPR:
+    case TRUTH_XOR_EXPR:
+    case TRUTH_OR_EXPR:
+    case WIDEN_MULT_EXPR:
+    case VEC_WIDEN_MULT_HI_EXPR:
+    case VEC_WIDEN_MULT_LO_EXPR:
+    case VEC_WIDEN_MULT_EVEN_EXPR:
+    case VEC_WIDEN_MULT_ODD_EXPR:
+      return true;
+
+    default:
+      break;
+    }
+  return false;
+}
+
+/* Return true if CODE represents a ternary tree code for which the
+   first two operands are commutative.  Otherwise return false.  */
+bool
+commutative_ternary_tree_code (enum tree_code code)
+{
+  switch (code)
+    {
+    case WIDEN_MULT_PLUS_EXPR:
+    case WIDEN_MULT_MINUS_EXPR:
+    case DOT_PROD_EXPR:
+    case FMA_EXPR:
+      return true;
+
+    default:
+      break;
+    }
+  return false;
+}
+
 
 /* Base class for all identifiers the parser knows.  */
 
@@ -1996,6 +2052,25 @@ dt_operand::gen_gimple_expr (FILE *f)
               child_opname, child_opname);
       fprintf (f, "{\n");
     }
+  /* While the toplevel operands are canonicalized by the caller
+     after valueizing operands of sub-expressions we have to
+     re-canonicalize operand order.  */
+  if (operator_id *code = dyn_cast <operator_id *> (id))
+    {
+      /* ???  We can't canonicalize tcc_comparison operands here
+         because that requires changing the comparison code which
+        we already matched...  */
+      if (commutative_tree_code (code->code)
+         || commutative_ternary_tree_code (code->code))
+       {
+         char child_opname0[20], child_opname1[20];
+         gen_opname (child_opname0, 0);
+         gen_opname (child_opname1, 1);
+         fprintf (f, "if (tree_swap_operands_p (%s, %s, false))\n"
+                  "  std::swap (%s, %s);\n", child_opname0, child_opname1,
+                  child_opname0, child_opname1);
+       }
+    }
 
   return n_ops;
 }