Mercurial > hg > CbC > CbC_gcc
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; +}