diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-05-25 08:09:39 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-05-25 08:09:39 +0000 |
commit | 0d2b3bca81acf226e6c10defbc6072de4cf7e75c (patch) | |
tree | 2a0e429a6a0d5569f6a5df85a05bb542308c387e /gcc/gimple-match.h | |
parent | 2c53b149b7476fabd329429b2a6dce090f580ff4 (diff) | |
download | gcc-0d2b3bca81acf226e6c10defbc6072de4cf7e75c.zip gcc-0d2b3bca81acf226e6c10defbc6072de4cf7e75c.tar.gz gcc-0d2b3bca81acf226e6c10defbc6072de4cf7e75c.tar.bz2 |
Fold VEC_COND_EXPRs to IFN_COND_* where possible
This patch adds the folds:
(vec_cond COND (foo A B) C) -> (IFN_COND_FOO COND A B C)
(vec_cond COND C (foo A B)) -> (IFN_COND_FOO (!COND) A B C)
with the usual implicit restriction that the target must support
the produced IFN_COND_FOO.
The results of these folds don't have identical semantics, since
the reverse transform would be invalid if (FOO A[i] B[i]) faults when
COND[i] is false. But this direction is OK since we're simply dropping
faults for operations whose results aren't needed.
The new gimple_resimplify4 doesn't try to do any constant folding
on the IFN_COND_*s. This is because a later patch will handle it
by folding the associated unconditional operation.
Doing this in gimple is better than doing it in .md patterns,
since the second form (with the inverted condition) is much more
common than the first, and it's better to fold away the inversion
in gimple and optimise the result before entering expand.
2018-05-24 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
* doc/sourcebuild.texi (vect_double_cond_arith: Document.
* gimple-match.h (gimple_match_op::MAX_NUM_OPS): Bump to 4.
(gimple_match_op::gimple_match_op): Add an overload for 4 operands.
(gimple_match_op::set_op): Likewise.
(gimple_resimplify4): Declare.
* genmatch.c (get_operand_type): Handle CFN_COND_* functions.
(expr::gen_transform): Likewise.
(decision_tree::gen): Generate a simplification routine for 4 operands.
* gimple-match-head.c (gimple_simplify): Add an overload for
4 operands. In the top-level function, handle up to 4 call
arguments and call gimple_resimplify4.
(gimple_resimplify4): New function.
(build_call_internal): Pass a fourth operand.
(maybe_push_to_seq): Likewise.
* match.pd (UNCOND_BINARY, COND_BINARY): New operator lists.
Fold VEC_COND_EXPRs of an operation and a default value into
an IFN_COND_* function if possible.
* config/aarch64/iterators.md (UNSPEC_COND_MAX, UNSPEC_COND_MIN):
New unspecs.
(SVE_COND_FP_BINARY): Include them.
(optab, sve_fp_op): Handle them.
(SVE_INT_BINARY_REV): New code iterator.
(SVE_COND_FP_BINARY_REV): New int iterator.
(commutative): New int attribute.
* config/aarch64/aarch64-protos.h (aarch64_sve_prepare_conditional_op):
Declare.
* config/aarch64/aarch64.c (aarch64_sve_prepare_conditional_op): New
function.
* config/aarch64/aarch64-sve.md (cond_<optab><mode>): Use it.
(*cond_<optab><mode>): New patterns for reversed operands.
gcc/testsuite/
* lib/target-supports.exp
(check_effective_target_vect_double_cond_arith): New proc.
* gcc.dg/vect/vect-cond-arith-1.c: New test.
* gcc.target/aarch64/sve/vcond_8.c: Likewise.
* gcc.target/aarch64/sve/vcond_8_run.c: Likewise.
* gcc.target/aarch64/sve/vcond_9.c: Likewise.
* gcc.target/aarch64/sve/vcond_9_run.c: Likewise.
* gcc.target/aarch64/sve/vcond_12.c: Likewise.
* gcc.target/aarch64/sve/vcond_12_run.c: Likewise.
From-SVN: r260710
Diffstat (limited to 'gcc/gimple-match.h')
-rw-r--r-- | gcc/gimple-match.h | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h index 9a4d3bb..69b53f2 100644 --- a/gcc/gimple-match.h +++ b/gcc/gimple-match.h @@ -49,17 +49,19 @@ struct gimple_match_op gimple_match_op (code_helper, tree, tree); gimple_match_op (code_helper, tree, tree, tree); gimple_match_op (code_helper, tree, tree, tree, tree); + gimple_match_op (code_helper, tree, tree, tree, tree, tree); void set_op (code_helper, tree, unsigned int); void set_op (code_helper, tree, tree); void set_op (code_helper, tree, tree, tree); void set_op (code_helper, tree, tree, tree, tree); + void set_op (code_helper, tree, tree, tree, tree, tree); void set_value (tree); tree op_or_null (unsigned int) const; /* The maximum value of NUM_OPS. */ - static const unsigned int MAX_NUM_OPS = 3; + static const unsigned int MAX_NUM_OPS = 4; /* The operation being performed. */ code_helper code; @@ -113,6 +115,17 @@ gimple_match_op::gimple_match_op (code_helper code_in, tree type_in, ops[2] = op2; } +inline +gimple_match_op::gimple_match_op (code_helper code_in, tree type_in, + tree op0, tree op1, tree op2, tree op3) + : code (code_in), type (type_in), num_ops (4) +{ + ops[0] = op0; + ops[1] = op1; + ops[2] = op2; + ops[3] = op3; +} + /* Change the operation performed to CODE_IN, the type of the result to TYPE_IN, and the number of operands to NUM_OPS_IN. The caller needs to set the operands itself. */ @@ -160,6 +173,19 @@ gimple_match_op::set_op (code_helper code_in, tree type_in, ops[2] = op2; } +inline void +gimple_match_op::set_op (code_helper code_in, tree type_in, + tree op0, tree op1, tree op2, tree op3) +{ + code = code_in; + type = type_in; + num_ops = 4; + ops[0] = op0; + ops[1] = op1; + ops[2] = op2; + ops[3] = op3; +} + /* Set the "operation" to be the single value VALUE, such as a constant or SSA_NAME. */ @@ -196,6 +222,7 @@ bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *, bool gimple_resimplify1 (gimple_seq *, gimple_match_op *, tree (*)(tree)); bool gimple_resimplify2 (gimple_seq *, gimple_match_op *, tree (*)(tree)); bool gimple_resimplify3 (gimple_seq *, gimple_match_op *, tree (*)(tree)); +bool gimple_resimplify4 (gimple_seq *, gimple_match_op *, tree (*)(tree)); tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *, tree res = NULL_TREE); void maybe_build_generic_op (gimple_match_op *); |