mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 18:40:53 +08:00
fold-const.c (omit_two_operands): New function.
* fold-const.c (omit_two_operands): New function. * tree.h (omit_two_operands): Prototype here. * builtins.c (fold_builtin_unordered_cmp): New function to lower C99 unordered comparison builtins to the appropriate tree nodes. (fold_builtin_1): Use fold_builtin_unordered_cmp to lower BUILT_IN_ISGREATER, BUILT_IN_ISGREATEREQUAL, BUILT_IN_ISLESS, BUILT_IN_ISLESSEQUAL and BUILT_IN_ISLESSGREATER. Manually lower BUILT_IN_ISUNORDERED comparisons to an UNORDERED_EXPR tree node. (simplify_builtin_memcmp, simplify_builtin_strncmp, simplify_builtin_strncat, simplify_builtin_strspn): Use the new omit_two_operands function to build the required COMPOUND_EXPRs. From-SVN: r83040
This commit is contained in:
parent
a2a2059fd7
commit
08039bd80b
@ -1,3 +1,17 @@
|
||||
2004-06-12 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* fold-const.c (omit_two_operands): New function.
|
||||
* tree.h (omit_two_operands): Prototype here.
|
||||
* builtins.c (fold_builtin_unordered_cmp): New function to lower
|
||||
C99 unordered comparison builtins to the appropriate tree nodes.
|
||||
(fold_builtin_1): Use fold_builtin_unordered_cmp to lower
|
||||
BUILT_IN_ISGREATER, BUILT_IN_ISGREATEREQUAL, BUILT_IN_ISLESS,
|
||||
BUILT_IN_ISLESSEQUAL and BUILT_IN_ISLESSGREATER. Manually lower
|
||||
BUILT_IN_ISUNORDERED comparisons to an UNORDERED_EXPR tree node.
|
||||
(simplify_builtin_memcmp, simplify_builtin_strncmp,
|
||||
simplify_builtin_strncat, simplify_builtin_strspn): Use the new
|
||||
omit_two_operands function to build the required COMPOUND_EXPRs.
|
||||
|
||||
2004-06-12 Steven Bosscher <stevenb@suse.de>,
|
||||
Andreas Jaeger <aj@suse.de>
|
||||
|
||||
|
@ -168,6 +168,8 @@ static tree fold_builtin_toascii (tree);
|
||||
static tree fold_builtin_isdigit (tree);
|
||||
static tree fold_builtin_fabs (tree, tree);
|
||||
static tree fold_builtin_abs (tree, tree);
|
||||
static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
|
||||
enum tree_code);
|
||||
|
||||
static tree simplify_builtin_memcmp (tree);
|
||||
static tree simplify_builtin_strcmp (tree);
|
||||
@ -7608,6 +7610,33 @@ fold_builtin_abs (tree arglist, tree type)
|
||||
return fold (build1 (ABS_EXPR, type, arg));
|
||||
}
|
||||
|
||||
/* Fold a call to an unordered comparison function such as
|
||||
__builtin_isgreater(). ARGLIST is the funtion's argument list
|
||||
and TYPE is the functions return type. UNORDERED_CODE and
|
||||
ORDERED_CODE are comparison codes that give the opposite of
|
||||
the desired result. UNORDERED_CODE is used for modes that can
|
||||
hold NaNs and ORDERED_CODE is used for the rest. */
|
||||
|
||||
static tree
|
||||
fold_builtin_unordered_cmp (tree arglist, tree type,
|
||||
enum tree_code unordered_code,
|
||||
enum tree_code ordered_code)
|
||||
{
|
||||
enum tree_code code;
|
||||
tree arg0, arg1;
|
||||
|
||||
if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
|
||||
return 0;
|
||||
|
||||
arg0 = TREE_VALUE (arglist);
|
||||
arg1 = TREE_VALUE (TREE_CHAIN (arglist));
|
||||
|
||||
code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
|
||||
: ordered_code;
|
||||
return fold (build1 (TRUTH_NOT_EXPR, type,
|
||||
fold (build2 (code, type, arg0, arg1))));
|
||||
}
|
||||
|
||||
/* Used by constant folding to eliminate some builtin calls early. EXP is
|
||||
the CALL_EXPR of a call to a builtin function. */
|
||||
|
||||
@ -8160,6 +8189,28 @@ fold_builtin_1 (tree exp)
|
||||
case BUILT_IN_COPYSIGNL:
|
||||
return fold_builtin_copysign (arglist, type);
|
||||
|
||||
case BUILT_IN_ISGREATER:
|
||||
return fold_builtin_unordered_cmp (arglist, type, UNLE_EXPR, LE_EXPR);
|
||||
case BUILT_IN_ISGREATEREQUAL:
|
||||
return fold_builtin_unordered_cmp (arglist, type, UNLT_EXPR, LT_EXPR);
|
||||
case BUILT_IN_ISLESS:
|
||||
return fold_builtin_unordered_cmp (arglist, type, UNGE_EXPR, GE_EXPR);
|
||||
case BUILT_IN_ISLESSEQUAL:
|
||||
return fold_builtin_unordered_cmp (arglist, type, UNGT_EXPR, GT_EXPR);
|
||||
case BUILT_IN_ISLESSGREATER:
|
||||
return fold_builtin_unordered_cmp (arglist, type, UNEQ_EXPR, EQ_EXPR);
|
||||
|
||||
case BUILT_IN_ISUNORDERED:
|
||||
if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
|
||||
{
|
||||
tree arg0 = TREE_VALUE (arglist);
|
||||
tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
|
||||
if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
|
||||
return omit_two_operands (type, integer_zero_node, arg0, arg1);
|
||||
return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -8772,13 +8823,9 @@ simplify_builtin_memcmp (tree arglist)
|
||||
|
||||
/* If the len parameter is zero, return zero. */
|
||||
if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
|
||||
{
|
||||
/* Evaluate and ignore arg1 and arg2 in case they have
|
||||
side-effects. */
|
||||
return build2 (COMPOUND_EXPR, integer_type_node, arg1,
|
||||
build2 (COMPOUND_EXPR, integer_type_node,
|
||||
arg2, integer_zero_node));
|
||||
}
|
||||
/* Evaluate and ignore arg1 and arg2 in case they have side-effects. */
|
||||
return omit_two_operands (integer_type_node, integer_zero_node,
|
||||
arg1, arg2);
|
||||
|
||||
p1 = c_getstr (arg1);
|
||||
p2 = c_getstr (arg2);
|
||||
@ -8913,13 +8960,9 @@ simplify_builtin_strncmp (tree arglist)
|
||||
|
||||
/* If the len parameter is zero, return zero. */
|
||||
if (integer_zerop (arg3))
|
||||
{
|
||||
/* Evaluate and ignore arg1 and arg2 in case they have
|
||||
side-effects. */
|
||||
return build2 (COMPOUND_EXPR, integer_type_node, arg1,
|
||||
build2 (COMPOUND_EXPR, integer_type_node,
|
||||
arg2, integer_zero_node));
|
||||
}
|
||||
/* Evaluate and ignore arg1 and arg2 in case they have side-effects. */
|
||||
return omit_two_operands (integer_type_node, integer_zero_node,
|
||||
arg1, arg2);
|
||||
|
||||
/* If arg1 and arg2 are equal (and not volatile), return zero. */
|
||||
if (operand_equal_p (arg1, arg2, 0))
|
||||
@ -9030,8 +9073,7 @@ simplify_builtin_strncat (tree arglist)
|
||||
/* If the requested length is zero, or the src parameter string
|
||||
length is zero, return the dst parameter. */
|
||||
if (integer_zerop (len) || (p && *p == '\0'))
|
||||
return build2 (COMPOUND_EXPR, TREE_TYPE (dst), src,
|
||||
build2 (COMPOUND_EXPR, integer_type_node, len, dst));
|
||||
return omit_two_operands (TREE_TYPE (dst), dst, src, len);
|
||||
|
||||
/* If the requested len is greater than or equal to the string
|
||||
length, call strcat. */
|
||||
@ -9089,13 +9131,10 @@ simplify_builtin_strspn (tree arglist)
|
||||
|
||||
/* If either argument is "", return 0. */
|
||||
if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
|
||||
{
|
||||
/* Evaluate and ignore both arguments in case either one has
|
||||
side-effects. */
|
||||
return build2 (COMPOUND_EXPR, integer_type_node, s1,
|
||||
build2 (COMPOUND_EXPR, integer_type_node,
|
||||
s2, integer_zero_node));
|
||||
}
|
||||
/* Evaluate and ignore both arguments in case either one has
|
||||
side-effects. */
|
||||
return omit_two_operands (integer_type_node, integer_zero_node,
|
||||
s1, s2);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -2828,6 +2828,29 @@ pedantic_omit_one_operand (tree type, tree result, tree omitted)
|
||||
|
||||
return pedantic_non_lvalue (t);
|
||||
}
|
||||
|
||||
/* Return a tree for the case when the result of an expression is RESULT
|
||||
converted to TYPE and OMITTED1 and OMITTED2 were previously operands
|
||||
of the expression but are now not needed.
|
||||
|
||||
If OMITTED1 or OMITTED2 has side effects, they must be evaluated.
|
||||
If both OMITTED1 and OMITTED2 have side effects, OMITTED1 is
|
||||
evaluated before OMITTED2. Otherwise, if neither has side effects,
|
||||
just do the conversion of RESULT to TYPE. */
|
||||
|
||||
tree
|
||||
omit_two_operands (tree type, tree result, tree omitted1, tree omitted2)
|
||||
{
|
||||
tree t = fold_convert (type, result);
|
||||
|
||||
if (TREE_SIDE_EFFECTS (omitted2))
|
||||
t = build2 (COMPOUND_EXPR, type, omitted2, t);
|
||||
if (TREE_SIDE_EFFECTS (omitted1))
|
||||
t = build2 (COMPOUND_EXPR, type, omitted1, t);
|
||||
|
||||
return TREE_CODE (t) != COMPOUND_EXPR ? non_lvalue (t) : t;
|
||||
}
|
||||
|
||||
|
||||
/* Return a simplified tree node for the truth-negation of ARG. This
|
||||
never alters ARG itself. We assume that ARG is an operation that
|
||||
|
@ -3508,6 +3508,7 @@ enum operand_equal_flag
|
||||
extern int operand_equal_p (tree, tree, unsigned int);
|
||||
|
||||
extern tree omit_one_operand (tree, tree, tree);
|
||||
extern tree omit_two_operands (tree, tree, tree, tree);
|
||||
extern tree invert_truthvalue (tree);
|
||||
extern tree nondestructive_fold_unary_to_constant (enum tree_code, tree, tree);
|
||||
extern tree nondestructive_fold_binary_to_constant (enum tree_code, tree, tree, tree);
|
||||
|
Loading…
x
Reference in New Issue
Block a user