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 38686496 : setup_can_eliminate (class lra_elim_table *ep, bool value)
146 : {
147 38686496 : ep->can_eliminate = ep->prev_can_eliminate = value;
148 38686496 : if (! value
149 6555990 : && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
150 2909897 : frame_pointer_needed = 1;
151 38686496 : if (!frame_pointer_needed)
152 25660077 : REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0;
153 38686496 : }
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 9652808 : setup_elimination_map (void)
178 : {
179 9652808 : int i;
180 9652808 : class lra_elim_table *ep;
181 :
182 897711144 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
183 888058336 : elimination_map[i] = NULL;
184 48264040 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
185 38611232 : if (ep->can_eliminate && elimination_map[ep->from] == NULL)
186 19305616 : elimination_map[ep->from] = ep;
187 9652808 : }
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 1655945 : form_sum (rtx x, rtx y)
199 : {
200 2018482 : machine_mode mode = GET_MODE (x);
201 2018482 : poly_int64 offset;
202 :
203 2018482 : if (mode == VOIDmode)
204 118243 : mode = GET_MODE (y);
205 :
206 2018482 : if (mode == VOIDmode)
207 0 : mode = Pmode;
208 :
209 2018482 : if (poly_int_rtx_p (x, &offset))
210 118243 : return plus_constant (mode, y, offset);
211 1900239 : else if (poly_int_rtx_p (y, &offset))
212 1021150 : return plus_constant (mode, x, offset);
213 879089 : else if (CONSTANT_P (x))
214 14 : std::swap (x, y);
215 :
216 879089 : if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
217 118257 : 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 760832 : if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
223 244280 : 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 516552 : 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 516552 : 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 120796583 : lra_get_elimination_hard_regno (int hard_regno)
244 : {
245 120796583 : class lra_elim_table *ep;
246 :
247 120796583 : if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
248 : return hard_regno;
249 120796583 : if ((ep = elimination_map[hard_regno]) == NULL)
250 : return hard_regno;
251 32105504 : 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 163269928 : get_elimination (rtx reg)
258 : {
259 163269928 : int hard_regno;
260 163269928 : class lra_elim_table *ep;
261 :
262 163269928 : lra_assert (REG_P (reg));
263 163269928 : if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
264 : return NULL;
265 135488683 : if ((ep = elimination_map[hard_regno]) != NULL)
266 129623200 : return ep->from_rtx != reg ? NULL : ep;
267 5865483 : poly_int64 offset = self_elim_offsets[hard_regno];
268 5865483 : 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 2773286 : move_plus_up (rtx x)
286 : {
287 2773286 : rtx subreg_reg;
288 2773286 : machine_mode x_mode, subreg_reg_mode;
289 :
290 2773286 : if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x))
291 2773114 : return x;
292 172 : subreg_reg = SUBREG_REG (x);
293 172 : x_mode = GET_MODE (x);
294 172 : subreg_reg_mode = GET_MODE (subreg_reg);
295 172 : if (!paradoxical_subreg_p (x)
296 172 : && GET_CODE (subreg_reg) == PLUS
297 4 : && CONSTANT_P (XEXP (subreg_reg, 1))
298 4 : && GET_MODE_CLASS (x_mode) == MODE_INT
299 176 : && 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 12798447 : note_spoff (poly_int64 offset)
322 : {
323 12798447 : if (maybe_ne (offset, 0))
324 1421833 : elimination_2sp_occurred_p = true;
325 12354436 : 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 144783698 : 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 144783698 : enum rtx_code code = GET_CODE (x);
353 144783698 : class lra_elim_table *ep;
354 144783698 : rtx new_rtx;
355 144783698 : int i, j;
356 144783698 : const char *fmt;
357 144783698 : int copied = 0;
358 :
359 144783698 : lra_assert (!update_p || !full_p);
360 144783698 : lra_assert (known_eq (update_sp_offset, 0)
361 : || (!subst_p && update_p && !full_p));
362 144783698 : if (! current_function_decl)
363 : return x;
364 :
365 144783698 : 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 41124207 : case REG:
379 : /* First handle the case where we encounter a bare hard register
380 : that is eliminable. Replace it with a PLUS. */
381 41124207 : if ((ep = get_elimination (x)) != NULL)
382 : {
383 11234907 : rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
384 :
385 11234907 : 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 11234907 : else if (update_p)
392 782468 : return plus_constant (Pmode, to, ep->offset - ep->previous_offset);
393 10523544 : else if (full_p)
394 11554305 : return plus_constant (Pmode, to,
395 9572197 : ep->offset
396 : - (insn != NULL_RTX
397 658517 : && ep->to_rtx == stack_pointer_rtx
398 10230714 : ? note_spoff (lra_get_insn_recog_data
399 444011 : (insn)->sp_offset)
400 : : 0));
401 : else
402 : return to;
403 : }
404 29889300 : return x;
405 :
406 50205429 : case PLUS:
407 : /* If this is the sum of an eliminable register and a constant, rework
408 : the sum. */
409 50205429 : if (REG_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
410 : {
411 48818786 : if ((ep = get_elimination (XEXP (x, 0))) != NULL)
412 : {
413 48720015 : poly_int64 offset, curr_offset;
414 48720015 : rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
415 :
416 48720015 : if (! update_p && ! full_p)
417 22685887 : return simplify_gen_binary (PLUS, Pmode, to, XEXP (x, 1));
418 :
419 29408914 : 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 29408914 : offset = (update_p
425 29408914 : ? ep->offset - ep->previous_offset : ep->offset);
426 29408914 : if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
427 24708872 : offset -= note_spoff (lra_get_insn_recog_data (insn)->sp_offset);
428 29408914 : if (poly_int_rtx_p (XEXP (x, 1), &curr_offset)
429 29408914 : && known_eq (curr_offset, -offset))
430 : return to;
431 : else
432 38968656 : 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 98771 : 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 1386643 : {
453 1386643 : rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
454 : subst_p, update_p,
455 : update_sp_offset, full_p);
456 1386643 : 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 1386643 : new0 = move_plus_up (new0);
461 1386643 : new1 = move_plus_up (new1);
462 1386643 : if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
463 1293408 : return form_sum (new0, new1);
464 : }
465 : return x;
466 :
467 257526 : 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 239586 : if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1))
474 495017 : && (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 386813 : case CALL:
510 386813 : case COMPARE:
511 : /* See comments before PLUS about handling MINUS. */
512 386813 : case MINUS:
513 386813 : case DIV: case UDIV:
514 386813 : case MOD: case UMOD:
515 386813 : case AND: case IOR: case XOR:
516 386813 : case ROTATERT: case ROTATE:
517 386813 : case ASHIFTRT: case LSHIFTRT: case ASHIFT:
518 386813 : case NE: case EQ:
519 386813 : case GE: case GT: case GEU: case GTU:
520 386813 : case LE: case LT: case LEU: case LTU:
521 386813 : {
522 386813 : rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
523 : subst_p, update_p,
524 : update_sp_offset, full_p);
525 386813 : rtx new1 = XEXP (x, 1)
526 386813 : ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
527 : subst_p, update_p,
528 : update_sp_offset, full_p) : 0;
529 :
530 386813 : if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
531 109442 : 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 534490 : case PRE_INC:
579 534490 : case POST_INC:
580 534490 : case PRE_DEC:
581 534490 : case POST_DEC:
582 : /* Recurse to adjust elimination offsets in a spilled pseudo. */
583 534490 : 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 33691 : case STRICT_LOW_PART:
614 33691 : case NEG: case NOT:
615 33691 : case SIGN_EXTEND: case ZERO_EXTEND:
616 33691 : case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE:
617 33691 : case FLOAT: case FIX:
618 33691 : case UNSIGNED_FIX: case UNSIGNED_FLOAT:
619 33691 : case ABS:
620 33691 : case SQRT:
621 33691 : case FFS:
622 33691 : case CLZ:
623 33691 : case CTZ:
624 33691 : case POPCOUNT:
625 33691 : case PARITY:
626 33691 : case BSWAP:
627 33691 : new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
628 : subst_p, update_p,
629 : update_sp_offset, full_p);
630 33691 : if (new_rtx != XEXP (x, 0))
631 24640 : return gen_rtx_fmt_e (code, GET_MODE (x), new_rtx);
632 : return x;
633 :
634 608926 : case SUBREG:
635 608926 : 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 608926 : if (new_rtx != SUBREG_REG (x))
640 : {
641 5133 : 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 5122 : 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 3150 : SUBREG_REG (x) = new_rtx;
655 3150 : return x;
656 : }
657 : else
658 : {
659 3944 : rtx nx = simplify_gen_subreg (GET_MODE (x), new_rtx,
660 1972 : 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 1972 : 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 1972 : return nx;
667 : }
668 : }
669 :
670 : return x;
671 :
672 44106568 : 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 44106568 : return
677 : replace_equiv_address_nv
678 44106568 : (x,
679 44106568 : lra_eliminate_regs_1 (insn, XEXP (x, 0), GET_MODE (x),
680 44106568 : 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 71201 : fmt = GET_RTX_FORMAT (code);
705 155184 : for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
706 : {
707 83983 : if (*fmt == 'e')
708 : {
709 24349 : new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, i), mem_mode,
710 : subst_p, update_p,
711 : update_sp_offset, full_p);
712 24349 : if (new_rtx != XEXP (x, i) && ! copied)
713 : {
714 11438 : x = shallow_copy_rtx (x);
715 11438 : copied = 1;
716 : }
717 24349 : XEXP (x, i) = new_rtx;
718 : }
719 59634 : else if (*fmt == 'E')
720 : {
721 : int copied_vec = 0;
722 38182 : for (j = 0; j < XVECLEN (x, i); j++)
723 : {
724 25952 : 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 25952 : if (new_rtx != XVECEXP (x, i, j) && ! copied_vec)
728 : {
729 22812 : rtvec new_v = gen_rtvec_v (XVECLEN (x, i),
730 11406 : XVEC (x, i)->elem);
731 11406 : if (! copied)
732 : {
733 11406 : x = shallow_copy_rtx (x);
734 11406 : copied = 1;
735 : }
736 11406 : XVEC (x, i) = new_v;
737 11406 : copied_vec = 1;
738 : }
739 25952 : XVECEXP (x, i, j) = new_rtx;
740 : }
741 : }
742 : }
743 :
744 71201 : 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 8913680 : lra_eliminate_regs (rtx x, machine_mode mem_mode,
751 : rtx insn ATTRIBUTE_UNUSED)
752 : {
753 8913680 : 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 355566687 : mark_not_eliminable (rtx x, machine_mode mem_mode)
768 : {
769 488888437 : enum rtx_code code = GET_CODE (x);
770 488888437 : class lra_elim_table *ep;
771 488888437 : int i, j;
772 488888437 : const char *fmt;
773 488888437 : poly_int64 offset = 0;
774 :
775 488888437 : switch (code)
776 : {
777 1990255 : case PRE_INC:
778 1990255 : case POST_INC:
779 1990255 : case PRE_DEC:
780 1990255 : case POST_DEC:
781 1990255 : case POST_MODIFY:
782 1990255 : case PRE_MODIFY:
783 1990255 : if (XEXP (x, 0) == stack_pointer_rtx
784 1990255 : && ((code != PRE_MODIFY && code != POST_MODIFY)
785 108393 : || (GET_CODE (XEXP (x, 1)) == PLUS
786 108393 : && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
787 108393 : && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset))))
788 : {
789 3980510 : 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 1990255 : size = PUSH_ROUNDING (size);
795 : #endif
796 1990255 : if (code == PRE_DEC || code == POST_DEC)
797 355566687 : curr_sp_change -= size;
798 108435 : else if (code == PRE_INC || code == POST_INC)
799 355566687 : curr_sp_change += size;
800 108393 : else if (code == PRE_MODIFY || code == POST_MODIFY)
801 355566687 : 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 874688 : case USE:
820 874688 : 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 3833140 : for (ep = reg_eliminate;
826 3833140 : ep < ®_eliminate[NUM_ELIMINABLE_REGS];
827 : ep++)
828 3066512 : 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 12867701 : case CLOBBER:
834 12867701 : 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 62645745 : for (ep = reg_eliminate;
840 62645745 : ep < ®_eliminate[NUM_ELIMINABLE_REGS];
841 : ep++)
842 50116596 : 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 98219240 : case SET:
848 98219240 : if (SET_DEST (x) == stack_pointer_rtx
849 2194811 : && GET_CODE (SET_SRC (x)) == PLUS
850 2166619 : && XEXP (SET_SRC (x), 0) == SET_DEST (x)
851 100385791 : && poly_int_rtx_p (XEXP (SET_SRC (x), 1), &offset))
852 : {
853 2166551 : curr_sp_change += offset;
854 2166551 : return;
855 : }
856 96052689 : if (! REG_P (SET_DEST (x))
857 96052689 : || REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER)
858 74455466 : 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 107986115 : for (ep = reg_eliminate;
873 107986115 : ep < ®_eliminate[NUM_ELIMINABLE_REGS];
874 : ep++)
875 86388892 : if (ep->to_rtx == SET_DEST (x)
876 58326 : && SET_DEST (x) != hard_frame_pointer_rtx)
877 56520 : setup_can_eliminate (ep, false);
878 : }
879 :
880 96052689 : mark_not_eliminable (SET_SRC (x), mem_mode);
881 96052689 : return;
882 :
883 37269061 : case MEM:
884 : /* Our only special processing is to pass the mode of the MEM to
885 : our recursive call. */
886 37269061 : mark_not_eliminable (XEXP (x, 0), GET_MODE (x));
887 37269061 : return;
888 :
889 337667492 : default:
890 337667492 : break;
891 : }
892 :
893 337667492 : fmt = GET_RTX_FORMAT (code);
894 755854408 : for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
895 : {
896 418186916 : if (*fmt == 'e')
897 146396528 : mark_not_eliminable (XEXP (x, i), mem_mode);
898 271790388 : else if (*fmt == 'E')
899 47571259 : for (j = 0; j < XVECLEN (x, i); j++)
900 31914559 : 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 48526231 : eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
922 : poly_int64 update_sp_offset)
923 : {
924 48526231 : int icode = recog_memoized (insn);
925 48526231 : rtx set, old_set = single_set (insn);
926 48526231 : bool validate_p;
927 48526231 : int i;
928 48526231 : rtx substed_operand[MAX_RECOG_OPERANDS];
929 48526231 : rtx orig_operand[MAX_RECOG_OPERANDS];
930 48526231 : class lra_elim_table *ep;
931 48526231 : rtx plus_src, plus_cst_src;
932 48526231 : lra_insn_recog_data_t id;
933 48526231 : struct lra_static_insn_data *static_id;
934 :
935 48526231 : if (icode < 0 && asm_noperands (PATTERN (insn)) < 0 && ! DEBUG_INSN_P (insn))
936 : {
937 11234 : lra_assert (GET_CODE (PATTERN (insn)) == USE
938 : || GET_CODE (PATTERN (insn)) == CLOBBER
939 : || GET_CODE (PATTERN (insn)) == ASM_INPUT);
940 7182936 : 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 48514997 : plus_src = plus_cst_src = 0;
947 48514997 : poly_int64 offset = 0;
948 48514997 : if (old_set && REG_P (SET_DEST (old_set)))
949 : {
950 20404849 : if (GET_CODE (SET_SRC (old_set)) == PLUS)
951 4357344 : plus_src = SET_SRC (old_set);
952 : /* First see if the source is of the form (plus (...) CST). */
953 4357344 : 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 16364625 : else if (plus_src && REG_P (XEXP (plus_src, 1)))
959 : {
960 31429 : int regno = REGNO (XEXP (plus_src, 1));
961 31429 : if (regno < ira_reg_equiv_len
962 31429 : && ira_reg_equiv[regno].constant != NULL_RTX
963 2827 : && !replace_p
964 34220 : && poly_int_rtx_p (ira_reg_equiv[regno].constant, &offset))
965 98 : 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 4040322 : if (plus_cst_src)
970 : {
971 4040322 : rtx reg = XEXP (plus_cst_src, 0);
972 :
973 4040322 : if (GET_CODE (reg) == SUBREG && subreg_lowpart_p (reg))
974 83 : reg = SUBREG_REG (reg);
975 :
976 4040322 : if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
977 : plus_cst_src = 0;
978 : }
979 : }
980 4015882 : if (plus_cst_src)
981 : {
982 4015882 : rtx reg = XEXP (plus_cst_src, 0);
983 :
984 4015882 : if (GET_CODE (reg) == SUBREG)
985 83 : reg = SUBREG_REG (reg);
986 :
987 4015882 : if (REG_P (reg) && (ep = get_elimination (reg)) != NULL)
988 : {
989 4015882 : rtx to_rtx = replace_p ? ep->to_rtx : ep->from_rtx;
990 :
991 1832907 : if (! replace_p)
992 : {
993 2182975 : if (known_eq (update_sp_offset, 0))
994 2182975 : offset += (!first_p
995 2182975 : ? ep->offset - ep->previous_offset : ep->offset);
996 2182975 : if (ep->to_rtx == stack_pointer_rtx)
997 : {
998 1646775 : if (first_p)
999 877843 : offset -= lra_get_insn_recog_data (insn)->sp_offset;
1000 : else
1001 2182975 : offset += update_sp_offset;
1002 : }
1003 2182975 : offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src));
1004 : }
1005 :
1006 4015882 : 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 4015882 : if (known_eq (offset, 0) || plus_src)
1014 : {
1015 4015882 : rtx new_src = plus_constant (GET_MODE (to_rtx), to_rtx, offset);
1016 :
1017 4015882 : 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 4015882 : 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 4015882 : lra_update_insn_recog_data (insn);
1034 : /* This can't have an effect on elimination offsets, so skip
1035 : right to the end. */
1036 4015882 : return;
1037 : }
1038 : }
1039 : }
1040 :
1041 : /* Eliminate all eliminable registers occurring in operands that
1042 : can be handled by the constraint pass. */
1043 44499115 : id = lra_get_insn_recog_data (insn);
1044 44499115 : static_id = id->insn_static_data;
1045 44499115 : validate_p = false;
1046 125936648 : for (i = 0; i < static_id->n_operands; i++)
1047 : {
1048 81437533 : orig_operand[i] = *id->operand_loc[i];
1049 81437533 : substed_operand[i] = *id->operand_loc[i];
1050 :
1051 : /* For an asm statement, every operand is eliminable. */
1052 81437533 : if (icode < 0 || insn_data[icode].operand[i].eliminable)
1053 : {
1054 : /* Check for setting a hard register that we know about. */
1055 81139835 : if (static_id->operand[i].type != OP_IN
1056 34083813 : && 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 76983260 : for (ep = reg_eliminate;
1064 76983260 : ep < ®_eliminate[NUM_ELIMINABLE_REGS];
1065 : ep++)
1066 61586608 : 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 81139835 : substed_operand[i]
1073 162279670 : = lra_eliminate_regs_1 (insn, *id->operand_loc[i], VOIDmode,
1074 81139835 : replace_p, ! replace_p && ! first_p,
1075 : update_sp_offset, first_p);
1076 81139835 : if (substed_operand[i] != orig_operand[i])
1077 81437533 : validate_p = true;
1078 : }
1079 : }
1080 :
1081 44499115 : if (! validate_p)
1082 : return;
1083 :
1084 : /* Substitute the operands; the new values are in the substed_operand
1085 : array. */
1086 116253798 : for (i = 0; i < static_id->n_operands; i++)
1087 74910503 : *id->operand_loc[i] = substed_operand[i];
1088 41443674 : for (i = 0; i < static_id->n_dups; i++)
1089 100379 : *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 21322698 : if (! replace_p && (set = single_set (insn)) != NULL
1097 15568449 : && GET_CODE (SET_SRC (set)) == PLUS
1098 41710790 : && GET_CODE (XEXP (SET_SRC (set), 0)) == PLUS)
1099 : {
1100 23042 : rtx reg1, reg2, op1, op2;
1101 :
1102 23042 : reg1 = op1 = XEXP (XEXP (SET_SRC (set), 0), 0);
1103 23042 : reg2 = op2 = XEXP (SET_SRC (set), 1);
1104 23042 : if (GET_CODE (reg1) == SUBREG)
1105 0 : reg1 = SUBREG_REG (reg1);
1106 23042 : if (GET_CODE (reg2) == SUBREG)
1107 0 : reg2 = SUBREG_REG (reg2);
1108 18727 : if (REG_P (reg1) && REG_P (reg2)
1109 8073 : && REGNO (reg1) < FIRST_PSEUDO_REGISTER
1110 8073 : && REGNO (reg2) >= FIRST_PSEUDO_REGISTER
1111 8110 : && GET_MODE (reg1) == Pmode
1112 31115 : && !have_addptr3_insn (lra_pmode_pseudo, reg1,
1113 : XEXP (XEXP (SET_SRC (set), 0), 1)))
1114 : {
1115 8073 : XEXP (XEXP (SET_SRC (set), 0), 0) = op2;
1116 8073 : 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 41343295 : 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 8164438 : spill_pseudos (HARD_REG_SET set, int *spilled_pseudos)
1133 : {
1134 8164438 : int i, n;
1135 8164438 : unsigned int j;
1136 8164438 : bitmap_head to_process;
1137 8164438 : rtx_insn *insn;
1138 :
1139 16328876 : if (hard_reg_set_empty_p (set))
1140 : return 0;
1141 8164438 : if (lra_dump_file != NULL)
1142 : {
1143 485 : fprintf (lra_dump_file, " Spilling non-eliminable hard regs:");
1144 485 : j = 0;
1145 485 : hard_reg_set_iterator hrsi;
1146 970 : EXECUTE_IF_SET_IN_HARD_REG_SET (set, 0, j, hrsi)
1147 485 : fprintf (lra_dump_file, " %d", j);
1148 485 : fprintf (lra_dump_file, "\n");
1149 : }
1150 8164438 : bitmap_initialize (&to_process, ®_obstack);
1151 8164438 : n = 0;
1152 528508498 : for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
1153 249326922 : if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
1154 520344060 : && overlaps_hard_reg_set_p (set,
1155 236725012 : PSEUDO_REGNO_MODE (i), reg_renumber[i]))
1156 : {
1157 26565 : if (lra_dump_file != NULL)
1158 0 : fprintf (lra_dump_file, " Spilling r%d(%d)\n",
1159 : i, reg_renumber[i]);
1160 26565 : reg_renumber[i] = -1;
1161 26565 : if (spilled_pseudos != NULL)
1162 0 : spilled_pseudos[n++] = i;
1163 26565 : bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap);
1164 : }
1165 8164438 : lra_no_alloc_regs |= set;
1166 1287959033 : for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
1167 1279794595 : if (bitmap_bit_p (&to_process, INSN_UID (insn)))
1168 : {
1169 172471 : lra_push_insn (insn);
1170 172471 : lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
1171 : }
1172 8164438 : bitmap_clear (&to_process);
1173 8164438 : return n;
1174 : }
1175 :
1176 : /* Update all offsets and possibility for elimination on eliminable
1177 : registers. Spill pseudos assigned to registers which are
1178 : uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET. Add
1179 : insns to INSNS_WITH_CHANGED_OFFSETS containing eliminable hard
1180 : registers whose offsets should be changed. Return true if any
1181 : elimination offset changed. */
1182 : static bool
1183 8164438 : update_reg_eliminate (bitmap insns_with_changed_offsets)
1184 : {
1185 8164438 : bool prev, result;
1186 8164438 : class lra_elim_table *ep, *ep1;
1187 8164438 : HARD_REG_SET temp_hard_reg_set;
1188 :
1189 8164438 : targetm.compute_frame_layout ();
1190 :
1191 : /* Clear self elimination offsets. */
1192 40822190 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1193 32657752 : self_elim_offsets[ep->from] = 0;
1194 40822190 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1195 : {
1196 : /* If it is a currently used elimination: update the previous
1197 : offset. */
1198 32657752 : if (elimination_map[ep->from] == ep)
1199 : {
1200 16328876 : ep->previous_offset = ep->offset;
1201 : /* Restore the stack_pointer_rtx into to_rtx, that
1202 : lra_update_fp2sp_elimination set to from_rtx, so that the assert
1203 : below still checks what it was supposed to check. */
1204 16328876 : if (ep->from_rtx == ep->to_rtx
1205 0 : && ep->from != ep->to
1206 0 : && ep->from == FRAME_POINTER_REGNUM)
1207 0 : ep->to_rtx = stack_pointer_rtx;
1208 : }
1209 :
1210 32657752 : prev = ep->prev_can_eliminate;
1211 32657752 : setup_can_eliminate (ep, targetm.can_eliminate (ep->from, ep->to));
1212 32657752 : if (ep->can_eliminate && ! prev)
1213 : {
1214 : /* It is possible that not eliminable register becomes
1215 : eliminable because we took other reasons into account to
1216 : set up eliminable regs in the initial set up. Just
1217 : ignore new eliminable registers. */
1218 0 : setup_can_eliminate (ep, false);
1219 0 : continue;
1220 : }
1221 32657752 : if (!ep->can_eliminate && elimination_map[ep->from] == ep)
1222 : {
1223 : /* We cannot use this elimination anymore -- find another
1224 : one. */
1225 0 : if (lra_dump_file != NULL)
1226 0 : fprintf (lra_dump_file,
1227 : " Elimination %d to %d is not possible anymore\n",
1228 : ep->from, ep->to);
1229 : /* If after processing RTL we decides that SP can be used as a result
1230 : of elimination, it cannot be changed. For frame pointer to stack
1231 : pointer elimination the condition is a bit relaxed and we just require
1232 : that actual elimination has not been done yet. */
1233 0 : gcc_assert (ep->to_rtx != stack_pointer_rtx
1234 : || !elimination_2sp_occurred_p
1235 : || (ep->from < FIRST_PSEUDO_REGISTER
1236 : && fixed_regs [ep->from]));
1237 :
1238 : /* Mark that is not eliminable anymore. */
1239 0 : elimination_map[ep->from] = NULL;
1240 0 : for (ep1 = ep + 1; ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep1++)
1241 0 : if (ep1->can_eliminate && ep1->from == ep->from)
1242 : break;
1243 0 : if (ep1 < ®_eliminate[NUM_ELIMINABLE_REGS])
1244 : {
1245 0 : if (lra_dump_file != NULL)
1246 0 : fprintf (lra_dump_file, " Using elimination %d to %d now\n",
1247 : ep1->from, ep1->to);
1248 0 : lra_assert (known_eq (ep1->previous_offset, -1));
1249 0 : ep1->previous_offset = ep->offset;
1250 : }
1251 : else
1252 : {
1253 : /* There is no elimination anymore just use the hard
1254 : register `from' itself. Setup self elimination
1255 : offset to restore the original offset values. */
1256 0 : if (lra_dump_file != NULL)
1257 0 : fprintf (lra_dump_file, " %d is not eliminable at all\n",
1258 : ep->from);
1259 0 : self_elim_offsets[ep->from] = -ep->offset;
1260 0 : if (maybe_ne (ep->offset, 0))
1261 0 : bitmap_ior_into (insns_with_changed_offsets,
1262 0 : &lra_reg_info[ep->from].insn_bitmap);
1263 : }
1264 : }
1265 :
1266 32657752 : INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->offset);
1267 : }
1268 8164438 : setup_elimination_map ();
1269 8164438 : result = false;
1270 8164438 : CLEAR_HARD_REG_SET (temp_hard_reg_set);
1271 40822190 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1272 32657752 : if (elimination_map[ep->from] == NULL)
1273 0 : add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->from);
1274 32657752 : else if (elimination_map[ep->from] == ep)
1275 : {
1276 : /* Prevent the hard register into which we eliminate from
1277 : the usage for pseudos. */
1278 16328876 : if (ep->from != ep->to)
1279 17934480 : add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->to);
1280 16328876 : if (maybe_ne (ep->previous_offset, ep->offset))
1281 : {
1282 3335422 : bitmap_ior_into (insns_with_changed_offsets,
1283 3335422 : &lra_reg_info[ep->from].insn_bitmap);
1284 :
1285 : /* Update offset when the eliminate offset have been
1286 : changed. */
1287 3335422 : lra_update_reg_val_offset (lra_reg_info[ep->from].val,
1288 3335422 : ep->offset - ep->previous_offset);
1289 3335422 : result = true;
1290 : }
1291 : }
1292 8164438 : lra_no_alloc_regs |= temp_hard_reg_set;
1293 8164438 : eliminable_regset &= ~temp_hard_reg_set;
1294 8164438 : spill_pseudos (temp_hard_reg_set, NULL);
1295 8164438 : return result;
1296 : }
1297 :
1298 : /* Initialize the table of hard registers to eliminate.
1299 : Pre-condition: global flag frame_pointer_needed has been set before
1300 : calling this function. */
1301 : static void
1302 1488370 : init_elim_table (void)
1303 : {
1304 1488370 : class lra_elim_table *ep;
1305 1488370 : bool value_p;
1306 1488370 : const struct elim_table_1 *ep1;
1307 :
1308 1488370 : if (!reg_eliminate)
1309 215317 : reg_eliminate = XCNEWVEC (class lra_elim_table, NUM_ELIMINABLE_REGS);
1310 :
1311 1488370 : memset (self_elim_offsets, 0, sizeof (self_elim_offsets));
1312 : /* Initiate member values which will be never changed. */
1313 1488370 : self_elim_table.can_eliminate = self_elim_table.prev_can_eliminate = true;
1314 1488370 : self_elim_table.previous_offset = 0;
1315 :
1316 1488370 : for (ep = reg_eliminate, ep1 = reg_eliminate_1;
1317 7441850 : ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++)
1318 : {
1319 5953480 : ep->offset = ep->previous_offset = -1;
1320 5953480 : ep->from = ep1->from;
1321 5953480 : ep->to = ep1->to;
1322 5953480 : value_p = (targetm.can_eliminate (ep->from, ep->to)
1323 5953480 : && ! (ep->to == STACK_POINTER_REGNUM
1324 2008117 : && frame_pointer_needed
1325 59859 : && (! SUPPORTS_STACK_ALIGNMENT
1326 59859 : || ! stack_realign_fp)));
1327 5953480 : setup_can_eliminate (ep, value_p);
1328 : }
1329 :
1330 : /* Build the FROM and TO REG rtx's. Note that code in gen_rtx_REG
1331 : will cause, e.g., gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to
1332 : equal stack_pointer_rtx. We depend on this. Therefore we switch
1333 : off that we are in LRA temporarily. */
1334 1488370 : lra_in_progress = false;
1335 7441850 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1336 : {
1337 6460208 : ep->from_rtx = gen_rtx_REG (Pmode, ep->from);
1338 6460208 : ep->to_rtx = gen_rtx_REG (Pmode, ep->to);
1339 5953480 : eliminable_reg_rtx[ep->from] = ep->from_rtx;
1340 : }
1341 1488370 : lra_in_progress = true;
1342 1488370 : }
1343 :
1344 : /* Function for initialization of elimination once per function. It
1345 : sets up sp offset for each insn. */
1346 : static void
1347 1488370 : init_elimination (void)
1348 : {
1349 1488370 : bool stop_to_sp_elimination_p;
1350 1488370 : basic_block bb;
1351 1488370 : rtx_insn *insn;
1352 1488370 : class lra_elim_table *ep;
1353 :
1354 1488370 : init_elim_table ();
1355 15885011 : FOR_EACH_BB_FN (bb, cfun)
1356 : {
1357 14396641 : curr_sp_change = 0;
1358 14396641 : stop_to_sp_elimination_p = false;
1359 173569778 : FOR_BB_INSNS (bb, insn)
1360 159173137 : if (INSN_P (insn))
1361 : {
1362 132620867 : lra_get_insn_recog_data (insn)->sp_offset = curr_sp_change;
1363 132620867 : if (NONDEBUG_INSN_P (insn))
1364 : {
1365 85211613 : mark_not_eliminable (PATTERN (insn), VOIDmode);
1366 85211613 : if (maybe_ne (curr_sp_change, 0)
1367 85211613 : && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX))
1368 : stop_to_sp_elimination_p = true;
1369 : }
1370 : }
1371 14396641 : if (! frame_pointer_needed
1372 9729871 : && (maybe_ne (curr_sp_change, 0) || stop_to_sp_elimination_p)
1373 14450250 : && bb->succs && bb->succs->length () != 0)
1374 46855 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1375 37484 : if (ep->to == STACK_POINTER_REGNUM)
1376 18742 : setup_can_eliminate (ep, false);
1377 : }
1378 1488370 : setup_elimination_map ();
1379 1488370 : }
1380 :
1381 : /* Update and return stack pointer OFFSET after processing X. */
1382 : poly_int64
1383 17588521 : lra_update_sp_offset (rtx x, poly_int64 offset)
1384 : {
1385 17588521 : curr_sp_change = offset;
1386 17588521 : mark_not_eliminable (x, VOIDmode);
1387 17588521 : return curr_sp_change;
1388 : }
1389 :
1390 :
1391 : /* Eliminate hard reg given by its location LOC. */
1392 : void
1393 93329033 : lra_eliminate_reg_if_possible (rtx *loc)
1394 : {
1395 93329033 : int regno;
1396 93329033 : class lra_elim_table *ep;
1397 :
1398 93329033 : lra_assert (REG_P (*loc));
1399 93329033 : if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
1400 93329033 : || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno))
1401 : return;
1402 69073562 : if ((ep = get_elimination (*loc)) != NULL)
1403 65652396 : *loc = ep->to_rtx;
1404 : }
1405 :
1406 : /* Do (final if FINAL_P or first if FIRST_P) elimination in INSN. Add
1407 : the insn for subsequent processing in the constraint pass, update
1408 : the insn info. */
1409 : static void
1410 48526122 : process_insn_for_elimination (rtx_insn *insn, bool final_p, bool first_p)
1411 : {
1412 48526122 : eliminate_regs_in_insn (insn, final_p, first_p, 0);
1413 48526122 : if (! final_p)
1414 : {
1415 : /* Check that insn changed its code. This is a case when a move
1416 : insn becomes an add insn and we do not want to process the
1417 : insn as a move anymore. */
1418 26658515 : int icode = recog (PATTERN (insn), insn, 0);
1419 :
1420 26658515 : if (icode >= 0 && icode != INSN_CODE (insn))
1421 : {
1422 101942 : if (INSN_CODE (insn) >= 0)
1423 : /* Insn code is changed. It may change its operand type
1424 : from IN to INOUT. Inform the subsequent assignment
1425 : subpass about this situation. */
1426 101942 : check_and_force_assignment_correctness_p = true;
1427 101942 : INSN_CODE (insn) = icode;
1428 101942 : lra_update_insn_recog_data (insn);
1429 : }
1430 26658515 : lra_update_insn_regno_info (insn);
1431 26658515 : lra_push_insn (insn);
1432 26658515 : lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
1433 : }
1434 48526122 : }
1435 :
1436 : /* Update frame pointer to stack pointer elimination if we started with
1437 : permitted frame pointer elimination and now target reports that we can not
1438 : do this elimination anymore. Record spilled pseudos in SPILLED_PSEUDOS
1439 : unless it is null, and return the recorded pseudos number. */
1440 : int
1441 196984 : lra_update_fp2sp_elimination (int *spilled_pseudos)
1442 : {
1443 196984 : int n;
1444 196984 : HARD_REG_SET set;
1445 196984 : class lra_elim_table *ep;
1446 :
1447 196984 : if (frame_pointer_needed || !targetm.frame_pointer_required ())
1448 196984 : return 0;
1449 0 : gcc_assert (!elimination_2sp_occurred_p);
1450 0 : ep = elimination_map[FRAME_POINTER_REGNUM];
1451 0 : if (ep->to == STACK_POINTER_REGNUM)
1452 : {
1453 : /* Prevent any further uses of fp, say in spill addresses, from being
1454 : eliminated to sp and affected by sp offsets. Alas, deactivating the
1455 : elimination altogether causes the next chosen fp elimination to miss
1456 : the offset propagation, so it may keep -1 as its prev_offset, and that
1457 : will make subsequent offsets incorrect. */
1458 0 : ep->to_rtx = ep->from_rtx;
1459 0 : setup_can_eliminate (ep, false);
1460 : }
1461 : else
1462 0 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1463 0 : if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
1464 0 : setup_can_eliminate (ep, false);
1465 0 : if (lra_dump_file != NULL)
1466 0 : fprintf (lra_dump_file,
1467 : " Frame pointer can not be eliminated anymore\n");
1468 0 : frame_pointer_needed = true;
1469 : /* If !lra_reg_spill_p, we likely have incomplete range information
1470 : for pseudos assigned to the frame pointer that will have to be
1471 : spilled, and so we may end up incorrectly sharing them unless we
1472 : get live range information for them. */
1473 0 : if (lra_complete_live_ranges ())
1474 : /* If lives ranges changed, update the aggregate live ranges in
1475 : slots as well before spilling any further pseudos. */
1476 0 : lra_recompute_slots_live_ranges ();
1477 0 : CLEAR_HARD_REG_SET (set);
1478 0 : add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM);
1479 0 : n = spill_pseudos (set, spilled_pseudos);
1480 0 : return n;
1481 : }
1482 :
1483 : /* Return true if we have a pseudo assigned to hard frame pointer. */
1484 : bool
1485 1684 : lra_fp_pseudo_p (void)
1486 : {
1487 1684 : HARD_REG_SET set;
1488 :
1489 1684 : if (frame_pointer_needed)
1490 : /* At this stage it means we have no pseudos assigned to FP: */
1491 : return false;
1492 1408 : CLEAR_HARD_REG_SET (set);
1493 1408 : add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM);
1494 143880 : for (int i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
1495 42644 : if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
1496 176938 : && overlaps_hard_reg_set_p (set, PSEUDO_REGNO_MODE (i),
1497 : reg_renumber[i]))
1498 : return true;
1499 : return false;
1500 : }
1501 :
1502 : /* Entry function to do final elimination if FINAL_P or to update
1503 : elimination register offsets (FIRST_P if we are doing it the first
1504 : time). */
1505 : void
1506 8164458 : lra_eliminate (bool final_p, bool first_p)
1507 : {
1508 8164458 : unsigned int uid;
1509 8164458 : bitmap_head insns_with_changed_offsets;
1510 8164458 : bitmap_iterator bi;
1511 8164458 : class lra_elim_table *ep;
1512 :
1513 8164458 : gcc_assert (! final_p || ! first_p);
1514 :
1515 8164458 : timevar_push (TV_LRA_ELIMINATE);
1516 :
1517 8164458 : if (first_p)
1518 : {
1519 1488370 : elimination_2sp_occurred_p = false;
1520 1488370 : init_elimination ();
1521 : }
1522 :
1523 8164458 : bitmap_initialize (&insns_with_changed_offsets, ®_obstack);
1524 8164458 : if (final_p)
1525 : {
1526 1488370 : if (flag_checking)
1527 : {
1528 1488350 : update_reg_eliminate (&insns_with_changed_offsets);
1529 1488350 : gcc_assert (bitmap_empty_p (&insns_with_changed_offsets));
1530 : }
1531 : /* We change eliminable hard registers in insns so we should do
1532 : this for all insns containing any eliminable hard
1533 : register. */
1534 7441850 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1535 5953480 : if (elimination_map[ep->from] != NULL)
1536 5953480 : bitmap_ior_into (&insns_with_changed_offsets,
1537 5953480 : &lra_reg_info[ep->from].insn_bitmap);
1538 : }
1539 6676088 : else if (! update_reg_eliminate (&insns_with_changed_offsets))
1540 4993006 : goto lra_eliminate_done;
1541 3171452 : if (lra_dump_file != NULL)
1542 : {
1543 194 : fprintf (lra_dump_file, "New elimination table:\n");
1544 194 : print_elim_table (lra_dump_file);
1545 : }
1546 51697574 : EXECUTE_IF_SET_IN_BITMAP (&insns_with_changed_offsets, 0, uid, bi)
1547 : /* A dead insn can be deleted in process_insn_for_elimination. */
1548 48526122 : if (lra_insn_recog_data[uid] != NULL)
1549 : {
1550 48526122 : rtx_insn *insn = lra_insn_recog_data[uid]->insn;
1551 48526122 : start_sequence ();
1552 48526122 : process_insn_for_elimination (insn, final_p, first_p);
1553 48526122 : rtx_insn *first = get_insns ();
1554 48526122 : end_sequence ();
1555 48526122 : if (first != NULL)
1556 : {
1557 0 : lra_assert (!final_p);
1558 0 : lra_process_new_insns (insn, first, NULL,
1559 : "Inserting elimination insn", true);
1560 : }
1561 : }
1562 3171452 : bitmap_clear (&insns_with_changed_offsets);
1563 :
1564 8164458 : lra_eliminate_done:
1565 8164458 : timevar_pop (TV_LRA_ELIMINATE);
1566 8164458 : }
|