天天看點

GCC-3.4.6源代碼學習筆記(48)

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_UIDs,epilogue則記錄了構成結尾(epilogue)指令的INSN_UIDs,而sibcall_epilogue記錄了在函數中構成每個兄弟調用結尾指令的INSN_UIDs。對于每個由編譯器産生的指令,其INSN_UID是一個唯一的号碼,用于區分源代碼中的指令。它們不必要為順序遞增。對于rtx對象INSN,INSN_UID是其第一個孩子。prologue,epilogue及sibcall_epilogue都是varray_type類型,這是能儲存多種類型的虛拟數組。varray_type的定義與rtx十分相似。這是個有趣的資料結構。

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

133      size_t       num_elements; 

134      size_t    elements_used; 

136      enum varray_data_enum type; 

137      const char   *name;              

138      varray_data  GTY ((desc ("%0.type"))) data; 

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初始化為0個int類型的元素——現在它是空的。

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則用于描述這些常量的别名集(常量的别名集隻包含自身)。

繼續閱讀