On Tue, Nov 3, 2015 at 5:53 PM, Marek Polacek <pola...@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