This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Simplify floating point conversions
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com, aj at suse dot de
- Date: Tue, 5 Nov 2002 18:14:00 +0100
- Subject: Simplify floating point conversions
Hi,
this patch makes us to simplify some of the floating point operations to
narrower mode when conversions are present. This include
+,-,/,*,abs,neg,sqrt/sin/cos/exp.
I believe it is IEEE safe, but some expert would be welcome.
The sqrt/sin/cos/exp conversion does not work in fortran mode, since
built_in_decls is not initialized. I was trying to get around but never
suceeded to produce working call there.
Honza
Tue Nov 5 02:06:18 PST 2002 Jan Hubicka <jh@suse.cz>
* convert.c (convert_to_real): Simplify some special 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 5 Nov 2002 17:09:53 -0000
*************** tree
*** 80,85 ****
--- 80,203 ----
convert_to_real (type, expr)
tree type, expr;
{
+ enum built_in_function fcode = builtin_mathfn_code (expr);
+ tree itype = TREE_TYPE (expr);
+
+ 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)
+ && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
+ || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
+ {
+ tree arg0 = TREE_VALUE (TREE_OPERAND (expr, 1));
+ tree newtype = type;
+
+ if (TREE_CODE (arg0) == NOP_EXPR)
+ arg0 = TREE_OPERAND (arg0, 0);
+
+ if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
+ newtype = TREE_TYPE (arg0);
+ 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, decl;
+ 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 ();
+ }
+
+ if (built_in_decls [fcode])
+ {
+ decl = build_function_call_expr (built_in_decls [fcode], arglist);
+ return decl;
+ }
+ }
+ }
+ if (itype != type && FLOAT_TYPE_P (type))
+ switch (TREE_CODE (expr))
+ {
+ case ABS_EXPR:
+ case NEGATE_EXPR:
+ return build1 (TREE_CODE (expr), type,
+ fold (convert_to_real (type,
+ TREE_OPERAND (expr, 0))));
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case RDIV_EXPR:
+ {
+ tree arg0 = TREE_OPERAND (expr, 0);
+ tree arg1 = TREE_OPERAND (expr, 1);
+ if (TREE_CODE (arg0) == NOP_EXPR)
+ arg0 = TREE_OPERAND (arg0, 0);
+ if (TREE_CODE (arg1) == NOP_EXPR)
+ arg1 = TREE_OPERAND (arg1, 0);
+ 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))
+ return build (TREE_CODE (expr), newtype,
+ fold (convert_to_real (newtype, arg0)),
+ fold (convert_to_real (newtype, arg1)));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
switch (TREE_CODE (TREE_TYPE (expr)))
{
case REAL_TYPE: