On Tue, Oct 20, 2015 at 11:03 AM, Richard Sandiford
<richard.sandif...@arm.com> wrote:
> Richi and I both had patches for cproj.  I thought I might as well
> post a rebased version of what I had, since for the other patches I'd
> been moving the constant handling into fold_builtin_1 (where functions
> without combinatorial folds also handled constants).  I'm hoping the
> switch statement there will eventually become the switch statement
> for folding a function with constant arguments.
>
> The patch also makes build_complex_cproj available globally and uses it
> for the existing match.pd rules.
>
> Certainly not a big deal or a big improvement, but... tested on
> x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi.  OK to install?

Ok with build_complex_cproj renamed to sth more descriptive - build_complex_inf?
After all it builds a complex Inf with an imag -0 eventually.

Richard.

> Thanks,
> Richard
>
>
> gcc/
>         * builtins.c (fold_builtin_cproj): Delete.
>         (fold_builtin_1): Handle constant arguments here.
>         (build_complex_cproj): Move to...
>         * tree.c: ...here.
>         * tree.h (build_complex_cproj): Declare.
>         * match.pd: Fold cproj(x)->x if x has no infinity.
>         Use build_complex_cproj for existing cproj rules.
>
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index a9872c4..16f3bfd 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -7539,50 +7539,6 @@ fold_fixed_mathfn (location_t loc, tree fndecl, tree 
> arg)
>    return NULL_TREE;
>  }
>
> -/* Build a complex (inf +- 0i) for the result of cproj.  TYPE is the
> -   complex tree type of the result.  If NEG is true, the imaginary
> -   zero is negative.  */
> -
> -static tree
> -build_complex_cproj (tree type, bool neg)
> -{
> -  REAL_VALUE_TYPE rinf, rzero = dconst0;
> -
> -  real_inf (&rinf);
> -  rzero.sign = neg;
> -  return build_complex (type, build_real (TREE_TYPE (type), rinf),
> -                       build_real (TREE_TYPE (type), rzero));
> -}
> -
> -/* Fold call to builtin cproj, cprojf or cprojl with argument ARG.  TYPE is 
> the
> -   return type.  Return NULL_TREE if no simplification can be made.  */
> -
> -static tree
> -fold_builtin_cproj (location_t loc, tree arg, tree type)
> -{
> -  if (!validate_arg (arg, COMPLEX_TYPE)
> -      || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
> -    return NULL_TREE;
> -
> -  /* If there are no infinities, return arg.  */
> -  if (! HONOR_INFINITIES (type))
> -    return non_lvalue_loc (loc, arg);
> -
> -  /* Calculate the result when the argument is a constant.  */
> -  if (TREE_CODE (arg) == COMPLEX_CST)
> -    {
> -      const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg));
> -      const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
> -
> -      if (real_isinf (real) || real_isinf (imag))
> -       return build_complex_cproj (type, imag->sign);
> -      else
> -       return arg;
> -    }
> -
> -  return NULL_TREE;
> -}
> -
>  /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
>     Return NULL_TREE if no simplification can be made.  */
>
> @@ -9505,7 +9461,20 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
>        break;
>
>      CASE_FLT_FN (BUILT_IN_CPROJ):
> -      return fold_builtin_cproj (loc, arg0, type);
> +      if (TREE_CODE (arg0) == COMPLEX_CST
> +         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
> +       {
> +         const REAL_VALUE_TYPE *real
> +           = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
> +         const REAL_VALUE_TYPE *imag
> +           = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
> +
> +         if (real_isinf (real) || real_isinf (imag))
> +           return build_complex_cproj (type, imag->sign);
> +         else
> +           return arg0;
> +       }
> +      break;
>
>      CASE_FLT_FN (BUILT_IN_CSIN):
>        if (validate_arg (arg0, COMPLEX_TYPE)
> diff --git a/gcc/match.pd b/gcc/match.pd
> index aaca3a0..7d16c52 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -2448,30 +2448,24 @@ along with GCC; see the file COPYING3.  If not see
>    (CABS (complex @0 @0))
>    (mult (abs @0) { build_real_truncate (type, dconst_sqrt2 ()); })))
>
> +/* cproj(x) -> x if we're ignoring infinities.  */
> +(simplify
> + (CPROJ @0)
> + (if (!HONOR_INFINITIES (type))
> +   @0))
> +
>  /* If the real part is inf and the imag part is known to be
>     nonnegative, return (inf + 0i).  */
>  (simplify
>   (CPROJ (complex REAL_CST@0 tree_expr_nonnegative_p@1))
>   (if (real_isinf (TREE_REAL_CST_PTR (@0)))
> -  (with
> -    {
> -      REAL_VALUE_TYPE rinf;
> -      real_inf (&rinf);
> -    }
> -   { build_complex (type, build_real (TREE_TYPE (type), rinf),
> -                   build_zero_cst (TREE_TYPE (type))); })))
> +  { build_complex_cproj (type, false); }))
> +
>  /* If the imag part is inf, return (inf+I*copysign(0,imag)).  */
>  (simplify
>   (CPROJ (complex @0 REAL_CST@1))
>   (if (real_isinf (TREE_REAL_CST_PTR (@1)))
> -  (with
> -    {
> -      REAL_VALUE_TYPE rinf, rzero = dconst0;
> -      real_inf (&rinf);
> -      rzero.sign = TREE_REAL_CST_PTR (@1)->sign;
> -    }
> -   { build_complex (type, build_real (TREE_TYPE (type), rinf),
> -                   build_real (TREE_TYPE (type), rzero)); })))
> +  { build_complex_cproj (type, TREE_REAL_CST_PTR (@1)->sign); }))
>
>
>  /* Narrowing of arithmetic and logical operations.
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 9d0e9de..1405328 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -1986,6 +1986,21 @@ build_complex (tree type, tree real, tree imag)
>    return t;
>  }
>
> +/* Build a complex (inf +- 0i) for the result of cproj.  TYPE is the
> +   complex tree type of the result.  If NEG is true, the imaginary
> +   zero is negative.  */
> +
> +tree
> +build_complex_cproj (tree type, bool neg)
> +{
> +  REAL_VALUE_TYPE rinf, rzero = dconst0;
> +
> +  real_inf (&rinf);
> +  rzero.sign = neg;
> +  return build_complex (type, build_real (TREE_TYPE (type), rinf),
> +                       build_real (TREE_TYPE (type), rzero));
> +}
> +
>  /* Return the constant 1 in type TYPE.  If TYPE has several elements, each
>     element is set to 1.  In particular, this is 1 + i for complex types.  */
>
> diff --git a/gcc/tree.h b/gcc/tree.h
> index f62cd27..2dbd81b 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -3847,6 +3847,7 @@ extern tree build_constructor_from_list (tree, tree);
>  extern tree build_constructor_va (tree, int, ...);
>  extern tree build_real_from_int_cst (tree, const_tree);
>  extern tree build_complex (tree, tree, tree);
> +extern tree build_complex_cproj (tree, bool);
>  extern tree build_each_one_cst (tree);
>  extern tree build_one_cst (tree);
>  extern tree build_minus_one_cst (tree);
>

Reply via email to