builtins.c (fold_trunc_transparent_mathfn): New function.
* builtins.c (fold_trunc_transparent_mathfn): New function. (fold_builtin): Use it. * convert.c (convert_to_real): Re-enable code to convert math functions; add support for floor familly functions. From-SVN: r61764
This commit is contained in:
parent
cd68f4e4c2
commit
27a6aa72db
@ -1,3 +1,10 @@
|
||||
Sat Jan 25 12:05:17 CET 2003 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* builtins.c (fold_trunc_transparent_mathfn): New function.
|
||||
(fold_builtin): Use it.
|
||||
* convert.c (convert_to_real): Re-enable code to convert
|
||||
math functions; add support for floor familly functions.
|
||||
|
||||
2003-01-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
|
||||
|
||||
* Makefile.in (cfgloop.o, cfgloopanal.o, cfgloopmanip.o): Add
|
||||
|
@ -157,6 +157,7 @@ static tree fold_builtin_classify_type PARAMS ((tree));
|
||||
static tree fold_builtin_inf PARAMS ((tree, int));
|
||||
static tree fold_builtin_nan PARAMS ((tree, tree, int));
|
||||
static int validate_arglist PARAMS ((tree, ...));
|
||||
static tree fold_trunc_transparent_mathfn PARAMS ((tree));
|
||||
|
||||
/* Return the alignment in bits of EXP, a pointer valued expression.
|
||||
But don't return more than MAX_ALIGN no matter what.
|
||||
@ -4423,6 +4424,36 @@ fold_builtin_nan (arglist, type, quiet)
|
||||
return build_real (type, real);
|
||||
}
|
||||
|
||||
/* EXP is assumed to me builtin call where truncation can be propagated
|
||||
across (for instance floor((double)f) == (double)floorf (f).
|
||||
Do the transformation. */
|
||||
static tree
|
||||
fold_trunc_transparent_mathfn (exp)
|
||||
tree exp;
|
||||
{
|
||||
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
|
||||
tree arglist = TREE_OPERAND (exp, 1);
|
||||
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
|
||||
|
||||
if (optimize && validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
|
||||
{
|
||||
tree arg0 = strip_float_extensions (TREE_VALUE (arglist));
|
||||
tree ftype = TREE_TYPE (exp);
|
||||
tree newtype = TREE_TYPE (arg0);
|
||||
tree decl;
|
||||
|
||||
if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
|
||||
&& (decl = mathfn_built_in (newtype, fcode)))
|
||||
{
|
||||
arglist =
|
||||
build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
|
||||
return convert (ftype,
|
||||
build_function_call_expr (decl, arglist));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used by constant folding to eliminate some builtin calls early. EXP is
|
||||
the CALL_EXPR of a call to a builtin function. */
|
||||
|
||||
@ -4574,6 +4605,23 @@ fold_builtin (exp)
|
||||
case BUILT_IN_NANSL:
|
||||
return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), false);
|
||||
|
||||
case BUILT_IN_FLOOR:
|
||||
case BUILT_IN_FLOORF:
|
||||
case BUILT_IN_FLOORL:
|
||||
case BUILT_IN_CEIL:
|
||||
case BUILT_IN_CEILF:
|
||||
case BUILT_IN_CEILL:
|
||||
case BUILT_IN_TRUNC:
|
||||
case BUILT_IN_TRUNCF:
|
||||
case BUILT_IN_TRUNCL:
|
||||
case BUILT_IN_ROUND:
|
||||
case BUILT_IN_ROUNDF:
|
||||
case BUILT_IN_ROUNDL:
|
||||
case BUILT_IN_NEARBYINT:
|
||||
case BUILT_IN_NEARBYINTF:
|
||||
case BUILT_IN_NEARBYINTL:
|
||||
return fold_trunc_transparent_mathfn (exp);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -127,13 +127,11 @@ tree
|
||||
convert_to_real (type, expr)
|
||||
tree type, expr;
|
||||
{
|
||||
enum built_in_function fcode = builtin_mathfn_code (expr);
|
||||
tree itype = TREE_TYPE (expr);
|
||||
|
||||
/* Disable until we figure out how to decide whether the functions are
|
||||
present in runtime. */
|
||||
#if 0
|
||||
enum built_in_function fcode = builtin_mathfn_code (expr);
|
||||
|
||||
/* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
|
||||
if ((fcode == BUILT_IN_SQRT
|
||||
|| fcode == BUILT_IN_SQRTL
|
||||
@ -155,72 +153,52 @@ convert_to_real (type, expr)
|
||||
if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
|
||||
newtype = TREE_TYPE (arg0);
|
||||
|
||||
/* Be careful about integer to fp conversions.
|
||||
/* 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_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 ();
|
||||
}
|
||||
tree fn = mathfn_built_in (newtype, fcode);
|
||||
|
||||
/* ??? 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])
|
||||
if (fn)
|
||||
{
|
||||
arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
|
||||
expr = build_function_call_expr (built_in_decls [fcode], arglist);
|
||||
expr = build_function_call_expr (fn, arglist);
|
||||
if (newtype == type)
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (optimize
|
||||
&& (((fcode == BUILT_IN_FLOORL
|
||||
|| fcode == BUILT_IN_CEILL
|
||||
|| fcode == BUILT_IN_ROUND
|
||||
|| fcode == BUILT_IN_TRUNC
|
||||
|| fcode == BUILT_IN_NEARBYINT)
|
||||
&& (TYPE_MODE (type) == TYPE_MODE (double_type_node)
|
||||
|| TYPE_MODE (type) == TYPE_MODE (float_type_node)))
|
||||
|| ((fcode == BUILT_IN_FLOOR
|
||||
|| fcode == BUILT_IN_CEIL
|
||||
|| fcode == BUILT_IN_ROUND
|
||||
|| fcode == BUILT_IN_TRUNC
|
||||
|| fcode == BUILT_IN_NEARBYINT)
|
||||
&& (TYPE_MODE (type) == TYPE_MODE (float_type_node)))))
|
||||
{
|
||||
tree fn = mathfn_built_in (type, fcode);
|
||||
|
||||
if (fn)
|
||||
{
|
||||
tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr,
|
||||
1)));
|
||||
tree arglist = build_tree_list (NULL_TREE,
|
||||
fold (convert_to_real (type, arg0)));
|
||||
|
||||
return build_function_call_expr (fn, arglist);
|
||||
}
|
||||
}
|
||||
|
||||
/* Propagate the cast into the operation. */
|
||||
if (itype != type && FLOAT_TYPE_P (type))
|
||||
|
Loading…
Reference in New Issue
Block a user