GCC-3.4.6源代码学习笔记(12)

2.2. 类型哈希表的初始化

完成标识符哈希表的初始化后,general_init调用init_ttree来初始化类型哈希表。

 

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  }

 

注意,这个哈希表指定了哈希函数及比较函数。

2.2.1. 哈希表的定义

该哈希表的对象是type_hash_table。它的定义如下。

 

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;

 

type_hash_table的类型是htab_t,它是指向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;

 

哈希表的创建函数htab_create_ggc的定义如下。

 

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是由GC(垃圾收集器)提供的方法。它负责分配由GC管理的对象。上面126行的PTRvoid*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  }

 

上面178行,higher_prime_number返回比size大而又小于比size大的最小2的指数的质数。目的为了减少哈希碰撞。

2.2.2. 哈希表的元素

在上面102行虽然这个表被声明为void*,它的元素实际上是type_hash类型。

 

85    struct type_hash GTY(())                                                                                   in tree.c

86    {

87      unsigned long hash;

88      tree type;

89    };

 

type_hashtype域实际是tree_type类型。

2.2.3. 查找哈希表

在这个哈希表中的查找是由函数type_hash_lookup执行,函数的type参数也是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不能用于添加或删除元素,它只能返回与hashcode匹配的表项,这表项可以为空。

2.2.3.1.      为新类型填写信息
2.2.3.1.1.            整数类型的信息

参考内建类型的树节点

2.2.3.1.2.            实数和复数类型信息

实数和复数类型所要求的信息与整数类型相同。见如下代码片段。

 

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_sizesmallest_mode_for_size相似,它返回对应有size比特的非标量的机器模式。这个模式必须是参数class指定的类别,而且确实具有那么多有效比特位,它可能还包含有填充位。如果参数limit非零,不能使用比MAX_FIXED_MODE_SIZE更宽的模式。

 

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  }

 

在没有合适的固定模式(fixed mode)时,只能选用BLKmode。它是用于结构或数组等的模式。

2.2.3.1.3.            其他简单类型的信息

x86系统为例,系统提供SSEMMX寄存器用于操作64位或更多位数据。因此数个总大小不超过特定尺寸的同型的整型或浮点型数据可以被存入这类寄存器。这组整数或浮点数就被定义为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;

 

对于VECTOR_TYPE,注意到在其tree_common域,其中的type域是单个数据(元素)本身的类型。而元素类型的细节也被保存入这个向量类型。向量类型所包含的元素个数由其机器模式决定。

2.2.3.1.4.            数组类型的信息

参考创建数组类型节点

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值