Move some complex simplifications to match.pd
Richard Biener
richard.guenther@gmail.com
Mon Aug 31 12:29:00 GMT 2015
On Sun, Aug 30, 2015 at 9:44 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> just trying to shrink fold-const.c a bit more.
>
> The tests "if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)" seem useless,
> I did one bootstrap+testsuite with asserts there to make sure, so I am
> dropping them. The CONJ_EXPR simplifications don't seem very useful, as far
> as I can tell CONJ_EXPR is immediatly replaced with a piecewise operation
> (where the transformations are obvious), but it seemed easier to keep the
> transformations, in case they are not completely useless. I may have been a
> bit too enthusiastic with the :s on some transformations, but again they
> seem to be dead code... The converts also seem to be not so useful since
> they are expanded piecewise, even the ones that should be NOPS,
> so for
> _Complex unsigned f(_Complex int i){return i;}
> we generate:
> movl %edi, %eax
> shrq $32, %rdi
> salq $32, %rdi
> orq %rdi, %rax
> ...
Yeah, it might help for GENERIC folding but on gimple we lower things
pretty quickly
(partly during gimplification).
> Bootstrap+testsuite on ppc64le-redhat-linux.
Ok.
Thanks,
Richard.
> 2015-08-31 Marc Glisse <marc.glisse@inria.fr>
>
> gcc/
> * match.pd (SIN, COS, TAN, COSH): Reorder for consistency.
> (CEXPI): New operator list.
> (real (conj (x)), imag (conj (x)), real (x +- y), real (cexpi (x)),
> imag (cexpi (x)), conj (conj (x)), conj (complex (x, y))):
> Converted from ...
> * fold-const.c (fold_unary_loc, fold_binary_loc): ... here. Remove.
>
> gcc/testsuite/
> * gcc.dg/tree-ssa/complex-7.c: New file.
>
> --
> Marc Glisse
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c (revision 227316)
> +++ gcc/fold-const.c (working copy)
> @@ -7725,35 +7725,20 @@ fold_unary_loc (location_t loc, enum tre
> /* Strip sign ops from argument. */
> if (TREE_CODE (type) == REAL_TYPE)
> {
> tem = fold_strip_sign_ops (arg0);
> if (tem)
> return fold_build1_loc (loc, ABS_EXPR, type,
> fold_convert_loc (loc, type, tem));
> }
> return NULL_TREE;
>
> - case CONJ_EXPR:
> - if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
> - return fold_convert_loc (loc, type, arg0);
> - if (TREE_CODE (arg0) == COMPLEX_EXPR)
> - {
> - tree itype = TREE_TYPE (type);
> - tree rpart = fold_convert_loc (loc, itype, TREE_OPERAND (arg0,
> 0));
> - tree ipart = fold_convert_loc (loc, itype, TREE_OPERAND (arg0,
> 1));
> - return fold_build2_loc (loc, COMPLEX_EXPR, type, rpart,
> - negate_expr (ipart));
> - }
> - if (TREE_CODE (arg0) == CONJ_EXPR)
> - return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
> - return NULL_TREE;
> -
> case BIT_NOT_EXPR:
> /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify. */
> if (TREE_CODE (arg0) == BIT_XOR_EXPR
> && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,
> fold_convert_loc (loc, type,
> TREE_OPERAND (arg0,
> 0)))))
> return fold_build2_loc (loc, BIT_XOR_EXPR, type, tem,
> fold_convert_loc (loc, type,
> TREE_OPERAND (arg0, 1)));
> else if (TREE_CODE (arg0) == BIT_XOR_EXPR
> @@ -7769,95 +7754,20 @@ fold_unary_loc (location_t loc, enum tre
> case TRUTH_NOT_EXPR:
> /* Note that the operand of this must be an int
> and its values must be 0 or 1.
> ("true" is a fixed value perhaps depending on the language,
> but we don't handle values other than 1 correctly yet.) */
> tem = fold_truth_not_expr (loc, arg0);
> if (!tem)
> return NULL_TREE;
> return fold_convert_loc (loc, type, tem);
>
> - case REALPART_EXPR:
> - if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
> - return fold_convert_loc (loc, type, arg0);
> - if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
> - {
> - tree itype = TREE_TYPE (TREE_TYPE (arg0));
> - tem = fold_build2_loc (loc, TREE_CODE (arg0), itype,
> - fold_build1_loc (loc, REALPART_EXPR, itype,
> - TREE_OPERAND (arg0, 0)),
> - fold_build1_loc (loc, REALPART_EXPR, itype,
> - TREE_OPERAND (arg0, 1)));
> - return fold_convert_loc (loc, type, tem);
> - }
> - if (TREE_CODE (arg0) == CONJ_EXPR)
> - {
> - tree itype = TREE_TYPE (TREE_TYPE (arg0));
> - tem = fold_build1_loc (loc, REALPART_EXPR, itype,
> - TREE_OPERAND (arg0, 0));
> - return fold_convert_loc (loc, type, tem);
> - }
> - if (TREE_CODE (arg0) == CALL_EXPR)
> - {
> - tree fn = get_callee_fndecl (arg0);
> - if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
> - switch (DECL_FUNCTION_CODE (fn))
> - {
> - CASE_FLT_FN (BUILT_IN_CEXPI):
> - fn = mathfn_built_in (type, BUILT_IN_COS);
> - if (fn)
> - return build_call_expr_loc (loc, fn, 1, CALL_EXPR_ARG
> (arg0, 0));
> - break;
> -
> - default:
> - break;
> - }
> - }
> - return NULL_TREE;
> -
> - case IMAGPART_EXPR:
> - if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
> - return build_zero_cst (type);
> - if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
> - {
> - tree itype = TREE_TYPE (TREE_TYPE (arg0));
> - tem = fold_build2_loc (loc, TREE_CODE (arg0), itype,
> - fold_build1_loc (loc, IMAGPART_EXPR, itype,
> - TREE_OPERAND (arg0, 0)),
> - fold_build1_loc (loc, IMAGPART_EXPR, itype,
> - TREE_OPERAND (arg0, 1)));
> - return fold_convert_loc (loc, type, tem);
> - }
> - if (TREE_CODE (arg0) == CONJ_EXPR)
> - {
> - tree itype = TREE_TYPE (TREE_TYPE (arg0));
> - tem = fold_build1_loc (loc, IMAGPART_EXPR, itype, TREE_OPERAND
> (arg0, 0));
> - return fold_convert_loc (loc, type, negate_expr (tem));
> - }
> - if (TREE_CODE (arg0) == CALL_EXPR)
> - {
> - tree fn = get_callee_fndecl (arg0);
> - if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
> - switch (DECL_FUNCTION_CODE (fn))
> - {
> - CASE_FLT_FN (BUILT_IN_CEXPI):
> - fn = mathfn_built_in (type, BUILT_IN_SIN);
> - if (fn)
> - return build_call_expr_loc (loc, fn, 1, CALL_EXPR_ARG
> (arg0, 0));
> - break;
> -
> - default:
> - break;
> - }
> - }
> - return NULL_TREE;
> -
> case INDIRECT_REF:
> /* Fold *&X to X if X is an lvalue. */
> if (TREE_CODE (op0) == ADDR_EXPR)
> {
> tree op00 = TREE_OPERAND (op0, 0);
> if ((TREE_CODE (op00) == VAR_DECL
> || TREE_CODE (op00) == PARM_DECL
> || TREE_CODE (op00) == RESULT_DECL)
> && !TREE_READONLY (op00))
> return op00;
> Index: gcc/match.pd
> ===================================================================
> --- gcc/match.pd (revision 227316)
> +++ gcc/match.pd (working copy)
> @@ -48,24 +48,25 @@ along with GCC; see the file COPYING3.
> (define_operator_list LOG BUILT_IN_LOGF BUILT_IN_LOG BUILT_IN_LOGL)
> (define_operator_list EXP BUILT_IN_EXPF BUILT_IN_EXP BUILT_IN_EXPL)
> (define_operator_list LOG2 BUILT_IN_LOG2F BUILT_IN_LOG2 BUILT_IN_LOG2L)
> (define_operator_list EXP2 BUILT_IN_EXP2F BUILT_IN_EXP2 BUILT_IN_EXP2L)
> (define_operator_list LOG10 BUILT_IN_LOG10F BUILT_IN_LOG10 BUILT_IN_LOG10L)
> (define_operator_list EXP10 BUILT_IN_EXP10F BUILT_IN_EXP10 BUILT_IN_EXP10L)
> (define_operator_list POW BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
> (define_operator_list POW10 BUILT_IN_POW10F BUILT_IN_POW10 BUILT_IN_POW10L)
> (define_operator_list SQRT BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL)
> (define_operator_list CBRT BUILT_IN_CBRTF BUILT_IN_CBRT BUILT_IN_CBRTL)
> -(define_operator_list SIN BUILT_IN_SIN BUILT_IN_SINL BUILT_IN_SINF)
> -(define_operator_list COS BUILT_IN_COS BUILT_IN_COSL BUILT_IN_COSF)
> -(define_operator_list TAN BUILT_IN_TAN BUILT_IN_TANL BUILT_IN_TANF)
> -(define_operator_list COSH BUILT_IN_COSH BUILT_IN_COSHL BUILT_IN_COSHF)
> +(define_operator_list SIN BUILT_IN_SINF BUILT_IN_SIN BUILT_IN_SINL)
> +(define_operator_list COS BUILT_IN_COSF BUILT_IN_COS BUILT_IN_COSL)
> +(define_operator_list TAN BUILT_IN_TANF BUILT_IN_TAN BUILT_IN_TANL)
> +(define_operator_list COSH BUILT_IN_COSHF BUILT_IN_COSH BUILT_IN_COSHL)
> +(define_operator_list CEXPI BUILT_IN_CEXPIF BUILT_IN_CEXPI BUILT_IN_CEXPIL)
>
> /* Simplifications of operations with one constant operand and
> simplifications to constants or single values. */
>
> (for op (plus pointer_plus minus bit_ior bit_xor)
> (simplify
> (op @0 integer_zerop)
> (non_lvalue @0)))
>
> /* 0 +p index -> (type)index */
> @@ -1305,20 +1306,50 @@ along with GCC; see the file COPYING3.
> (simplify
> (complex (realpart @0) (imagpart @0))
> @0)
> (simplify
> (realpart (complex @0 @1))
> @0)
> (simplify
> (imagpart (complex @0 @1))
> @1)
>
> +/* Sometimes we only care about half of a complex expression. */
> +(simplify
> + (realpart (convert?:s (conj:s @0)))
> + (convert (realpart @0)))
> +(simplify
> + (imagpart (convert?:s (conj:s @0)))
> + (convert (negate (imagpart @0))))
> +(for part (realpart imagpart)
> + (for op (plus minus)
> + (simplify
> + (part (convert?:s@2 (op:s @0 @1)))
> + (convert (op (part @0) (part @1))))))
> +(simplify
> + (realpart (convert?:s (CEXPI:s @0)))
> + (convert (COS @0)))
> +(simplify
> + (imagpart (convert?:s (CEXPI:s @0)))
> + (convert (SIN @0)))
> +
> +/* conj(conj(x)) -> x */
> +(simplify
> + (conj (convert? (conj @0)))
> + (if (tree_nop_conversion_p (TREE_TYPE (@0), type))
> + (convert @0)))
> +
> +/* conj({x,y}) -> {x,-y} */
> +(simplify
> + (conj (convert?:s (complex:s @0 @1)))
> + (with { tree itype = TREE_TYPE (type); }
> + (complex (convert:itype @0) (negate (convert:itype @1)))))
>
> /* BSWAP simplifications, transforms checked by gcc.dg/builtin-bswap-8.c.
> */
> (for bswap (BUILT_IN_BSWAP16 BUILT_IN_BSWAP32 BUILT_IN_BSWAP64)
> (simplify
> (bswap (bswap @0))
> @0)
> (simplify
> (bswap (bit_not (bswap @0)))
> (bit_not @0))
> (for bitop (bit_xor bit_ior bit_and)
> Index: gcc/testsuite/gcc.dg/tree-ssa/complex-7.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/tree-ssa/complex-7.c (revision 0)
> +++ gcc/testsuite/gcc.dg/tree-ssa/complex-7.c (working copy)
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-forwprop1" } */
> +
> +float f(_Complex float x, _Complex float y){
> + x += y;
> + return __builtin_cimagf (x);
> +}
> +
> +double g(double x){
> + _Complex double c = __builtin_cexpi (x);
> + return __builtin_creal (c);
> +}
> +
> +/* { dg-final { scan-tree-dump "__builtin_cos" "forwprop1"} } */
> +/* { dg-final { scan-tree-dump-times "IMAGPART_EXPR" 2 "forwprop1"} } */
>
More information about the Gcc-patches
mailing list