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