X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree.c;h=1353f3288c7bbdbd2ad957a85face5755fa84ead;hb=59f38b0b33f88ff7045d339ff43778eef204f92b;hp=69615e10b99d86eb8b2173e2949c9f487edd5e4d;hpb=1dd25100e1854950b31063816480c2396e885d25;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree.c b/gcc/tree.c index 69615e10b99..1353f3288c7 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -37,6 +37,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "system.h" #include "flags.h" #include "tree.h" +#include "real.h" #include "tm_p.h" #include "function.h" #include "obstack.h" @@ -47,8 +48,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "target.h" #include "langhooks.h" -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free /* obstack.[ch] explicitly declined to prototype this. */ extern int _obstack_allocated_p PARAMS ((struct obstack *h, PTR obj)); @@ -56,6 +55,7 @@ extern int _obstack_allocated_p PARAMS ((struct obstack *h, PTR obj)); struct obstack permanent_obstack; +#ifdef GATHER_STATISTICS /* Statistics-gathering stuff. */ typedef enum { @@ -95,6 +95,7 @@ static const char * const tree_node_kind_names[] = { "lang_decl kinds", "lang_type kinds" }; +#endif /* GATHER_STATISTICS */ /* Unique id for next decl created. */ static int next_decl_uid; @@ -104,7 +105,7 @@ static int next_type_uid = 1; /* Since we cannot rehash a type after it is in the table, we have to keep the hash code. */ -struct type_hash +struct type_hash GTY(()) { unsigned long hash; tree type; @@ -120,18 +121,17 @@ struct type_hash same table, they are completely independent, and the hash code is computed differently for each of these. */ -htab_t type_hash_table; +static GTY ((if_marked ("type_hash_marked_p"), param_is (struct type_hash))) + htab_t type_hash_table; static void set_type_quals PARAMS ((tree, int)); static void append_random_chars PARAMS ((char *)); -static int type_hash_eq PARAMS ((const void*, const void*)); -static unsigned int type_hash_hash PARAMS ((const void*)); +static int type_hash_eq PARAMS ((const void *, const void *)); +static unsigned int type_hash_hash PARAMS ((const void *)); static void print_type_hash_statistics PARAMS((void)); static void finish_vector_type PARAMS((tree)); static tree make_vector PARAMS ((enum machine_mode, tree, int)); static int type_hash_marked_p PARAMS ((const void *)); -static void type_hash_mark PARAMS ((const void *)); -static int mark_tree_hashtable_entry PARAMS((void **, void *)); tree global_trees[TI_MAX]; tree integer_types[itk_none]; @@ -146,10 +146,6 @@ init_obstacks () /* Initialize the hash table of types. */ type_hash_table = htab_create (TYPE_HASH_INITIAL_SIZE, type_hash_hash, type_hash_eq, 0); - ggc_add_deletable_htab (type_hash_table, type_hash_marked_p, - type_hash_mark); - ggc_add_tree_root (global_trees, TI_MAX); - ggc_add_tree_root (integer_types, itk_none); } @@ -233,12 +229,12 @@ tree_size (node) case 'x': /* something random, like an identifier. */ { - size_t length; - length = (sizeof (struct tree_common) - + TREE_CODE_LENGTH (code) * sizeof (char *)); - if (code == TREE_VEC) - length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *); - return length; + size_t length; + length = (sizeof (struct tree_common) + + TREE_CODE_LENGTH (code) * sizeof (char *)); + if (code == TREE_VEC) + length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *); + return length; } default: @@ -263,12 +259,12 @@ make_node (code) tree_node_kind kind; #endif struct tree_common ttmp; - + /* We can't allocate a TREE_VEC without knowing how many elements it will have. */ if (code == TREE_VEC) abort (); - + TREE_SET_CODE ((tree)&ttmp, code); length = tree_size ((tree)&ttmp); @@ -494,7 +490,7 @@ build_vector (type, vals) over1 |= TREE_OVERFLOW (value); over2 |= TREE_CONSTANT_OVERFLOW (value); } - + TREE_OVERFLOW (v) = over1; TREE_CONSTANT_OVERFLOW (v) = over2; @@ -509,6 +505,7 @@ build_real (type, d) REAL_VALUE_TYPE d; { tree v; + REAL_VALUE_TYPE *dp; int overflow = 0; /* Check for valid float value for this type on this target machine; @@ -518,8 +515,11 @@ build_real (type, d) #endif v = make_node (REAL_CST); + dp = ggc_alloc (sizeof (REAL_VALUE_TYPE)); + memcpy (dp, &d, sizeof (REAL_VALUE_TYPE)); + TREE_TYPE (v) = type; - TREE_REAL_CST (v) = d; + TREE_REAL_CST_PTR (v) = dp; TREE_OVERFLOW (v) = TREE_CONSTANT_OVERFLOW (v) = overflow; return v; } @@ -556,20 +556,11 @@ build_real_from_int_cst (type, i) { tree v; int overflow = TREE_OVERFLOW (i); - REAL_VALUE_TYPE d; - - v = make_node (REAL_CST); - TREE_TYPE (v) = type; - d = real_value_from_int_cst (type, i); + v = build_real (type, real_value_from_int_cst (type, i)); - /* Check for valid float value for this type on this target machine. */ -#ifdef CHECK_FLOAT_VALUE - CHECK_FLOAT_VALUE (TYPE_MODE (type), d, overflow); -#endif - - TREE_REAL_CST (v) = d; - TREE_OVERFLOW (v) = TREE_CONSTANT_OVERFLOW (v) = overflow; + TREE_OVERFLOW (v) |= overflow; + TREE_CONSTANT_OVERFLOW (v) |= overflow; return v; } @@ -618,11 +609,11 @@ make_tree_vec (len) int len; { tree t; - int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec); + int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec); #ifdef GATHER_STATISTICS - tree_node_counts[(int)vec_kind]++; - tree_node_sizes[(int)vec_kind] += length; + tree_node_counts[(int) vec_kind]++; + tree_node_sizes[(int) vec_kind] += length; #endif t = ggc_alloc_tree (length); @@ -896,6 +887,22 @@ real_twop (expr) && real_zerop (TREE_IMAGPART (expr)))); } +/* Return 1 if EXPR is the real constant minus one. */ + +int +real_minus_onep (expr) + tree expr; +{ + STRIP_NOPS (expr); + + return ((TREE_CODE (expr) == REAL_CST + && ! TREE_CONSTANT_OVERFLOW (expr) + && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1)) + || (TREE_CODE (expr) == COMPLEX_CST + && real_minus_onep (TREE_REALPART (expr)) + && real_zerop (TREE_IMAGPART (expr)))); +} + /* Nonzero if EXP is a constant or a cast of a constant. */ int @@ -1063,8 +1070,8 @@ chainon (op1, op2) TREE_CHAIN (t1) = op2; #ifdef ENABLE_TREE_CHECKING for (t2 = op2; t2; t2 = TREE_CHAIN (t2)) - if (t2 == t1) - abort (); /* Circularity created. */ + if (t2 == t1) + abort (); /* Circularity created. */ #endif return op1; } @@ -1349,12 +1356,13 @@ staticp (arg) case FUNCTION_DECL: /* Nested functions aren't static, since taking their address involves a trampoline. */ - return (decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg)) - && ! DECL_NON_ADDR_CONST_P (arg); + return ((decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg)) + && ! DECL_NON_ADDR_CONST_P (arg)); case VAR_DECL: - return (TREE_STATIC (arg) || DECL_EXTERNAL (arg)) - && ! DECL_NON_ADDR_CONST_P (arg); + return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg)) + && ! DECL_THREAD_LOCAL (arg) + && ! DECL_NON_ADDR_CONST_P (arg)); case CONSTRUCTOR: return TREE_STATIC (arg); @@ -1514,6 +1522,44 @@ first_rtl_op (code) } } +/* Return which tree structure is used by T. */ + +enum tree_node_structure_enum +tree_node_structure (t) + tree t; +{ + enum tree_code code = TREE_CODE (t); + + switch (TREE_CODE_CLASS (code)) + { + case 'd': return TS_DECL; + case 't': return TS_TYPE; + case 'b': return TS_BLOCK; + case 'r': case '<': case '1': case '2': case 'e': case 's': + return TS_EXP; + default: /* 'c' and 'x' */ + break; + } + switch (code) + { + /* 'c' cases. */ + case INTEGER_CST: return TS_INT_CST; + case REAL_CST: return TS_REAL_CST; + case COMPLEX_CST: return TS_COMPLEX; + case VECTOR_CST: return TS_VECTOR; + case STRING_CST: return TS_STRING; + /* 'x' cases. */ + case ERROR_MARK: return TS_COMMON; + case IDENTIFIER_NODE: return TS_IDENTIFIER; + case TREE_LIST: return TS_LIST; + case TREE_VEC: return TS_VEC; + case PLACEHOLDER_EXPR: return TS_COMMON; + + default: + abort (); + } +} + /* Perform any modifications to EXPR required when it is unsaved. Does not recurse into EXPR's subtrees. */ @@ -2313,7 +2359,7 @@ build1 (code, type, node) #endif #ifdef ENABLE_CHECKING - if (TREE_CODE_CLASS (code) == '2' + if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<' || TREE_CODE_LENGTH (code) != 1) abort (); @@ -2498,7 +2544,7 @@ tree build_type_attribute_variant (ttype, attribute) tree ttype, attribute; { - if ( ! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute)) + if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute)) { unsigned int hashcode; tree ntype; @@ -2570,12 +2616,6 @@ default_insert_attributes (decl, attr_ptr) { } -/* Default value of targetm.attribute_table that is empty. */ -const struct attribute_spec default_target_attribute_table[] = -{ - { NULL, 0, 0, false, false, false, NULL } -}; - /* Default value of targetm.function_attribute_inlinable_p that always returns false. */ bool @@ -3037,41 +3077,6 @@ type_hash_marked_p (p) return ggc_marked_p (type) || TYPE_SYMTAB_POINTER (type); } -/* Mark the entry in the type hash table the type it points to is marked. - Also mark the type in case we are considering this entry "marked" by - virtue of TYPE_SYMTAB_POINTER being set. */ - -static void -type_hash_mark (p) - const void *p; -{ - ggc_mark (p); - ggc_mark_tree (((struct type_hash *) p)->type); -} - -/* Mark the hashtable slot pointed to by ENTRY (which is really a - `tree**') for GC. */ - -static int -mark_tree_hashtable_entry (entry, data) - void **entry; - void *data ATTRIBUTE_UNUSED; -{ - ggc_mark_tree ((tree) *entry); - return 1; -} - -/* Mark ARG (which is really a htab_t whose slots are trees) for - GC. */ - -void -mark_tree_hashtable (arg) - void *arg; -{ - htab_t t = *(htab_t *) arg; - htab_traverse (t, mark_tree_hashtable_entry, 0); -} - static void print_type_hash_statistics () { @@ -3105,8 +3110,8 @@ int attribute_list_equal (l1, l2) tree l1, l2; { - return attribute_list_contained (l1, l2) - && attribute_list_contained (l2, l1); + return attribute_list_contained (l1, l2) + && attribute_list_contained (l2, l1); } /* Given two lists of attributes, return true if list L2 is @@ -3236,7 +3241,20 @@ tree_int_cst_lt (t1, t2) if (t1 == t2) return 0; - if (! TREE_UNSIGNED (TREE_TYPE (t1))) + if (TREE_UNSIGNED (TREE_TYPE (t1)) != TREE_UNSIGNED (TREE_TYPE (t2))) + { + int t1_sgn = tree_int_cst_sgn (t1); + int t2_sgn = tree_int_cst_sgn (t2); + + if (t1_sgn < t2_sgn) + return 1; + else if (t1_sgn > t2_sgn) + return 0; + /* Otherwise, both are non-negative, so we compare them as + unsigned just in case one of them would overflow a signed + type. */ + } + else if (! TREE_UNSIGNED (TREE_TYPE (t1))) return INT_CST_LT (t1, t2); return INT_CST_LT_UNSIGNED (t1, t2); @@ -3253,7 +3271,7 @@ tree_int_cst_compare (t1, t2) return -1; else if (tree_int_cst_lt (t2, t1)) return 1; - else + else return 0; } @@ -3781,6 +3799,32 @@ build_function_type (value_type, arg_types) return t; } +/* Build a function type. The RETURN_TYPE is the type retured by the + function. If additional arguments are provided, they are + additional argument types. The list of argument types must always + be terminated by NULL_TREE. */ + +tree +build_function_type_list VPARAMS ((tree return_type, ...)) +{ + tree t, args, last; + + VA_OPEN (p, return_type); + VA_FIXEDARG (p, tree, return_type); + + t = va_arg (p, tree); + for (args = NULL_TREE; t != NULL_TREE; t = va_arg (p, tree)) + args = tree_cons (NULL_TREE, t, args); + + last = args; + args = nreverse (args); + TREE_CHAIN (last) = void_list_node; + args = build_function_type (return_type, args); + + VA_CLOSE (p); + return args; +} + /* Construct, lay out and return the type of methods belonging to class BASETYPE and whose arguments and values are described by TYPE. If that type exists already, reuse it. @@ -4204,6 +4248,9 @@ decl_type_context (decl) while (context) { + if (TREE_CODE (context) == NAMESPACE_DECL) + return NULL_TREE; + if (TREE_CODE (context) == RECORD_TYPE || TREE_CODE (context) == UNION_TYPE || TREE_CODE (context) == QUAL_UNION_TYPE) @@ -4400,7 +4447,7 @@ clean_symbol_name (p) )) *p = '_'; } - + /* Generate a name for a function unique to this translation unit. TYPE is some string to identify the purpose of this function to the linker or collect2. */ @@ -4757,6 +4804,8 @@ build_common_tree_nodes_2 (short_double) = make_vector (V4SImode, unsigned_intSI_type_node, 1); unsigned_V2SI_type_node = make_vector (V2SImode, unsigned_intSI_type_node, 1); + unsigned_V2DI_type_node + = make_vector (V2DImode, unsigned_intDI_type_node, 1); unsigned_V4HI_type_node = make_vector (V4HImode, unsigned_intHI_type_node, 1); unsigned_V8QI_type_node @@ -4770,10 +4819,12 @@ build_common_tree_nodes_2 (short_double) V4SF_type_node = make_vector (V4SFmode, float_type_node, 0); V4SI_type_node = make_vector (V4SImode, intSI_type_node, 0); V2SI_type_node = make_vector (V2SImode, intSI_type_node, 0); + V2DI_type_node = make_vector (V2DImode, intDI_type_node, 0); V4HI_type_node = make_vector (V4HImode, intHI_type_node, 0); V8QI_type_node = make_vector (V8QImode, intQI_type_node, 0); V8HI_type_node = make_vector (V8HImode, intHI_type_node, 0); V2SF_type_node = make_vector (V2SFmode, float_type_node, 0); + V2DF_type_node = make_vector (V2DFmode, double_type_node, 0); V16QI_type_node = make_vector (V16QImode, intQI_type_node, 0); } @@ -4821,20 +4872,22 @@ initializer_zerop (init) case CONSTRUCTOR: { if (AGGREGATE_TYPE_P (TREE_TYPE (init))) - { - tree aggr_init = TREE_OPERAND (init, 1); - - while (aggr_init) - { - if (! initializer_zerop (TREE_VALUE (aggr_init))) - return false; - aggr_init = TREE_CHAIN (aggr_init); - } - return true; - } + { + tree aggr_init = TREE_OPERAND (init, 1); + + while (aggr_init) + { + if (! initializer_zerop (TREE_VALUE (aggr_init))) + return false; + aggr_init = TREE_CHAIN (aggr_init); + } + return true; + } return false; } default: return false; } } + +#include "gt-tree.h"