After initializing hashtable for identifier, general_init invokes init_ttree to initialize the hashtable for type.
116 void
117 init_ttree (void) in tree.c
118 {
119 /* Initialize the hash table of types. */
120 type_hash_table = htab_create_ggc (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
121 type_hash_eq, 0);
122 }
Note that the hashtable requires special functions for hashing and comparison.
type_hash_table is the hashtable for type information. It is declared as following.
94 /* Now here is the hash table. When recording a type, it is added to
95 the slot whose index is the hash code. Note that the hash table is
96 used for several kinds of types (function types, array types and
97 array index range types, for now). While all these live in the
98 same table, they are completely independent, and the hash code is
99 computed differently for each of these. */
100
101 static GTY ((if_marked ("type_hash_marked_p"), param_is (struct type_hash)))
102 htab_t type_hash_table;
The type of type_hash_table is htab_t, it’s pointer pointing to htab.
90 struct htab GTY(()) in hashtab.h
91 {
92 /* Pointer to hash function. */
93 htab_hash hash_f;
94
95 /* Pointer to comparison function. */
96 htab_eq eq_f;
97
98 /* Pointer to cleanup function. */
99 htab_del del_f;
100
101 /* Table itself. */
102 PTR * GTY ((use_param (""), length ("%h.size"))) entries;
103
104 /* Current size (in entries) of the hash table */
105 size_t size;
106
107 /* Current number of elements including also deleted elements */
108 size_t n_elements;
109
110 /* Current number of deleted elements in the table */
111 size_t n_deleted;
112
113 /* The following member is used for debugging. Its value is number
114 of all calls of `htab_find_slot' for the hash table. */
115 unsigned int searches;
116
117 /* The following member is used for debugging. Its value is number
118 of collisions fixed for time of work with the hash table. */
119 unsigned int collisions;
120
121 /* Pointers to allocate/free functions. */
122 htab_alloc alloc_f;
123 htab_free free_f;
124
125 /* Alternate allocate/free functions, which take an extra argument. */
126 PTR GTY((skip (""))) alloc_arg;
127 htab_alloc_with_arg alloc_with_arg_f;
128 htab_free_with_arg free_with_arg_f;
129 };
130
131 typedef struct htab *htab_t;
The creation function htab_create_ggc has following definition.
236 #define htab_create_ggc(SIZE, HASH, EQ, DEL) / in ggc.h
237 htab_create_alloc (SIZE, HASH, EQ, DEL, ggc_calloc, NULL)
ggc_alloc is a method provided by GC (garbage collector), which allocates kinds of objects managed by the GC. PTR above at line 126 in htab is void* or char*.
167 htab_t
168 htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f) in hashtab.c
169 size_t size;
170 htab_hash hash_f;
171 htab_eq eq_f;
172 htab_del del_f;
173 htab_alloc alloc_f;
174 htab_free free_f;
175 {
176 htab_t result;
177
178 size = higher_prime_number (size);
179 result = (htab_t) (*alloc_f) (1, sizeof (struct htab));
180 if (result == NULL)
181 return NULL;
182 result->entries = (PTR *) (*alloc_f) (size, sizeof (PTR));
183 if (result->entries == NULL)
184 {
185 if (free_f != NULL)
186 (*free_f) (result);
187 return NULL;
188 }
189 result->size = size;
190 result->hash_f = hash_f;
191 result->eq_f = eq_f;
192 result->del_f = del_f;
193 result->alloc_f = alloc_f;
194 result->free_f = free_f;
195 return result;
196 }
Above, at line 178, higher_prime_number will return a prime number which is greater than size, and slightly smaller than power of two. The purpose is to reduce the hash clash.
Above at line 102, though the entry of this table is declared as void*, the type of the element in fact is type_hash.
85 struct type_hash GTY(()) in tree.c
86 {
87 unsigned long hash;
88 tree type;
89 };
The type field of type_hash is the type of tree_type.
Searching elements in this hashtable is done by type_hash_lookup, the parameter type of the function in fact is of type of tree_type.
3008 tree
3009 type_hash_lookup (unsigned int hashcode, tree type) in tree.c
3010 {
3011 struct type_hash *h, in;
3012
3013 /* The TYPE_ALIGN field of a type is set by layout_type(), so we
3014 must call that routine before comparing TYPE_ALIGNs. */
3015 layout_type (type);
3016
3017 in.hash = hashcode;
3018 in.type = type;
3019
3020 h = htab_find_with_hash (type_hash_table, &in, hashcode);
3021 if (h)
3022 return h->type;
3023 return NULL_TREE;
3024 }
htab_find_with_hash cannot be used to insert or delete an element. It only returns the entry matching hashcode and the entry can be empty.
Refer to Create node for internal types for the detail.
Information required by real and complex type is same as integer type. See below code scrap.
layout_type (continue)
1552 case REAL_TYPE:
1553 TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);
1554 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
1555 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
1556 break;
1557
1558 case COMPLEX_TYPE:
1559 TREE_UNSIGNED (type) = TREE_UNSIGNED (TREE_TYPE (type));
1560 TYPE_MODE (type)
1561 = mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),
1562 (TREE_CODE (TTREE_TYPE (type)) == INTEGER_TYPE
1563 ? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT),
1564 0);
1565 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
1566 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
1567 break;
mode_for_size is similar with smallest_mode_for_size, it returns the machine mode to use for a nonscalar of size bits. The mode must be in class specified by parameter class, and have exactly that many value bits; it may have padding as well. If limit is nonzero, modes of wider than MAX_FIXED_MODE_SIZE will not be used.
211 enum machine_mode
212 mode_for_size (unsigned int size, enum mode_class class, int limit) in stor_layout.c
213 {
214 enum machine_mode mode;
215
216 if (limit && size > MAX_FIXED_MODE_SIZE)
217 return BLKmode;
218
219 /* Get the first mode which has this size, in the specified class. */
220 for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
221 mode = GET_MODE_WIDER_MODE (mode))
222 if (GET_MODE_PRECISION (mode) == size)
223 return mode;
224
225 return BLKmode;
226 }
When no fixed mode is found, BLKmode would be selected. It is the mode for structures, arrays, etc.
Take i386 system for exmaple, the machine will provide SSE or MMX registers which are 64 bits or more. Thus several integers or floats no larger than certain size can be saved in every these registers. These integer or float values are defined as VECTOR_TYPE.
layout_type (continue)
1569 case VECTOR_TYPE:
1570 {
1571 tree subtype;
1572
1573 subtype = TREE_TYPE (type);
1574 TREE_UNSIGNED (type) = TREE_UNSIGNED (subtype);
1575 TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
1576 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
1577 }
1578 break;
1579
1580 case VOID_TYPE:
1581 /* This is an incomplete type and so doesn't have a size. */
1582 TYPE_ALIGN (type) = 1;
1583 TYPE_USER_ALIGN (type) = 0;
1584 TYPE_MODE (type) = VOIDmode;
1585 break;
1586
1587 case OFFSET_TYPE:
1588 TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
1589 TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
1590 /* A pointer might be MODE_PARTIAL_INT,
1591 but ptrdiff_t must be integral. */
1592 TYPE_MODE (type) = mode_for_size (POINTER_SIZE, MODE_INT, 0);
1593 break;
1594
1595 case FUNCTION_TYPE:
1596 case METHOD_TYPE:
1597 TYPE_MODE (type) = mode_for_size (2 * POINTER_SIZE, MODE_INT, 0);
1598 TYPE_SIZE (type) = bitsize_int (2 * POINTER_SIZE);
1599 TYPE_SIZE_UNIT (type) = size_int ((2 * POINTER_SIZE) / BITS_PER_UNIT);
1600 break;
1601
1602 case POINTER_TYPE:
1603 case REFERENCE_TYPE:
1604 {
1605
1606 enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE
1607 && reference_types_internal)
1608 ? Pmode : TYPE_MODE (type));
1609
1610 int nbits = GET_MODE_BITSIZE (mode);
1611
1612 TYPE_SIZE (type) = bitsize_int (nbits);
1613 TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
1614 TREE_UNSIGNED (type) = 1;
1615 TYPE_PRECISION (type) = nbits;
1616 }
1617 break;
For VECTOR_TYPE, notice that type field in tree_common is the type of the elements. The details about the type of the elements are saved as those of the vector type. The number of elements of certain VECTOR_TYPE is determined by its machine mode.
Refer to Create node for array type for detail.