diff gcc/gimple-match-head.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
line wrap: on
line diff
--- a/gcc/gimple-match-head.c	Thu Oct 25 07:37:49 2018 +0900
+++ b/gcc/gimple-match-head.c	Thu Feb 13 11:34:05 2020 +0900
@@ -1,5 +1,5 @@
 /* Preamble and helpers for the autogenerated gimple-match.c file.
-   Copyright (C) 2014-2018 Free Software Foundation, Inc.
+   Copyright (C) 2014-2020 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -27,6 +27,7 @@
 #include "gimple.h"
 #include "ssa.h"
 #include "cgraph.h"
+#include "vec-perm-indices.h"
 #include "fold-const.h"
 #include "fold-const-call.h"
 #include "stor-layout.h"
@@ -41,7 +42,7 @@
 #include "gimplify.h"
 #include "optabs-tree.h"
 #include "tree-eh.h"
-
+#include "dbgcnt.h"
 
 /* Forward declarations of the private auto-generated matchers.
    They expect valueized operands in canonical order and do not
@@ -56,6 +57,16 @@
 			     code_helper, tree, tree, tree, tree, tree);
 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
 			     code_helper, tree, tree, tree, tree, tree, tree);
+static bool gimple_resimplify1 (gimple_seq *, gimple_match_op *,
+				tree (*)(tree));
+static bool gimple_resimplify2 (gimple_seq *, gimple_match_op *,
+				tree (*)(tree));
+static bool gimple_resimplify3 (gimple_seq *, gimple_match_op *,
+				tree (*)(tree));
+static bool gimple_resimplify4 (gimple_seq *, gimple_match_op *,
+				tree (*)(tree));
+static bool gimple_resimplify5 (gimple_seq *, gimple_match_op *,
+				tree (*)(tree));
 
 const unsigned int gimple_match_op::MAX_NUM_OPS;
 
@@ -133,9 +144,21 @@
       /* Likewise if the operation would not trap.  */
       bool honor_trapv = (INTEGRAL_TYPE_P (res_op->type)
 			  && TYPE_OVERFLOW_TRAPS (res_op->type));
-      if (!operation_could_trap_p ((tree_code) res_op->code,
-				   FLOAT_TYPE_P (res_op->type),
-				   honor_trapv, res_op->op_or_null (1)))
+      tree_code op_code = (tree_code) res_op->code;
+      bool op_could_trap;
+
+      /* COND_EXPR and VEC_COND_EXPR will trap if, and only if, the condition
+	 traps and hence we have to check this.  For all other operations, we
+	 don't need to consider the operands.  */
+      if (op_code == COND_EXPR || op_code == VEC_COND_EXPR)
+	op_could_trap = generic_expr_could_trap_p (res_op->ops[0]);
+      else
+	op_could_trap = operation_could_trap_p ((tree_code) res_op->code,
+						FLOAT_TYPE_P (res_op->type),
+						honor_trapv,
+						res_op->op_or_null (1));
+
+      if (!op_could_trap)
 	{
 	  res_op->cond.cond = NULL_TREE;
 	  return false;
@@ -172,7 +195,7 @@
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
 
-bool
+static bool
 gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
 		    tree (*valueize)(tree))
 {
@@ -180,7 +203,12 @@
     {
       tree tem = NULL_TREE;
       if (res_op->code.is_tree_code ())
-	tem = const_unop (res_op->code, res_op->type, res_op->ops[0]);
+	{
+	  tree_code code = res_op->code;
+	  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
+	      && TREE_CODE_LENGTH (code) == 1)
+	    tem = const_unop (res_op->code, res_op->type, res_op->ops[0]);
+	}
       else
 	tem = fold_const_call (combined_fn (res_op->code), res_op->type,
 			       res_op->ops[0]);
@@ -232,7 +260,7 @@
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
 
-bool
+static bool
 gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
 		    tree (*valueize)(tree))
 {
@@ -241,8 +269,13 @@
     {
       tree tem = NULL_TREE;
       if (res_op->code.is_tree_code ())
-	tem = const_binop (res_op->code, res_op->type,
-			   res_op->ops[0], res_op->ops[1]);
+	{
+	  tree_code code = res_op->code;
+	  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
+	      && TREE_CODE_LENGTH (code) == 2)
+	    tem = const_binop (res_op->code, res_op->type,
+			       res_op->ops[0], res_op->ops[1]);
+	}
       else
 	tem = fold_const_call (combined_fn (res_op->code), res_op->type,
 			       res_op->ops[0], res_op->ops[1]);
@@ -304,7 +337,7 @@
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
 
-bool
+static bool
 gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
 		    tree (*valueize)(tree))
 {
@@ -314,9 +347,14 @@
     {
       tree tem = NULL_TREE;
       if (res_op->code.is_tree_code ())
-	tem = fold_ternary/*_to_constant*/ (res_op->code, res_op->type,
-					    res_op->ops[0], res_op->ops[1],
-					    res_op->ops[2]);
+	{
+	  tree_code code = res_op->code;
+	  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
+	      && TREE_CODE_LENGTH (code) == 3)
+	    tem = fold_ternary/*_to_constant*/ (res_op->code, res_op->type,
+						res_op->ops[0], res_op->ops[1],
+						res_op->ops[2]);
+	}
       else
 	tem = fold_const_call (combined_fn (res_op->code), res_op->type,
 			       res_op->ops[0], res_op->ops[1], res_op->ops[2]);
@@ -375,7 +413,7 @@
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
 
-bool
+static bool
 gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
 		    tree (*valueize)(tree))
 {
@@ -416,7 +454,7 @@
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
 
-bool
+static bool
 gimple_resimplify5 (gimple_seq *seq, gimple_match_op *res_op,
 		    tree (*valueize)(tree))
 {
@@ -438,6 +476,30 @@
   return false;
 }
 
+/* Match and simplify the toplevel valueized operation THIS.
+   Replaces THIS with a simplified and/or canonicalized result and
+   returns whether any change was made.  */
+
+bool
+gimple_match_op::resimplify (gimple_seq *seq, tree (*valueize)(tree))
+{
+  switch (num_ops)
+    {
+    case 1:
+      return gimple_resimplify1 (seq, this, valueize);
+    case 2:
+      return gimple_resimplify2 (seq, this, valueize);
+    case 3:
+      return gimple_resimplify3 (seq, this, valueize);
+    case 4:
+      return gimple_resimplify4 (seq, this, valueize);
+    case 5:
+      return gimple_resimplify5 (seq, this, valueize);
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* If in GIMPLE the operation described by RES_OP should be single-rhs,
    build a GENERIC tree for that expression and update RES_OP accordingly.  */
 
@@ -802,8 +864,8 @@
   gimple_match_op cond_op (gimple_match_cond (res_op->ops[0],
 					      res_op->ops[num_ops - 1]),
 			   op, res_op->type, num_ops - 2);
-  for (unsigned int i = 1; i < num_ops - 1; ++i)
-    cond_op.ops[i - 1] = res_op->ops[i];
+
+  memcpy (cond_op.ops, res_op->ops + 1, (num_ops - 1) * sizeof *cond_op.ops);
   switch (num_ops - 2)
     {
     case 2:
@@ -1163,3 +1225,27 @@
     return false;
   return true;
 }
+
+/* Return true if a division INNER_DIV / DIVISOR where INNER_DIV
+   is another division can be optimized.  Don't optimize if INNER_DIV
+   is used in a TRUNC_MOD_EXPR with DIVISOR as second operand.  */
+
+static bool
+optimize_successive_divisions_p (tree divisor, tree inner_div)
+{
+  if (!gimple_in_ssa_p (cfun))
+    return false;
+
+  imm_use_iterator imm_iter;
+  use_operand_p use_p;
+  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, inner_div)
+    {
+      gimple *use_stmt = USE_STMT (use_p);
+      if (!is_gimple_assign (use_stmt)
+	  || gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR
+	  || !operand_equal_p (gimple_assign_rhs2 (use_stmt), divisor, 0))
+	continue;
+      return false;
+    }
+  return true;
+}