Studying note of GCC-3.4.6 source (12)

来源:互联网 发布:iphonex同步数据 编辑:程序博客网 时间:2024/05/11 04:54

2.2. Initialize hashtable for type

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.

2.2.1. Definition of the hashtable

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.

2.2.2. The element of the hashtable

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.

2.2.3. Searching in the hashtable

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.

2.2.3.1.    Fill up type information for new types

2.2.3.1.1.            Information of integer type

Refer to Create node for internal types for the detail.

2.2.3.1.2.            Information of real and complex type

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.

2.2.3.1.3.            Information of other simple types

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.

2.2.3.1.4.            Information of aggregate type

Refer to Create node for array type for detail.

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 两岁半宝宝发热灌肠后便秘怎么办 发烧灌肠后一直拉稀怎么办 孩子便秘用开塞露引起肚子疼怎么办 老人大便干燥拉不出来怎么办 海底捞排队过号怎么办 脱毛后吃了海鲜怎么办 脂肪填充变丑了怎么办 全切双眼皮伤口长包怎么办 鼻综合修复眼中心修太宽怎么办 fgo的id忘了怎么办 电脑下载模拟器显示内存不够怎么办 安逍遥模拟器运行一段时间卡怎么办 pos机微信支付签到失败怎么办 逆水寒fps过低怎么办 电脑卡怎么办怎么清理磁盘 苹果手机设置找不到了怎么办 苹果手机自动拨出电话怎么办 机械键盘灯坏了怎么办 黄金塔花叶子卷怎么办 办的宽带不用了怎么办 取卵后3天还出血怎么办 取卵后腹水怎么办9天了 取卵后第三天肚子涨第天移植怎么办 取卵移植后肚子涨怎么办 没有成熟的卵泡不排卵怎么办 产后9年妊娠纹痒怎么办 手机屏幕锁了忘记密码怎么办 电脑被黑客锁屏怎么办 r9解锁密码忘了怎么办 oppor9开机密码忘了怎么办 vivo手机忘记解锁图案怎么办 oppor9s解锁图案忘了怎么办 oppor9图案解锁忘记了怎么办 oppor9解锁图案忘了怎么办 oppor9s锁屏密码忘了怎么办 oppor9s忘记锁屏图案怎么办 oppor9忘记锁屏图案怎么办 电脑锁屏卡住了怎么办 dell电脑密码忘了怎么办 dell电脑密码忘记了怎么办 手机锁屏为什么打不开怎么办