public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [c++-delayed-folding] Introduce convert_to_real_nofold
@ 2015-11-03 16:53 Marek Polacek
  2015-11-04  9:32 ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2015-11-03 16:53 UTC (permalink / raw)
  To: GCC Patches, Jason Merrill

The last piece for convert.c.  Since convert_to_real uses fold ()
rather than fold_buildN, I defined a new macro to keep the code
more compact.

With this committed, convert.c should be dealt with.  If there's
anything else I could help with, please let me know.

Bootstrapped/regtested on x86_64-linux, ok for branch?

diff --git gcc/convert.c gcc/convert.c
index ec6ff37..3e593db 100644
--- gcc/convert.c
+++ gcc/convert.c
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "ubsan.h"
 
+#define maybe_fold(FOLD_P, EXPR) \
+  ((FOLD_P) ? fold (EXPR) : (EXPR))
 #define maybe_fold_build1_loc(FOLD_P, LOC, CODE, TYPE, EXPR) \
   ((FOLD_P) ? fold_build1_loc (LOC, CODE, TYPE, EXPR)	     \
    : build1_loc (LOC, CODE, TYPE, EXPR))
@@ -119,17 +121,19 @@ convert_to_pointer_nofold (tree type, tree expr)
 /* Convert EXPR to some floating-point type TYPE.
 
    EXPR must be float, fixed-point, integer, or enumeral;
-   in other cases error is called.  */
+   in other cases error is called.  If FOLD_P is true, try to fold
+   the expression.  */
 
-tree
-convert_to_real (tree type, tree expr)
+static tree
+convert_to_real_1 (tree type, tree expr, bool fold_p)
 {
   enum built_in_function fcode = builtin_mathfn_code (expr);
   tree itype = TREE_TYPE (expr);
+  location_t loc = EXPR_LOCATION (expr);
 
   if (TREE_CODE (expr) == COMPOUND_EXPR)
     {
-      tree t = convert_to_real (type, TREE_OPERAND (expr, 1));
+      tree t = convert_to_real_1 (type, TREE_OPERAND (expr, 1), fold_p);
       if (t == TREE_OPERAND (expr, 1))
 	return expr;
       return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
@@ -237,14 +241,13 @@ convert_to_real (tree type, tree expr)
 		      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
 		{
 		  tree fn = mathfn_built_in (newtype, fcode);
-
 		  if (fn)
-		  {
-		    tree arg = fold (convert_to_real (newtype, arg0));
-		    expr = build_call_expr (fn, 1, arg);
-		    if (newtype == type)
-		      return expr;
-		  }
+		    {
+		      tree arg = convert_to_real_1 (newtype, arg0, fold_p);
+		      expr = build_call_expr (fn, 1, maybe_fold (fold_p, arg));
+		      if (newtype == type)
+			return expr;
+		    }
 		}
 	    }
 	default:
@@ -263,9 +266,11 @@ convert_to_real (tree type, tree expr)
 	  if (!flag_rounding_math
 	      && FLOAT_TYPE_P (itype)
 	      && TYPE_PRECISION (type) < TYPE_PRECISION (itype))
-	    return build1 (TREE_CODE (expr), type,
-			   fold (convert_to_real (type,
-						  TREE_OPERAND (expr, 0))));
+	    {
+	      tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
+					    fold_p);
+	      return build1 (TREE_CODE (expr), type, maybe_fold (fold_p, arg));
+	    }
 	  break;
 	/* Convert (outertype)((innertype0)a+(innertype1)b)
 	   into ((newtype)a+(newtype)b) where newtype
@@ -301,8 +306,14 @@ convert_to_real (tree type, tree expr)
 		      || newtype == dfloat128_type_node)
 		    {
 		      expr = build2 (TREE_CODE (expr), newtype,
-				     fold (convert_to_real (newtype, arg0)),
-				     fold (convert_to_real (newtype, arg1)));
+				     maybe_fold (fold_p,
+						 convert_to_real_1 (newtype,
+								    arg0,
+								    fold_p)),
+				     maybe_fold (fold_p,
+						 convert_to_real_1 (newtype,
+								    arg1,
+								    fold_p)));
 		      if (newtype == type)
 			return expr;
 		      break;
@@ -341,8 +352,14 @@ convert_to_real (tree type, tree expr)
 			      && !excess_precision_type (newtype))))
 		    {
 		      expr = build2 (TREE_CODE (expr), newtype,
-				     fold (convert_to_real (newtype, arg0)),
-				     fold (convert_to_real (newtype, arg1)));
+				     maybe_fold (fold_p,
+						 convert_to_real_1 (newtype,
+								    arg0,
+								    fold_p)),
+				     maybe_fold (fold_p,
+						 convert_to_real_1 (newtype,
+								    arg1,
+								    fold_p)));
 		      if (newtype == type)
 			return expr;
 		    }
@@ -373,20 +390,39 @@ convert_to_real (tree type, tree expr)
 
     case COMPLEX_TYPE:
       return convert (type,
-		      fold_build1 (REALPART_EXPR,
-				   TREE_TYPE (TREE_TYPE (expr)), expr));
+		      maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
+					     TREE_TYPE (TREE_TYPE (expr)),
+					     expr));
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       error ("pointer value used where a floating point value was expected");
-      return convert_to_real (type, integer_zero_node);
+      return convert_to_real_1 (type, integer_zero_node, fold_p);
 
     default:
       error ("aggregate value used where a float was expected");
-      return convert_to_real (type, integer_zero_node);
+      return convert_to_real_1 (type, integer_zero_node, fold_p);
     }
 }
 
+/* A wrapper around convert_to_real_1 that always folds the
+   expression.  */
+
+tree
+convert_to_real (tree type, tree expr)
+{
+  return convert_to_real_1 (type, expr, true);
+}
+
+/* A wrapper around convert_to_real_1 that only folds the
+   expression if it is CONSTANT_CLASS_P.  */
+
+tree
+convert_to_real_nofold (tree type, tree expr)
+{
+  return convert_to_real_1 (type, expr, CONSTANT_CLASS_P (expr));
+}
+
 /* Convert EXPR to some integer (or enum) type TYPE.
 
    EXPR must be pointer, integer, discrete (enum, char, or bool), float,
diff --git gcc/convert.h gcc/convert.h
index 6cb439e..7cc3168 100644
--- gcc/convert.h
+++ gcc/convert.h
@@ -25,6 +25,7 @@ extern tree convert_to_integer_nofold (tree, tree);
 extern tree convert_to_pointer (tree, tree);
 extern tree convert_to_pointer_nofold (tree, tree);
 extern tree convert_to_real (tree, tree);
+extern tree convert_to_real_nofold (tree, tree);
 extern tree convert_to_fixed (tree, tree);
 extern tree convert_to_complex (tree, tree);
 extern tree convert_to_complex_nofold (tree, tree);
diff --git gcc/cp/call.c gcc/cp/call.c
index 79f8cfa..5b21b9f 100644
--- gcc/cp/call.c
+++ gcc/cp/call.c
@@ -6742,7 +6742,7 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
 		    "implicit conversion from %qT to %qT when passing "
 		    "argument to function",
 		    arg_type, double_type_node);
-      arg = convert_to_real (double_type_node, arg);
+      arg = convert_to_real_nofold (double_type_node, arg);
     }
   else if (NULLPTR_TYPE_P (arg_type))
     arg = null_pointer_node;
diff --git gcc/cp/cvt.c gcc/cp/cvt.c
index 1368f15..97b0b89 100644
--- gcc/cp/cvt.c
+++ gcc/cp/cvt.c
@@ -846,7 +846,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
 		      TREE_TYPE (e));
 	}
       if (code == REAL_TYPE)
-	return convert_to_real (type, e);
+	return convert_to_real_nofold (type, e);
       else if (code == COMPLEX_TYPE)
 	return convert_to_complex_nofold (type, e);
     }

	Marek

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [c++-delayed-folding] Introduce convert_to_real_nofold
  2015-11-03 16:53 [c++-delayed-folding] Introduce convert_to_real_nofold Marek Polacek
@ 2015-11-04  9:32 ` Richard Biener
  2015-11-04 14:03   ` Marek Polacek
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Biener @ 2015-11-04  9:32 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches, Jason Merrill

On Tue, Nov 3, 2015 at 5:53 PM, Marek Polacek <polacek@redhat.com> wrote:
> The last piece for convert.c.  Since convert_to_real uses fold ()
> rather than fold_buildN, I defined a new macro to keep the code
> more compact.
>
> With this committed, convert.c should be dealt with.  If there's
> anything else I could help with, please let me know.
>
> Bootstrapped/regtested on x86_64-linux, ok for branch?

I wonder what happens (on trunk) when you just remove the fold () calls.

Richard.

> diff --git gcc/convert.c gcc/convert.c
> index ec6ff37..3e593db 100644
> --- gcc/convert.c
> +++ gcc/convert.c
> @@ -37,6 +37,8 @@ along with GCC; see the file COPYING3.  If not see
>  #include "builtins.h"
>  #include "ubsan.h"
>
> +#define maybe_fold(FOLD_P, EXPR) \
> +  ((FOLD_P) ? fold (EXPR) : (EXPR))
>  #define maybe_fold_build1_loc(FOLD_P, LOC, CODE, TYPE, EXPR) \
>    ((FOLD_P) ? fold_build1_loc (LOC, CODE, TYPE, EXPR)       \
>     : build1_loc (LOC, CODE, TYPE, EXPR))
> @@ -119,17 +121,19 @@ convert_to_pointer_nofold (tree type, tree expr)
>  /* Convert EXPR to some floating-point type TYPE.
>
>     EXPR must be float, fixed-point, integer, or enumeral;
> -   in other cases error is called.  */
> +   in other cases error is called.  If FOLD_P is true, try to fold
> +   the expression.  */
>
> -tree
> -convert_to_real (tree type, tree expr)
> +static tree
> +convert_to_real_1 (tree type, tree expr, bool fold_p)
>  {
>    enum built_in_function fcode = builtin_mathfn_code (expr);
>    tree itype = TREE_TYPE (expr);
> +  location_t loc = EXPR_LOCATION (expr);
>
>    if (TREE_CODE (expr) == COMPOUND_EXPR)
>      {
> -      tree t = convert_to_real (type, TREE_OPERAND (expr, 1));
> +      tree t = convert_to_real_1 (type, TREE_OPERAND (expr, 1), fold_p);
>        if (t == TREE_OPERAND (expr, 1))
>         return expr;
>        return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
> @@ -237,14 +241,13 @@ convert_to_real (tree type, tree expr)
>                       || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
>                 {
>                   tree fn = mathfn_built_in (newtype, fcode);
> -
>                   if (fn)
> -                 {
> -                   tree arg = fold (convert_to_real (newtype, arg0));
> -                   expr = build_call_expr (fn, 1, arg);
> -                   if (newtype == type)
> -                     return expr;
> -                 }
> +                   {
> +                     tree arg = convert_to_real_1 (newtype, arg0, fold_p);
> +                     expr = build_call_expr (fn, 1, maybe_fold (fold_p, arg));
> +                     if (newtype == type)
> +                       return expr;
> +                   }
>                 }
>             }
>         default:
> @@ -263,9 +266,11 @@ convert_to_real (tree type, tree expr)
>           if (!flag_rounding_math
>               && FLOAT_TYPE_P (itype)
>               && TYPE_PRECISION (type) < TYPE_PRECISION (itype))
> -           return build1 (TREE_CODE (expr), type,
> -                          fold (convert_to_real (type,
> -                                                 TREE_OPERAND (expr, 0))));
> +           {
> +             tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
> +                                           fold_p);
> +             return build1 (TREE_CODE (expr), type, maybe_fold (fold_p, arg));
> +           }
>           break;
>         /* Convert (outertype)((innertype0)a+(innertype1)b)
>            into ((newtype)a+(newtype)b) where newtype
> @@ -301,8 +306,14 @@ convert_to_real (tree type, tree expr)
>                       || newtype == dfloat128_type_node)
>                     {
>                       expr = build2 (TREE_CODE (expr), newtype,
> -                                    fold (convert_to_real (newtype, arg0)),
> -                                    fold (convert_to_real (newtype, arg1)));
> +                                    maybe_fold (fold_p,
> +                                                convert_to_real_1 (newtype,
> +                                                                   arg0,
> +                                                                   fold_p)),
> +                                    maybe_fold (fold_p,
> +                                                convert_to_real_1 (newtype,
> +                                                                   arg1,
> +                                                                   fold_p)));
>                       if (newtype == type)
>                         return expr;
>                       break;
> @@ -341,8 +352,14 @@ convert_to_real (tree type, tree expr)
>                               && !excess_precision_type (newtype))))
>                     {
>                       expr = build2 (TREE_CODE (expr), newtype,
> -                                    fold (convert_to_real (newtype, arg0)),
> -                                    fold (convert_to_real (newtype, arg1)));
> +                                    maybe_fold (fold_p,
> +                                                convert_to_real_1 (newtype,
> +                                                                   arg0,
> +                                                                   fold_p)),
> +                                    maybe_fold (fold_p,
> +                                                convert_to_real_1 (newtype,
> +                                                                   arg1,
> +                                                                   fold_p)));
>                       if (newtype == type)
>                         return expr;
>                     }
> @@ -373,20 +390,39 @@ convert_to_real (tree type, tree expr)
>
>      case COMPLEX_TYPE:
>        return convert (type,
> -                     fold_build1 (REALPART_EXPR,
> -                                  TREE_TYPE (TREE_TYPE (expr)), expr));
> +                     maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
> +                                            TREE_TYPE (TREE_TYPE (expr)),
> +                                            expr));
>
>      case POINTER_TYPE:
>      case REFERENCE_TYPE:
>        error ("pointer value used where a floating point value was expected");
> -      return convert_to_real (type, integer_zero_node);
> +      return convert_to_real_1 (type, integer_zero_node, fold_p);
>
>      default:
>        error ("aggregate value used where a float was expected");
> -      return convert_to_real (type, integer_zero_node);
> +      return convert_to_real_1 (type, integer_zero_node, fold_p);
>      }
>  }
>
> +/* A wrapper around convert_to_real_1 that always folds the
> +   expression.  */
> +
> +tree
> +convert_to_real (tree type, tree expr)
> +{
> +  return convert_to_real_1 (type, expr, true);
> +}
> +
> +/* A wrapper around convert_to_real_1 that only folds the
> +   expression if it is CONSTANT_CLASS_P.  */
> +
> +tree
> +convert_to_real_nofold (tree type, tree expr)
> +{
> +  return convert_to_real_1 (type, expr, CONSTANT_CLASS_P (expr));
> +}
> +
>  /* Convert EXPR to some integer (or enum) type TYPE.
>
>     EXPR must be pointer, integer, discrete (enum, char, or bool), float,
> diff --git gcc/convert.h gcc/convert.h
> index 6cb439e..7cc3168 100644
> --- gcc/convert.h
> +++ gcc/convert.h
> @@ -25,6 +25,7 @@ extern tree convert_to_integer_nofold (tree, tree);
>  extern tree convert_to_pointer (tree, tree);
>  extern tree convert_to_pointer_nofold (tree, tree);
>  extern tree convert_to_real (tree, tree);
> +extern tree convert_to_real_nofold (tree, tree);
>  extern tree convert_to_fixed (tree, tree);
>  extern tree convert_to_complex (tree, tree);
>  extern tree convert_to_complex_nofold (tree, tree);
> diff --git gcc/cp/call.c gcc/cp/call.c
> index 79f8cfa..5b21b9f 100644
> --- gcc/cp/call.c
> +++ gcc/cp/call.c
> @@ -6742,7 +6742,7 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
>                     "implicit conversion from %qT to %qT when passing "
>                     "argument to function",
>                     arg_type, double_type_node);
> -      arg = convert_to_real (double_type_node, arg);
> +      arg = convert_to_real_nofold (double_type_node, arg);
>      }
>    else if (NULLPTR_TYPE_P (arg_type))
>      arg = null_pointer_node;
> diff --git gcc/cp/cvt.c gcc/cp/cvt.c
> index 1368f15..97b0b89 100644
> --- gcc/cp/cvt.c
> +++ gcc/cp/cvt.c
> @@ -846,7 +846,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
>                       TREE_TYPE (e));
>         }
>        if (code == REAL_TYPE)
> -       return convert_to_real (type, e);
> +       return convert_to_real_nofold (type, e);
>        else if (code == COMPLEX_TYPE)
>         return convert_to_complex_nofold (type, e);
>      }
>
>         Marek

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [c++-delayed-folding] Introduce convert_to_real_nofold
  2015-11-04  9:32 ` Richard Biener
@ 2015-11-04 14:03   ` Marek Polacek
  2015-11-04 15:31     ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2015-11-04 14:03 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches, Jason Merrill

On Wed, Nov 04, 2015 at 10:32:52AM +0100, Richard Biener wrote:
> On Tue, Nov 3, 2015 at 5:53 PM, Marek Polacek <polacek@redhat.com> wrote:
> > The last piece for convert.c.  Since convert_to_real uses fold ()
> > rather than fold_buildN, I defined a new macro to keep the code
> > more compact.
> >
> > With this committed, convert.c should be dealt with.  If there's
> > anything else I could help with, please let me know.
> >
> > Bootstrapped/regtested on x86_64-linux, ok for branch?
> 
> I wonder what happens (on trunk) when you just remove the fold () calls.

Nothing much, at least the following patch passes testing.

Bootstrapped/regtested on x86_64-linux.

2015-11-04  Marek Polacek  <polacek@redhat.com>

	* convert.c (convert_to_real): Remove calls to fold.

diff --git gcc/convert.c gcc/convert.c
index 113c11f..8ef1949 100644
--- gcc/convert.c
+++ gcc/convert.c
@@ -211,7 +211,7 @@ convert_to_real (tree type, tree expr)
 
 		  if (fn)
 		  {
-		    tree arg = fold (convert_to_real (newtype, arg0));
+		    tree arg = convert_to_real (newtype, arg0);
 		    expr = build_call_expr (fn, 1, arg);
 		    if (newtype == type)
 		      return expr;
@@ -235,8 +235,7 @@ convert_to_real (tree type, tree expr)
 	      && FLOAT_TYPE_P (itype)
 	      && TYPE_PRECISION (type) < TYPE_PRECISION (itype))
 	    return build1 (TREE_CODE (expr), type,
-			   fold (convert_to_real (type,
-						  TREE_OPERAND (expr, 0))));
+			   convert_to_real (type, TREE_OPERAND (expr, 0)));
 	  break;
 	/* Convert (outertype)((innertype0)a+(innertype1)b)
 	   into ((newtype)a+(newtype)b) where newtype
@@ -272,8 +271,8 @@ convert_to_real (tree type, tree expr)
 		      || newtype == dfloat128_type_node)
 		    {
 		      expr = build2 (TREE_CODE (expr), newtype,
-				     fold (convert_to_real (newtype, arg0)),
-				     fold (convert_to_real (newtype, arg1)));
+				     convert_to_real (newtype, arg0),
+				     convert_to_real (newtype, arg1));
 		      if (newtype == type)
 			return expr;
 		      break;
@@ -312,8 +311,8 @@ convert_to_real (tree type, tree expr)
 			      && !excess_precision_type (newtype))))
 		    {
 		      expr = build2 (TREE_CODE (expr), newtype,
-				     fold (convert_to_real (newtype, arg0)),
-				     fold (convert_to_real (newtype, arg1)));
+				     convert_to_real (newtype, arg0),
+				     convert_to_real (newtype, arg1));
 		      if (newtype == type)
 			return expr;
 		    }

	Marek

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [c++-delayed-folding] Introduce convert_to_real_nofold
  2015-11-04 14:03   ` Marek Polacek
@ 2015-11-04 15:31     ` Jason Merrill
  2015-11-04 17:34       ` Marek Polacek
  0 siblings, 1 reply; 6+ messages in thread
From: Jason Merrill @ 2015-11-04 15:31 UTC (permalink / raw)
  To: Marek Polacek, Richard Biener; +Cc: GCC Patches

On 11/04/2015 09:03 AM, Marek Polacek wrote:
> On Wed, Nov 04, 2015 at 10:32:52AM +0100, Richard Biener wrote:
>> On Tue, Nov 3, 2015 at 5:53 PM, Marek Polacek <polacek@redhat.com> wrote:
>>> The last piece for convert.c.  Since convert_to_real uses fold ()
>>> rather than fold_buildN, I defined a new macro to keep the code
>>> more compact.
>>>
>>> With this committed, convert.c should be dealt with.  If there's
>>> anything else I could help with, please let me know.
>>>
>>> Bootstrapped/regtested on x86_64-linux, ok for branch?
>>
>> I wonder what happens (on trunk) when you just remove the fold () calls.
>
> Nothing much, at least the following patch passes testing.

Then let's do that rather than introduce maybe_fold.

Jason

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [c++-delayed-folding] Introduce convert_to_real_nofold
  2015-11-04 15:31     ` Jason Merrill
@ 2015-11-04 17:34       ` Marek Polacek
  2015-11-04 19:05         ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Marek Polacek @ 2015-11-04 17:34 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Richard Biener, GCC Patches

On Wed, Nov 04, 2015 at 10:31:44AM -0500, Jason Merrill wrote:
> Then let's do that rather than introduce maybe_fold.

Like so?

Bootstrapped/regtested on x86_64-linux, ok for branch?

diff --git gcc/convert.c gcc/convert.c
index ec6ff37..9355f2b 100644
--- gcc/convert.c
+++ gcc/convert.c
@@ -119,17 +119,19 @@ convert_to_pointer_nofold (tree type, tree expr)
 /* Convert EXPR to some floating-point type TYPE.
 
    EXPR must be float, fixed-point, integer, or enumeral;
-   in other cases error is called.  */
+   in other cases error is called.  If FOLD_P is true, try to fold
+   the expression.  */
 
-tree
-convert_to_real (tree type, tree expr)
+static tree
+convert_to_real_1 (tree type, tree expr, bool fold_p)
 {
   enum built_in_function fcode = builtin_mathfn_code (expr);
   tree itype = TREE_TYPE (expr);
+  location_t loc = EXPR_LOCATION (expr);
 
   if (TREE_CODE (expr) == COMPOUND_EXPR)
     {
-      tree t = convert_to_real (type, TREE_OPERAND (expr, 1));
+      tree t = convert_to_real_1 (type, TREE_OPERAND (expr, 1), fold_p);
       if (t == TREE_OPERAND (expr, 1))
 	return expr;
       return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
@@ -237,14 +239,13 @@ convert_to_real (tree type, tree expr)
 		      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
 		{
 		  tree fn = mathfn_built_in (newtype, fcode);
-
 		  if (fn)
-		  {
-		    tree arg = fold (convert_to_real (newtype, arg0));
-		    expr = build_call_expr (fn, 1, arg);
-		    if (newtype == type)
-		      return expr;
-		  }
+		    {
+		      tree arg = convert_to_real_1 (newtype, arg0, fold_p);
+		      expr = build_call_expr (fn, 1, arg);
+		      if (newtype == type)
+			return expr;
+		    }
 		}
 	    }
 	default:
@@ -263,9 +264,11 @@ convert_to_real (tree type, tree expr)
 	  if (!flag_rounding_math
 	      && FLOAT_TYPE_P (itype)
 	      && TYPE_PRECISION (type) < TYPE_PRECISION (itype))
-	    return build1 (TREE_CODE (expr), type,
-			   fold (convert_to_real (type,
-						  TREE_OPERAND (expr, 0))));
+	    {
+	      tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
+					    fold_p);
+	      return build1 (TREE_CODE (expr), type, arg);
+	    }
 	  break;
 	/* Convert (outertype)((innertype0)a+(innertype1)b)
 	   into ((newtype)a+(newtype)b) where newtype
@@ -301,8 +304,10 @@ convert_to_real (tree type, tree expr)
 		      || newtype == dfloat128_type_node)
 		    {
 		      expr = build2 (TREE_CODE (expr), newtype,
-				     fold (convert_to_real (newtype, arg0)),
-				     fold (convert_to_real (newtype, arg1)));
+				     convert_to_real_1 (newtype, arg0,
+							fold_p),
+				     convert_to_real_1 (newtype, arg1,
+							fold_p));
 		      if (newtype == type)
 			return expr;
 		      break;
@@ -341,8 +346,10 @@ convert_to_real (tree type, tree expr)
 			      && !excess_precision_type (newtype))))
 		    {
 		      expr = build2 (TREE_CODE (expr), newtype,
-				     fold (convert_to_real (newtype, arg0)),
-				     fold (convert_to_real (newtype, arg1)));
+				     convert_to_real_1 (newtype, arg0,
+							fold_p),
+				     convert_to_real_1 (newtype, arg1,
+							fold_p));
 		      if (newtype == type)
 			return expr;
 		    }
@@ -373,20 +380,39 @@ convert_to_real (tree type, tree expr)
 
     case COMPLEX_TYPE:
       return convert (type,
-		      fold_build1 (REALPART_EXPR,
-				   TREE_TYPE (TREE_TYPE (expr)), expr));
+		      maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
+					     TREE_TYPE (TREE_TYPE (expr)),
+					     expr));
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       error ("pointer value used where a floating point value was expected");
-      return convert_to_real (type, integer_zero_node);
+      return convert_to_real_1 (type, integer_zero_node, fold_p);
 
     default:
       error ("aggregate value used where a float was expected");
-      return convert_to_real (type, integer_zero_node);
+      return convert_to_real_1 (type, integer_zero_node, fold_p);
     }
 }
 
+/* A wrapper around convert_to_real_1 that always folds the
+   expression.  */
+
+tree
+convert_to_real (tree type, tree expr)
+{
+  return convert_to_real_1 (type, expr, true);
+}
+
+/* A wrapper around convert_to_real_1 that only folds the
+   expression if it is CONSTANT_CLASS_P.  */
+
+tree
+convert_to_real_nofold (tree type, tree expr)
+{
+  return convert_to_real_1 (type, expr, CONSTANT_CLASS_P (expr));
+}
+
 /* Convert EXPR to some integer (or enum) type TYPE.
 
    EXPR must be pointer, integer, discrete (enum, char, or bool), float,
diff --git gcc/convert.h gcc/convert.h
index 6cb439e..7cc3168 100644
--- gcc/convert.h
+++ gcc/convert.h
@@ -25,6 +25,7 @@ extern tree convert_to_integer_nofold (tree, tree);
 extern tree convert_to_pointer (tree, tree);
 extern tree convert_to_pointer_nofold (tree, tree);
 extern tree convert_to_real (tree, tree);
+extern tree convert_to_real_nofold (tree, tree);
 extern tree convert_to_fixed (tree, tree);
 extern tree convert_to_complex (tree, tree);
 extern tree convert_to_complex_nofold (tree, tree);
diff --git gcc/cp/call.c gcc/cp/call.c
index 79f8cfa..5b21b9f 100644
--- gcc/cp/call.c
+++ gcc/cp/call.c
@@ -6742,7 +6742,7 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
 		    "implicit conversion from %qT to %qT when passing "
 		    "argument to function",
 		    arg_type, double_type_node);
-      arg = convert_to_real (double_type_node, arg);
+      arg = convert_to_real_nofold (double_type_node, arg);
     }
   else if (NULLPTR_TYPE_P (arg_type))
     arg = null_pointer_node;
diff --git gcc/cp/cvt.c gcc/cp/cvt.c
index 1368f15..97b0b89 100644
--- gcc/cp/cvt.c
+++ gcc/cp/cvt.c
@@ -846,7 +846,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
 		      TREE_TYPE (e));
 	}
       if (code == REAL_TYPE)
-	return convert_to_real (type, e);
+	return convert_to_real_nofold (type, e);
       else if (code == COMPLEX_TYPE)
 	return convert_to_complex_nofold (type, e);
     }

	Marek

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [c++-delayed-folding] Introduce convert_to_real_nofold
  2015-11-04 17:34       ` Marek Polacek
@ 2015-11-04 19:05         ` Jason Merrill
  0 siblings, 0 replies; 6+ messages in thread
From: Jason Merrill @ 2015-11-04 19:05 UTC (permalink / raw)
  To: Marek Polacek; +Cc: Richard Biener, GCC Patches

On 11/04/2015 12:34 PM, Marek Polacek wrote:
> On Wed, Nov 04, 2015 at 10:31:44AM -0500, Jason Merrill wrote:
>> Then let's do that rather than introduce maybe_fold.
>
> Like so?

> Bootstrapped/regtested on x86_64-linux, ok for branch?

Yes, thanks.

> diff --git gcc/convert.c gcc/convert.c
> index ec6ff37..9355f2b 100644
> --- gcc/convert.c
> +++ gcc/convert.c
> @@ -119,17 +119,19 @@ convert_to_pointer_nofold (tree type, tree expr)
>   /* Convert EXPR to some floating-point type TYPE.
>
>      EXPR must be float, fixed-point, integer, or enumeral;
> -   in other cases error is called.  */
> +   in other cases error is called.  If FOLD_P is true, try to fold
> +   the expression.  */
>
> -tree
> -convert_to_real (tree type, tree expr)
> +static tree
> +convert_to_real_1 (tree type, tree expr, bool fold_p)
>   {
>     enum built_in_function fcode = builtin_mathfn_code (expr);
>     tree itype = TREE_TYPE (expr);
> +  location_t loc = EXPR_LOCATION (expr);
>
>     if (TREE_CODE (expr) == COMPOUND_EXPR)
>       {
> -      tree t = convert_to_real (type, TREE_OPERAND (expr, 1));
> +      tree t = convert_to_real_1 (type, TREE_OPERAND (expr, 1), fold_p);
>         if (t == TREE_OPERAND (expr, 1))
>   	return expr;
>         return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR, TREE_TYPE (t),
> @@ -237,14 +239,13 @@ convert_to_real (tree type, tree expr)
>   		      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
>   		{
>   		  tree fn = mathfn_built_in (newtype, fcode);
> -
>   		  if (fn)
> -		  {
> -		    tree arg = fold (convert_to_real (newtype, arg0));
> -		    expr = build_call_expr (fn, 1, arg);
> -		    if (newtype == type)
> -		      return expr;
> -		  }
> +		    {
> +		      tree arg = convert_to_real_1 (newtype, arg0, fold_p);
> +		      expr = build_call_expr (fn, 1, arg);
> +		      if (newtype == type)
> +			return expr;
> +		    }
>   		}
>   	    }
>   	default:
> @@ -263,9 +264,11 @@ convert_to_real (tree type, tree expr)
>   	  if (!flag_rounding_math
>   	      && FLOAT_TYPE_P (itype)
>   	      && TYPE_PRECISION (type) < TYPE_PRECISION (itype))
> -	    return build1 (TREE_CODE (expr), type,
> -			   fold (convert_to_real (type,
> -						  TREE_OPERAND (expr, 0))));
> +	    {
> +	      tree arg = convert_to_real_1 (type, TREE_OPERAND (expr, 0),
> +					    fold_p);
> +	      return build1 (TREE_CODE (expr), type, arg);
> +	    }
>   	  break;
>   	/* Convert (outertype)((innertype0)a+(innertype1)b)
>   	   into ((newtype)a+(newtype)b) where newtype
> @@ -301,8 +304,10 @@ convert_to_real (tree type, tree expr)
>   		      || newtype == dfloat128_type_node)
>   		    {
>   		      expr = build2 (TREE_CODE (expr), newtype,
> -				     fold (convert_to_real (newtype, arg0)),
> -				     fold (convert_to_real (newtype, arg1)));
> +				     convert_to_real_1 (newtype, arg0,
> +							fold_p),
> +				     convert_to_real_1 (newtype, arg1,
> +							fold_p));
>   		      if (newtype == type)
>   			return expr;
>   		      break;
> @@ -341,8 +346,10 @@ convert_to_real (tree type, tree expr)
>   			      && !excess_precision_type (newtype))))
>   		    {
>   		      expr = build2 (TREE_CODE (expr), newtype,
> -				     fold (convert_to_real (newtype, arg0)),
> -				     fold (convert_to_real (newtype, arg1)));
> +				     convert_to_real_1 (newtype, arg0,
> +							fold_p),
> +				     convert_to_real_1 (newtype, arg1,
> +							fold_p));
>   		      if (newtype == type)
>   			return expr;
>   		    }
> @@ -373,20 +380,39 @@ convert_to_real (tree type, tree expr)
>
>       case COMPLEX_TYPE:
>         return convert (type,
> -		      fold_build1 (REALPART_EXPR,
> -				   TREE_TYPE (TREE_TYPE (expr)), expr));
> +		      maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
> +					     TREE_TYPE (TREE_TYPE (expr)),
> +					     expr));
>
>       case POINTER_TYPE:
>       case REFERENCE_TYPE:
>         error ("pointer value used where a floating point value was expected");
> -      return convert_to_real (type, integer_zero_node);
> +      return convert_to_real_1 (type, integer_zero_node, fold_p);
>
>       default:
>         error ("aggregate value used where a float was expected");
> -      return convert_to_real (type, integer_zero_node);
> +      return convert_to_real_1 (type, integer_zero_node, fold_p);
>       }
>   }
>
> +/* A wrapper around convert_to_real_1 that always folds the
> +   expression.  */
> +
> +tree
> +convert_to_real (tree type, tree expr)
> +{
> +  return convert_to_real_1 (type, expr, true);
> +}
> +
> +/* A wrapper around convert_to_real_1 that only folds the
> +   expression if it is CONSTANT_CLASS_P.  */
> +
> +tree
> +convert_to_real_nofold (tree type, tree expr)
> +{
> +  return convert_to_real_1 (type, expr, CONSTANT_CLASS_P (expr));
> +}
> +
>   /* Convert EXPR to some integer (or enum) type TYPE.
>
>      EXPR must be pointer, integer, discrete (enum, char, or bool), float,
> diff --git gcc/convert.h gcc/convert.h
> index 6cb439e..7cc3168 100644
> --- gcc/convert.h
> +++ gcc/convert.h
> @@ -25,6 +25,7 @@ extern tree convert_to_integer_nofold (tree, tree);
>   extern tree convert_to_pointer (tree, tree);
>   extern tree convert_to_pointer_nofold (tree, tree);
>   extern tree convert_to_real (tree, tree);
> +extern tree convert_to_real_nofold (tree, tree);
>   extern tree convert_to_fixed (tree, tree);
>   extern tree convert_to_complex (tree, tree);
>   extern tree convert_to_complex_nofold (tree, tree);
> diff --git gcc/cp/call.c gcc/cp/call.c
> index 79f8cfa..5b21b9f 100644
> --- gcc/cp/call.c
> +++ gcc/cp/call.c
> @@ -6742,7 +6742,7 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
>   		    "implicit conversion from %qT to %qT when passing "
>   		    "argument to function",
>   		    arg_type, double_type_node);
> -      arg = convert_to_real (double_type_node, arg);
> +      arg = convert_to_real_nofold (double_type_node, arg);
>       }
>     else if (NULLPTR_TYPE_P (arg_type))
>       arg = null_pointer_node;
> diff --git gcc/cp/cvt.c gcc/cp/cvt.c
> index 1368f15..97b0b89 100644
> --- gcc/cp/cvt.c
> +++ gcc/cp/cvt.c
> @@ -846,7 +846,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
>   		      TREE_TYPE (e));
>   	}
>         if (code == REAL_TYPE)
> -	return convert_to_real (type, e);
> +	return convert_to_real_nofold (type, e);
>         else if (code == COMPLEX_TYPE)
>   	return convert_to_complex_nofold (type, e);
>       }
>
> 	Marek
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-11-04 19:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-03 16:53 [c++-delayed-folding] Introduce convert_to_real_nofold Marek Polacek
2015-11-04  9:32 ` Richard Biener
2015-11-04 14:03   ` Marek Polacek
2015-11-04 15:31     ` Jason Merrill
2015-11-04 17:34       ` Marek Polacek
2015-11-04 19:05         ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).