After init_loop returns, in backend_init, next calls init_reload which prepare for reloading pass.
What does reloading pass for?
Reloading pass renumbers pseudo registers with the hardware registers numbers they were allocated. Pseudo registers that did not get hard registers are replaced with stack slots. Then it finds instructions that are invalid because a value has failed to end up in a register, or has ended up in a register of the wrong kind. It fixes up these instructions by reloading the problematical values temporarily into registers. Additional instructions are generated to do the copying.
The reload pass also optionally eliminates the frame pointer and inserts instructions to save and restore call-clobbered registers around calls.
T To make reload pass possible, init_reload now needs collect some informations. These informations include level of indirect addressing via register, level of indirect addressing via symbol, and if addressing supported in form of (frame register + GPR).
431 void
432 init_reload (void) in reload1.c
433 {
434 int i;
435
436 /* Often (MEM (REG n)) is still valid even if (REG n) is put on the stack.
437 Set spill_indirect_levels to the number of levels such addressing is
438 permitted, zero if it is not permitted at all. */
439
440 rtx tem
441 = gen_rtx_MEM (Pmode,
442 gen_rtx_PLUS (Pmode,
443 gen_rtx_REG (Pmode,
444 LAST_VIRTUAL_REGISTER + 1),
445 GEN_INT (4)));
The function first creates a rtx object representing address in form of memory+register to evaluate the level of indirect addressing via register. gen_rtx_PLUS is defined in genrtl.h. It invokes gen_rtx_fmt_ee to create the rtx object. This function will create a rtx object with two children, both are rtx expressions.
Above, line 440 after executing, following rtx object is created.
figure 20: indirect addressing via register
init_reload (continue)
446 spill_indirect_levels = 0;
447
448 while (memory_address_p (QImode, tem))
449 {
450 spill_indirect_levels++;
451 tem = gen_rtx_MEM (Pmode, tem);
452 }
spill_indirect_levels indicates the level of indirect addressing. Here the indirect addressing just means, for example, if spill_indirect_levels is 1, fetching the content of memory pointed by register n ( we marks as (mem (reg n)) ) is still valid even if register n is spilled out (that means memory can be accessed directly without aid of register). If spill_indirect_level is 2, (mem (mem (reg n))) is still valid even if register n is spilled out.
With spill_indirect_levels, we can avoid unnecessary restore register during reload pass.
For the x86 machine here, memory_address_p returns false, leaves spill_indirect_levels as 0. Next init_reload evaluates the level of indirect addressing via symbol.
init_reload (continue)
454 /* See if indirect addressing is valid for (MEM (SYMBOL_REF ...)). */
455
456 tem = gen_rtx_MEM (Pmode, gen_rtx_SYMBOL_REF (Pmode, "foo"));
457 indirect_symref_ok = memory_address_p (QImode, tem);
gen_rtx_SYMBOL_REF also generated ones defined in genrtl.h. It invokes gen_rtx_fmt_s00. Again its name reveals that the rtx object created has 3 children, the first is string, the rest are not used. The rtx object created is shown in following.
figure 17: indirect addressing via symbol
Also indirect_symbolref_ok is 0 for x86 machine. This variable if nonzero, indicates indirect addressing is supported when the innermost MEM is of the form (MEM (SYMBOL_REF sym)) (memory pointed by the content of memory referred by symbol). So how about addressing in form of (frame register + GPR)?
init_reload (continue)
459 /* See if reg+reg is a valid (and offsettable) address. */
460
461 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
462 {
463 tem = gen_rtx_PLUS (Pmode,
464 gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
465 gen_rtx_REG (Pmode, i));
466
467 /* This way, we make sure that reg+reg is an offsettable address. */
468 tem = plus_constant (tem, 4);
469
470 if (memory_address_p (QImode, tem))
471 {
472 double_reg_address_ok = 1;
473 break;
474 }
475 }
double_reg_adress_ok indicates if addressing can be supported by (reg_frame_pointer+GPR) +constant. The rtx object created at line 463 is as following, it is not the final one.
figure 18: addressing in form of (frame register + GPR)
As comment says, at line 468, plus_constant adds an offset for the rtx object created above.
1432 #define plus_constant(X, C) plus_constant_wide ((X), (HOST_WIDE_INT) (C)) in rtl.h
78 rtx
79 plus_constant_wide (rtx x, HOST_WIDE_INT c) in explow.c
80 {
81 RTX_CODE code;
82 rtx y;
83 enum machine_mode mode;
84 rtx tem;
85 int all_constant = 0;
86
87 if (c == 0)
88 return x;
89
90 restart:
91
92 code = GET_CODE (x);
93 mode = GET_MODE (x);
94 y = x;
95
96 switch (code)
97 {
98 case CONST_INT:
99 return GEN_INT (INTVAL (x) + c);
100
101 case CONST_DOUBLE:
102 {
…
113 }
114
115 case MEM:
…
129 break;
130
131 case CONST:
132 /* If adding to something entirely constant, set a flag
133 so that we can add a CONST around the result. */
134 x = XEXP (x, 0);
135 all_constant = 1;
136 goto restart;
137
138 case SYMBOL_REF:
139 case LABEL_REF:
140 all_constant = 1;
141 break;
142
143 case PLUS:
144 /* The interesting case is adding the integer to a sum.
145 Look for constant term in the sum and combine
146 with C. For an integer constant term, we make a combined
147 integer. For a constant term that is not an explicit integer,
148 we cannot really combine, but group them together anyway.
149
150 Restart or use a recursive call in case the remaining operand is
151 something that we handle specially, such as a SYMBOL_REF.
152
153 We may not immediately return from the recursive call here, lest
154 all_constant gets lost. */
155
156 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
157 {
158 c += INTVAL (XEXP (x, 1));
159
160 if (GET_MODE (x) != VOIDmode)
161 c = trunc_int_for_mode (c, GET_MODE (x));
162
163 x = XEXP (x, 0);
164 goto restart;
165 }
166 else if (CONSTANT_P (XEXP (x, 1)))
167 {
168 x = gen_rtx_PLUS (mode, XEXP (x, 0), plus_constant (XEXP (x, 1), c));
169 c = 0;
170 }
171 else if (find_constant_term_loc (&y))
172 {
173 /* We need to be careful since X may be shared and we can't
174 modify it in place. */
175 rtx copy = copy_rtx (x);
176 rtx *const_loc = find_constant_term_loc (©);
177
178 *const_loc = plus_constant (*const_loc, c);
179 x = copy;
180 c = 0;
181 }
182 break;
183
184 default:
185 break;
186 }
187
188 if (c != 0)
189 x = gen_rtx_PLUS (mode, x, GEN_INT (c));
190
191 if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
192 return x;
193 else if (all_constant)
194 return gen_rtx_CONST (mode, x);
195 else
196 return x;
197 }
At line 166, CONSTANT_P checks if the rtx object represents a constant or not.
293 #define CONSTANT_P(X) / in rtl.h
294 (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF /
295 || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE /
296 || GET_CODE (X) == CONST || GET_CODE (X) == HIGH /
297 || GET_CODE (X) == CONST_VECTOR /
298 || GET_CODE (X) == CONSTANT_P_RTX)
For our rtx object, case statement at line 143 will be executed, and then statement at line 171, function find_constant_term_loc.
1818 rtx *
1819 find_constant_term_loc (rtx *p) in recog.c
1820 {
1821 rtx *tem;
1822 enum rtx_code code = GET_CODE (*p);
1823
1824 /* If *P IS such a constant term, P is its location. */
1825
1826 if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
1827 || code == CONST)
1828 return p;
1829
1830 /* Otherwise, if not a sum, it has no constant term. */
1831
1832 if (GET_CODE (*p) != PLUS)
1833 return 0;
1834
1835 /* If one of the summands is constant, return its location. */
1836
1837 if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
1838 && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
1839 return p;
1840
1841 /* Otherwise, check each summand for containing a constant term. */
1842
1843 if (XEXP (*p, 0) != 0)
1844 {
1845 tem = find_constant_term_loc (&XEXP (*p, 0));
1846 if (tem != 0)
1847 return tem;
1848 }
1849
1850 if (XEXP (*p, 1) != 0)
1851 {
1852 tem = find_constant_term_loc (&XEXP (*p, 1));
1853 if (tem != 0)
1854 return tem;
1855 }
1856
1857 return 0;
1858 }
Note that first time this function invoked, the rtx object passed in is the one created in init_reload, at line 463. For the object, in find_constant_term_loc, line 1843 will be executed, which will invoke find_constant_term_loc again for its first child. It will return 0 as result. Then line 1850 will be executed in turn, the invoked find_constant_term_loc returns 0 also. In the end the original invoked find_constant_term_loc returns 0 in plus_constant_wide at line 171.
In plus_constant_wide, at line 189, a new rtx object created as following. Note that the expression takes form of infix notation. It makes operator priority unnecessary.
figure 23: addressing in form of (frame register + GPR) final
Then in init_reload, line 470, memory_address_p invoked again. From above, we know for x86 machine, legitimate_address_p will be the place for the job.
6033 int
6034 legitimate_address_p (enum machine_mode mode, rtx addr, int strict) in i386.c
6035 {
6036 struct ix86_address parts;
6037 rtx base, index, disp;
6038 HOST_WIDE_INT scale;
6039 const char *reason = NULL;
6040 rtx reason_rtx = NULL_RTX;
6041
6042 if (TARGET_DEBUG_ADDR)
6043 {
6044 fprintf (stderr,
6045 "/n======/nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d/n",
6046 GET_MODE_NAME (mode), strict);
6047 debug_rtx (addr);
6048 }
6049
6050 if (ix86_decompose_address (addr, &parts) <= 0)
6051 {
6052 reason = "decomposition failed";
6053 goto report_error;
6054 }
Again ix86_decompose_address will fill out ix86_address for the addressing expression.
5566 static int
5567 ix86_decompose_address (rtx addr, struct ix86_address *out) in i386.c
5568 {
5569 rtx base = NULL_RTX;
5570 rtx index = NULL_RTX;
5571 rtx disp = NULL_RTX;
5572 HOST_WIDE_INT scale = 1;
5573 rtx scale_rtx = NULL_RTX;
5574 int retval = 1;
5575 enum ix86_address_seg seg = SEG_DEFAULT;
5576
5577 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
5578 base = addr;
5579 else if (GET_CODE (addr) == PLUS)
5580 {
5581 rtx addends[4], op;
5582 int n = 0, i;
5583
5584 op = addr;
5585 do
5586 {
5587 if (n >= 4)
5588 return 0;
5589 addends[n++] = XEXP (op, 1);
5590 op = XEXP (op, 0);
5591 }
5592 while (GET_CODE (op) == PLUS);
5593 if (n >= 4)
5594 return 0;
5595 addends[n] = op;
5596
5597 for (i = n; i >= 0; --i)
5598 {
5599 op = addends[i];
5600 switch (GET_CODE (op))
5601 {
5602 case MULT:
…
5607 break;
5608
5609 case UNSPEC:
…
5616 break;
5617
5618 case REG:
5619 case SUBREG:
5620 if (!base)
5621 base = op;
5622 else if (!index)
5623 index = op;
5624 else
5625 return 0;
5626 break;
5627
5628 case CONST:
5629 case CONST_INT:
5630 case SYMBOL_REF:
5631 case LABEL_REF:
5632 if (disp)
5633 return 0;
5634 disp = op;
5635 break;
5636
5637 default:
5638 return 0;
5639 }
5640 }
5641 }
5642 else if (GET_CODE (addr) == MULT)
5643 {
5644 index = XEXP (addr, 0); /* index*scale */
5645 scale_rtx = XEXP (addr, 1);
5646 }
5647 else if (GET_CODE (addr) == ASHIFT)
5648 {
...
5661 }
5662 else
5663 disp = addr; /* displacement */
5664
5665 /* Extract the integral value of scale. */
5666 if (scale_rtx)
5667 {
5668 if (GET_CODE (scale_rtx) != CONST_INT)
5669 return 0;
5670 scale = INTVAL (scale_rtx);
5671 }
5672
5673 /* Allow arg pointer and stack pointer as index if there is not scaling. */
5674 if (base && index && scale == 1
5675 && (index == arg_pointer_rtx
5676 || index == frame_pointer_rtx
5677 || (REG_P (index) && REGNO (index) == STACK_POINTER_REGNUM)))
5678 {
5679 rtx tmp = base;
5680 base = index;
5681 index = tmp;
5682 }
5683
5684 /* Special case: %ebp cannot be encoded as a base without a displacement. */
5685 if ((base == hard_frame_pointer_rtx
5686 || base == frame_pointer_rtx
5687 || base == arg_pointer_rtx) && !disp)
5688 disp = const0_rtx;
5689
5690 /* Special case: on K6, [%esi] makes the instruction vector decoded.
5691 Avoid this by transforming to [%esi+0]. */
5692 if (ix86_tune == PROCESSOR_K6 && !optimize_size
5693 && base && !index && !disp
5694 && REG_P (base)
5695 && REGNO_REG_CLASS (REGNO (base)) == SIREG)
5696 disp = const0_rtx;
5697
5698 /* Special case: encode reg+reg instead of reg*2. */
5699 if (!base && index && scale && scale == 2)
5700 base = index, scale = 1;
5701
5702 /* Special case: scaling cannot be encoded without base or displacement. */
5703 if (!base && !disp && index && scale != 1)
5704 disp = const0_rtx;
5705
5706 out->base = base;
5707 out->index = index;
5708 out->disp = disp;
5709 out->scale = scale;
5710 out->seg = seg;
5711
5712 return retval;
5713 }
Above do…while loop begins at line 5585 handles the infix form expression. Can see infix notation makes the handling so easy. The base will point to rtx object of hard_frame_pointer_rtx, the index will point to the rtx object of the other register, and disp will point to rtx object of 4.
Then in legitimate_address_p following, remember if not within register rename or reload pass, strict will be zero.
legitimate_address_p (continue)
6056 base = parts.base;
6057 index = parts.index;
6058 disp = parts.disp;
6059 scale = parts.scale;
6060
6061 /* Validate base register.
6062
6063 Don't allow SUBREG's here, it can lead to spill failures when the base
6064 is one word out of a two word structure, which is represented internally
6065 as a DImode int. */
6066
6067 if (base)
6068 {
6069 reason_rtx = base;
6070
6071 if (GET_CODE (base) != REG)
6072 {
6073 reason = "base is not a register";
6074 goto report_error;
6075 }
6076
6077 if (GET_MODE (base) != Pmode)
6078 {
6079 reason = "base is not in Pmode";
6080 goto report_error;
6081 }
6082
6083 if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
6084 || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
6085 {
6086 reason = "base is not valid";
6087 goto report_error;
6088 }
6089 }
6090
6091 /* Validate index register.
6092
6093 Don't allow SUBREG's here, it can lead to spill failures when the index
6094 is one word out of a two word structure, which is represented internally
6095 as a DImode int. */
6096
6097 if (index)
6098 {
6099 reason_rtx = index;
6100
6101 if (GET_CODE (index) != REG)
6102 {
6103 reason = "index is not a register";
6104 goto report_error;
6105 }
6106
6107 if (GET_MODE (index) != Pmode)
6108 {
6109 reason = "index is not in Pmode";
6110 goto report_error;
6111 }
6112
6113 if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (index))
6114 || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (index)))
6115 {
6116 reason = "index is not valid";
6117 goto report_error;
6118 }
6119 }
Macro REG_OK_FOR_INDEX_NONSTRICT_P checks if specified register can hold index for the addressing.
1964 #define REG_OK_FOR_INDEX_NONSTRICT_P(X) / in i386.h
1965 (REGNO (X) < STACK_POINTER_REGNUM /
1966 || (REGNO (X) >= FIRST_REX_INT_REG /
1967 && REGNO (X) <= LAST_REX_INT_REG) /
1968 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
See that registers of ax, dx, cx, bx, si, di, bp, r8 ~ r15, and pseudo registers can be used to hold address index.
legitimate_address_p (continue)
6121 /* Validate scale factor. */
6122 if (scale != 1)
6123 {
…
6136 }
6137
6138 /* Validate displacement. */
6139 if (disp)
6140 {
6141 reason_rtx = disp;
6142
6143 if (GET_CODE (disp) == CONST
6144 && GET_CODE (XEXP (disp, 0)) == UNSPEC)
…
6166 else if (flag_pic && (SYMBOLIC_CONST (disp)
6167 #if TARGET_MACHO
6168 && !machopic_operand_p (disp)
6169 #endif
6170 ))
6171 {
…
6214 }
6215 else if (GET_CODE (disp) != LABEL_REF
6216 && GET_CODE (disp) != CONST_INT
6217 && (GET_CODE (disp) != CONST
6218 || !legitimate_constant_p (disp))
6219 && (GET_CODE (disp) != SYMBOL_REF
6220 || !legitimate_constant_p (disp)))
6221 {
6222 reason = "displacement is not constant";
6223 goto report_error;
6224 }
6225 else if (TARGET_64BIT && !x86_64_sign_extended_value (disp))
6226 {
6227 reason = "displacement is out of range";
6228 goto report_error;
6229 }
6230 }
6231
6232 /* Everything looks valid. */
6233 if (TARGET_DEBUG_ADDR)
6234 fprintf (stderr, "Success./n");
6235 return TRUE;
6236
6237 report_error:
6238 if (TARGET_DEBUG_ADDR)
6239 {
6240 fprintf (stderr, "Error: %s/n", reason);
6241 debug_rtx (reason_rtx);
6242 }
6243 return FALSE;
6244 }
legitimate_address_p returns true for the first register of ax, and so is memory_address_p. The FOR loop at line 461 is exited immediately and continue running code below.
init_reload (continue)
477 /* Initialize obstack for our rtl allocation. */
478 gcc_obstack_init (&reload_obstack);
479 reload_startobj = obstack_alloc (&reload_obstack, 0);
480
481 INIT_REG_SET (&spilled_pseudos);
482 INIT_REG_SET (&pseudos_counted);
483 }
Above at line 481, spilled_pseudos records which pseudos needed to be spilled. And line 482, pseudos_counted is used for communication between function order_regs_for_reload and function count_pseudo, and used to avoid counting one pseudo twice. These two varialbes are of type bitmap. INIT_REG_SET initializes these two variables.