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 39388986 : setup_can_eliminate (class lra_elim_table *ep, bool value)
146 : {
147 39388986 : ep->can_eliminate = ep->prev_can_eliminate = value;
148 39388986 : if (! value
149 6631358 : && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
150 : {
151 2945539 : frame_pointer_needed = 1;
152 : /* ira_setup_eliminable_regset marks the hard frame pointer live when
153 : it decides a frame pointer is needed. When we make that decision
154 : here instead, we have to do the same, otherwise a target whose
155 : prologue keys the register save off df_regs_ever_live_p would
156 : clobber the caller's hard frame pointer without saving it. */
157 3060723 : int fp_reg_count = hard_regno_nregs (HARD_FRAME_POINTER_REGNUM, Pmode);
158 5891078 : for (int i = 0; i < fp_reg_count; i++)
159 2945539 : df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM + i, true);
160 : }
161 39388986 : if (!frame_pointer_needed)
162 26211695 : REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0;
163 39388986 : }
164 :
165 : /* Map: eliminable "from" register -> its current elimination,
166 : or NULL if none. The elimination table may contain more than
167 : one elimination for the same hard register, but this map specifies
168 : the one that we are currently using. */
169 : static class lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER];
170 :
171 : /* When an eliminable hard register becomes not eliminable, we use the
172 : following special structure to restore original offsets for the
173 : register. */
174 : static class lra_elim_table self_elim_table;
175 :
176 : /* Offsets should be used to restore original offsets for eliminable
177 : hard register which just became not eliminable. Zero,
178 : otherwise. */
179 : static poly_int64 self_elim_offsets[FIRST_PSEUDO_REGISTER];
180 :
181 : /* Map: hard regno -> RTL presentation. RTL presentations of all
182 : potentially eliminable hard registers are stored in the map. */
183 : static rtx eliminable_reg_rtx[FIRST_PSEUDO_REGISTER];
184 :
185 : /* Set up ELIMINATION_MAP of the currently used eliminations. */
186 : static void
187 9828468 : setup_elimination_map (void)
188 : {
189 9828468 : int i;
190 9828468 : class lra_elim_table *ep;
191 :
192 914047524 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
193 904219056 : elimination_map[i] = NULL;
194 49142340 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
195 39313872 : if (ep->can_eliminate && elimination_map[ep->from] == NULL)
196 19656936 : elimination_map[ep->from] = ep;
197 9828468 : }
198 :
199 :
200 :
201 : /* Compute the sum of X and Y, making canonicalizations assumed in an
202 : address, namely: sum constant integers, surround the sum of two
203 : constants with a CONST, put the constant as the second operand, and
204 : group the constant on the outermost sum.
205 :
206 : This routine assumes both inputs are already in canonical form. */
207 : static rtx
208 1763248 : form_sum (rtx x, rtx y)
209 : {
210 2131496 : machine_mode mode = GET_MODE (x);
211 2131496 : poly_int64 offset;
212 :
213 2131496 : if (mode == VOIDmode)
214 117526 : mode = GET_MODE (y);
215 :
216 2131496 : if (mode == VOIDmode)
217 0 : mode = Pmode;
218 :
219 2131496 : if (poly_int_rtx_p (x, &offset))
220 117526 : return plus_constant (mode, y, offset);
221 2013970 : else if (poly_int_rtx_p (y, &offset))
222 1116030 : return plus_constant (mode, x, offset);
223 897940 : else if (CONSTANT_P (x))
224 14 : std::swap (x, y);
225 :
226 897940 : if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
227 117540 : return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
228 :
229 : /* Note that if the operands of Y are specified in the opposite
230 : order in the recursive calls below, infinite recursion will
231 : occur. */
232 780400 : if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
233 250708 : return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
234 :
235 : /* If both constant, encapsulate sum. Otherwise, just form sum. A
236 : constant will have been placed second. */
237 529692 : if (CONSTANT_P (x) && CONSTANT_P (y))
238 : {
239 0 : if (GET_CODE (x) == CONST)
240 0 : x = XEXP (x, 0);
241 0 : if (GET_CODE (y) == CONST)
242 0 : y = XEXP (y, 0);
243 :
244 0 : return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y));
245 : }
246 :
247 529692 : return gen_rtx_PLUS (mode, x, y);
248 : }
249 :
250 : /* Return the current substitution hard register of the elimination of
251 : HARD_REGNO. If HARD_REGNO is not eliminable, return itself. */
252 : int
253 124276624 : lra_get_elimination_hard_regno (int hard_regno)
254 : {
255 124276624 : class lra_elim_table *ep;
256 :
257 124276624 : if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
258 : return hard_regno;
259 124276624 : if ((ep = elimination_map[hard_regno]) == NULL)
260 : return hard_regno;
261 33285629 : return ep->to;
262 : }
263 :
264 : /* Return elimination which will be used for hard reg REG, NULL
265 : otherwise. */
266 : static class lra_elim_table *
267 170272533 : get_elimination (rtx reg)
268 : {
269 170272533 : int hard_regno;
270 170272533 : class lra_elim_table *ep;
271 :
272 170272533 : lra_assert (REG_P (reg));
273 170272533 : if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
274 : return NULL;
275 141715957 : if ((ep = elimination_map[hard_regno]) != NULL)
276 135812519 : return ep->from_rtx != reg ? NULL : ep;
277 5903438 : poly_int64 offset = self_elim_offsets[hard_regno];
278 5903438 : if (known_eq (offset, 0))
279 : return NULL;
280 : /* This is an iteration to restore offsets just after HARD_REGNO
281 : stopped to be eliminable. */
282 0 : self_elim_table.from = self_elim_table.to = hard_regno;
283 0 : self_elim_table.from_rtx
284 0 : = self_elim_table.to_rtx
285 0 : = eliminable_reg_rtx[hard_regno];
286 0 : lra_assert (self_elim_table.from_rtx != NULL);
287 0 : self_elim_table.offset = offset;
288 0 : return &self_elim_table;
289 : }
290 :
291 : /* Transform (subreg (plus reg const)) to (plus (subreg reg) const)
292 : when it is possible. Return X or the transformation result if the
293 : transformation is done. */
294 : static rtx
295 2976026 : move_plus_up (rtx x)
296 : {
297 2976026 : rtx subreg_reg;
298 2976026 : machine_mode x_mode, subreg_reg_mode;
299 :
300 2976026 : if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x))
301 : return x;
302 254 : subreg_reg = SUBREG_REG (x);
303 254 : x_mode = GET_MODE (x);
304 254 : subreg_reg_mode = GET_MODE (subreg_reg);
305 254 : if (!paradoxical_subreg_p (x)
306 254 : && GET_CODE (subreg_reg) == PLUS
307 3 : && CONSTANT_P (XEXP (subreg_reg, 1))
308 3 : && GET_MODE_CLASS (x_mode) == MODE_INT
309 257 : && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT)
310 : {
311 1 : rtx cst = simplify_subreg (x_mode, XEXP (subreg_reg, 1), subreg_reg_mode,
312 : subreg_lowpart_offset (x_mode,
313 : subreg_reg_mode));
314 1 : if (cst && CONSTANT_P (cst))
315 : {
316 1 : rtx lowpart = lowpart_subreg (x_mode, XEXP (subreg_reg, 0),
317 : subreg_reg_mode);
318 1 : if (lowpart)
319 1 : return gen_rtx_PLUS (x_mode, lowpart, cst);
320 : }
321 : }
322 : return x;
323 : }
324 :
325 : /* Flag that we already applied nonzero stack pointer elimination
326 : offset; such sp updates cannot currently be undone. */
327 : static bool elimination_2sp_occurred_p = false;
328 :
329 : /* Take note of any nonzero sp-OFFSET used in eliminations to sp. */
330 : static inline poly_int64
331 13695263 : note_spoff (poly_int64 offset)
332 : {
333 13695263 : if (maybe_ne (offset, 0))
334 1418872 : elimination_2sp_occurred_p = true;
335 13236074 : return offset;
336 : }
337 :
338 : /* Scan X and replace any eliminable registers (such as fp) with a
339 : replacement (such as sp) if SUBST_P, plus an offset. The offset is
340 : a change in the offset between the eliminable register and its
341 : substitution if UPDATE_P, or the full offset if FULL_P, or
342 : otherwise zero. If FULL_P, we also use the SP offsets for
343 : elimination to SP. If UPDATE_P, use UPDATE_SP_OFFSET for updating
344 : offsets of register elimnable to SP. If UPDATE_SP_OFFSET is
345 : non-zero, don't use difference of the offset and the previous
346 : offset.
347 :
348 : MEM_MODE is the mode of an enclosing MEM. We need this to know how
349 : much to adjust a register for, e.g., PRE_DEC. Also, if we are
350 : inside a MEM, we are allowed to replace a sum of a hard register
351 : and the constant zero with the hard register, which we cannot do
352 : outside a MEM. In addition, we need to record the fact that a
353 : hard register is referenced outside a MEM.
354 :
355 : If we make full substitution to SP for non-null INSN, add the insn
356 : sp offset. */
357 : rtx
358 151466371 : lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
359 : bool subst_p, bool update_p,
360 : poly_int64 update_sp_offset, bool full_p)
361 : {
362 151466371 : enum rtx_code code = GET_CODE (x);
363 151466371 : class lra_elim_table *ep;
364 151466371 : rtx new_rtx;
365 151466371 : int i, j;
366 151466371 : const char *fmt;
367 151466371 : int copied = 0;
368 :
369 151466371 : lra_assert (!update_p || !full_p);
370 151466371 : lra_assert (known_eq (update_sp_offset, 0)
371 : || (!subst_p && update_p && !full_p));
372 151466371 : if (! current_function_decl)
373 : return x;
374 :
375 151466371 : switch (code)
376 : {
377 : CASE_CONST_ANY:
378 : case CONST:
379 : case SYMBOL_REF:
380 : case CODE_LABEL:
381 : case PC:
382 : case ASM_INPUT:
383 : case ADDR_VEC:
384 : case ADDR_DIFF_VEC:
385 : case RETURN:
386 : return x;
387 :
388 43096762 : case REG:
389 : /* First handle the case where we encounter a bare hard register
390 : that is eliminable. Replace it with a PLUS. */
391 43096762 : if ((ep = get_elimination (x)) != NULL)
392 : {
393 12413414 : rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
394 :
395 12413414 : if (maybe_ne (update_sp_offset, 0))
396 : {
397 0 : if (ep->to_rtx == stack_pointer_rtx)
398 0 : return plus_constant (Pmode, to, note_spoff (update_sp_offset));
399 : return to;
400 : }
401 12413414 : else if (update_p)
402 707783 : return plus_constant (Pmode, to, ep->offset - ep->previous_offset);
403 11776718 : else if (full_p)
404 12841781 : return plus_constant (Pmode, to,
405 10788167 : ep->offset
406 : - (insn != NULL_RTX
407 674616 : && ep->to_rtx == stack_pointer_rtx
408 11462783 : ? note_spoff (lra_get_insn_recog_data
409 459189 : (insn)->sp_offset)
410 : : 0));
411 : else
412 : return to;
413 : }
414 30683348 : return x;
415 :
416 53022387 : case PLUS:
417 : /* If this is the sum of an eliminable register and a constant, rework
418 : the sum. */
419 53022387 : if (REG_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
420 : {
421 51534374 : if ((ep = get_elimination (XEXP (x, 0))) != NULL)
422 : {
423 51423081 : poly_int64 offset, curr_offset;
424 51423081 : rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
425 :
426 51423081 : if (! update_p && ! full_p)
427 23620974 : return simplify_gen_binary (PLUS, Pmode, to, XEXP (x, 1));
428 :
429 31210367 : if (maybe_ne (update_sp_offset, 0))
430 0 : offset = (ep->to_rtx == stack_pointer_rtx
431 0 : ? note_spoff (update_sp_offset)
432 : : 0);
433 : else
434 31210367 : offset = (update_p
435 31210367 : ? ep->offset - ep->previous_offset : ep->offset);
436 31210367 : if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
437 26472148 : offset -= note_spoff (lra_get_insn_recog_data (insn)->sp_offset);
438 31210367 : if (poly_int_rtx_p (XEXP (x, 1), &curr_offset)
439 31210367 : && known_eq (curr_offset, -offset))
440 : return to;
441 : else
442 40965020 : return gen_rtx_PLUS (Pmode, to,
443 : plus_constant (Pmode,
444 : XEXP (x, 1), offset));
445 : }
446 :
447 : /* If the hard register is not eliminable, we are done since
448 : the other operand is a constant. */
449 111293 : return x;
450 : }
451 :
452 : /* If this is part of an address, we want to bring any constant
453 : to the outermost PLUS. We will do this by doing hard
454 : register replacement in our operands and seeing if a constant
455 : shows up in one of them.
456 :
457 : Note that there is no risk of modifying the structure of the
458 : insn, since we only get called for its operands, thus we are
459 : either modifying the address inside a MEM, or something like
460 : an address operand of a load-address insn. */
461 :
462 1488013 : {
463 1488013 : rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
464 : subst_p, update_p,
465 : update_sp_offset, full_p);
466 1488013 : rtx new1 = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
467 : subst_p, update_p,
468 : update_sp_offset, full_p);
469 :
470 1488013 : new0 = move_plus_up (new0);
471 1488013 : new1 = move_plus_up (new1);
472 1488013 : if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
473 1395000 : return form_sum (new0, new1);
474 : }
475 : return x;
476 :
477 265072 : case MULT:
478 : /* If this is the product of an eliminable hard register and a
479 : constant, apply the distribute law and move the constant out
480 : so that we have (plus (mult ..) ..). This is needed in order
481 : to keep load-address insns valid. This case is pathological.
482 : We ignore the possibility of overflow here. */
483 243211 : if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1))
484 506027 : && (ep = get_elimination (XEXP (x, 0))) != NULL)
485 : {
486 0 : rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
487 :
488 0 : if (maybe_ne (update_sp_offset, 0))
489 : {
490 0 : if (ep->to_rtx == stack_pointer_rtx)
491 0 : return plus_constant (Pmode,
492 0 : gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
493 0 : note_spoff (update_sp_offset)
494 0 : * INTVAL (XEXP (x, 1)));
495 0 : return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
496 : }
497 0 : else if (update_p)
498 0 : return plus_constant (Pmode,
499 0 : gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
500 0 : (ep->offset - ep->previous_offset)
501 0 : * INTVAL (XEXP (x, 1)));
502 0 : else if (full_p)
503 : {
504 0 : poly_int64 offset = ep->offset;
505 :
506 0 : if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
507 0 : offset -= note_spoff (lra_get_insn_recog_data (insn)->sp_offset);
508 0 : return
509 0 : plus_constant (Pmode,
510 0 : gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
511 0 : offset * INTVAL (XEXP (x, 1)));
512 : }
513 : else
514 0 : return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
515 : }
516 :
517 : /* fall through */
518 :
519 435635 : case CALL:
520 435635 : case COMPARE:
521 : /* See comments before PLUS about handling MINUS. */
522 435635 : case MINUS:
523 435635 : case DIV: case UDIV:
524 435635 : case MOD: case UMOD:
525 435635 : case AND: case IOR: case XOR:
526 435635 : case ROTATERT: case ROTATE:
527 435635 : case ASHIFTRT: case LSHIFTRT: case ASHIFT:
528 435635 : case NE: case EQ:
529 435635 : case GE: case GT: case GEU: case GTU:
530 435635 : case LE: case LT: case LEU: case LTU:
531 435635 : {
532 435635 : rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
533 : subst_p, update_p,
534 : update_sp_offset, full_p);
535 435635 : rtx new1 = XEXP (x, 1)
536 435635 : ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
537 : subst_p, update_p,
538 : update_sp_offset, full_p) : 0;
539 :
540 435635 : if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
541 139611 : return gen_rtx_fmt_ee (code, GET_MODE (x), new0, new1);
542 : }
543 : return x;
544 :
545 55 : case EXPR_LIST:
546 : /* If we have something in XEXP (x, 0), the usual case,
547 : eliminate it. */
548 55 : if (XEXP (x, 0))
549 : {
550 55 : new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
551 : subst_p, update_p,
552 : update_sp_offset, full_p);
553 55 : if (new_rtx != XEXP (x, 0))
554 : {
555 : /* If this is a REG_DEAD note, it is not valid anymore.
556 : Using the eliminated version could result in creating a
557 : REG_DEAD note for the stack or frame pointer. */
558 0 : if (REG_NOTE_KIND (x) == REG_DEAD)
559 0 : return (XEXP (x, 1)
560 0 : ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
561 : subst_p, update_p,
562 : update_sp_offset, full_p)
563 : : NULL_RTX);
564 :
565 0 : x = alloc_reg_note (REG_NOTE_KIND (x), new_rtx, XEXP (x, 1));
566 : }
567 : }
568 :
569 : /* fall through */
570 :
571 55 : case INSN_LIST:
572 55 : case INT_LIST:
573 : /* Now do eliminations in the rest of the chain. If this was
574 : an EXPR_LIST, this might result in allocating more memory than is
575 : strictly needed, but it simplifies the code. */
576 55 : if (XEXP (x, 1))
577 : {
578 55 : new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
579 : subst_p, update_p,
580 : update_sp_offset, full_p);
581 55 : if (new_rtx != XEXP (x, 1))
582 0 : return
583 0 : gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x),
584 : XEXP (x, 0), new_rtx);
585 : }
586 55 : return x;
587 :
588 536297 : case PRE_INC:
589 536297 : case POST_INC:
590 536297 : case PRE_DEC:
591 536297 : case POST_DEC:
592 : /* Recurse to adjust elimination offsets in a spilled pseudo. */
593 536297 : if (GET_CODE (XEXP (x, 0)) == MEM)
594 : break;
595 : /* We do not support elimination of a register that is modified.
596 : elimination_effects has already make sure that this does not
597 : happen. */
598 : return x;
599 :
600 192 : case PRE_MODIFY:
601 192 : case POST_MODIFY:
602 : /* Recurse to adjust elimination offsets in a spilled pseudo. */
603 192 : if (GET_CODE (XEXP (x, 0)) == MEM)
604 : break;
605 : /* We do not support elimination of a hard register that is
606 : modified. LRA has already make sure that this does not
607 : happen. The only remaining case we need to consider here is
608 : that the increment value may be an eliminable register. */
609 192 : if (GET_CODE (XEXP (x, 1)) == PLUS
610 192 : && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
611 : {
612 192 : rtx new_rtx = lra_eliminate_regs_1 (insn, XEXP (XEXP (x, 1), 1),
613 : mem_mode, subst_p, update_p,
614 : update_sp_offset, full_p);
615 :
616 192 : if (new_rtx != XEXP (XEXP (x, 1), 1))
617 0 : return gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (x, 0),
618 : gen_rtx_PLUS (GET_MODE (x),
619 : XEXP (x, 0), new_rtx));
620 : }
621 192 : return x;
622 :
623 42760 : case STRICT_LOW_PART:
624 42760 : case NEG: case NOT:
625 42760 : case SIGN_EXTEND: case ZERO_EXTEND:
626 42760 : case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE:
627 42760 : case FLOAT: case FIX:
628 42760 : case UNSIGNED_FIX: case UNSIGNED_FLOAT:
629 42760 : case ABS:
630 42760 : case SQRT:
631 42760 : case FFS:
632 42760 : case CLZ:
633 42760 : case CTZ:
634 42760 : case POPCOUNT:
635 42760 : case PARITY:
636 42760 : case BSWAP:
637 42760 : new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
638 : subst_p, update_p,
639 : update_sp_offset, full_p);
640 42760 : if (new_rtx != XEXP (x, 0))
641 31312 : return gen_rtx_fmt_e (code, GET_MODE (x), new_rtx);
642 : return x;
643 :
644 643072 : case SUBREG:
645 643072 : new_rtx = lra_eliminate_regs_1 (insn, SUBREG_REG (x), mem_mode,
646 : subst_p, update_p,
647 : update_sp_offset, full_p);
648 :
649 643072 : if (new_rtx != SUBREG_REG (x))
650 : {
651 4611 : if (MEM_P (new_rtx) && !paradoxical_subreg_p (x))
652 : {
653 13 : SUBREG_REG (x) = new_rtx;
654 13 : alter_subreg (&x, false);
655 13 : return x;
656 : }
657 4598 : else if (! subst_p)
658 : {
659 : /* LRA can transform subregs itself. So don't call
660 : simplify_gen_subreg until LRA transformations are
661 : finished. Function simplify_gen_subreg can do
662 : non-trivial transformations (like truncation) which
663 : might make LRA work to fail. */
664 2753 : SUBREG_REG (x) = new_rtx;
665 2753 : return x;
666 : }
667 : else
668 : {
669 3690 : rtx nx = simplify_gen_subreg (GET_MODE (x), new_rtx,
670 1845 : GET_MODE (new_rtx), SUBREG_BYTE (x));
671 : /* If inside a debug insn, then generate the subreg manually as it might
672 : be an invalid one for outside of a debug insn. */
673 1845 : if (DEBUG_INSN_P (insn) && !nx)
674 1 : nx = gen_rtx_raw_SUBREG (GET_MODE (x), new_rtx, SUBREG_BYTE (x));
675 6 : gcc_assert (nx);
676 : return nx;
677 : }
678 : }
679 :
680 : return x;
681 :
682 45549331 : case MEM:
683 : /* Our only special processing is to pass the mode of the MEM to our
684 : recursive call and copy the flags. While we are here, handle this
685 : case more efficiently. */
686 45549331 : return
687 : replace_equiv_address_nv
688 45549331 : (x,
689 45549331 : lra_eliminate_regs_1 (insn, XEXP (x, 0), GET_MODE (x),
690 45549331 : subst_p, update_p, update_sp_offset, full_p));
691 :
692 0 : case USE:
693 : /* Handle insn_list USE that a call to a pure function may generate. */
694 0 : new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), VOIDmode,
695 : subst_p, update_p, update_sp_offset, full_p);
696 0 : if (new_rtx != XEXP (x, 0))
697 0 : return gen_rtx_USE (GET_MODE (x), new_rtx);
698 : return x;
699 :
700 0 : case CLOBBER:
701 0 : case ASM_OPERANDS:
702 0 : gcc_assert (insn && DEBUG_INSN_P (insn));
703 : break;
704 :
705 0 : case SET:
706 0 : gcc_unreachable ();
707 :
708 : default:
709 : break;
710 : }
711 :
712 : /* Process each of our operands recursively. If any have changed, make a
713 : copy of the rtx. */
714 88197 : fmt = GET_RTX_FORMAT (code);
715 190796 : for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
716 : {
717 102599 : if (*fmt == 'e')
718 : {
719 27453 : new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, i), mem_mode,
720 : subst_p, update_p,
721 : update_sp_offset, full_p);
722 27453 : if (new_rtx != XEXP (x, i) && ! copied)
723 : {
724 12882 : x = shallow_copy_rtx (x);
725 12882 : copied = 1;
726 : }
727 27453 : XEXP (x, i) = new_rtx;
728 : }
729 75146 : else if (*fmt == 'E')
730 : {
731 : int copied_vec = 0;
732 55555 : for (j = 0; j < XVECLEN (x, i); j++)
733 : {
734 38242 : new_rtx = lra_eliminate_regs_1 (insn, XVECEXP (x, i, j), mem_mode,
735 : subst_p, update_p,
736 : update_sp_offset, full_p);
737 38242 : if (new_rtx != XVECEXP (x, i, j) && ! copied_vec)
738 : {
739 31260 : rtvec new_v = gen_rtvec_v (XVECLEN (x, i),
740 15630 : XVEC (x, i)->elem);
741 15630 : if (! copied)
742 : {
743 15630 : x = shallow_copy_rtx (x);
744 15630 : copied = 1;
745 : }
746 15630 : XVEC (x, i) = new_v;
747 15630 : copied_vec = 1;
748 : }
749 38242 : XVECEXP (x, i, j) = new_rtx;
750 : }
751 : }
752 : }
753 :
754 88197 : return x;
755 : }
756 :
757 : /* This function is used externally in subsequent passes of GCC. It
758 : always does a full elimination of X. */
759 : rtx
760 10113551 : lra_eliminate_regs (rtx x, machine_mode mem_mode,
761 : rtx insn ATTRIBUTE_UNUSED)
762 : {
763 10113551 : return lra_eliminate_regs_1 (NULL, x, mem_mode, true, false, 0, true);
764 : }
765 :
766 : /* Stack pointer offset before the current insn relative to one at the
767 : func start. RTL insns can change SP explicitly. We keep the
768 : changes from one insn to another through this variable. */
769 : static poly_int64 curr_sp_change;
770 :
771 : /* Scan rtx X for references to elimination source or target registers
772 : in contexts that would prevent the elimination from happening.
773 : Update the table of eliminables to reflect the changed state.
774 : MEM_MODE is the mode of an enclosing MEM rtx, or VOIDmode if not
775 : within a MEM. */
776 : static void
777 366104716 : mark_not_eliminable (rtx x, machine_mode mem_mode)
778 : {
779 503178960 : enum rtx_code code = GET_CODE (x);
780 503178960 : class lra_elim_table *ep;
781 503178960 : int i, j;
782 503178960 : const char *fmt;
783 503178960 : poly_int64 offset = 0;
784 :
785 503178960 : switch (code)
786 : {
787 1993236 : case PRE_INC:
788 1993236 : case POST_INC:
789 1993236 : case PRE_DEC:
790 1993236 : case POST_DEC:
791 1993236 : case POST_MODIFY:
792 1993236 : case PRE_MODIFY:
793 1993236 : if (XEXP (x, 0) == stack_pointer_rtx
794 1993236 : && ((code != PRE_MODIFY && code != POST_MODIFY)
795 108808 : || (GET_CODE (XEXP (x, 1)) == PLUS
796 108808 : && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
797 108808 : && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset))))
798 : {
799 3986472 : poly_int64 size = GET_MODE_SIZE (mem_mode);
800 :
801 : #ifdef PUSH_ROUNDING
802 : /* If more bytes than MEM_MODE are pushed, account for
803 : them. */
804 1993236 : size = PUSH_ROUNDING (size);
805 : #endif
806 1993236 : if (code == PRE_DEC || code == POST_DEC)
807 366104716 : curr_sp_change -= size;
808 108850 : else if (code == PRE_INC || code == POST_INC)
809 366104716 : curr_sp_change += size;
810 108808 : else if (code == PRE_MODIFY || code == POST_MODIFY)
811 366104716 : curr_sp_change += offset;
812 : }
813 0 : else if (REG_P (XEXP (x, 0))
814 0 : && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
815 : {
816 : /* If we modify the source of an elimination rule, disable
817 : it. Do the same if it is the destination and not the
818 : hard frame register. */
819 0 : for (ep = reg_eliminate;
820 0 : ep < ®_eliminate[NUM_ELIMINABLE_REGS];
821 : ep++)
822 0 : if (ep->from_rtx == XEXP (x, 0)
823 0 : || (ep->to_rtx == XEXP (x, 0)
824 0 : && ep->to_rtx != hard_frame_pointer_rtx))
825 0 : setup_can_eliminate (ep, false);
826 : }
827 : return;
828 :
829 894160 : case USE:
830 894160 : if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
831 : /* If using a hard register that is the source of an eliminate
832 : we still think can be performed, note it cannot be
833 : performed since we don't know how this hard register is
834 : used. */
835 3886435 : for (ep = reg_eliminate;
836 3886435 : ep < ®_eliminate[NUM_ELIMINABLE_REGS];
837 : ep++)
838 3109148 : if (ep->from_rtx == XEXP (x, 0)
839 0 : && ep->to_rtx != hard_frame_pointer_rtx)
840 0 : setup_can_eliminate (ep, false);
841 : return;
842 :
843 13214653 : case CLOBBER:
844 13214653 : if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
845 : /* If clobbering a hard register that is the replacement
846 : register for an elimination we still think can be
847 : performed, note that it cannot be performed. Otherwise, we
848 : need not be concerned about it. */
849 64380865 : for (ep = reg_eliminate;
850 64380865 : ep < ®_eliminate[NUM_ELIMINABLE_REGS];
851 : ep++)
852 51504692 : if (ep->to_rtx == XEXP (x, 0)
853 4392 : && ep->to_rtx != hard_frame_pointer_rtx)
854 2 : setup_can_eliminate (ep, false);
855 : return;
856 :
857 101190419 : case SET:
858 101190419 : if (SET_DEST (x) == stack_pointer_rtx
859 2197150 : && GET_CODE (SET_SRC (x)) == PLUS
860 2169047 : && XEXP (SET_SRC (x), 0) == SET_DEST (x)
861 103359398 : && poly_int_rtx_p (XEXP (SET_SRC (x), 1), &offset))
862 : {
863 2168979 : curr_sp_change += offset;
864 2168979 : return;
865 : }
866 99021440 : if (! REG_P (SET_DEST (x))
867 99021440 : || REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER)
868 76659975 : mark_not_eliminable (SET_DEST (x), mem_mode);
869 : else
870 : {
871 : /* See if this is setting the replacement hard register for
872 : an elimination.
873 :
874 : If DEST is the hard frame pointer, we do nothing because
875 : we assume that all assignments to the frame pointer are
876 : for non-local gotos and are being done at a time when
877 : they are valid and do not disturb anything else. Some
878 : machines want to eliminate a fake argument pointer (or
879 : even a fake frame pointer) with either the real frame
880 : pointer or the stack pointer. Assignments to the hard
881 : frame pointer must not prevent this elimination. */
882 111807325 : for (ep = reg_eliminate;
883 111807325 : ep < ®_eliminate[NUM_ELIMINABLE_REGS];
884 : ep++)
885 89445860 : if (ep->to_rtx == SET_DEST (x)
886 58150 : && SET_DEST (x) != hard_frame_pointer_rtx)
887 56342 : setup_can_eliminate (ep, false);
888 : }
889 :
890 99021440 : mark_not_eliminable (SET_SRC (x), mem_mode);
891 99021440 : return;
892 :
893 38052804 : case MEM:
894 : /* Our only special processing is to pass the mode of the MEM to
895 : our recursive call. */
896 38052804 : mark_not_eliminable (XEXP (x, 0), GET_MODE (x));
897 38052804 : return;
898 :
899 347833688 : default:
900 347833688 : break;
901 : }
902 :
903 347833688 : fmt = GET_RTX_FORMAT (code);
904 778362074 : for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
905 : {
906 430528386 : if (*fmt == 'e')
907 150550077 : mark_not_eliminable (XEXP (x, i), mem_mode);
908 279978309 : else if (*fmt == 'E')
909 49134399 : for (j = 0; j < XVECLEN (x, i); j++)
910 33034809 : mark_not_eliminable (XVECEXP (x, i, j), mem_mode);
911 : }
912 : }
913 :
914 :
915 :
916 : /* Scan INSN and eliminate all eliminable hard registers in it.
917 :
918 : If REPLACE_P is true, do the replacement destructively. Also
919 : delete the insn as dead it if it is setting an eliminable register.
920 :
921 : If REPLACE_P is false, just update the offsets while keeping the
922 : base register the same. If FIRST_P, use the sp offset for
923 : elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this. If
924 : UPDATE_SP_OFFSET is non-zero, don't use difference of the offset
925 : and the previous offset. Attach the note about used elimination
926 : for insns setting frame pointer to update elimination easy (without
927 : parsing already generated elimination insns to find offset
928 : previously used) in future. */
929 :
930 : void
931 51170909 : eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
932 : poly_int64 update_sp_offset)
933 : {
934 51170909 : int icode = recog_memoized (insn);
935 51170909 : rtx set, old_set = single_set (insn);
936 51170909 : bool validate_p;
937 51170909 : int i;
938 51170909 : rtx substed_operand[MAX_RECOG_OPERANDS];
939 51170909 : rtx orig_operand[MAX_RECOG_OPERANDS];
940 51170909 : class lra_elim_table *ep;
941 51170909 : rtx plus_src, plus_cst_src;
942 51170909 : lra_insn_recog_data_t id;
943 51170909 : struct lra_static_insn_data *static_id;
944 :
945 51170909 : if (icode < 0 && asm_noperands (PATTERN (insn)) < 0 && ! DEBUG_INSN_P (insn))
946 : {
947 11943 : lra_assert (GET_CODE (PATTERN (insn)) == USE
948 : || GET_CODE (PATTERN (insn)) == CLOBBER
949 : || GET_CODE (PATTERN (insn)) == ASM_INPUT);
950 7488278 : return;
951 : }
952 :
953 : /* We allow one special case which happens to work on all machines we
954 : currently support: a single set with the source or a REG_EQUAL
955 : note being a PLUS of an eliminable register and a constant. */
956 51158966 : plus_src = plus_cst_src = 0;
957 51158966 : poly_int64 offset = 0;
958 51158966 : if (old_set && REG_P (SET_DEST (old_set)))
959 : {
960 21059893 : if (GET_CODE (SET_SRC (old_set)) == PLUS)
961 4618956 : plus_src = SET_SRC (old_set);
962 : /* First see if the source is of the form (plus (...) CST). */
963 4618956 : if (plus_src && poly_int_rtx_p (XEXP (plus_src, 1), &offset))
964 : plus_cst_src = plus_src;
965 : /* If we are doing initial offset computation, then utilize
966 : eqivalences to discover a constant for the second term
967 : of PLUS_SRC. */
968 16766270 : else if (plus_src && REG_P (XEXP (plus_src, 1)))
969 : {
970 32238 : int regno = REGNO (XEXP (plus_src, 1));
971 32238 : if (regno < ira_reg_equiv_len
972 32238 : && ira_reg_equiv[regno].constant != NULL_RTX
973 2828 : && !replace_p
974 35029 : && poly_int_rtx_p (ira_reg_equiv[regno].constant, &offset))
975 98 : plus_cst_src = plus_src;
976 : }
977 : /* Check that the first operand of the PLUS is a hard reg or
978 : the lowpart subreg of one. */
979 4293721 : if (plus_cst_src)
980 : {
981 4293721 : rtx reg = XEXP (plus_cst_src, 0);
982 :
983 4293721 : if (GET_CODE (reg) == SUBREG && subreg_lowpart_p (reg))
984 83 : reg = SUBREG_REG (reg);
985 :
986 4293721 : if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
987 : plus_cst_src = 0;
988 : }
989 : }
990 4268036 : if (plus_cst_src)
991 : {
992 4268036 : rtx reg = XEXP (plus_cst_src, 0);
993 :
994 4268036 : if (GET_CODE (reg) == SUBREG)
995 83 : reg = SUBREG_REG (reg);
996 :
997 4268036 : if (REG_P (reg) && (ep = get_elimination (reg)) != NULL)
998 : {
999 4268036 : rtx to_rtx = replace_p ? ep->to_rtx : ep->from_rtx;
1000 :
1001 1934759 : if (! replace_p)
1002 : {
1003 2333277 : if (known_eq (update_sp_offset, 0))
1004 2333277 : offset += (!first_p
1005 2333277 : ? ep->offset - ep->previous_offset : ep->offset);
1006 2333277 : if (ep->to_rtx == stack_pointer_rtx)
1007 : {
1008 1791153 : if (first_p)
1009 932221 : offset -= lra_get_insn_recog_data (insn)->sp_offset;
1010 : else
1011 2333277 : offset += update_sp_offset;
1012 : }
1013 2333277 : offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src));
1014 : }
1015 :
1016 4268036 : if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG)
1017 83 : to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)), to_rtx);
1018 : /* If we have a nonzero offset, and the source is already a
1019 : simple REG, the following transformation would increase
1020 : the cost of the insn by replacing a simple REG with (plus
1021 : (reg sp) CST). So try only when we already had a PLUS
1022 : before. */
1023 4268036 : if (known_eq (offset, 0) || plus_src)
1024 : {
1025 4268036 : rtx new_src = plus_constant (GET_MODE (to_rtx), to_rtx, offset);
1026 :
1027 4268036 : old_set = single_set (insn);
1028 :
1029 : /* First see if this insn remains valid when we make the
1030 : change. If not, try to replace the whole pattern
1031 : with a simple set (this may help if the original insn
1032 : was a PARALLEL that was only recognized as single_set
1033 : due to REG_UNUSED notes). If this isn't valid
1034 : either, keep the INSN_CODE the same and let the
1035 : constraint pass fix it up. */
1036 4268036 : if (! validate_change (insn, &SET_SRC (old_set), new_src, 0))
1037 : {
1038 10 : rtx new_pat = gen_rtx_SET (SET_DEST (old_set), new_src);
1039 :
1040 10 : if (! validate_change (insn, &PATTERN (insn), new_pat, 0))
1041 10 : SET_SRC (old_set) = new_src;
1042 : }
1043 4268036 : lra_update_insn_recog_data (insn);
1044 : /* This can't have an effect on elimination offsets, so skip
1045 : right to the end. */
1046 4268036 : return;
1047 : }
1048 : }
1049 : }
1050 :
1051 : /* Eliminate all eliminable registers occurring in operands that
1052 : can be handled by the constraint pass. */
1053 46890930 : id = lra_get_insn_recog_data (insn);
1054 46890930 : static_id = id->insn_static_data;
1055 46890930 : validate_p = false;
1056 131725753 : for (i = 0; i < static_id->n_operands; i++)
1057 : {
1058 84834823 : orig_operand[i] = *id->operand_loc[i];
1059 84834823 : substed_operand[i] = *id->operand_loc[i];
1060 :
1061 : /* For an asm statement, every operand is eliminable. */
1062 84834823 : if (icode < 0 || insn_data[icode].operand[i].eliminable)
1063 : {
1064 : /* Check for setting a hard register that we know about. */
1065 84536363 : if (static_id->operand[i].type != OP_IN
1066 34998266 : && REG_P (orig_operand[i]))
1067 : {
1068 : /* If we are assigning to a hard register that can be
1069 : eliminated, it must be as part of a PARALLEL, since
1070 : the code above handles single SETs. This reg cannot
1071 : be longer eliminated -- it is forced by
1072 : mark_not_eliminable. */
1073 78847925 : for (ep = reg_eliminate;
1074 78847925 : ep < ®_eliminate[NUM_ELIMINABLE_REGS];
1075 : ep++)
1076 63078340 : lra_assert (ep->from_rtx != orig_operand[i]
1077 : || ! ep->can_eliminate);
1078 : }
1079 :
1080 : /* Companion to the above plus substitution, we can allow
1081 : invariants as the source of a plain move. */
1082 84536363 : substed_operand[i]
1083 84536363 : = lra_eliminate_regs_1 (insn, *id->operand_loc[i], VOIDmode,
1084 : replace_p, ! replace_p && ! first_p,
1085 : update_sp_offset, first_p);
1086 84536363 : if (substed_operand[i] != orig_operand[i])
1087 84834823 : validate_p = true;
1088 : }
1089 : }
1090 :
1091 46890930 : if (! validate_p)
1092 : return;
1093 :
1094 : /* Substitute the operands; the new values are in the substed_operand
1095 : array. */
1096 121877251 : for (i = 0; i < static_id->n_operands; i++)
1097 78194620 : *id->operand_loc[i] = substed_operand[i];
1098 43783049 : for (i = 0; i < static_id->n_dups; i++)
1099 100418 : *id->dup_loc[i] = substed_operand[(int) static_id->dup_num[i]];
1100 :
1101 : /* Transform plus (plus (hard reg, const), pseudo) to plus (plus (pseudo,
1102 : const), hard reg) in order to keep insn containing eliminated register
1103 : after all reloads calculating its offset. This permits to keep register
1104 : pressure under control and helps to avoid LRA cycling in patalogical
1105 : cases. */
1106 22733574 : if (! replace_p && (set = single_set (insn)) != NULL
1107 16048889 : && GET_CODE (SET_SRC (set)) == PLUS
1108 44049321 : && GET_CODE (XEXP (SET_SRC (set), 0)) == PLUS)
1109 : {
1110 24471 : rtx reg1, reg2, op1, op2;
1111 :
1112 24471 : reg1 = op1 = XEXP (XEXP (SET_SRC (set), 0), 0);
1113 24471 : reg2 = op2 = XEXP (SET_SRC (set), 1);
1114 24471 : if (GET_CODE (reg1) == SUBREG)
1115 0 : reg1 = SUBREG_REG (reg1);
1116 24471 : if (GET_CODE (reg2) == SUBREG)
1117 0 : reg2 = SUBREG_REG (reg2);
1118 20254 : if (REG_P (reg1) && REG_P (reg2)
1119 8721 : && REGNO (reg1) < FIRST_PSEUDO_REGISTER
1120 8721 : && REGNO (reg2) >= FIRST_PSEUDO_REGISTER
1121 8736 : && GET_MODE (reg1) == Pmode
1122 33192 : && !have_addptr3_insn (lra_pmode_pseudo, reg1,
1123 : XEXP (XEXP (SET_SRC (set), 0), 1)))
1124 : {
1125 8721 : XEXP (XEXP (SET_SRC (set), 0), 0) = op2;
1126 8721 : XEXP (SET_SRC (set), 1) = op1;
1127 : }
1128 : }
1129 :
1130 : /* If we had a move insn but now we don't, re-recognize it.
1131 : This will cause spurious re-recognition if the old move had a
1132 : PARALLEL since the new one still will, but we can't call
1133 : single_set without having put new body into the insn and the
1134 : re-recognition won't hurt in this rare case. */
1135 43682631 : lra_update_insn_recog_data (insn);
1136 : }
1137 :
1138 : /* Spill pseudos which are assigned to hard registers in SET, record them in
1139 : SPILLED_PSEUDOS unless it is null, and return the recorded pseudos number.
1140 : Add affected insns for processing in the subsequent constraint pass. */
1141 : static int
1142 8313347 : spill_pseudos (HARD_REG_SET set, int *spilled_pseudos)
1143 : {
1144 8313347 : int i, n;
1145 8313347 : unsigned int j;
1146 8313347 : bitmap_head to_process;
1147 8313347 : rtx_insn *insn;
1148 :
1149 16626694 : if (hard_reg_set_empty_p (set))
1150 : return 0;
1151 8313347 : if (lra_dump_file != NULL)
1152 : {
1153 485 : fprintf (lra_dump_file, " Spilling non-eliminable hard regs:");
1154 485 : j = 0;
1155 485 : hard_reg_set_iterator hrsi;
1156 970 : EXECUTE_IF_SET_IN_HARD_REG_SET (set, 0, j, hrsi)
1157 485 : fprintf (lra_dump_file, " %d", j);
1158 485 : fprintf (lra_dump_file, "\n");
1159 : }
1160 8313347 : bitmap_initialize (&to_process, ®_obstack);
1161 8313347 : n = 0;
1162 546965393 : for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
1163 256880136 : if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
1164 538652046 : && overlaps_hard_reg_set_p (set,
1165 243814649 : PSEUDO_REGNO_MODE (i), reg_renumber[i]))
1166 : {
1167 26799 : if (lra_dump_file != NULL)
1168 0 : fprintf (lra_dump_file, " Spilling r%d(%d)\n",
1169 : i, reg_renumber[i]);
1170 26799 : reg_renumber[i] = -1;
1171 26799 : if (spilled_pseudos != NULL)
1172 0 : spilled_pseudos[n++] = i;
1173 26799 : bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap);
1174 : }
1175 8313347 : lra_no_alloc_regs |= set;
1176 1369318462 : for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
1177 1361005115 : if (bitmap_bit_p (&to_process, INSN_UID (insn)))
1178 : {
1179 175360 : lra_push_insn (insn);
1180 175360 : lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
1181 : }
1182 8313347 : bitmap_clear (&to_process);
1183 8313347 : return n;
1184 : }
1185 :
1186 : /* Update all offsets and possibility for elimination on eliminable
1187 : registers. Spill pseudos assigned to registers which are
1188 : uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET. Add
1189 : insns to INSNS_WITH_CHANGED_OFFSETS containing eliminable hard
1190 : registers whose offsets should be changed. Return true if any
1191 : elimination offset changed. */
1192 : static bool
1193 8313347 : update_reg_eliminate (bitmap insns_with_changed_offsets)
1194 : {
1195 8313347 : bool prev, result;
1196 8313347 : class lra_elim_table *ep, *ep1;
1197 8313347 : HARD_REG_SET temp_hard_reg_set;
1198 :
1199 8313347 : targetm.compute_frame_layout ();
1200 :
1201 : /* Clear self elimination offsets. */
1202 41566735 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1203 33253388 : self_elim_offsets[ep->from] = 0;
1204 41566735 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1205 : {
1206 : /* If it is a currently used elimination: update the previous
1207 : offset. */
1208 33253388 : if (elimination_map[ep->from] == ep)
1209 : {
1210 16626694 : ep->previous_offset = ep->offset;
1211 : /* Restore the stack_pointer_rtx into to_rtx, that
1212 : lra_update_fp2sp_elimination set to from_rtx, so that the assert
1213 : below still checks what it was supposed to check. */
1214 16626694 : if (ep->from_rtx == ep->to_rtx
1215 0 : && ep->from != ep->to
1216 0 : && ep->from == FRAME_POINTER_REGNUM)
1217 0 : ep->to_rtx = stack_pointer_rtx;
1218 : }
1219 :
1220 33253388 : prev = ep->prev_can_eliminate;
1221 33253388 : setup_can_eliminate (ep, targetm.can_eliminate (ep->from, ep->to));
1222 33253388 : if (ep->can_eliminate && ! prev)
1223 : {
1224 : /* It is possible that not eliminable register becomes
1225 : eliminable because we took other reasons into account to
1226 : set up eliminable regs in the initial set up. Just
1227 : ignore new eliminable registers. */
1228 0 : setup_can_eliminate (ep, false);
1229 0 : continue;
1230 : }
1231 33253388 : if (!ep->can_eliminate && elimination_map[ep->from] == ep)
1232 : {
1233 : /* We cannot use this elimination anymore -- find another
1234 : one. */
1235 0 : if (lra_dump_file != NULL)
1236 0 : fprintf (lra_dump_file,
1237 : " Elimination %d to %d is not possible anymore\n",
1238 : ep->from, ep->to);
1239 : /* If after processing RTL we decides that SP can be used as a result
1240 : of elimination, it cannot be changed. For frame pointer to stack
1241 : pointer elimination the condition is a bit relaxed and we just require
1242 : that actual elimination has not been done yet. */
1243 0 : gcc_assert (ep->to_rtx != stack_pointer_rtx
1244 : || !elimination_2sp_occurred_p
1245 : || (ep->from < FIRST_PSEUDO_REGISTER
1246 : && fixed_regs [ep->from]));
1247 :
1248 : /* Mark that is not eliminable anymore. */
1249 0 : elimination_map[ep->from] = NULL;
1250 0 : for (ep1 = ep + 1; ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep1++)
1251 0 : if (ep1->can_eliminate && ep1->from == ep->from)
1252 : break;
1253 0 : if (ep1 < ®_eliminate[NUM_ELIMINABLE_REGS])
1254 : {
1255 0 : if (lra_dump_file != NULL)
1256 0 : fprintf (lra_dump_file, " Using elimination %d to %d now\n",
1257 : ep1->from, ep1->to);
1258 0 : lra_assert (known_eq (ep1->previous_offset, -1));
1259 0 : ep1->previous_offset = ep->offset;
1260 : }
1261 : else
1262 : {
1263 : /* There is no elimination anymore just use the hard
1264 : register `from' itself. Setup self elimination
1265 : offset to restore the original offset values. */
1266 0 : if (lra_dump_file != NULL)
1267 0 : fprintf (lra_dump_file, " %d is not eliminable at all\n",
1268 : ep->from);
1269 0 : self_elim_offsets[ep->from] = -ep->offset;
1270 0 : if (maybe_ne (ep->offset, 0))
1271 0 : bitmap_ior_into (insns_with_changed_offsets,
1272 0 : &lra_reg_info[ep->from].insn_bitmap);
1273 : }
1274 : }
1275 :
1276 33253388 : INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->offset);
1277 : }
1278 8313347 : setup_elimination_map ();
1279 8313347 : result = false;
1280 8313347 : CLEAR_HARD_REG_SET (temp_hard_reg_set);
1281 41566735 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1282 33253388 : if (elimination_map[ep->from] == NULL)
1283 0 : add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->from);
1284 33253388 : else if (elimination_map[ep->from] == ep)
1285 : {
1286 : /* Prevent the hard register into which we eliminate from
1287 : the usage for pseudos. */
1288 16626694 : if (ep->from != ep->to)
1289 18234788 : add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->to);
1290 16626694 : if (maybe_ne (ep->previous_offset, ep->offset))
1291 : {
1292 3397752 : bitmap_ior_into (insns_with_changed_offsets,
1293 3397752 : &lra_reg_info[ep->from].insn_bitmap);
1294 :
1295 : /* Update offset when the eliminate offset have been
1296 : changed. */
1297 3397752 : lra_update_reg_val_offset (lra_reg_info[ep->from].val,
1298 3397752 : ep->offset - ep->previous_offset);
1299 3397752 : result = true;
1300 : }
1301 : }
1302 8313347 : lra_no_alloc_regs |= temp_hard_reg_set;
1303 8313347 : eliminable_regset &= ~temp_hard_reg_set;
1304 8313347 : spill_pseudos (temp_hard_reg_set, NULL);
1305 8313347 : return result;
1306 : }
1307 :
1308 : /* Initialize the table of hard registers to eliminate.
1309 : Pre-condition: global flag frame_pointer_needed has been set before
1310 : calling this function. */
1311 : static void
1312 1515121 : init_elim_table (void)
1313 : {
1314 1515121 : class lra_elim_table *ep;
1315 1515121 : bool value_p;
1316 1515121 : const struct elim_table_1 *ep1;
1317 :
1318 1515121 : if (!reg_eliminate)
1319 214671 : reg_eliminate = XCNEWVEC (class lra_elim_table, NUM_ELIMINABLE_REGS);
1320 :
1321 1515121 : memset (self_elim_offsets, 0, sizeof (self_elim_offsets));
1322 : /* Initiate member values which will be never changed. */
1323 1515121 : self_elim_table.can_eliminate = self_elim_table.prev_can_eliminate = true;
1324 1515121 : self_elim_table.previous_offset = 0;
1325 :
1326 1515121 : for (ep = reg_eliminate, ep1 = reg_eliminate_1;
1327 7575605 : ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++)
1328 : {
1329 6060484 : ep->offset = ep->previous_offset = -1;
1330 6060484 : ep->from = ep1->from;
1331 6060484 : ep->to = ep1->to;
1332 6060484 : value_p = (targetm.can_eliminate (ep->from, ep->to)
1333 6060484 : && ! (ep->to == STACK_POINTER_REGNUM
1334 2049339 : && frame_pointer_needed
1335 60399 : && (! SUPPORTS_STACK_ALIGNMENT
1336 60399 : || ! stack_realign_fp)));
1337 6060484 : setup_can_eliminate (ep, value_p);
1338 : }
1339 :
1340 : /* Build the FROM and TO REG rtx's. Note that code in gen_rtx_REG
1341 : will cause, e.g., gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to
1342 : equal stack_pointer_rtx. We depend on this. Therefore we switch
1343 : off that we are in LRA temporarily. */
1344 1515121 : lra_in_progress = false;
1345 7575605 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1346 : {
1347 6567560 : ep->from_rtx = gen_rtx_REG (Pmode, ep->from);
1348 6567560 : ep->to_rtx = gen_rtx_REG (Pmode, ep->to);
1349 6060484 : eliminable_reg_rtx[ep->from] = ep->from_rtx;
1350 : }
1351 1515121 : lra_in_progress = true;
1352 1515121 : }
1353 :
1354 : /* Function for initialization of elimination once per function. It
1355 : sets up sp offset for each insn. */
1356 : static void
1357 1515121 : init_elimination (void)
1358 : {
1359 1515121 : bool stop_to_sp_elimination_p;
1360 1515121 : basic_block bb;
1361 1515121 : rtx_insn *insn;
1362 1515121 : class lra_elim_table *ep;
1363 :
1364 1515121 : init_elim_table ();
1365 16348385 : FOR_EACH_BB_FN (bb, cfun)
1366 : {
1367 14833264 : curr_sp_change = 0;
1368 14833264 : stop_to_sp_elimination_p = false;
1369 183272964 : FOR_BB_INSNS (bb, insn)
1370 168439700 : if (INSN_P (insn))
1371 : {
1372 141108863 : lra_get_insn_recog_data (insn)->sp_offset = curr_sp_change;
1373 141108863 : if (NONDEBUG_INSN_P (insn))
1374 : {
1375 87545194 : mark_not_eliminable (PATTERN (insn), VOIDmode);
1376 87545194 : if (maybe_ne (curr_sp_change, 0)
1377 87545194 : && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX))
1378 : stop_to_sp_elimination_p = true;
1379 : }
1380 : }
1381 14833264 : if (! frame_pointer_needed
1382 10128114 : && (maybe_ne (curr_sp_change, 0) || stop_to_sp_elimination_p)
1383 14886949 : && bb->succs && bb->succs->length () != 0)
1384 46925 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1385 37540 : if (ep->to == STACK_POINTER_REGNUM)
1386 18770 : setup_can_eliminate (ep, false);
1387 : }
1388 1515121 : setup_elimination_map ();
1389 1515121 : }
1390 :
1391 : /* Update and return stack pointer OFFSET after processing X. */
1392 : poly_int64
1393 18314661 : lra_update_sp_offset (rtx x, poly_int64 offset)
1394 : {
1395 18314661 : curr_sp_change = offset;
1396 18314661 : mark_not_eliminable (x, VOIDmode);
1397 18314661 : return curr_sp_change;
1398 : }
1399 :
1400 :
1401 : /* Eliminate hard reg given by its location LOC. */
1402 : void
1403 95795181 : lra_eliminate_reg_if_possible (rtx *loc)
1404 : {
1405 95795181 : int regno;
1406 95795181 : class lra_elim_table *ep;
1407 :
1408 95795181 : lra_assert (REG_P (*loc));
1409 95795181 : if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
1410 95795181 : || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno))
1411 : return;
1412 71132406 : if ((ep = get_elimination (*loc)) != NULL)
1413 67707988 : *loc = ep->to_rtx;
1414 : }
1415 :
1416 : /* Do (final if FINAL_P or first if FIRST_P) elimination in INSN. Add
1417 : the insn for subsequent processing in the constraint pass, update
1418 : the insn info. */
1419 : static void
1420 51170797 : process_insn_for_elimination (rtx_insn *insn, bool final_p, bool first_p)
1421 : {
1422 51170797 : eliminate_regs_in_insn (insn, final_p, first_p, 0);
1423 51170797 : if (! final_p)
1424 : {
1425 : /* Check that insn changed its code. This is a case when a move
1426 : insn becomes an add insn and we do not want to process the
1427 : insn as a move anymore. */
1428 28272199 : int icode = recog (PATTERN (insn), insn, 0);
1429 :
1430 28272199 : if (icode >= 0 && icode != INSN_CODE (insn))
1431 : {
1432 96740 : if (INSN_CODE (insn) >= 0)
1433 : /* Insn code is changed. It may change its operand type
1434 : from IN to INOUT. Inform the subsequent assignment
1435 : subpass about this situation. */
1436 96740 : check_and_force_assignment_correctness_p = true;
1437 96740 : INSN_CODE (insn) = icode;
1438 96740 : lra_update_insn_recog_data (insn);
1439 : }
1440 28272199 : lra_update_insn_regno_info (insn);
1441 28272199 : lra_push_insn (insn);
1442 28272199 : lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT);
1443 : }
1444 51170797 : }
1445 :
1446 : /* Update frame pointer to stack pointer elimination if we started with
1447 : permitted frame pointer elimination and now target reports that we can not
1448 : do this elimination anymore. Record spilled pseudos in SPILLED_PSEUDOS
1449 : unless it is null, and return the recorded pseudos number. */
1450 : int
1451 201322 : lra_update_fp2sp_elimination (int *spilled_pseudos)
1452 : {
1453 201322 : int n;
1454 201322 : HARD_REG_SET set;
1455 201322 : class lra_elim_table *ep;
1456 :
1457 201322 : if (frame_pointer_needed || !targetm.frame_pointer_required ())
1458 : return 0;
1459 0 : gcc_assert (!elimination_2sp_occurred_p);
1460 0 : ep = elimination_map[FRAME_POINTER_REGNUM];
1461 0 : if (ep->to == STACK_POINTER_REGNUM)
1462 : {
1463 : /* Prevent any further uses of fp, say in spill addresses, from being
1464 : eliminated to sp and affected by sp offsets. Alas, deactivating the
1465 : elimination altogether causes the next chosen fp elimination to miss
1466 : the offset propagation, so it may keep -1 as its prev_offset, and that
1467 : will make subsequent offsets incorrect. */
1468 0 : ep->to_rtx = ep->from_rtx;
1469 0 : setup_can_eliminate (ep, false);
1470 : }
1471 : else
1472 0 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1473 0 : if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
1474 0 : setup_can_eliminate (ep, false);
1475 0 : if (lra_dump_file != NULL)
1476 0 : fprintf (lra_dump_file,
1477 : " Frame pointer can not be eliminated anymore\n");
1478 0 : frame_pointer_needed = true;
1479 : /* If !lra_reg_spill_p, we likely have incomplete range information
1480 : for pseudos assigned to the frame pointer that will have to be
1481 : spilled, and so we may end up incorrectly sharing them unless we
1482 : get live range information for them. */
1483 0 : if (lra_complete_live_ranges ())
1484 : /* If lives ranges changed, update the aggregate live ranges in
1485 : slots as well before spilling any further pseudos. */
1486 0 : lra_recompute_slots_live_ranges ();
1487 0 : CLEAR_HARD_REG_SET (set);
1488 0 : add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM);
1489 0 : n = spill_pseudos (set, spilled_pseudos);
1490 0 : return n;
1491 : }
1492 :
1493 : /* Return true if we have a pseudo assigned to hard frame pointer. */
1494 : bool
1495 1746 : lra_fp_pseudo_p (void)
1496 : {
1497 1746 : HARD_REG_SET set;
1498 :
1499 1746 : if (frame_pointer_needed)
1500 : /* At this stage it means we have no pseudos assigned to FP: */
1501 : return false;
1502 1465 : CLEAR_HARD_REG_SET (set);
1503 1465 : add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM);
1504 141335 : for (int i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
1505 37990 : if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
1506 169159 : && overlaps_hard_reg_set_p (set, PSEUDO_REGNO_MODE (i),
1507 : reg_renumber[i]))
1508 : return true;
1509 : return false;
1510 : }
1511 :
1512 : /* Entry function to do final elimination if FINAL_P or to update
1513 : elimination register offsets (FIRST_P if we are doing it the first
1514 : time). */
1515 : void
1516 8313367 : lra_eliminate (bool final_p, bool first_p)
1517 : {
1518 8313367 : unsigned int uid;
1519 8313367 : bitmap_head insns_with_changed_offsets;
1520 8313367 : bitmap_iterator bi;
1521 8313367 : class lra_elim_table *ep;
1522 :
1523 8313367 : gcc_assert (! final_p || ! first_p);
1524 :
1525 8313367 : timevar_push (TV_LRA_ELIMINATE);
1526 :
1527 8313367 : if (first_p)
1528 : {
1529 1515121 : elimination_2sp_occurred_p = false;
1530 1515121 : init_elimination ();
1531 : }
1532 :
1533 8313367 : bitmap_initialize (&insns_with_changed_offsets, ®_obstack);
1534 8313367 : if (final_p)
1535 : {
1536 1515121 : if (flag_checking)
1537 : {
1538 1515101 : update_reg_eliminate (&insns_with_changed_offsets);
1539 1515101 : gcc_assert (bitmap_empty_p (&insns_with_changed_offsets));
1540 : }
1541 : /* We change eliminable hard registers in insns so we should do
1542 : this for all insns containing any eliminable hard
1543 : register. */
1544 7575605 : for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1545 6060484 : if (elimination_map[ep->from] != NULL)
1546 6060484 : bitmap_ior_into (&insns_with_changed_offsets,
1547 6060484 : &lra_reg_info[ep->from].insn_bitmap);
1548 : }
1549 6798246 : else if (! update_reg_eliminate (&insns_with_changed_offsets))
1550 5083970 : goto lra_eliminate_done;
1551 3229397 : if (lra_dump_file != NULL)
1552 : {
1553 194 : fprintf (lra_dump_file, "New elimination table:\n");
1554 194 : print_elim_table (lra_dump_file);
1555 : }
1556 54400194 : EXECUTE_IF_SET_IN_BITMAP (&insns_with_changed_offsets, 0, uid, bi)
1557 : /* A dead insn can be deleted in process_insn_for_elimination. */
1558 51170797 : if (lra_insn_recog_data[uid] != NULL)
1559 : {
1560 51170797 : rtx_insn *insn = lra_insn_recog_data[uid]->insn;
1561 51170797 : start_sequence ();
1562 51170797 : process_insn_for_elimination (insn, final_p, first_p);
1563 51170797 : rtx_insn *first = get_insns ();
1564 51170797 : end_sequence ();
1565 51170797 : if (first != NULL)
1566 : {
1567 0 : lra_assert (!final_p);
1568 0 : lra_process_new_insns (insn, first, NULL,
1569 : "Inserting elimination insn", true);
1570 : }
1571 : }
1572 3229397 : bitmap_clear (&insns_with_changed_offsets);
1573 :
1574 8313367 : lra_eliminate_done:
1575 8313367 : timevar_pop (TV_LRA_ELIMINATE);
1576 8313367 : }
|