lra-eliminations.cc revision 1.1 1 1.1 mrg /* Code for RTL register eliminations.
2 1.1 mrg Copyright (C) 2010-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Vladimir Makarov <vmakarov (at) redhat.com>.
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
8 1.1 mrg the terms of the GNU General Public License as published by the Free
9 1.1 mrg Software Foundation; either version 3, or (at your option) any later
10 1.1 mrg version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 1.1 mrg for more details.
16 1.1 mrg
17 1.1 mrg You should have received a copy of the GNU General Public License
18 1.1 mrg along with GCC; see the file COPYING3. If not see
19 1.1 mrg <http://www.gnu.org/licenses/>. */
20 1.1 mrg
21 1.1 mrg /* Eliminable registers (like a soft argument or frame pointer) are
22 1.1 mrg widely used in RTL. These eliminable registers should be replaced
23 1.1 mrg by real hard registers (like the stack pointer or hard frame
24 1.1 mrg pointer) plus some offset. The offsets usually change whenever the
25 1.1 mrg stack is expanded. We know the final offsets only at the very end
26 1.1 mrg of LRA.
27 1.1 mrg
28 1.1 mrg Within LRA, we usually keep the RTL in such a state that the
29 1.1 mrg eliminable registers can be replaced by just the corresponding hard
30 1.1 mrg register (without any offset). To achieve this we should add the
31 1.1 mrg initial elimination offset at the beginning of LRA and update the
32 1.1 mrg offsets whenever the stack is expanded. We need to do this before
33 1.1 mrg every constraint pass because the choice of offset often affects
34 1.1 mrg whether a particular address or memory constraint is satisfied.
35 1.1 mrg
36 1.1 mrg We keep RTL code at most time in such state that the virtual
37 1.1 mrg registers can be changed by just the corresponding hard registers
38 1.1 mrg (with zero offsets) and we have the right RTL code. To achieve this
39 1.1 mrg we should add initial offset at the beginning of LRA work and update
40 1.1 mrg offsets after each stack expanding. But actually we update virtual
41 1.1 mrg registers to the same virtual registers + corresponding offsets
42 1.1 mrg before every constraint pass because it affects constraint
43 1.1 mrg satisfaction (e.g. an address displacement became too big for some
44 1.1 mrg target).
45 1.1 mrg
46 1.1 mrg The final change of eliminable registers to the corresponding hard
47 1.1 mrg registers are done at the very end of LRA when there were no change
48 1.1 mrg in offsets anymore:
49 1.1 mrg
50 1.1 mrg fp + 42 => sp + 42
51 1.1 mrg
52 1.1 mrg */
53 1.1 mrg
54 1.1 mrg #include "config.h"
55 1.1 mrg #include "system.h"
56 1.1 mrg #include "coretypes.h"
57 1.1 mrg #include "backend.h"
58 1.1 mrg #include "target.h"
59 1.1 mrg #include "rtl.h"
60 1.1 mrg #include "tree.h"
61 1.1 mrg #include "df.h"
62 1.1 mrg #include "memmodel.h"
63 1.1 mrg #include "tm_p.h"
64 1.1 mrg #include "optabs.h"
65 1.1 mrg #include "regs.h"
66 1.1 mrg #include "ira.h"
67 1.1 mrg #include "recog.h"
68 1.1 mrg #include "output.h"
69 1.1 mrg #include "rtl-error.h"
70 1.1 mrg #include "lra-int.h"
71 1.1 mrg
72 1.1 mrg /* This structure is used to record information about hard register
73 1.1 mrg eliminations. */
74 1.1 mrg class lra_elim_table
75 1.1 mrg {
76 1.1 mrg public:
77 1.1 mrg /* Hard register number to be eliminated. */
78 1.1 mrg int from;
79 1.1 mrg /* Hard register number used as replacement. */
80 1.1 mrg int to;
81 1.1 mrg /* Difference between values of the two hard registers above on
82 1.1 mrg previous iteration. */
83 1.1 mrg poly_int64 previous_offset;
84 1.1 mrg /* Difference between the values on the current iteration. */
85 1.1 mrg poly_int64 offset;
86 1.1 mrg /* Nonzero if this elimination can be done. */
87 1.1 mrg bool can_eliminate;
88 1.1 mrg /* CAN_ELIMINATE since the last check. */
89 1.1 mrg bool prev_can_eliminate;
90 1.1 mrg /* REG rtx for the register to be eliminated. We cannot simply
91 1.1 mrg compare the number since we might then spuriously replace a hard
92 1.1 mrg register corresponding to a pseudo assigned to the reg to be
93 1.1 mrg eliminated. */
94 1.1 mrg rtx from_rtx;
95 1.1 mrg /* REG rtx for the replacement. */
96 1.1 mrg rtx to_rtx;
97 1.1 mrg };
98 1.1 mrg
99 1.1 mrg /* The elimination table. Each array entry describes one possible way
100 1.1 mrg of eliminating a register in favor of another. If there is more
101 1.1 mrg than one way of eliminating a particular register, the most
102 1.1 mrg preferred should be specified first. */
103 1.1 mrg static class lra_elim_table *reg_eliminate = 0;
104 1.1 mrg
105 1.1 mrg /* This is an intermediate structure to initialize the table. It has
106 1.1 mrg exactly the members provided by ELIMINABLE_REGS. */
107 1.1 mrg static const struct elim_table_1
108 1.1 mrg {
109 1.1 mrg const int from;
110 1.1 mrg const int to;
111 1.1 mrg } reg_eliminate_1[] =
112 1.1 mrg
113 1.1 mrg ELIMINABLE_REGS;
114 1.1 mrg
115 1.1 mrg #define NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1)
116 1.1 mrg
117 1.1 mrg /* Print info about elimination table to file F. */
118 1.1 mrg static void
119 1.1 mrg print_elim_table (FILE *f)
120 1.1 mrg {
121 1.1 mrg class lra_elim_table *ep;
122 1.1 mrg
123 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
124 1.1 mrg {
125 1.1 mrg fprintf (f, "%s eliminate %d to %d (offset=",
126 1.1 mrg ep->can_eliminate ? "Can" : "Can't", ep->from, ep->to);
127 1.1 mrg print_dec (ep->offset, f);
128 1.1 mrg fprintf (f, ", prev_offset=");
129 1.1 mrg print_dec (ep->previous_offset, f);
130 1.1 mrg fprintf (f, ")\n");
131 1.1 mrg }
132 1.1 mrg }
133 1.1 mrg
134 1.1 mrg /* Print info about elimination table to stderr. */
135 1.1 mrg void
136 1.1 mrg lra_debug_elim_table (void)
137 1.1 mrg {
138 1.1 mrg print_elim_table (stderr);
139 1.1 mrg }
140 1.1 mrg
141 1.1 mrg /* Setup possibility of elimination in elimination table element EP to
142 1.1 mrg VALUE. Setup FRAME_POINTER_NEEDED if elimination from frame
143 1.1 mrg pointer to stack pointer is not possible anymore. */
144 1.1 mrg static void
145 1.1 mrg setup_can_eliminate (class lra_elim_table *ep, bool value)
146 1.1 mrg {
147 1.1 mrg ep->can_eliminate = ep->prev_can_eliminate = value;
148 1.1 mrg if (! value
149 1.1 mrg && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
150 1.1 mrg frame_pointer_needed = 1;
151 1.1 mrg if (!frame_pointer_needed)
152 1.1 mrg REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0;
153 1.1 mrg }
154 1.1 mrg
155 1.1 mrg /* Map: eliminable "from" register -> its current elimination,
156 1.1 mrg or NULL if none. The elimination table may contain more than
157 1.1 mrg one elimination for the same hard register, but this map specifies
158 1.1 mrg the one that we are currently using. */
159 1.1 mrg static class lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER];
160 1.1 mrg
161 1.1 mrg /* When an eliminable hard register becomes not eliminable, we use the
162 1.1 mrg following special structure to restore original offsets for the
163 1.1 mrg register. */
164 1.1 mrg static class lra_elim_table self_elim_table;
165 1.1 mrg
166 1.1 mrg /* Offsets should be used to restore original offsets for eliminable
167 1.1 mrg hard register which just became not eliminable. Zero,
168 1.1 mrg otherwise. */
169 1.1 mrg static poly_int64_pod self_elim_offsets[FIRST_PSEUDO_REGISTER];
170 1.1 mrg
171 1.1 mrg /* Map: hard regno -> RTL presentation. RTL presentations of all
172 1.1 mrg potentially eliminable hard registers are stored in the map. */
173 1.1 mrg static rtx eliminable_reg_rtx[FIRST_PSEUDO_REGISTER];
174 1.1 mrg
175 1.1 mrg /* Set up ELIMINATION_MAP of the currently used eliminations. */
176 1.1 mrg static void
177 1.1 mrg setup_elimination_map (void)
178 1.1 mrg {
179 1.1 mrg int i;
180 1.1 mrg class lra_elim_table *ep;
181 1.1 mrg
182 1.1 mrg for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
183 1.1 mrg elimination_map[i] = NULL;
184 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
185 1.1 mrg if (ep->can_eliminate && elimination_map[ep->from] == NULL)
186 1.1 mrg elimination_map[ep->from] = ep;
187 1.1 mrg }
188 1.1 mrg
189 1.1 mrg
190 1.1 mrg
192 1.1 mrg /* Compute the sum of X and Y, making canonicalizations assumed in an
193 1.1 mrg address, namely: sum constant integers, surround the sum of two
194 1.1 mrg constants with a CONST, put the constant as the second operand, and
195 1.1 mrg group the constant on the outermost sum.
196 1.1 mrg
197 1.1 mrg This routine assumes both inputs are already in canonical form. */
198 1.1 mrg static rtx
199 1.1 mrg form_sum (rtx x, rtx y)
200 1.1 mrg {
201 1.1 mrg machine_mode mode = GET_MODE (x);
202 1.1 mrg poly_int64 offset;
203 1.1 mrg
204 1.1 mrg if (mode == VOIDmode)
205 1.1 mrg mode = GET_MODE (y);
206 1.1 mrg
207 1.1 mrg if (mode == VOIDmode)
208 1.1 mrg mode = Pmode;
209 1.1 mrg
210 1.1 mrg if (poly_int_rtx_p (x, &offset))
211 1.1 mrg return plus_constant (mode, y, offset);
212 1.1 mrg else if (poly_int_rtx_p (y, &offset))
213 1.1 mrg return plus_constant (mode, x, offset);
214 1.1 mrg else if (CONSTANT_P (x))
215 1.1 mrg std::swap (x, y);
216 1.1 mrg
217 1.1 mrg if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
218 1.1 mrg return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
219 1.1 mrg
220 1.1 mrg /* Note that if the operands of Y are specified in the opposite
221 1.1 mrg order in the recursive calls below, infinite recursion will
222 1.1 mrg occur. */
223 1.1 mrg if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
224 1.1 mrg return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
225 1.1 mrg
226 1.1 mrg /* If both constant, encapsulate sum. Otherwise, just form sum. A
227 1.1 mrg constant will have been placed second. */
228 1.1 mrg if (CONSTANT_P (x) && CONSTANT_P (y))
229 1.1 mrg {
230 1.1 mrg if (GET_CODE (x) == CONST)
231 1.1 mrg x = XEXP (x, 0);
232 1.1 mrg if (GET_CODE (y) == CONST)
233 1.1 mrg y = XEXP (y, 0);
234 1.1 mrg
235 1.1 mrg return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y));
236 1.1 mrg }
237 1.1 mrg
238 1.1 mrg return gen_rtx_PLUS (mode, x, y);
239 1.1 mrg }
240 1.1 mrg
241 1.1 mrg /* Return the current substitution hard register of the elimination of
242 1.1 mrg HARD_REGNO. If HARD_REGNO is not eliminable, return itself. */
243 1.1 mrg int
244 1.1 mrg lra_get_elimination_hard_regno (int hard_regno)
245 1.1 mrg {
246 1.1 mrg class lra_elim_table *ep;
247 1.1 mrg
248 1.1 mrg if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
249 1.1 mrg return hard_regno;
250 1.1 mrg if ((ep = elimination_map[hard_regno]) == NULL)
251 1.1 mrg return hard_regno;
252 1.1 mrg return ep->to;
253 1.1 mrg }
254 1.1 mrg
255 1.1 mrg /* Return elimination which will be used for hard reg REG, NULL
256 1.1 mrg otherwise. */
257 1.1 mrg static class lra_elim_table *
258 1.1 mrg get_elimination (rtx reg)
259 1.1 mrg {
260 1.1 mrg int hard_regno;
261 1.1 mrg class lra_elim_table *ep;
262 1.1 mrg
263 1.1 mrg lra_assert (REG_P (reg));
264 1.1 mrg if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
265 1.1 mrg return NULL;
266 1.1 mrg if ((ep = elimination_map[hard_regno]) != NULL)
267 1.1 mrg return ep->from_rtx != reg ? NULL : ep;
268 1.1 mrg poly_int64 offset = self_elim_offsets[hard_regno];
269 1.1 mrg if (known_eq (offset, 0))
270 1.1 mrg return NULL;
271 1.1 mrg /* This is an iteration to restore offsets just after HARD_REGNO
272 1.1 mrg stopped to be eliminable. */
273 1.1 mrg self_elim_table.from = self_elim_table.to = hard_regno;
274 1.1 mrg self_elim_table.from_rtx
275 1.1 mrg = self_elim_table.to_rtx
276 1.1 mrg = eliminable_reg_rtx[hard_regno];
277 1.1 mrg lra_assert (self_elim_table.from_rtx != NULL);
278 1.1 mrg self_elim_table.offset = offset;
279 1.1 mrg return &self_elim_table;
280 1.1 mrg }
281 1.1 mrg
282 1.1 mrg /* Transform (subreg (plus reg const)) to (plus (subreg reg) const)
283 1.1 mrg when it is possible. Return X or the transformation result if the
284 1.1 mrg transformation is done. */
285 1.1 mrg static rtx
286 1.1 mrg move_plus_up (rtx x)
287 1.1 mrg {
288 1.1 mrg rtx subreg_reg;
289 1.1 mrg machine_mode x_mode, subreg_reg_mode;
290 1.1 mrg
291 1.1 mrg if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x))
292 1.1 mrg return x;
293 1.1 mrg subreg_reg = SUBREG_REG (x);
294 1.1 mrg x_mode = GET_MODE (x);
295 1.1 mrg subreg_reg_mode = GET_MODE (subreg_reg);
296 1.1 mrg if (!paradoxical_subreg_p (x)
297 1.1 mrg && GET_CODE (subreg_reg) == PLUS
298 1.1 mrg && CONSTANT_P (XEXP (subreg_reg, 1))
299 1.1 mrg && GET_MODE_CLASS (x_mode) == MODE_INT
300 1.1 mrg && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT)
301 1.1 mrg {
302 1.1 mrg rtx cst = simplify_subreg (x_mode, XEXP (subreg_reg, 1), subreg_reg_mode,
303 1.1 mrg subreg_lowpart_offset (x_mode,
304 1.1 mrg subreg_reg_mode));
305 1.1 mrg if (cst && CONSTANT_P (cst))
306 1.1 mrg return gen_rtx_PLUS (x_mode, lowpart_subreg (x_mode,
307 1.1 mrg XEXP (subreg_reg, 0),
308 1.1 mrg subreg_reg_mode), cst);
309 1.1 mrg }
310 1.1 mrg return x;
311 1.1 mrg }
312 1.1 mrg
313 1.1 mrg /* Scan X and replace any eliminable registers (such as fp) with a
314 1.1 mrg replacement (such as sp) if SUBST_P, plus an offset. The offset is
315 1.1 mrg a change in the offset between the eliminable register and its
316 1.1 mrg substitution if UPDATE_P, or the full offset if FULL_P, or
317 1.1 mrg otherwise zero. If FULL_P, we also use the SP offsets for
318 1.1 mrg elimination to SP. If UPDATE_P, use UPDATE_SP_OFFSET for updating
319 1.1 mrg offsets of register elimnable to SP. If UPDATE_SP_OFFSET is
320 1.1 mrg non-zero, don't use difference of the offset and the previous
321 1.1 mrg offset.
322 1.1 mrg
323 1.1 mrg MEM_MODE is the mode of an enclosing MEM. We need this to know how
324 1.1 mrg much to adjust a register for, e.g., PRE_DEC. Also, if we are
325 1.1 mrg inside a MEM, we are allowed to replace a sum of a hard register
326 1.1 mrg and the constant zero with the hard register, which we cannot do
327 1.1 mrg outside a MEM. In addition, we need to record the fact that a
328 1.1 mrg hard register is referenced outside a MEM.
329 1.1 mrg
330 1.1 mrg If we make full substitution to SP for non-null INSN, add the insn
331 1.1 mrg sp offset. */
332 1.1 mrg rtx
333 1.1 mrg lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
334 1.1 mrg bool subst_p, bool update_p,
335 1.1 mrg poly_int64 update_sp_offset, bool full_p)
336 1.1 mrg {
337 1.1 mrg enum rtx_code code = GET_CODE (x);
338 1.1 mrg class lra_elim_table *ep;
339 1.1 mrg rtx new_rtx;
340 1.1 mrg int i, j;
341 1.1 mrg const char *fmt;
342 1.1 mrg int copied = 0;
343 1.1 mrg
344 1.1 mrg lra_assert (!update_p || !full_p);
345 1.1 mrg lra_assert (known_eq (update_sp_offset, 0)
346 1.1 mrg || (!subst_p && update_p && !full_p));
347 1.1 mrg if (! current_function_decl)
348 1.1 mrg return x;
349 1.1 mrg
350 1.1 mrg switch (code)
351 1.1 mrg {
352 1.1 mrg CASE_CONST_ANY:
353 1.1 mrg case CONST:
354 1.1 mrg case SYMBOL_REF:
355 1.1 mrg case CODE_LABEL:
356 1.1 mrg case PC:
357 1.1 mrg case ASM_INPUT:
358 1.1 mrg case ADDR_VEC:
359 1.1 mrg case ADDR_DIFF_VEC:
360 1.1 mrg case RETURN:
361 1.1 mrg return x;
362 1.1 mrg
363 1.1 mrg case REG:
364 1.1 mrg /* First handle the case where we encounter a bare hard register
365 1.1 mrg that is eliminable. Replace it with a PLUS. */
366 1.1 mrg if ((ep = get_elimination (x)) != NULL)
367 1.1 mrg {
368 1.1 mrg rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
369 1.1 mrg
370 1.1 mrg if (maybe_ne (update_sp_offset, 0))
371 1.1 mrg {
372 1.1 mrg if (ep->to_rtx == stack_pointer_rtx)
373 1.1 mrg return plus_constant (Pmode, to, update_sp_offset);
374 1.1 mrg return to;
375 1.1 mrg }
376 1.1 mrg else if (update_p)
377 1.1 mrg return plus_constant (Pmode, to, ep->offset - ep->previous_offset);
378 1.1 mrg else if (full_p)
379 1.1 mrg return plus_constant (Pmode, to,
380 1.1 mrg ep->offset
381 1.1 mrg - (insn != NULL_RTX
382 1.1 mrg && ep->to_rtx == stack_pointer_rtx
383 1.1 mrg ? lra_get_insn_recog_data (insn)->sp_offset
384 1.1 mrg : 0));
385 1.1 mrg else
386 1.1 mrg return to;
387 1.1 mrg }
388 1.1 mrg return x;
389 1.1 mrg
390 1.1 mrg case PLUS:
391 1.1 mrg /* If this is the sum of an eliminable register and a constant, rework
392 1.1 mrg the sum. */
393 1.1 mrg if (REG_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
394 1.1 mrg {
395 1.1 mrg if ((ep = get_elimination (XEXP (x, 0))) != NULL)
396 1.1 mrg {
397 1.1 mrg poly_int64 offset, curr_offset;
398 1.1 mrg rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
399 1.1 mrg
400 1.1 mrg if (! update_p && ! full_p)
401 1.1 mrg return simplify_gen_binary (PLUS, Pmode, to, XEXP (x, 1));
402 1.1 mrg
403 1.1 mrg if (maybe_ne (update_sp_offset, 0))
404 1.1 mrg offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0;
405 1.1 mrg else
406 1.1 mrg offset = (update_p
407 1.1 mrg ? ep->offset - ep->previous_offset : ep->offset);
408 1.1 mrg if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
409 1.1 mrg offset -= lra_get_insn_recog_data (insn)->sp_offset;
410 1.1 mrg if (poly_int_rtx_p (XEXP (x, 1), &curr_offset)
411 1.1 mrg && known_eq (curr_offset, -offset))
412 1.1 mrg return to;
413 1.1 mrg else
414 1.1 mrg return gen_rtx_PLUS (Pmode, to,
415 1.1 mrg plus_constant (Pmode,
416 1.1 mrg XEXP (x, 1), offset));
417 1.1 mrg }
418 1.1 mrg
419 1.1 mrg /* If the hard register is not eliminable, we are done since
420 1.1 mrg the other operand is a constant. */
421 1.1 mrg return x;
422 1.1 mrg }
423 1.1 mrg
424 1.1 mrg /* If this is part of an address, we want to bring any constant
425 1.1 mrg to the outermost PLUS. We will do this by doing hard
426 1.1 mrg register replacement in our operands and seeing if a constant
427 1.1 mrg shows up in one of them.
428 1.1 mrg
429 1.1 mrg Note that there is no risk of modifying the structure of the
430 1.1 mrg insn, since we only get called for its operands, thus we are
431 1.1 mrg either modifying the address inside a MEM, or something like
432 1.1 mrg an address operand of a load-address insn. */
433 1.1 mrg
434 1.1 mrg {
435 1.1 mrg rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
436 1.1 mrg subst_p, update_p,
437 1.1 mrg update_sp_offset, full_p);
438 1.1 mrg rtx new1 = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
439 1.1 mrg subst_p, update_p,
440 1.1 mrg update_sp_offset, full_p);
441 1.1 mrg
442 1.1 mrg new0 = move_plus_up (new0);
443 1.1 mrg new1 = move_plus_up (new1);
444 1.1 mrg if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
445 1.1 mrg return form_sum (new0, new1);
446 1.1 mrg }
447 1.1 mrg return x;
448 1.1 mrg
449 1.1 mrg case MULT:
450 1.1 mrg /* If this is the product of an eliminable hard register and a
451 1.1 mrg constant, apply the distribute law and move the constant out
452 1.1 mrg so that we have (plus (mult ..) ..). This is needed in order
453 1.1 mrg to keep load-address insns valid. This case is pathological.
454 1.1 mrg We ignore the possibility of overflow here. */
455 1.1 mrg if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1))
456 1.1 mrg && (ep = get_elimination (XEXP (x, 0))) != NULL)
457 1.1 mrg {
458 1.1 mrg rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
459 1.1 mrg
460 1.1 mrg if (maybe_ne (update_sp_offset, 0))
461 1.1 mrg {
462 1.1 mrg if (ep->to_rtx == stack_pointer_rtx)
463 1.1 mrg return plus_constant (Pmode,
464 1.1 mrg gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
465 1.1 mrg update_sp_offset * INTVAL (XEXP (x, 1)));
466 1.1 mrg return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
467 1.1 mrg }
468 1.1 mrg else if (update_p)
469 1.1 mrg return plus_constant (Pmode,
470 1.1 mrg gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
471 1.1 mrg (ep->offset - ep->previous_offset)
472 1.1 mrg * INTVAL (XEXP (x, 1)));
473 1.1 mrg else if (full_p)
474 1.1 mrg {
475 1.1 mrg poly_int64 offset = ep->offset;
476 1.1 mrg
477 1.1 mrg if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
478 1.1 mrg offset -= lra_get_insn_recog_data (insn)->sp_offset;
479 1.1 mrg return
480 1.1 mrg plus_constant (Pmode,
481 1.1 mrg gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
482 1.1 mrg offset * INTVAL (XEXP (x, 1)));
483 1.1 mrg }
484 1.1 mrg else
485 1.1 mrg return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
486 1.1 mrg }
487 1.1 mrg
488 1.1 mrg /* fall through */
489 1.1 mrg
490 1.1 mrg case CALL:
491 1.1 mrg case COMPARE:
492 1.1 mrg /* See comments before PLUS about handling MINUS. */
493 1.1 mrg case MINUS:
494 1.1 mrg case DIV: case UDIV:
495 1.1 mrg case MOD: case UMOD:
496 1.1 mrg case AND: case IOR: case XOR:
497 1.1 mrg case ROTATERT: case ROTATE:
498 1.1 mrg case ASHIFTRT: case LSHIFTRT: case ASHIFT:
499 1.1 mrg case NE: case EQ:
500 1.1 mrg case GE: case GT: case GEU: case GTU:
501 1.1 mrg case LE: case LT: case LEU: case LTU:
502 1.1 mrg {
503 1.1 mrg rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
504 1.1 mrg subst_p, update_p,
505 1.1 mrg update_sp_offset, full_p);
506 1.1 mrg rtx new1 = XEXP (x, 1)
507 1.1 mrg ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
508 1.1 mrg subst_p, update_p,
509 1.1 mrg update_sp_offset, full_p) : 0;
510 1.1 mrg
511 1.1 mrg if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
512 1.1 mrg return gen_rtx_fmt_ee (code, GET_MODE (x), new0, new1);
513 1.1 mrg }
514 1.1 mrg return x;
515 1.1 mrg
516 1.1 mrg case EXPR_LIST:
517 1.1 mrg /* If we have something in XEXP (x, 0), the usual case,
518 1.1 mrg eliminate it. */
519 1.1 mrg if (XEXP (x, 0))
520 1.1 mrg {
521 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
522 1.1 mrg subst_p, update_p,
523 1.1 mrg update_sp_offset, full_p);
524 1.1 mrg if (new_rtx != XEXP (x, 0))
525 1.1 mrg {
526 1.1 mrg /* If this is a REG_DEAD note, it is not valid anymore.
527 1.1 mrg Using the eliminated version could result in creating a
528 1.1 mrg REG_DEAD note for the stack or frame pointer. */
529 1.1 mrg if (REG_NOTE_KIND (x) == REG_DEAD)
530 1.1 mrg return (XEXP (x, 1)
531 1.1 mrg ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
532 1.1 mrg subst_p, update_p,
533 1.1 mrg update_sp_offset, full_p)
534 1.1 mrg : NULL_RTX);
535 1.1 mrg
536 1.1 mrg x = alloc_reg_note (REG_NOTE_KIND (x), new_rtx, XEXP (x, 1));
537 1.1 mrg }
538 1.1 mrg }
539 1.1 mrg
540 1.1 mrg /* fall through */
541 1.1 mrg
542 1.1 mrg case INSN_LIST:
543 1.1 mrg case INT_LIST:
544 1.1 mrg /* Now do eliminations in the rest of the chain. If this was
545 1.1 mrg an EXPR_LIST, this might result in allocating more memory than is
546 1.1 mrg strictly needed, but it simplifies the code. */
547 1.1 mrg if (XEXP (x, 1))
548 1.1 mrg {
549 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
550 1.1 mrg subst_p, update_p,
551 1.1 mrg update_sp_offset, full_p);
552 1.1 mrg if (new_rtx != XEXP (x, 1))
553 1.1 mrg return
554 1.1 mrg gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x),
555 1.1 mrg XEXP (x, 0), new_rtx);
556 1.1 mrg }
557 1.1 mrg return x;
558 1.1 mrg
559 1.1 mrg case PRE_INC:
560 1.1 mrg case POST_INC:
561 1.1 mrg case PRE_DEC:
562 1.1 mrg case POST_DEC:
563 1.1 mrg /* We do not support elimination of a register that is modified.
564 1.1 mrg elimination_effects has already make sure that this does not
565 1.1 mrg happen. */
566 1.1 mrg return x;
567 1.1 mrg
568 1.1 mrg case PRE_MODIFY:
569 1.1 mrg case POST_MODIFY:
570 1.1 mrg /* We do not support elimination of a hard register that is
571 1.1 mrg modified. LRA has already make sure that this does not
572 1.1 mrg happen. The only remaining case we need to consider here is
573 1.1 mrg that the increment value may be an eliminable register. */
574 1.1 mrg if (GET_CODE (XEXP (x, 1)) == PLUS
575 1.1 mrg && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
576 1.1 mrg {
577 1.1 mrg rtx new_rtx = lra_eliminate_regs_1 (insn, XEXP (XEXP (x, 1), 1),
578 1.1 mrg mem_mode, subst_p, update_p,
579 1.1 mrg update_sp_offset, full_p);
580 1.1 mrg
581 1.1 mrg if (new_rtx != XEXP (XEXP (x, 1), 1))
582 1.1 mrg return gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (x, 0),
583 1.1 mrg gen_rtx_PLUS (GET_MODE (x),
584 1.1 mrg XEXP (x, 0), new_rtx));
585 1.1 mrg }
586 1.1 mrg return x;
587 1.1 mrg
588 1.1 mrg case STRICT_LOW_PART:
589 1.1 mrg case NEG: case NOT:
590 1.1 mrg case SIGN_EXTEND: case ZERO_EXTEND:
591 1.1 mrg case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE:
592 1.1 mrg case FLOAT: case FIX:
593 1.1 mrg case UNSIGNED_FIX: case UNSIGNED_FLOAT:
594 1.1 mrg case ABS:
595 1.1 mrg case SQRT:
596 1.1 mrg case FFS:
597 1.1 mrg case CLZ:
598 1.1 mrg case CTZ:
599 1.1 mrg case POPCOUNT:
600 1.1 mrg case PARITY:
601 1.1 mrg case BSWAP:
602 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
603 1.1 mrg subst_p, update_p,
604 1.1 mrg update_sp_offset, full_p);
605 1.1 mrg if (new_rtx != XEXP (x, 0))
606 1.1 mrg return gen_rtx_fmt_e (code, GET_MODE (x), new_rtx);
607 1.1 mrg return x;
608 1.1 mrg
609 1.1 mrg case SUBREG:
610 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, SUBREG_REG (x), mem_mode,
611 1.1 mrg subst_p, update_p,
612 1.1 mrg update_sp_offset, full_p);
613 1.1 mrg
614 1.1 mrg if (new_rtx != SUBREG_REG (x))
615 1.1 mrg {
616 1.1 mrg if (MEM_P (new_rtx) && !paradoxical_subreg_p (x))
617 1.1 mrg {
618 1.1 mrg SUBREG_REG (x) = new_rtx;
619 1.1 mrg alter_subreg (&x, false);
620 1.1 mrg return x;
621 1.1 mrg }
622 1.1 mrg else if (! subst_p)
623 1.1 mrg {
624 1.1 mrg /* LRA can transform subregs itself. So don't call
625 1.1 mrg simplify_gen_subreg until LRA transformations are
626 1.1 mrg finished. Function simplify_gen_subreg can do
627 1.1 mrg non-trivial transformations (like truncation) which
628 1.1 mrg might make LRA work to fail. */
629 1.1 mrg SUBREG_REG (x) = new_rtx;
630 1.1 mrg return x;
631 1.1 mrg }
632 1.1 mrg else
633 1.1 mrg return simplify_gen_subreg (GET_MODE (x), new_rtx,
634 1.1 mrg GET_MODE (new_rtx), SUBREG_BYTE (x));
635 1.1 mrg }
636 1.1 mrg
637 1.1 mrg return x;
638 1.1 mrg
639 1.1 mrg case MEM:
640 1.1 mrg /* Our only special processing is to pass the mode of the MEM to our
641 1.1 mrg recursive call and copy the flags. While we are here, handle this
642 1.1 mrg case more efficiently. */
643 1.1 mrg return
644 1.1 mrg replace_equiv_address_nv
645 1.1 mrg (x,
646 1.1 mrg lra_eliminate_regs_1 (insn, XEXP (x, 0), GET_MODE (x),
647 1.1 mrg subst_p, update_p, update_sp_offset, full_p));
648 1.1 mrg
649 1.1 mrg case USE:
650 1.1 mrg /* Handle insn_list USE that a call to a pure function may generate. */
651 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), VOIDmode,
652 1.1 mrg subst_p, update_p, update_sp_offset, full_p);
653 1.1 mrg if (new_rtx != XEXP (x, 0))
654 1.1 mrg return gen_rtx_USE (GET_MODE (x), new_rtx);
655 1.1 mrg return x;
656 1.1 mrg
657 1.1 mrg case CLOBBER:
658 1.1 mrg case SET:
659 1.1 mrg gcc_unreachable ();
660 1.1 mrg
661 1.1 mrg default:
662 1.1 mrg break;
663 1.1 mrg }
664 1.1 mrg
665 1.1 mrg /* Process each of our operands recursively. If any have changed, make a
666 1.1 mrg copy of the rtx. */
667 1.1 mrg fmt = GET_RTX_FORMAT (code);
668 1.1 mrg for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
669 1.1 mrg {
670 1.1 mrg if (*fmt == 'e')
671 1.1 mrg {
672 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, i), mem_mode,
673 1.1 mrg subst_p, update_p,
674 1.1 mrg update_sp_offset, full_p);
675 1.1 mrg if (new_rtx != XEXP (x, i) && ! copied)
676 1.1 mrg {
677 1.1 mrg x = shallow_copy_rtx (x);
678 1.1 mrg copied = 1;
679 1.1 mrg }
680 1.1 mrg XEXP (x, i) = new_rtx;
681 1.1 mrg }
682 1.1 mrg else if (*fmt == 'E')
683 1.1 mrg {
684 1.1 mrg int copied_vec = 0;
685 1.1 mrg for (j = 0; j < XVECLEN (x, i); j++)
686 1.1 mrg {
687 1.1 mrg new_rtx = lra_eliminate_regs_1 (insn, XVECEXP (x, i, j), mem_mode,
688 1.1 mrg subst_p, update_p,
689 1.1 mrg update_sp_offset, full_p);
690 1.1 mrg if (new_rtx != XVECEXP (x, i, j) && ! copied_vec)
691 1.1 mrg {
692 1.1 mrg rtvec new_v = gen_rtvec_v (XVECLEN (x, i),
693 1.1 mrg XVEC (x, i)->elem);
694 1.1 mrg if (! copied)
695 1.1 mrg {
696 1.1 mrg x = shallow_copy_rtx (x);
697 1.1 mrg copied = 1;
698 1.1 mrg }
699 1.1 mrg XVEC (x, i) = new_v;
700 1.1 mrg copied_vec = 1;
701 1.1 mrg }
702 1.1 mrg XVECEXP (x, i, j) = new_rtx;
703 1.1 mrg }
704 1.1 mrg }
705 1.1 mrg }
706 1.1 mrg
707 1.1 mrg return x;
708 1.1 mrg }
709 1.1 mrg
710 1.1 mrg /* This function is used externally in subsequent passes of GCC. It
711 1.1 mrg always does a full elimination of X. */
712 1.1 mrg rtx
713 1.1 mrg lra_eliminate_regs (rtx x, machine_mode mem_mode,
714 1.1 mrg rtx insn ATTRIBUTE_UNUSED)
715 1.1 mrg {
716 1.1 mrg return lra_eliminate_regs_1 (NULL, x, mem_mode, true, false, 0, true);
717 1.1 mrg }
718 1.1 mrg
719 1.1 mrg /* Stack pointer offset before the current insn relative to one at the
720 1.1 mrg func start. RTL insns can change SP explicitly. We keep the
721 1.1 mrg changes from one insn to another through this variable. */
722 1.1 mrg static poly_int64 curr_sp_change;
723 1.1 mrg
724 1.1 mrg /* Scan rtx X for references to elimination source or target registers
725 1.1 mrg in contexts that would prevent the elimination from happening.
726 1.1 mrg Update the table of eliminables to reflect the changed state.
727 1.1 mrg MEM_MODE is the mode of an enclosing MEM rtx, or VOIDmode if not
728 1.1 mrg within a MEM. */
729 1.1 mrg static void
730 1.1 mrg mark_not_eliminable (rtx x, machine_mode mem_mode)
731 1.1 mrg {
732 1.1 mrg enum rtx_code code = GET_CODE (x);
733 1.1 mrg class lra_elim_table *ep;
734 1.1 mrg int i, j;
735 1.1 mrg const char *fmt;
736 1.1 mrg poly_int64 offset = 0;
737 1.1 mrg
738 1.1 mrg switch (code)
739 1.1 mrg {
740 1.1 mrg case PRE_INC:
741 1.1 mrg case POST_INC:
742 1.1 mrg case PRE_DEC:
743 1.1 mrg case POST_DEC:
744 1.1 mrg case POST_MODIFY:
745 1.1 mrg case PRE_MODIFY:
746 1.1 mrg if (XEXP (x, 0) == stack_pointer_rtx
747 1.1 mrg && ((code != PRE_MODIFY && code != POST_MODIFY)
748 1.1 mrg || (GET_CODE (XEXP (x, 1)) == PLUS
749 1.1 mrg && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
750 1.1 mrg && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset))))
751 1.1 mrg {
752 1.1 mrg poly_int64 size = GET_MODE_SIZE (mem_mode);
753 1.1 mrg
754 1.1 mrg #ifdef PUSH_ROUNDING
755 1.1 mrg /* If more bytes than MEM_MODE are pushed, account for
756 1.1 mrg them. */
757 1.1 mrg size = PUSH_ROUNDING (size);
758 1.1 mrg #endif
759 1.1 mrg if (code == PRE_DEC || code == POST_DEC)
760 1.1 mrg curr_sp_change -= size;
761 1.1 mrg else if (code == PRE_INC || code == POST_INC)
762 1.1 mrg curr_sp_change += size;
763 1.1 mrg else if (code == PRE_MODIFY || code == POST_MODIFY)
764 1.1 mrg curr_sp_change += offset;
765 1.1 mrg }
766 1.1 mrg else if (REG_P (XEXP (x, 0))
767 1.1 mrg && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER)
768 1.1 mrg {
769 1.1 mrg /* If we modify the source of an elimination rule, disable
770 1.1 mrg it. Do the same if it is the destination and not the
771 1.1 mrg hard frame register. */
772 1.1 mrg for (ep = reg_eliminate;
773 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS];
774 1.1 mrg ep++)
775 1.1 mrg if (ep->from_rtx == XEXP (x, 0)
776 1.1 mrg || (ep->to_rtx == XEXP (x, 0)
777 1.1 mrg && ep->to_rtx != hard_frame_pointer_rtx))
778 1.1 mrg setup_can_eliminate (ep, false);
779 1.1 mrg }
780 1.1 mrg return;
781 1.1 mrg
782 1.1 mrg case USE:
783 1.1 mrg if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
784 1.1 mrg /* If using a hard register that is the source of an eliminate
785 1.1 mrg we still think can be performed, note it cannot be
786 1.1 mrg performed since we don't know how this hard register is
787 1.1 mrg used. */
788 1.1 mrg for (ep = reg_eliminate;
789 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS];
790 1.1 mrg ep++)
791 1.1 mrg if (ep->from_rtx == XEXP (x, 0)
792 1.1 mrg && ep->to_rtx != hard_frame_pointer_rtx)
793 1.1 mrg setup_can_eliminate (ep, false);
794 1.1 mrg return;
795 1.1 mrg
796 1.1 mrg case CLOBBER:
797 1.1 mrg if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
798 1.1 mrg /* If clobbering a hard register that is the replacement
799 1.1 mrg register for an elimination we still think can be
800 1.1 mrg performed, note that it cannot be performed. Otherwise, we
801 1.1 mrg need not be concerned about it. */
802 1.1 mrg for (ep = reg_eliminate;
803 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS];
804 1.1 mrg ep++)
805 1.1 mrg if (ep->to_rtx == XEXP (x, 0)
806 1.1 mrg && ep->to_rtx != hard_frame_pointer_rtx)
807 1.1 mrg setup_can_eliminate (ep, false);
808 1.1 mrg return;
809 1.1 mrg
810 1.1 mrg case SET:
811 1.1 mrg if (SET_DEST (x) == stack_pointer_rtx
812 1.1 mrg && GET_CODE (SET_SRC (x)) == PLUS
813 1.1 mrg && XEXP (SET_SRC (x), 0) == SET_DEST (x)
814 1.1 mrg && poly_int_rtx_p (XEXP (SET_SRC (x), 1), &offset))
815 1.1 mrg {
816 1.1 mrg curr_sp_change += offset;
817 1.1 mrg return;
818 1.1 mrg }
819 1.1 mrg if (! REG_P (SET_DEST (x))
820 1.1 mrg || REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER)
821 1.1 mrg mark_not_eliminable (SET_DEST (x), mem_mode);
822 1.1 mrg else
823 1.1 mrg {
824 1.1 mrg /* See if this is setting the replacement hard register for
825 1.1 mrg an elimination.
826 1.1 mrg
827 1.1 mrg If DEST is the hard frame pointer, we do nothing because
828 1.1 mrg we assume that all assignments to the frame pointer are
829 1.1 mrg for non-local gotos and are being done at a time when
830 1.1 mrg they are valid and do not disturb anything else. Some
831 1.1 mrg machines want to eliminate a fake argument pointer (or
832 1.1 mrg even a fake frame pointer) with either the real frame
833 1.1 mrg pointer or the stack pointer. Assignments to the hard
834 1.1 mrg frame pointer must not prevent this elimination. */
835 1.1 mrg for (ep = reg_eliminate;
836 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS];
837 1.1 mrg ep++)
838 1.1 mrg if (ep->to_rtx == SET_DEST (x)
839 1.1 mrg && SET_DEST (x) != hard_frame_pointer_rtx)
840 1.1 mrg setup_can_eliminate (ep, false);
841 1.1 mrg }
842 1.1 mrg
843 1.1 mrg mark_not_eliminable (SET_SRC (x), mem_mode);
844 1.1 mrg return;
845 1.1 mrg
846 1.1 mrg case MEM:
847 1.1 mrg /* Our only special processing is to pass the mode of the MEM to
848 1.1 mrg our recursive call. */
849 1.1 mrg mark_not_eliminable (XEXP (x, 0), GET_MODE (x));
850 1.1 mrg return;
851 1.1 mrg
852 1.1 mrg default:
853 1.1 mrg break;
854 1.1 mrg }
855 1.1 mrg
856 1.1 mrg fmt = GET_RTX_FORMAT (code);
857 1.1 mrg for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
858 1.1 mrg {
859 1.1 mrg if (*fmt == 'e')
860 1.1 mrg mark_not_eliminable (XEXP (x, i), mem_mode);
861 1.1 mrg else if (*fmt == 'E')
862 1.1 mrg for (j = 0; j < XVECLEN (x, i); j++)
863 1.1 mrg mark_not_eliminable (XVECEXP (x, i, j), mem_mode);
864 1.1 mrg }
865 1.1 mrg }
866 1.1 mrg
867 1.1 mrg
868 1.1 mrg
870 1.1 mrg /* Scan INSN and eliminate all eliminable hard registers in it.
871 1.1 mrg
872 1.1 mrg If REPLACE_P is true, do the replacement destructively. Also
873 1.1 mrg delete the insn as dead it if it is setting an eliminable register.
874 1.1 mrg
875 1.1 mrg If REPLACE_P is false, just update the offsets while keeping the
876 1.1 mrg base register the same. If FIRST_P, use the sp offset for
877 1.1 mrg elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this. If
878 1.1 mrg UPDATE_SP_OFFSET is non-zero, don't use difference of the offset
879 1.1 mrg and the previous offset. Attach the note about used elimination
880 1.1 mrg for insns setting frame pointer to update elimination easy (without
881 1.1 mrg parsing already generated elimination insns to find offset
882 1.1 mrg previously used) in future. */
883 1.1 mrg
884 1.1 mrg void
885 1.1 mrg eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
886 1.1 mrg poly_int64 update_sp_offset)
887 1.1 mrg {
888 1.1 mrg int icode = recog_memoized (insn);
889 1.1 mrg rtx set, old_set = single_set (insn);
890 1.1 mrg bool validate_p;
891 1.1 mrg int i;
892 1.1 mrg rtx substed_operand[MAX_RECOG_OPERANDS];
893 1.1 mrg rtx orig_operand[MAX_RECOG_OPERANDS];
894 1.1 mrg class lra_elim_table *ep;
895 1.1 mrg rtx plus_src, plus_cst_src;
896 1.1 mrg lra_insn_recog_data_t id;
897 1.1 mrg struct lra_static_insn_data *static_id;
898 1.1 mrg
899 1.1 mrg if (icode < 0 && asm_noperands (PATTERN (insn)) < 0 && ! DEBUG_INSN_P (insn))
900 1.1 mrg {
901 1.1 mrg lra_assert (GET_CODE (PATTERN (insn)) == USE
902 1.1 mrg || GET_CODE (PATTERN (insn)) == CLOBBER
903 1.1 mrg || GET_CODE (PATTERN (insn)) == ASM_INPUT);
904 1.1 mrg return;
905 1.1 mrg }
906 1.1 mrg
907 1.1 mrg /* We allow one special case which happens to work on all machines we
908 1.1 mrg currently support: a single set with the source or a REG_EQUAL
909 1.1 mrg note being a PLUS of an eliminable register and a constant. */
910 1.1 mrg plus_src = plus_cst_src = 0;
911 1.1 mrg poly_int64 offset = 0;
912 1.1 mrg if (old_set && REG_P (SET_DEST (old_set)))
913 1.1 mrg {
914 1.1 mrg if (GET_CODE (SET_SRC (old_set)) == PLUS)
915 1.1 mrg plus_src = SET_SRC (old_set);
916 1.1 mrg /* First see if the source is of the form (plus (...) CST). */
917 1.1 mrg if (plus_src && poly_int_rtx_p (XEXP (plus_src, 1), &offset))
918 1.1 mrg plus_cst_src = plus_src;
919 1.1 mrg /* Check that the first operand of the PLUS is a hard reg or
920 1.1 mrg the lowpart subreg of one. */
921 1.1 mrg if (plus_cst_src)
922 1.1 mrg {
923 1.1 mrg rtx reg = XEXP (plus_cst_src, 0);
924 1.1 mrg
925 1.1 mrg if (GET_CODE (reg) == SUBREG && subreg_lowpart_p (reg))
926 1.1 mrg reg = SUBREG_REG (reg);
927 1.1 mrg
928 1.1 mrg if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
929 1.1 mrg plus_cst_src = 0;
930 1.1 mrg }
931 1.1 mrg }
932 1.1 mrg if (plus_cst_src)
933 1.1 mrg {
934 1.1 mrg rtx reg = XEXP (plus_cst_src, 0);
935 1.1 mrg
936 1.1 mrg if (GET_CODE (reg) == SUBREG)
937 1.1 mrg reg = SUBREG_REG (reg);
938 1.1 mrg
939 1.1 mrg if (REG_P (reg) && (ep = get_elimination (reg)) != NULL)
940 1.1 mrg {
941 1.1 mrg rtx to_rtx = replace_p ? ep->to_rtx : ep->from_rtx;
942 1.1 mrg
943 1.1 mrg if (! replace_p)
944 1.1 mrg {
945 1.1 mrg if (known_eq (update_sp_offset, 0))
946 1.1 mrg offset += (ep->offset - ep->previous_offset);
947 1.1 mrg if (ep->to_rtx == stack_pointer_rtx)
948 1.1 mrg {
949 1.1 mrg if (first_p)
950 1.1 mrg offset -= lra_get_insn_recog_data (insn)->sp_offset;
951 1.1 mrg else
952 1.1 mrg offset += update_sp_offset;
953 1.1 mrg }
954 1.1 mrg offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src));
955 1.1 mrg }
956 1.1 mrg
957 1.1 mrg if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG)
958 1.1 mrg to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)), to_rtx);
959 1.1 mrg /* If we have a nonzero offset, and the source is already a
960 1.1 mrg simple REG, the following transformation would increase
961 1.1 mrg the cost of the insn by replacing a simple REG with (plus
962 1.1 mrg (reg sp) CST). So try only when we already had a PLUS
963 1.1 mrg before. */
964 1.1 mrg if (known_eq (offset, 0) || plus_src)
965 1.1 mrg {
966 1.1 mrg rtx new_src = plus_constant (GET_MODE (to_rtx), to_rtx, offset);
967 1.1 mrg
968 1.1 mrg old_set = single_set (insn);
969 1.1 mrg
970 1.1 mrg /* First see if this insn remains valid when we make the
971 1.1 mrg change. If not, try to replace the whole pattern
972 1.1 mrg with a simple set (this may help if the original insn
973 1.1 mrg was a PARALLEL that was only recognized as single_set
974 1.1 mrg due to REG_UNUSED notes). If this isn't valid
975 1.1 mrg either, keep the INSN_CODE the same and let the
976 1.1 mrg constraint pass fix it up. */
977 1.1 mrg if (! validate_change (insn, &SET_SRC (old_set), new_src, 0))
978 1.1 mrg {
979 1.1 mrg rtx new_pat = gen_rtx_SET (SET_DEST (old_set), new_src);
980 1.1 mrg
981 1.1 mrg if (! validate_change (insn, &PATTERN (insn), new_pat, 0))
982 1.1 mrg SET_SRC (old_set) = new_src;
983 1.1 mrg }
984 1.1 mrg lra_update_insn_recog_data (insn);
985 1.1 mrg /* This can't have an effect on elimination offsets, so skip
986 1.1 mrg right to the end. */
987 1.1 mrg return;
988 1.1 mrg }
989 1.1 mrg }
990 1.1 mrg }
991 1.1 mrg
992 1.1 mrg /* Eliminate all eliminable registers occurring in operands that
993 1.1 mrg can be handled by the constraint pass. */
994 1.1 mrg id = lra_get_insn_recog_data (insn);
995 1.1 mrg static_id = id->insn_static_data;
996 1.1 mrg validate_p = false;
997 1.1 mrg for (i = 0; i < static_id->n_operands; i++)
998 1.1 mrg {
999 1.1 mrg orig_operand[i] = *id->operand_loc[i];
1000 1.1 mrg substed_operand[i] = *id->operand_loc[i];
1001 1.1 mrg
1002 1.1 mrg /* For an asm statement, every operand is eliminable. */
1003 1.1 mrg if (icode < 0 || insn_data[icode].operand[i].eliminable)
1004 1.1 mrg {
1005 1.1 mrg /* Check for setting a hard register that we know about. */
1006 1.1 mrg if (static_id->operand[i].type != OP_IN
1007 1.1 mrg && REG_P (orig_operand[i]))
1008 1.1 mrg {
1009 1.1 mrg /* If we are assigning to a hard register that can be
1010 1.1 mrg eliminated, it must be as part of a PARALLEL, since
1011 1.1 mrg the code above handles single SETs. This reg cannot
1012 1.1 mrg be longer eliminated -- it is forced by
1013 1.1 mrg mark_not_eliminable. */
1014 1.1 mrg for (ep = reg_eliminate;
1015 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS];
1016 1.1 mrg ep++)
1017 1.1 mrg lra_assert (ep->from_rtx != orig_operand[i]
1018 1.1 mrg || ! ep->can_eliminate);
1019 1.1 mrg }
1020 1.1 mrg
1021 1.1 mrg /* Companion to the above plus substitution, we can allow
1022 1.1 mrg invariants as the source of a plain move. */
1023 1.1 mrg substed_operand[i]
1024 1.1 mrg = lra_eliminate_regs_1 (insn, *id->operand_loc[i], VOIDmode,
1025 1.1 mrg replace_p, ! replace_p && ! first_p,
1026 1.1 mrg update_sp_offset, first_p);
1027 1.1 mrg if (substed_operand[i] != orig_operand[i])
1028 1.1 mrg validate_p = true;
1029 1.1 mrg }
1030 1.1 mrg }
1031 1.1 mrg
1032 1.1 mrg if (! validate_p)
1033 1.1 mrg return;
1034 1.1 mrg
1035 1.1 mrg /* Substitute the operands; the new values are in the substed_operand
1036 1.1 mrg array. */
1037 1.1 mrg for (i = 0; i < static_id->n_operands; i++)
1038 1.1 mrg *id->operand_loc[i] = substed_operand[i];
1039 1.1 mrg for (i = 0; i < static_id->n_dups; i++)
1040 1.1 mrg *id->dup_loc[i] = substed_operand[(int) static_id->dup_num[i]];
1041 1.1 mrg
1042 1.1 mrg /* Transform plus (plus (hard reg, const), pseudo) to plus (plus (pseudo,
1043 1.1 mrg const), hard reg) in order to keep insn containing eliminated register
1044 1.1 mrg after all reloads calculating its offset. This permits to keep register
1045 1.1 mrg pressure under control and helps to avoid LRA cycling in patalogical
1046 1.1 mrg cases. */
1047 1.1 mrg if (! replace_p && (set = single_set (insn)) != NULL
1048 1.1 mrg && GET_CODE (SET_SRC (set)) == PLUS
1049 1.1 mrg && GET_CODE (XEXP (SET_SRC (set), 0)) == PLUS)
1050 1.1 mrg {
1051 1.1 mrg rtx reg1, reg2, op1, op2;
1052 1.1 mrg
1053 1.1 mrg reg1 = op1 = XEXP (XEXP (SET_SRC (set), 0), 0);
1054 1.1 mrg reg2 = op2 = XEXP (SET_SRC (set), 1);
1055 1.1 mrg if (GET_CODE (reg1) == SUBREG)
1056 1.1 mrg reg1 = SUBREG_REG (reg1);
1057 1.1 mrg if (GET_CODE (reg2) == SUBREG)
1058 1.1 mrg reg2 = SUBREG_REG (reg2);
1059 1.1 mrg if (REG_P (reg1) && REG_P (reg2)
1060 1.1 mrg && REGNO (reg1) < FIRST_PSEUDO_REGISTER
1061 1.1 mrg && REGNO (reg2) >= FIRST_PSEUDO_REGISTER
1062 1.1 mrg && GET_MODE (reg1) == Pmode
1063 1.1 mrg && !have_addptr3_insn (lra_pmode_pseudo, reg1,
1064 1.1 mrg XEXP (XEXP (SET_SRC (set), 0), 1)))
1065 1.1 mrg {
1066 1.1 mrg XEXP (XEXP (SET_SRC (set), 0), 0) = op2;
1067 1.1 mrg XEXP (SET_SRC (set), 1) = op1;
1068 1.1 mrg }
1069 1.1 mrg }
1070 1.1 mrg
1071 1.1 mrg /* If we had a move insn but now we don't, re-recognize it.
1072 1.1 mrg This will cause spurious re-recognition if the old move had a
1073 1.1 mrg PARALLEL since the new one still will, but we can't call
1074 1.1 mrg single_set without having put new body into the insn and the
1075 1.1 mrg re-recognition won't hurt in this rare case. */
1076 1.1 mrg lra_update_insn_recog_data (insn);
1077 1.1 mrg }
1078 1.1 mrg
1079 1.1 mrg /* Spill pseudos which are assigned to hard registers in SET. Add
1080 1.1 mrg affected insns for processing in the subsequent constraint
1081 1.1 mrg pass. */
1082 1.1 mrg static void
1083 1.1 mrg spill_pseudos (HARD_REG_SET set)
1084 1.1 mrg {
1085 1.1 mrg int i;
1086 1.1 mrg bitmap_head to_process;
1087 1.1 mrg rtx_insn *insn;
1088 1.1 mrg
1089 1.1 mrg if (hard_reg_set_empty_p (set))
1090 1.1 mrg return;
1091 1.1 mrg if (lra_dump_file != NULL)
1092 1.1 mrg {
1093 1.1 mrg fprintf (lra_dump_file, " Spilling non-eliminable hard regs:");
1094 1.1 mrg for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1095 1.1 mrg if (TEST_HARD_REG_BIT (set, i))
1096 1.1 mrg fprintf (lra_dump_file, " %d", i);
1097 1.1 mrg fprintf (lra_dump_file, "\n");
1098 1.1 mrg }
1099 1.1 mrg bitmap_initialize (&to_process, ®_obstack);
1100 1.1 mrg for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
1101 1.1 mrg if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
1102 1.1 mrg && overlaps_hard_reg_set_p (set,
1103 1.1 mrg PSEUDO_REGNO_MODE (i), reg_renumber[i]))
1104 1.1 mrg {
1105 1.1 mrg if (lra_dump_file != NULL)
1106 1.1 mrg fprintf (lra_dump_file, " Spilling r%d(%d)\n",
1107 1.1 mrg i, reg_renumber[i]);
1108 1.1 mrg reg_renumber[i] = -1;
1109 1.1 mrg bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap);
1110 1.1 mrg }
1111 1.1 mrg lra_no_alloc_regs |= set;
1112 1.1 mrg for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
1113 1.1 mrg if (bitmap_bit_p (&to_process, INSN_UID (insn)))
1114 1.1 mrg {
1115 1.1 mrg lra_push_insn (insn);
1116 1.1 mrg lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
1117 1.1 mrg }
1118 1.1 mrg bitmap_clear (&to_process);
1119 1.1 mrg }
1120 1.1 mrg
1121 1.1 mrg /* Update all offsets and possibility for elimination on eliminable
1122 1.1 mrg registers. Spill pseudos assigned to registers which are
1123 1.1 mrg uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET. Add
1124 1.1 mrg insns to INSNS_WITH_CHANGED_OFFSETS containing eliminable hard
1125 1.1 mrg registers whose offsets should be changed. Return true if any
1126 1.1 mrg elimination offset changed. */
1127 1.1 mrg static bool
1128 1.1 mrg update_reg_eliminate (bitmap insns_with_changed_offsets)
1129 1.1 mrg {
1130 1.1 mrg bool prev, result;
1131 1.1 mrg class lra_elim_table *ep, *ep1;
1132 1.1 mrg HARD_REG_SET temp_hard_reg_set;
1133 1.1 mrg
1134 1.1 mrg targetm.compute_frame_layout ();
1135 1.1 mrg
1136 1.1 mrg /* Clear self elimination offsets. */
1137 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1138 1.1 mrg self_elim_offsets[ep->from] = 0;
1139 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1140 1.1 mrg {
1141 1.1 mrg /* If it is a currently used elimination: update the previous
1142 1.1 mrg offset. */
1143 1.1 mrg if (elimination_map[ep->from] == ep)
1144 1.1 mrg ep->previous_offset = ep->offset;
1145 1.1 mrg
1146 1.1 mrg prev = ep->prev_can_eliminate;
1147 1.1 mrg setup_can_eliminate (ep, targetm.can_eliminate (ep->from, ep->to));
1148 1.1 mrg if (ep->can_eliminate && ! prev)
1149 1.1 mrg {
1150 1.1 mrg /* It is possible that not eliminable register becomes
1151 1.1 mrg eliminable because we took other reasons into account to
1152 1.1 mrg set up eliminable regs in the initial set up. Just
1153 1.1 mrg ignore new eliminable registers. */
1154 1.1 mrg setup_can_eliminate (ep, false);
1155 1.1 mrg continue;
1156 1.1 mrg }
1157 1.1 mrg if (ep->can_eliminate != prev && elimination_map[ep->from] == ep)
1158 1.1 mrg {
1159 1.1 mrg /* We cannot use this elimination anymore -- find another
1160 1.1 mrg one. */
1161 1.1 mrg if (lra_dump_file != NULL)
1162 1.1 mrg fprintf (lra_dump_file,
1163 1.1 mrg " Elimination %d to %d is not possible anymore\n",
1164 1.1 mrg ep->from, ep->to);
1165 1.1 mrg /* If after processing RTL we decides that SP can be used as
1166 1.1 mrg a result of elimination, it cannot be changed. */
1167 1.1 mrg gcc_assert ((ep->to_rtx != stack_pointer_rtx)
1168 1.1 mrg || (ep->from < FIRST_PSEUDO_REGISTER
1169 1.1 mrg && fixed_regs [ep->from]));
1170 1.1 mrg /* Mark that is not eliminable anymore. */
1171 1.1 mrg elimination_map[ep->from] = NULL;
1172 1.1 mrg for (ep1 = ep + 1; ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep1++)
1173 1.1 mrg if (ep1->can_eliminate && ep1->from == ep->from)
1174 1.1 mrg break;
1175 1.1 mrg if (ep1 < ®_eliminate[NUM_ELIMINABLE_REGS])
1176 1.1 mrg {
1177 1.1 mrg if (lra_dump_file != NULL)
1178 1.1 mrg fprintf (lra_dump_file, " Using elimination %d to %d now\n",
1179 1.1 mrg ep1->from, ep1->to);
1180 1.1 mrg lra_assert (known_eq (ep1->previous_offset, 0));
1181 1.1 mrg ep1->previous_offset = ep->offset;
1182 1.1 mrg }
1183 1.1 mrg else
1184 1.1 mrg {
1185 1.1 mrg /* There is no elimination anymore just use the hard
1186 1.1 mrg register `from' itself. Setup self elimination
1187 1.1 mrg offset to restore the original offset values. */
1188 1.1 mrg if (lra_dump_file != NULL)
1189 1.1 mrg fprintf (lra_dump_file, " %d is not eliminable at all\n",
1190 1.1 mrg ep->from);
1191 1.1 mrg self_elim_offsets[ep->from] = -ep->offset;
1192 1.1 mrg if (maybe_ne (ep->offset, 0))
1193 1.1 mrg bitmap_ior_into (insns_with_changed_offsets,
1194 1.1 mrg &lra_reg_info[ep->from].insn_bitmap);
1195 1.1 mrg }
1196 1.1 mrg }
1197 1.1 mrg
1198 1.1 mrg INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->offset);
1199 1.1 mrg }
1200 1.1 mrg setup_elimination_map ();
1201 1.1 mrg result = false;
1202 1.1 mrg CLEAR_HARD_REG_SET (temp_hard_reg_set);
1203 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1204 1.1 mrg if (elimination_map[ep->from] == NULL)
1205 1.1 mrg add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->from);
1206 1.1 mrg else if (elimination_map[ep->from] == ep)
1207 1.1 mrg {
1208 1.1 mrg /* Prevent the hard register into which we eliminate from
1209 1.1 mrg the usage for pseudos. */
1210 1.1 mrg if (ep->from != ep->to)
1211 1.1 mrg add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->to);
1212 1.1 mrg if (maybe_ne (ep->previous_offset, ep->offset))
1213 1.1 mrg {
1214 1.1 mrg bitmap_ior_into (insns_with_changed_offsets,
1215 1.1 mrg &lra_reg_info[ep->from].insn_bitmap);
1216 1.1 mrg
1217 1.1 mrg /* Update offset when the eliminate offset have been
1218 1.1 mrg changed. */
1219 1.1 mrg lra_update_reg_val_offset (lra_reg_info[ep->from].val,
1220 1.1 mrg ep->offset - ep->previous_offset);
1221 1.1 mrg result = true;
1222 1.1 mrg }
1223 1.1 mrg }
1224 1.1 mrg lra_no_alloc_regs |= temp_hard_reg_set;
1225 1.1 mrg eliminable_regset &= ~temp_hard_reg_set;
1226 1.1 mrg spill_pseudos (temp_hard_reg_set);
1227 1.1 mrg return result;
1228 1.1 mrg }
1229 1.1 mrg
1230 1.1 mrg /* Initialize the table of hard registers to eliminate.
1231 1.1 mrg Pre-condition: global flag frame_pointer_needed has been set before
1232 1.1 mrg calling this function. */
1233 1.1 mrg static void
1234 1.1 mrg init_elim_table (void)
1235 1.1 mrg {
1236 1.1 mrg class lra_elim_table *ep;
1237 1.1 mrg bool value_p;
1238 1.1 mrg const struct elim_table_1 *ep1;
1239 1.1 mrg
1240 1.1 mrg if (!reg_eliminate)
1241 1.1 mrg reg_eliminate = XCNEWVEC (class lra_elim_table, NUM_ELIMINABLE_REGS);
1242 1.1 mrg
1243 1.1 mrg memset (self_elim_offsets, 0, sizeof (self_elim_offsets));
1244 1.1 mrg /* Initiate member values which will be never changed. */
1245 1.1 mrg self_elim_table.can_eliminate = self_elim_table.prev_can_eliminate = true;
1246 1.1 mrg self_elim_table.previous_offset = 0;
1247 1.1 mrg
1248 1.1 mrg for (ep = reg_eliminate, ep1 = reg_eliminate_1;
1249 1.1 mrg ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++)
1250 1.1 mrg {
1251 1.1 mrg ep->offset = ep->previous_offset = 0;
1252 1.1 mrg ep->from = ep1->from;
1253 1.1 mrg ep->to = ep1->to;
1254 1.1 mrg value_p = (targetm.can_eliminate (ep->from, ep->to)
1255 1.1 mrg && ! (ep->to == STACK_POINTER_REGNUM
1256 1.1 mrg && frame_pointer_needed
1257 1.1 mrg && (! SUPPORTS_STACK_ALIGNMENT
1258 1.1 mrg || ! stack_realign_fp)));
1259 1.1 mrg setup_can_eliminate (ep, value_p);
1260 1.1 mrg }
1261 1.1 mrg
1262 1.1 mrg /* Build the FROM and TO REG rtx's. Note that code in gen_rtx_REG
1263 1.1 mrg will cause, e.g., gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to
1264 1.1 mrg equal stack_pointer_rtx. We depend on this. Threfore we switch
1265 1.1 mrg off that we are in LRA temporarily. */
1266 1.1 mrg lra_in_progress = 0;
1267 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1268 1.1 mrg {
1269 1.1 mrg ep->from_rtx = gen_rtx_REG (Pmode, ep->from);
1270 1.1 mrg ep->to_rtx = gen_rtx_REG (Pmode, ep->to);
1271 1.1 mrg eliminable_reg_rtx[ep->from] = ep->from_rtx;
1272 1.1 mrg }
1273 1.1 mrg lra_in_progress = 1;
1274 1.1 mrg }
1275 1.1 mrg
1276 1.1 mrg /* Function for initialization of elimination once per function. It
1277 1.1 mrg sets up sp offset for each insn. */
1278 1.1 mrg static void
1279 1.1 mrg init_elimination (void)
1280 1.1 mrg {
1281 1.1 mrg bool stop_to_sp_elimination_p;
1282 1.1 mrg basic_block bb;
1283 1.1 mrg rtx_insn *insn;
1284 1.1 mrg class lra_elim_table *ep;
1285 1.1 mrg
1286 1.1 mrg init_elim_table ();
1287 1.1 mrg FOR_EACH_BB_FN (bb, cfun)
1288 1.1 mrg {
1289 1.1 mrg curr_sp_change = 0;
1290 1.1 mrg stop_to_sp_elimination_p = false;
1291 1.1 mrg FOR_BB_INSNS (bb, insn)
1292 1.1 mrg if (INSN_P (insn))
1293 1.1 mrg {
1294 1.1 mrg lra_get_insn_recog_data (insn)->sp_offset = curr_sp_change;
1295 1.1 mrg if (NONDEBUG_INSN_P (insn))
1296 1.1 mrg {
1297 1.1 mrg mark_not_eliminable (PATTERN (insn), VOIDmode);
1298 1.1 mrg if (maybe_ne (curr_sp_change, 0)
1299 1.1 mrg && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX))
1300 1.1 mrg stop_to_sp_elimination_p = true;
1301 1.1 mrg }
1302 1.1 mrg }
1303 1.1 mrg if (! frame_pointer_needed
1304 1.1 mrg && (maybe_ne (curr_sp_change, 0) || stop_to_sp_elimination_p)
1305 1.1 mrg && bb->succs && bb->succs->length () != 0)
1306 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1307 1.1 mrg if (ep->to == STACK_POINTER_REGNUM)
1308 1.1 mrg setup_can_eliminate (ep, false);
1309 1.1 mrg }
1310 1.1 mrg setup_elimination_map ();
1311 1.1 mrg }
1312 1.1 mrg
1313 1.1 mrg /* Eliminate hard reg given by its location LOC. */
1314 1.1 mrg void
1315 1.1 mrg lra_eliminate_reg_if_possible (rtx *loc)
1316 1.1 mrg {
1317 1.1 mrg int regno;
1318 1.1 mrg class lra_elim_table *ep;
1319 1.1 mrg
1320 1.1 mrg lra_assert (REG_P (*loc));
1321 1.1 mrg if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
1322 1.1 mrg || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno))
1323 1.1 mrg return;
1324 1.1 mrg if ((ep = get_elimination (*loc)) != NULL)
1325 1.1 mrg *loc = ep->to_rtx;
1326 1.1 mrg }
1327 1.1 mrg
1328 1.1 mrg /* Do (final if FINAL_P or first if FIRST_P) elimination in INSN. Add
1329 1.1 mrg the insn for subsequent processing in the constraint pass, update
1330 1.1 mrg the insn info. */
1331 1.1 mrg static void
1332 1.1 mrg process_insn_for_elimination (rtx_insn *insn, bool final_p, bool first_p)
1333 1.1 mrg {
1334 1.1 mrg eliminate_regs_in_insn (insn, final_p, first_p, 0);
1335 1.1 mrg if (! final_p)
1336 1.1 mrg {
1337 1.1 mrg /* Check that insn changed its code. This is a case when a move
1338 1.1 mrg insn becomes an add insn and we do not want to process the
1339 1.1 mrg insn as a move anymore. */
1340 1.1 mrg int icode = recog (PATTERN (insn), insn, 0);
1341 1.1 mrg
1342 1.1 mrg if (icode >= 0 && icode != INSN_CODE (insn))
1343 1.1 mrg {
1344 1.1 mrg if (INSN_CODE (insn) >= 0)
1345 1.1 mrg /* Insn code is changed. It may change its operand type
1346 1.1 mrg from IN to INOUT. Inform the subsequent assignment
1347 1.1 mrg subpass about this situation. */
1348 1.1 mrg check_and_force_assignment_correctness_p = true;
1349 1.1 mrg INSN_CODE (insn) = icode;
1350 1.1 mrg lra_update_insn_recog_data (insn);
1351 1.1 mrg }
1352 1.1 mrg lra_update_insn_regno_info (insn);
1353 1.1 mrg lra_push_insn (insn);
1354 1.1 mrg lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
1355 1.1 mrg }
1356 1.1 mrg }
1357 1.1 mrg
1358 1.1 mrg /* Entry function to do final elimination if FINAL_P or to update
1359 1.1 mrg elimination register offsets (FIRST_P if we are doing it the first
1360 1.1 mrg time). */
1361 1.1 mrg void
1362 1.1 mrg lra_eliminate (bool final_p, bool first_p)
1363 1.1 mrg {
1364 1.1 mrg unsigned int uid;
1365 1.1 mrg bitmap_head insns_with_changed_offsets;
1366 1.1 mrg bitmap_iterator bi;
1367 1.1 mrg class lra_elim_table *ep;
1368 1.1 mrg
1369 1.1 mrg gcc_assert (! final_p || ! first_p);
1370 1.1 mrg
1371 1.1 mrg timevar_push (TV_LRA_ELIMINATE);
1372 1.1 mrg
1373 1.1 mrg if (first_p)
1374 1.1 mrg init_elimination ();
1375 1.1 mrg
1376 1.1 mrg bitmap_initialize (&insns_with_changed_offsets, ®_obstack);
1377 1.1 mrg if (final_p)
1378 1.1 mrg {
1379 1.1 mrg if (flag_checking)
1380 1.1 mrg {
1381 1.1 mrg update_reg_eliminate (&insns_with_changed_offsets);
1382 1.1 mrg gcc_assert (bitmap_empty_p (&insns_with_changed_offsets));
1383 1.1 mrg }
1384 1.1 mrg /* We change eliminable hard registers in insns so we should do
1385 1.1 mrg this for all insns containing any eliminable hard
1386 1.1 mrg register. */
1387 1.1 mrg for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1388 1.1 mrg if (elimination_map[ep->from] != NULL)
1389 1.1 mrg bitmap_ior_into (&insns_with_changed_offsets,
1390 1.1 mrg &lra_reg_info[ep->from].insn_bitmap);
1391 1.1 mrg }
1392 1.1 mrg else if (! update_reg_eliminate (&insns_with_changed_offsets))
1393 1.1 mrg goto lra_eliminate_done;
1394 1.1 mrg if (lra_dump_file != NULL)
1395 1.1 mrg {
1396 1.1 mrg fprintf (lra_dump_file, "New elimination table:\n");
1397 1.1 mrg print_elim_table (lra_dump_file);
1398 1.1 mrg }
1399 1.1 mrg EXECUTE_IF_SET_IN_BITMAP (&insns_with_changed_offsets, 0, uid, bi)
1400 1.1 mrg /* A dead insn can be deleted in process_insn_for_elimination. */
1401 1.1 mrg if (lra_insn_recog_data[uid] != NULL)
1402 1.1 mrg process_insn_for_elimination (lra_insn_recog_data[uid]->insn,
1403 1.1 mrg final_p, first_p);
1404 1.1 mrg bitmap_clear (&insns_with_changed_offsets);
1405 1.1 mrg
1406 1.1 mrg lra_eliminate_done:
1407 timevar_pop (TV_LRA_ELIMINATE);
1408 }
1409