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

来源:互联网 发布:淘宝奇葩评价 编辑:程序博客网 时间:2024/04/27 06:57

4.2.8. 用于函数调用序幕、结尾,兄弟调用结尾的数据

backend_init中,接下来调用init_function_once

 

8140 void

8141 init_function_once (void)                                                                           in function.c

8142 {

8143   VARRAY_INT_INIT (prologue, 0, "prologue");

8144   VARRAY_INT_INIT (epilogue, 0, "epilogue");

8145   VARRAY_INT_INIT (sibcall_epilogue, 0, "sibcall_epilogue");

8146 }

 

上面,prologue记录了构成序幕(prologue)指令的INSN_UIDsepilogue则记录了构成结尾(epilogue)指令的INSN_UIDs,而sibcall_epilogue记录了在函数中构成每个兄弟调用结尾指令的INSN_UIDs。对于每个由编译器产生的指令,其INSN_UID是一个唯一的号码,用于区分源代码中的指令。它们不必要为顺序递增。对于rtx对象INSNINSN_UID是其第一个孩子。prologueepiloguesibcall_epilogue都是varray_type类型,这是能保存多种类型的虚拟数组。varray_type的定义与rtx十分相似。这是个有趣的数据结构。

 

132    struct varray_head_tag GTY(()) {                                                              in varray.h

133      size_t       num_elements;  /* Maximum element number allocated.  */

134      size_t    elements_used;  /* The number of elements used, if

135                                           using VARRAY_PUSH/VARRAY_POP.  */

136      enum varray_data_enum type;  /* The kind of elements in the varray.  */

137      const char   *name;               /* name of the varray for reporting errors */

138      varray_data  GTY ((desc ("%0.type"))) data;  /* The data elements follow,

139                                                                 must be last.  */

140    };

141    typedef struct varray_head_tag *varray_type;

 

注意到varray_head_tag不仅仅是定义了成员类型及大小尺寸的头,还包含了主体——varray_data

 

88      typedef union varray_data_tag GTY (()) {                                                  in varray.h

89        char          GTY ((length ("%0.num_elements"),

90                         tag ("VARRAY_DATA_C"))) c[1];

91        unsigned char   GTY ((length ("%0.num_elements"),

92                         tag ("VARRAY_DATA_UC"))) uc[1];

93        short        GTY ((length ("%0.num_elements"),

94                         tag ("VARRAY_DATA_S")))       s[1];

95        unsigned short  GTY ((length ("%0.num_elements"),

96                         tag ("VARRAY_DATA_US"))) us[1];

97        int                  GTY ((length ("%0.num_elements"),

98                         tag ("VARRAY_DATA_I"))) i[1];

99        unsigned int     GTY ((length ("%0.num_elements"),

100                       tag ("VARRAY_DATA_U"))) u[1];

101      long                GTY ((length ("%0.num_elements"),

102                       tag ("VARRAY_DATA_L"))) l[1];

103      unsigned long  GTY ((length ("%0.num_elements"),

104                       tag ("VARRAY_DATA_UL"))) ul[1];

105      HOST_WIDE_INT  GTY ((length ("%0.num_elements"),

106                       tag ("VARRAY_DATA_HINT"))) hint[1];

107      unsigned HOST_WIDE_INT GTY ((length ("%0.num_elements"),

108                       tag ("VARRAY_DATA_UHINT"))) uhint[1];

109      PTR                GTY ((length ("%0.num_elements"), use_param (""),

110                        tag ("VARRAY_DATA_GENERIC"))) generic[1];

111       char                *GTY ((length ("%0.num_elements"),

112                        tag ("VARRAY_DATA_CPTR"))) cptr[1];

113       rtx                  GTY ((length ("%0.num_elements"),

114                        tag ("VARRAY_DATA_RTX"))) rtx[1];

115       rtvec               GTY ((length ("%0.num_elements"),

116                        tag ("VARRAY_DATA_RTVEC"))) rtvec[1];

117       tree                 GTY ((length ("%0.num_elements"),

118                        tag ("VARRAY_DATA_TREE"))) tree[1];

119       struct bitmap_head_def *GTY ((length ("%0.num_elements"),

120                       tag ("VARRAY_DATA_BITMAP"))) bitmap[1];

121      struct reg_info_def  *GTY ((length ("%0.num_elements"), skip (""),

122                       tag ("VARRAY_DATA_REG"))) reg[1];

123      struct const_equiv_data GTY ((length ("%0.num_elements"),

124                       tag ("VARRAY_DATA_CONST_EQUIV"))) const_equiv[1];

125      struct basic_block_def *GTY ((length ("%0.num_elements"), skip (""),

126                       tag ("VARRAY_DATA_BB"))) bb[1];

127      struct elt_list    *GTY ((length ("%0.num_elements"),

128                       tag ("VARRAY_DATA_TE"))) te[1];

129    } varray_data;

 

VARRAY_INT_INIT把这些varray初始化为0int类型的元素——现在它是空的。

 

159    #define VARRAY_INT_INIT(va, num, name) /                                           in varray.h

160      va = varray_init (num, VARRAY_DATA_I, name)

 

115     varray_type

116     varray_init (size_t num_elements, enum varray_data_enum element_kind,    in varray.c

117               const char *name)

118     {

119      size_t data_size = num_elements * element[element_kind].size;

120      varray_type ptr;

121    #ifdef GATHER_STATISTICS

122      struct varray_descriptor *desc = varray_descriptor (name);

123   

124      desc->created++;

125      desc->allocated += data_size + VARRAY_HDR_SIZE;

126    #endif

127      if (element[element_kind].uses_ggc)

128        ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);

129      else

130        ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);

131   

132      ptr->num_elements = num_elements;

133      ptr->elements_used = 0;

134      ptr->type = element_kind;

135      ptr->name = name;

136      return ptr;

137    }

 

为了确定数组成员所保存的数据类型及其大小,还需要一些信息。这些信息就保存在名为element的静态常量数组中,其定义如下。

 

87      static const struct {                                                                                   in varray.c

88        unsigned char size;

89        bool uses_ggc;

90      } element[NUM_VARRAY_DATA] = {

91        { sizeof (char), 1 },

92        { sizeof (unsigned char), 1 },

93        { sizeof (short), 1 },

94        { sizeof (unsigned short), 1 },

95        { sizeof (int), 1 },

96        { sizeof (unsigned int), 1 },

97        { sizeof (long), 1 },

98        { sizeof (unsigned long), 1 },

99        { sizeof (HOST_WIDE_INT), 1 },

100      { sizeof (unsigned HOST_WIDE_INT), 1 },

101      { sizeof (void *), 1 },

102      { sizeof (char *), 1 },

103      { sizeof (struct rtx_def *), 1 },

104      { sizeof (struct rtvec_def *), 1 },

105      { sizeof (union tree_node *), 1 },

106      { sizeof (struct bitmap_head_def *), 1 },

107      { sizeof (struct reg_info_def *), 0 },

108      { sizeof (struct const_equiv_data), 0 },

109      { sizeof (struct basic_block_def *), 0 },

110       { sizeof (struct elt_list *), 1 },

111     };

4.2.9. 准备汇编的生成

回到backend_init,接下来调用的函数是init_varasm_once

 

4584 void

4585 init_varasm_once (void)                                                                             in varasm.c

4586 {

4587   in_named_htab = htab_create_ggc (31, in_named_entry_hash,

4588                        in_named_entry_eq, NULL);

4589   const_desc_htab = htab_create_ggc (1009, const_desc_hash,

4590                          const_desc_eq, NULL);

4591  

4592     const_alias_set = new_alias_set ();

4593   }

 

上面的in_named_htab是用于保存各具名段标识符的哈希表。const_desc_htab则是保存汇编生成阶段的rtx常量对象的哈希表。const_alias_set则用于描述这些常量的别名集(常量的别名集只包含自身)。

 

原创粉丝点击