Jan Hubicka - Simplify floating point conversions IV (original) (raw)
This is the mail archive of the gcc-patches@gcc.gnu.orgmailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
- From: Jan Hubicka
- To: Richard Henderson , Jan Hubicka ,gcc-patches at gcc dot gnu dot org, aj at suse dot de
- Date: Thu, 7 Nov 2002 11:54:55 +0100
- Subject: Simplify floating point conversions IV
- References: <20021105171400.GX14655@kam.mff.cuni.cz> <20021105173800.GD20534@redhat.com> <20021106092310.GE22059@kam.mff.cuni.cz> <20021106175441.GZ22059@kam.mff.cuni.cz> <20021106180930.GA22066@redhat.com> <20021106214803.GD22059@kam.mff.cuni.cz> <20021106225454.GL22215@redhat.com>
On Wed, Nov 06, 2002 at 10:48:03PM +0100, Jan Hubicka wrote:
/* Wind away possible cast. */
if (TREE_CODE (arg0) == NOP_EXPR
&& (TYPE_PRECISION (TREE_TYPE (arg0))
> TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
[...]arg0 = TREE_OPERAND (arg0, 0);
/* Be curefull about integer to fp conversions.
These may overflow still. */
if (FLOAT_TYPE_P (TREE_TYPE (arg0))
I'd rather something like
static tree strip_float_extensions (exp) tree exp; { tree sub, expt, subt;
if (TREE_CODE (exp) != NOP_EXPR) return exp;
sub = TREE_OPERAND (exp, 0); subt = TREE_TYPE (sub); expt = TREE_TYPE (exp);
if (!FLOAT_TYPE_P (subt)) return exp;
if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt)) return exp;
return strip_float_extensions (sub); }
case RDIV_EXPR:
{
tree arg0 = TREE_OPERAND (expr, 0);
tree arg1 = TREE_OPERAND (expr, 1);
/* Unwind possible casts. */
Useful here as well. Nice. I've added that and suppressed the builtin transformation when not optimizing.
OK now?
Wed Nov 6 19:48:32 PST 2002 Jan Hubicka jh@suse.cz * convert.c (strip_float_extensions): New function. (convert_to_real): Optimize some cases. Index: convert.c
RCS file: /cvs/gcc/egcs/gcc/convert.c,v retrieving revision 1.19 diff -c -3 -p -r1.19 convert.c *** convert.c 4 Jul 2002 06:38:54 -0000 1.19 --- convert.c 7 Nov 2002 10:53:27 -0000 *************** Software Foundation, 59 Temple Place - S *** 30,35 **** --- 30,36 ---- #include "convert.h" #include "toplev.h" #include "langhooks.h"
static tree strip_float_extensions PARAMS ((tree));
/* Convert EXPR to some pointer or reference type TYPE.
*************** convert_to_pointer (type, expr) *** 71,76 **** --- 72,101 ---- } }
/* Avoid any floating point extensions from EXP. */
static tree
strip_float_extensions (exp)
tree exp;
{
tree sub, expt, subt;
if (TREE_CODE (exp) != NOP_EXPR)
return exp;
sub = TREE_OPERAND (exp, 0);
subt = TREE_TYPE (sub);
expt = TREE_TYPE (exp);
if (!FLOAT_TYPE_P (subt))
return exp;
if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
return exp;
return strip_float_extensions (sub);
}
/* Convert EXPR to some floating-point type TYPE.
EXPR must be float, integer, or enumeral;
*************** tree *** 80,85 **** --- 105,244 ---- convert_to_real (type, expr) tree type, expr; {
- enum built_in_function fcode = builtin_mathfn_code (expr);
- tree itype = TREE_TYPE (expr);
- /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
- if ((fcode == BUILT_IN_SQRT
|| fcode == BUILT_IN_SQRTL
|| fcode == BUILT_IN_SIN
|| fcode == BUILT_IN_SINL
|| fcode == BUILT_IN_COS
|| fcode == BUILT_IN_COSL
|| fcode == BUILT_IN_EXP
|| fcode == BUILT_IN_EXPL)
&& optimize
&& (TYPE_MODE (type) == TYPE_MODE (double_type_node)
|| TYPE_MODE (type) == TYPE_MODE (float_type_node)))
{
tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
tree newtype = type;
/* We have (outertype)sqrt((innertype)x). Choose the wider mode from
the both as the safe type for operation. */
if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
newtype = TREE_TYPE (arg0);
/* Be curefull about integer to fp conversions.
These may overflow still. */
if (FLOAT_TYPE_P (TREE_TYPE (arg0))
&& TYPE_PRECISION (newtype) <= TYPE_PRECISION (itype)
&& (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
|| TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
{
tree arglist;
if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
switch (fcode)
{
case BUILT_IN_SQRT:
case BUILT_IN_SQRTL:
fcode = BUILT_IN_SQRTF;
break;
case BUILT_IN_SIN:
case BUILT_IN_SINL:
fcode = BUILT_IN_SINF;
break;
case BUILT_IN_COS:
case BUILT_IN_COSL:
fcode = BUILT_IN_COSF;
break;
case BUILT_IN_EXP:
case BUILT_IN_EXPL:
fcode = BUILT_IN_EXPF;
break;
default:
abort ();
}
else
switch (fcode)
{
case BUILT_IN_SQRT:
case BUILT_IN_SQRTL:
fcode = BUILT_IN_SQRT;
break;
case BUILT_IN_SIN:
case BUILT_IN_SINL:
fcode = BUILT_IN_SIN;
break;
case BUILT_IN_COS:
case BUILT_IN_COSL:
fcode = BUILT_IN_COS;
break;
case BUILT_IN_EXP:
case BUILT_IN_EXPL:
fcode = BUILT_IN_EXP;
break;
default:
abort ();
}
/* ??? Fortran frontend does not initialize built_in_decls.
For some reason creating the decl using builtin_function does not
work as it should. */
if (built_in_decls [fcode])
{
arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
expr = build_function_call_expr (built_in_decls [fcode], arglist);
if (newtype == type)
return expr;
}
}
}
- /* Propagate the cast into the operation. */
- if (itype != type && FLOAT_TYPE_P (type))
switch (TREE_CODE (expr))
{
/* convert (float)-x into -(float)x. This is always safe. */
case ABS_EXPR:
case NEGATE_EXPR:
return build1 (TREE_CODE (expr), type,
fold (convert_to_real (type,
TREE_OPERAND (expr, 0))));
/* convert (outertype)((innertype0)a+(innertype1)b)
into ((newtype)a+(newtype)b) where newtype
is the widest mode from all of these. */
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
case RDIV_EXPR:
{
tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0));
tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1));
if (FLOAT_TYPE_P (TREE_TYPE (arg0))
&& FLOAT_TYPE_P (TREE_TYPE (arg1)))
{
tree newtype = type;
if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
newtype = TREE_TYPE (arg0);
if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
newtype = TREE_TYPE (arg1);
if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
{
expr = build (TREE_CODE (expr), newtype,
fold (convert_to_real (newtype, arg0)),
fold (convert_to_real (newtype, arg1)));
if (newtype == type)
return expr;
}
}
}
break;
default:
break;
}
- switch (TREE_CODE (TREE_TYPE (expr))) { case REAL_TYPE:
- Follow-Ups:
- Re: Simplify floating point conversions IV
* From: Richard Henderson
- Re: Simplify floating point conversions IV
- References:
- Simplify floating point conversions
* From: Jan Hubicka - Re: Simplify floating point conversions
* From: Richard Henderson - Simplify floating point conversions II
* From: Jan Hubicka - Re: Simplify floating point conversions II
* From: Jan Hubicka - Re: Simplify floating point conversions II
* From: Richard Henderson - Simplify floating point conversions III
* From: Jan Hubicka - Re: Simplify floating point conversions III
* From: Richard Henderson
- Simplify floating point conversions
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |