/* Language-independent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
return inner;
}
-/* Returns the index of the first non-tree operand for CODE, or the number
- of operands if all are trees. */
-
-int
-first_rtl_op (enum tree_code code)
-{
- switch (code)
- {
- default:
- return TREE_CODE_LENGTH (code);
- }
-}
-
/* Return which tree structure is used by T. */
enum tree_node_structure_enum
break;
}
- switch (first_rtl_op (code))
+ switch (TREE_CODE_LENGTH (code))
{
case 1:
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
case METHOD_TYPE:
case FILE_TYPE:
case FUNCTION_TYPE:
+ case VECTOR_TYPE:
return false;
case INTEGER_TYPE:
|| CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (type)));
case ARRAY_TYPE:
- case SET_TYPE:
- case VECTOR_TYPE:
/* We're already checked the component type (TREE_TYPE), so just check
the index type. */
return type_contains_placeholder_p (TYPE_DOMAIN (type));
case tcc_comparison:
case tcc_expression:
case tcc_reference:
- switch (first_rtl_op (code))
+ switch (TREE_CODE_LENGTH (code))
{
case 0:
return exp;
case tcc_expression:
case tcc_reference:
case tcc_statement:
- switch (first_rtl_op (code))
+ switch (TREE_CODE_LENGTH (code))
{
case 0:
return exp;
TREE_COMPLEXITY (t) = 0;
TREE_OPERAND (t, 0) = node;
TREE_BLOCK (t) = NULL_TREE;
- if (node && !TYPE_P (node) && first_rtl_op (code) != 0)
+ if (node && !TYPE_P (node))
{
TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
TREE_READONLY (t) = TREE_READONLY (node);
#define PROCESS_ARG(N) \
do { \
TREE_OPERAND (t, N) = arg##N; \
- if (arg##N &&!TYPE_P (arg##N) && fro > N) \
+ if (arg##N &&!TYPE_P (arg##N)) \
{ \
if (TREE_SIDE_EFFECTS (arg##N)) \
side_effects = 1; \
{
bool constant, read_only, side_effects, invariant;
tree t;
- int fro;
gcc_assert (TREE_CODE_LENGTH (code) == 2);
result based on those same flags for the arguments. But if the
arguments aren't really even `tree' expressions, we shouldn't be trying
to do this. */
- fro = first_rtl_op (code);
/* Expressions without side effects may be constant if their
arguments are as well. */
{
bool constant, read_only, side_effects, invariant;
tree t;
- int fro;
gcc_assert (TREE_CODE_LENGTH (code) == 3);
t = make_node_stat (code PASS_MEM_STAT);
TREE_TYPE (t) = tt;
- fro = first_rtl_op (code);
-
side_effects = TREE_SIDE_EFFECTS (t);
PROCESS_ARG(0);
{
bool constant, read_only, side_effects, invariant;
tree t;
- int fro;
gcc_assert (TREE_CODE_LENGTH (code) == 4);
t = make_node_stat (code PASS_MEM_STAT);
TREE_TYPE (t) = tt;
- fro = first_rtl_op (code);
-
side_effects = TREE_SIDE_EFFECTS (t);
PROCESS_ARG(0);
TYPE_ARG_TYPES (b->type)))));
case ARRAY_TYPE:
- case SET_TYPE:
return TYPE_DOMAIN (a->type) == TYPE_DOMAIN (b->type);
case RECORD_TYPE:
for (; t; t = TREE_CHAIN (t))
val = iterative_hash_expr (TREE_VALUE (t), val);
return val;
+ case FUNCTION_DECL:
+ /* When referring to a built-in FUNCTION_DECL, use the
+ __builtin__ form. Otherwise nodes that compare equal
+ according to operand_equal_p might get different
+ hash codes. */
+ if (DECL_BUILT_IN (t))
+ {
+ val = iterative_hash_pointer (built_in_decls[DECL_FUNCTION_CODE (t)],
+ val);
+ return val;
+ }
+ /* else FALL THROUGH */
default:
class = TREE_CODE_CLASS (code);
if (class == tcc_declaration)
{
- /* Decls we can just compare by pointer. */
+ /* Otherwise, we can just compare decls by pointer. */
val = iterative_hash_pointer (t, val);
}
else
val = iterative_hash_hashval_t (two, val);
}
else
- for (i = first_rtl_op (code) - 1; i >= 0; --i)
+ for (i = TREE_CODE_LENGTH (code) - 1; i >= 0; --i)
val = iterative_hash_expr (TREE_OPERAND (t, i), val);
}
return val;
{
tree type_low_bound = TYPE_MIN_VALUE (type);
tree type_high_bound = TYPE_MAX_VALUE (type);
- int ok_for_low_bound, ok_for_high_bound;
-
- /* Perform some generic filtering first, which may allow making a decision
- even if the bounds are not constant. First, negative integers never fit
- in unsigned types, */
- if ((TYPE_UNSIGNED (type) && tree_int_cst_sgn (c) < 0)
- /* Also, unsigned integers with top bit set never fit signed types. */
- || (! TYPE_UNSIGNED (type)
- && TYPE_UNSIGNED (TREE_TYPE (c)) && tree_int_cst_msb (c)))
- return 0;
+ bool ok_for_low_bound, ok_for_high_bound;
+ tree tmp;
/* If at least one bound of the type is a constant integer, we can check
ourselves and maybe make a decision. If no such decision is possible, but
for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
for "constant known to fit". */
- ok_for_low_bound = -1;
- ok_for_high_bound = -1;
-
/* Check if C >= type_low_bound. */
if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
{
- ok_for_low_bound = ! tree_int_cst_lt (c, type_low_bound);
- if (! ok_for_low_bound)
+ if (tree_int_cst_lt (c, type_low_bound))
return 0;
+ ok_for_low_bound = true;
}
+ else
+ ok_for_low_bound = false;
/* Check if c <= type_high_bound. */
if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
{
- ok_for_high_bound = ! tree_int_cst_lt (type_high_bound, c);
- if (! ok_for_high_bound)
+ if (tree_int_cst_lt (type_high_bound, c))
return 0;
+ ok_for_high_bound = true;
}
+ else
+ ok_for_high_bound = false;
/* If the constant fits both bounds, the result is known. */
- if (ok_for_low_bound == 1 && ok_for_high_bound == 1)
+ if (ok_for_low_bound && ok_for_high_bound)
+ return 1;
+
+ /* Perform some generic filtering which may allow making a decision
+ even if the bounds are not constant. First, negative integers
+ never fit in unsigned types, */
+ if (TYPE_UNSIGNED (type) && tree_int_cst_sgn (c) < 0)
+ return 0;
+
+ /* Second, narrower types always fit in wider ones. */
+ if (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (c)))
return 1;
+ /* Third, unsigned integers with top bit set never fit signed types. */
+ if (! TYPE_UNSIGNED (type)
+ && TYPE_UNSIGNED (TREE_TYPE (c))
+ && tree_int_cst_msb (c))
+ return 0;
+
/* If we haven't been able to decide at this point, there nothing more we
can check ourselves here. Look at the base type if we have one. */
- else if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != 0)
+ if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != 0)
return int_fits_type_p (c, TREE_TYPE (type));
/* Or to force_fit_type, if nothing else. */
- else
- {
- c = copy_node (c);
- TREE_TYPE (c) = type;
- c = force_fit_type (c, -1, false, false);
- return !TREE_OVERFLOW (c);
- }
+ tmp = copy_node (c);
+ TREE_TYPE (tmp) = type;
+ tmp = force_fit_type (tmp, -1, false, false);
+ return TREE_INT_CST_HIGH (tmp) == TREE_INT_CST_HIGH (c)
+ && TREE_INT_CST_LOW (tmp) == TREE_INT_CST_LOW (c);
}
/* Subprogram of following function. Called by walk_tree.
case POINTER_TYPE:
case REFERENCE_TYPE:
case ARRAY_TYPE:
- case SET_TYPE:
case VECTOR_TYPE:
if (variably_modified_type_p (TREE_TYPE (type), fn))
return true;
if (elt == NULL_TREE)
return true;
- /* A set is empty only if it has no elements. */
- if (TREE_CODE (TREE_TYPE (init)) == SET_TYPE)
- return false;
-
for (; elt ; elt = TREE_CHAIN (elt))
if (! initializer_zerop (TREE_VALUE (elt)))
return false;