fold-const.c (fold_convert): Rename to fold_convert_const.

* fold-const.c (fold_convert): Rename to fold_convert_const.
	(fold_convert_const): Change arguments to take a tree_code,
	a type and the operand/expression to be converted.  Return
	NULL_TREE if no simplification is possible.  Add support for
	FIX_CEIL_EXPR and FIX_FLOOR_EXPR in addition to FIX_TRUNC_EXPR.
	(fold): Handle FIX_CEIL_EXPR and FIX_FLOOR_EXPR.
	Adjust call to fold_convert to match new fold_convert_const.
	Avoid modifying the tree passed to fold in-place.

From-SVN: r76237
This commit is contained in:
Roger Sayle 2004-01-20 22:59:59 +00:00 committed by Roger Sayle
parent 34c80057fc
commit fdb33708b4
2 changed files with 55 additions and 33 deletions

View File

@ -1,3 +1,14 @@
2004-01-20 Roger Sayle <roger@eyesopen.com>
* fold-const.c (fold_convert): Rename to fold_convert_const.
(fold_convert_const): Change arguments to take a tree_code,
a type and the operand/expression to be converted. Return
NULL_TREE if no simplification is possible. Add support for
FIX_CEIL_EXPR and FIX_FLOOR_EXPR in addition to FIX_TRUNC_EXPR.
(fold): Handle FIX_CEIL_EXPR and FIX_FLOOR_EXPR.
Adjust call to fold_convert to match new fold_convert_const.
Avoid modifying the tree passed to fold in-place.
2004-01-21 Alan Modra <amodra@bigpond.net.au>
* config/rs6000/sysv4.h (DWARF2_FRAME_REG_OUT): Define.

View File

@ -1,6 +1,6 @@
/* Fold a constant sub-tree into a single node for C-compiler
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003 Free Software Foundation, Inc.
2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@ -69,7 +69,7 @@ static tree int_const_binop (enum tree_code, tree, tree, int);
static tree const_binop (enum tree_code, tree, tree, int);
static hashval_t size_htab_hash (const void *);
static int size_htab_eq (const void *, const void *);
static tree fold_convert (tree, tree);
static tree fold_convert_const (enum tree_code, tree, tree);
static enum tree_code invert_tree_comparison (enum tree_code);
static enum tree_code swap_tree_comparison (enum tree_code);
static int comparison_to_compcode (enum tree_code);
@ -1657,14 +1657,17 @@ size_diffop (tree arg0, tree arg1)
}
/* Given T, a tree representing type conversion of ARG1, a constant,
return a constant tree representing the result of conversion. */
/* Attempt to fold type conversion operation CODE of expression ARG1 to
type TYPE. If no simplification can be done return NULL_TREE. */
static tree
fold_convert (tree t, tree arg1)
fold_convert_const (enum tree_code code, tree type, tree arg1)
{
tree type = TREE_TYPE (t);
int overflow = 0;
tree t;
if (TREE_TYPE (arg1) == type)
return arg1;
if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
{
@ -1673,7 +1676,7 @@ fold_convert (tree t, tree arg1)
/* If we would build a constant wider than GCC supports,
leave the conversion unfolded. */
if (TYPE_PRECISION (type) > 2 * HOST_BITS_PER_WIDE_INT)
return t;
return NULL_TREE;
/* If we are trying to make a sizetype for a small integer, use
size_int to pick up cached types to reduce duplicate nodes. */
@ -1701,6 +1704,7 @@ fold_convert (tree t, tree arg1)
|| TREE_OVERFLOW (arg1));
TREE_CONSTANT_OVERFLOW (t)
= TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
return t;
}
else if (TREE_CODE (arg1) == REAL_CST)
{
@ -1715,25 +1719,43 @@ fold_convert (tree t, tree arg1)
HOST_WIDE_INT high, low;
REAL_VALUE_TYPE r;
REAL_VALUE_TYPE x = TREE_REAL_CST (arg1);
/* If x is NaN, return zero and show we have an overflow. */
if (REAL_VALUE_ISNAN (x))
switch (code)
{
case FIX_TRUNC_EXPR:
real_trunc (&r, VOIDmode, &x);
break;
case FIX_CEIL_EXPR:
real_ceil (&r, VOIDmode, &x);
break;
case FIX_FLOOR_EXPR:
real_floor (&r, VOIDmode, &x);
break;
default:
abort ();
}
/* If R is NaN, return zero and show we have an overflow. */
if (REAL_VALUE_ISNAN (r))
{
overflow = 1;
high = 0;
low = 0;
}
/* See if X will be in range after truncation towards 0.
To compensate for truncation, move the bounds away from 0,
but reject if X exactly equals the adjusted bounds. */
/* See if R is less than the lower bound or greater than the
upper bound. */
if (! overflow)
{
tree lt = TYPE_MIN_VALUE (type);
REAL_VALUE_TYPE l = real_value_from_int_cst (NULL_TREE, lt);
REAL_ARITHMETIC (l, MINUS_EXPR, l, dconst1);
if (! REAL_VALUES_LESS (l, x))
if (REAL_VALUES_LESS (r, l))
{
overflow = 1;
high = TREE_INT_CST_HIGH (lt);
@ -1747,8 +1769,7 @@ fold_convert (tree t, tree arg1)
if (ut)
{
REAL_VALUE_TYPE u = real_value_from_int_cst (NULL_TREE, ut);
REAL_ARITHMETIC (u, PLUS_EXPR, u, dconst1);
if (! REAL_VALUES_LESS (x, u))
if (REAL_VALUES_LESS (u, r))
{
overflow = 1;
high = TREE_INT_CST_HIGH (ut);
@ -1758,7 +1779,7 @@ fold_convert (tree t, tree arg1)
}
if (! overflow)
REAL_VALUE_TO_INT (&low, &high, x);
REAL_VALUE_TO_INT (&low, &high, r);
t = build_int_2 (low, high);
TREE_TYPE (t) = type;
@ -1766,8 +1787,8 @@ fold_convert (tree t, tree arg1)
= TREE_OVERFLOW (arg1) | force_fit_type (t, overflow);
TREE_CONSTANT_OVERFLOW (t)
= TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
return t;
}
TREE_TYPE (t) = type;
}
else if (TREE_CODE (type) == REAL_TYPE)
{
@ -1795,8 +1816,7 @@ fold_convert (tree t, tree arg1)
return t;
}
}
TREE_CONSTANT (t) = 1;
return t;
return NULL_TREE;
}
/* Return an expr equal to X but certainly not valid as an lvalue. */
@ -5432,8 +5452,8 @@ fold (tree expr)
case FLOAT_EXPR:
case CONVERT_EXPR:
case FIX_TRUNC_EXPR:
/* Other kinds of FIX are not handled properly by fold_convert. */
case FIX_CEIL_EXPR:
case FIX_FLOOR_EXPR:
if (TREE_TYPE (TREE_OPERAND (t, 0)) == TREE_TYPE (t))
return TREE_OPERAND (t, 0);
@ -5577,17 +5597,8 @@ fold (tree expr)
convert (TREE_TYPE (t), and1)));
}
if (!wins)
{
if (TREE_CONSTANT (t) != TREE_CONSTANT (arg0))
{
if (t == orig_t)
t = copy_node (t);
TREE_CONSTANT (t) = TREE_CONSTANT (arg0);
}
return t;
}
return fold_convert (t, arg0);
tem = fold_convert_const (code, TREE_TYPE (t), arg0);
return tem ? tem : t;
case VIEW_CONVERT_EXPR:
if (TREE_CODE (TREE_OPERAND (t, 0)) == VIEW_CONVERT_EXPR)