* [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).