回到prepare_function_start,跟着它调用了init_emit来初始化与RTL生成有关的数据结构及变量。这个数据结构是emit_status,它是function 结构体中的emit域。
57 struct emit_status GTY(()) in function.h
58 {
59 /* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
60 After rtl generation, it is 1 plus the largest register number used. */
61 int x_reg_rtx_no;
62
63 /* Lowest label number in current function. */
64 int x_first_label_num;
65
66 /* The ends of the doubly-linked chain of rtl for the current function.
67 Both are reset to null at the start of rtl generation for the function.
68
69 start_sequence saves both of these on `sequence_stack' along with
70 `sequence_rtl_expr' and then starts a new, nested sequence of insns. */
71 rtx x_first_insn;
72 rtx x_last_insn;
73
74 /* RTL_EXPR within which the current sequence will be placed. Use to
75 prevent reuse of any temporaries within the sequence until after the
76 RTL_EXPR is emitted. */
77 tree sequence_rtl_expr;
78
79 /* Stack of pending (incomplete) sequences saved by `start_sequence'.
80 Each element describes one pending sequence.
81 The main insn-chain is saved in the last element of the chain,
82 unless the chain is empty. */
83 struct sequence_stack *sequence_stack;
84
85 /* INSN_UID for next insn emitted.
86 Reset to 1 for each function compiled. */
87 int x_cur_insn_uid;
88
89 /* Location the last line-number NOTE emitted.
90 This is used to avoid generating duplicates. */
91 location_t x_last_location;
92
93 /* The length of the regno_pointer_align, regno_decl, and x_regno_reg_rtx
94 vectors. Since these vectors are needed during the expansion phase when
95 the total number of registers in the function is not yet known, the
96 vectors are copied and made bigger when necessary. */
97 int regno_pointer_align_length;
98
99 /* Indexed by pseudo register number, if nonzero gives the known alignment
100 for that pseudo (if REG_POINTER is set in x_regno_reg_rtx).
101 Allocated in parallel with x_regno_reg_rtx. */
102 unsigned char * GTY ((length ("%h.x_reg_rtx_no")))
103 regno_pointer_align;
104
105 /* Indexed by pseudo register number, gives the rtx for that pseudo.
106 Allocated in parallel with regno_pointer_align.
107
108 Note MEM expressions can appear in this array due to the actions
109 of put_var_into_stack. */
110 rtx * GTY ((length ("%h.x_reg_rtx_no"))) x_regno_reg_rtx;
111 };
这个结构体控制了被编译函数的rtl形式表达式的生成。
5333 void
5334 init_emit (void) in emit-rtl.c
5335 {
5336 struct function *f = cfun;
5337
5338 f->emit = ggc_alloc (sizeof (struct emit_status));
5339 first_insn = NULL;
5340 last_insn = NULL;
5341 seq_rtl_expr = NULL;
5342 cur_insn_uid = 1;
5343 reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
5344 last_location.line = 0;
5345 last_location.file = 0;
5346 first_label_num = label_num;
5347 last_label_num = 0;
5348 seq_stack = NULL;
5349
5350 /* Init the tables that describe all the pseudo regs. */
5351
5352 f->emit->regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
5353
5354 f->emit->regno_pointer_align
5355 = ggc_alloc_cleared (f->emit->regno_pointer_align_length
5356 * sizeof (unsigned char));
5357
5358 regno_reg_rtx
5359 = ggc_alloc (f->emit->regno_pointer_align_length * sizeof (rtx));
5360
5361 /* Put copies of all the hard registers into regno_reg_rtx. */
5362 memcpy (regno_reg_rtx,
5363 static_regno_reg_rtx,
5364 FIRST_PSEUDO_REGISTER * sizeof (rtx));
5365
5366 /* Put copies of all the virtual register rtx into regno_reg_rtx. */
5367 init_virtual_regs (f->emit);
5368
5369 /* Indicate that the virtual registers and stack locations are
5370 all pointers. */
5371 REG_POINTER (stack_pointer_rtx) = 1;
5372 REG_POINTER (frame_pointer_rtx) = 1;
5373 REG_POINTER (hard_frame_pointer_rtx) = 1;
5374 REG_POINTER (arg_pointer_rtx) = 1;
5375
5376 REG_POINTER (virtual_incoming_args_rtx) = 1;
5377 REG_POINTER (virtual_stack_vars_rtx) = 1;
5378 REG_POINTER (virtual_stack_dynamic_rtx) = 1;
5379 REG_POINTER (virtual_outgoing_args_rtx) = 1;
5380 REG_POINTER (virtual_cfa_rtx) = 1;
5381
5382 #ifdef STACK_BOUNDARY
5383 REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
5384 REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
5385 REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
5386 REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY;
5387
5388 REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM) = STACK_BOUNDARY;
5389 REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM) = STACK_BOUNDARY;
5390 REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) = STACK_BOUNDARY;
5391 REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
5392 REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = BITS_PER_WORD;
5393 #endif
5394
5395 #ifdef INIT_EXPANDERS
5396 INIT_EXPANDERS;
5397 #endif
5398 }
在代码中,为了方便访问数据成员,function结构体中所有成员都有相应定义了访问宏。下面就是在上面函数中所用到的宏的定义。
114 #define reg_rtx_no (cfun->emit->x_reg_rtx_no) in function.h
115 #define seq_rtl_expr (cfun->emit->sequence_rtl_expr)
116 #define regno_reg_rtx (cfun->emit->x_regno_reg_rtx)
117 #define seq_stack (cfun->emit->sequence_stack)
173 #define first_insn (cfun->emit->x_first_insn) in emit-rtl.h
174 #define last_insn (cfun->emit->x_last_insn)
175 #define cur_insn_uid (cfun->emit->x_cur_insn_uid)
176 #define last_location (cfun->emit->x_last_location)
177 #define first_label_num (cfun->emit->x_first_label_num)
在5362行,回忆static_regno_reg_rtx在init_emit_once中创建,代表了可用在rtl中的物理寄存器。它可被视为一个常量集,因为在每次编译一个函数前,整个static_regno_reg_rtx被拷贝入emit_status的x_reg_rtx_no,像这里所做的那样。然后init_virtual_regs如下地更新特定的虚拟寄存器。
5147 void
5148 init_virtual_regs (struct emit_status *es) in emit-rtl.c
5149 {
5150 rtx *ptr = es->x_regno_reg_rtx;
5151 ptr[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
5152 ptr[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
5153 ptr[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
5154 ptr[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
5155 ptr[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
5156 }
上面,在赋值语句的右手边,都是从global_rtx中选出特定项的宏,这些项都是由init_emit_once所创建,而且它们都是Pmode模式。Pmode依赖于目标平台,并且在static_regno_reg_rtx的创建过程中不做考虑。
宏REG_POINTER检查rtx对象是否是可以保存指针值的寄存器。
1032 #define REG_POINTER(RTX) / in rtl.h
1033 (RTL_FLAG_CHECK1("REG_POINTER", (RTX), REG)->frame_related)
405 #define RTL_FLAG_CHECK1(NAME, RTX, C1) __extension__ / in rtl.h
406 ({ rtx const _rtx = (RTX); /
407 if (GET_CODE(_rtx) != C1) /
408 rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, /
409 __FUNCTION__); /
410 _rtx; })
可以看到这些特别处理的寄存器都是与栈框相关的。宏REGNO_POINTER_ALIGN为emit_status实例中指定的寄存器选择对齐要求。STACK_BOUNDARY在32位ABI的x86机器上是字大小的(4字节)。
119 #define REGNO_POINTER_ALIGN(REGNO) (cfun->emit->regno_pointer_align[REGNO])
x86机器不需要定义5395行的INIT_EXPANDERS。
在prepare_function_start中,下一个函数是init_varasm_status,它为新的function对象初始化了常量哈希池(constant hashing pool)。常量哈希池被包含在varasm_status结构体中。
75 #define MAX_RTX_HASH_TABLE 61
76
77 struct varasm_status GTY(()) in varasm.c
78 {
79 /* Hash facility for making memory-constants
80 from constant rtl-expressions. It is used on RISC machines
81 where immediate integer arguments and constant addresses are restricted
82 so that such constants must be stored in memory.
83
84 This pool of constants is reinitialized for each function
85 so each function gets its own constants-pool that comes right before
86 it. */
87 struct constant_descriptor_rtx ** GTY ((length ("MAX_RTX_HASH_TABLE")))
88 x_const_rtx_hash_table;
89 struct pool_constant ** GTY ((length ("MAX_RTX_HASH_TABLE")))
90 x_const_rtx_sym_hash_table;
91
92 /* Pointers to first and last constant in pool. */
93 struct pool_constant *x_first_pool;
94 struct pool_constant *x_last_pool;
95
96 /* Current offset in constant pool (does not include any machine-specific
97 header). */
98 HOST_WIDE_INT x_pool_offset;
99
100 /* Number of tree-constants deferred during the expansion of this
101 function. */
102 unsigned int deferred_constants;
103 };
在上面的89,93及94行,pool_constant记录了关于常量的足够的信息。其中,关键部分是下面2642行的rtx对象constant。
2636 struct pool_constant GTY(()) in varasm.c
2637 {
2638 struct constant_descriptor_rtx *desc;
2639 struct pool_constant *next;
2640 struct pool_constant *next_sym;
2641 rtx constant;
2642 enum machine_mode mode;
2643 int labelno;
2644 unsigned int align;
2645 HOST_WIDE_INT offset;
2646 int mark;
2647 };
2657 void
2658 init_varasm_status (struct function *f) in varasm.c
2659 {
2660 struct varasm_status *p;
2661 p = ggc_alloc (sizeof (struct varasm_status));
2662 f->varasm = p;
2663 p->x_const_rtx_hash_table
2664 = ggc_alloc_cleared (MAX_RTX_HASH_TABLE
2665 * sizeof (struct constant_descriptor_rtx *));
2666 p->x_const_rtx_sym_hash_table
2667 = ggc_alloc_cleared (MAX_RTX_HASH_TABLE
2668 * sizeof (struct pool_constant *));
2669
2670 p->x_first_pool = p->x_last_pool = 0;
2671 p->x_pool_offset = 0;
2672 p->deferred_constants = 0;
2673 }
继续回到prepare_function_start,它接着调用init_expr来创建expr_status的实例。这个实例用来控制函数中的每个表达式的处理。
121 struct expr_status GTY(()) in function.h
122 {
123 /* Number of units that we should eventually pop off the stack.
124 These are the arguments to function calls that have already returned. */
125 int x_pending_stack_adjust;
126
127 /* Under some ABIs, it is the caller's responsibility to pop arguments
128 pushed for function calls. A naive implementation would simply pop
129 the arguments immediately after each call. However, if several
130 function calls are made in a row, it is typically cheaper to pop
131 all the arguments after all of the calls are complete since a
132 single pop instruction can be used. Therefore, GCC attempts to
133 defer popping the arguments until absolutely necessary. (For
134 example, at the end of a conditional, the arguments must be popped,
135 since code outside the conditional won't know whether or not the
136 arguments need to be popped.)
137
138 When INHIBIT_DEFER_POP is nonzero, however, the compiler does not
139 attempt to defer pops. Instead, the stack is popped immediately
140 after each call. Rather then setting this variable directly, use
141 NO_DEFER_POP and OK_DEFER_POP. */
142 int x_inhibit_defer_pop;
143
144 /* If PREFERRED_STACK_BOUNDARY and PUSH_ROUNDING are defined, the
145 stack boundary can be momentarily unaligned while pushing the arguments.
146 Record the delta since last aligned boundary here in order to get
147 stack alignment in the nested function calls working right. */
148 int x_stack_pointer_delta;
149
150 /* Nonzero means __builtin_saveregs has already been done in this function.
151 The value is the pseudoreg containing the value __builtin_saveregs
152 returned. */
153 rtx x_saveregs_value;
154
155 /* Similarly for __builtin_apply_args. */
156 rtx x_apply_args_value;
157
158 /* List of labels that must never be deleted. */
159 rtx x_forced_labels;
160
161 /* Postincrements that still need to be expanded. */
162 rtx x_pending_chain;
163 };
最终ggc_alloc_cleared创建了一个由0填充的对象。
325 void
326 init_expr (void) in expr.c
327 {
328 cfun->expr = ggc_alloc_cleared (sizeof (struct expr_status));
329 }