2016-01-26 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / lra-eliminations.c
blob1494263c06f80a52b9ce42a644ec46ab06e9dd77
1 /* Code for RTL register eliminations.
2 Copyright (C) 2010-2016 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
5 This file is part of GCC.
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.
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.
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/>. */
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.
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.
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).
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:
50 fp + 42 => sp + 42
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 "tm_p.h"
63 #include "optabs.h"
64 #include "regs.h"
65 #include "ira.h"
66 #include "recog.h"
67 #include "output.h"
68 #include "rtl-error.h"
69 #include "lra-int.h"
71 /* This structure is used to record information about hard register
72 eliminations. */
73 struct lra_elim_table
75 /* Hard register number to be eliminated. */
76 int from;
77 /* Hard register number used as replacement. */
78 int to;
79 /* Difference between values of the two hard registers above on
80 previous iteration. */
81 HOST_WIDE_INT previous_offset;
82 /* Difference between the values on the current iteration. */
83 HOST_WIDE_INT offset;
84 /* Nonzero if this elimination can be done. */
85 bool can_eliminate;
86 /* CAN_ELIMINATE since the last check. */
87 bool prev_can_eliminate;
88 /* REG rtx for the register to be eliminated. We cannot simply
89 compare the number since we might then spuriously replace a hard
90 register corresponding to a pseudo assigned to the reg to be
91 eliminated. */
92 rtx from_rtx;
93 /* REG rtx for the replacement. */
94 rtx to_rtx;
97 /* The elimination table. Each array entry describes one possible way
98 of eliminating a register in favor of another. If there is more
99 than one way of eliminating a particular register, the most
100 preferred should be specified first. */
101 static struct lra_elim_table *reg_eliminate = 0;
103 /* This is an intermediate structure to initialize the table. It has
104 exactly the members provided by ELIMINABLE_REGS. */
105 static const struct elim_table_1
107 const int from;
108 const int to;
109 } reg_eliminate_1[] =
111 /* If a set of eliminable hard registers was specified, define the
112 table from it. Otherwise, default to the normal case of the frame
113 pointer being replaced by the stack pointer. */
115 #ifdef ELIMINABLE_REGS
116 ELIMINABLE_REGS;
117 #else
118 {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}};
119 #endif
121 #define NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1)
123 /* Print info about elimination table to file F. */
124 static void
125 print_elim_table (FILE *f)
127 struct lra_elim_table *ep;
129 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
130 fprintf (f, "%s eliminate %d to %d (offset=" HOST_WIDE_INT_PRINT_DEC
131 ", prev_offset=" HOST_WIDE_INT_PRINT_DEC ")\n",
132 ep->can_eliminate ? "Can" : "Can't",
133 ep->from, ep->to, ep->offset, ep->previous_offset);
136 /* Print info about elimination table to stderr. */
137 void
138 lra_debug_elim_table (void)
140 print_elim_table (stderr);
143 /* Setup possibility of elimination in elimination table element EP to
144 VALUE. Setup FRAME_POINTER_NEEDED if elimination from frame
145 pointer to stack pointer is not possible anymore. */
146 static void
147 setup_can_eliminate (struct lra_elim_table *ep, bool value)
149 ep->can_eliminate = ep->prev_can_eliminate = value;
150 if (! value
151 && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
152 frame_pointer_needed = 1;
153 if (!frame_pointer_needed)
154 REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0;
157 /* Map: eliminable "from" register -> its current elimination,
158 or NULL if none. The elimination table may contain more than
159 one elimination for the same hard register, but this map specifies
160 the one that we are currently using. */
161 static struct lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER];
163 /* When an eliminable hard register becomes not eliminable, we use the
164 following special structure to restore original offsets for the
165 register. */
166 static struct lra_elim_table self_elim_table;
168 /* Offsets should be used to restore original offsets for eliminable
169 hard register which just became not eliminable. Zero,
170 otherwise. */
171 static HOST_WIDE_INT self_elim_offsets[FIRST_PSEUDO_REGISTER];
173 /* Map: hard regno -> RTL presentation. RTL presentations of all
174 potentially eliminable hard registers are stored in the map. */
175 static rtx eliminable_reg_rtx[FIRST_PSEUDO_REGISTER];
177 /* Set up ELIMINATION_MAP of the currently used eliminations. */
178 static void
179 setup_elimination_map (void)
181 int i;
182 struct lra_elim_table *ep;
184 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
185 elimination_map[i] = NULL;
186 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
187 if (ep->can_eliminate && elimination_map[ep->from] == NULL)
188 elimination_map[ep->from] = ep;
193 /* Compute the sum of X and Y, making canonicalizations assumed in an
194 address, namely: sum constant integers, surround the sum of two
195 constants with a CONST, put the constant as the second operand, and
196 group the constant on the outermost sum.
198 This routine assumes both inputs are already in canonical form. */
199 static rtx
200 form_sum (rtx x, rtx y)
202 machine_mode mode = GET_MODE (x);
204 if (mode == VOIDmode)
205 mode = GET_MODE (y);
207 if (mode == VOIDmode)
208 mode = Pmode;
210 if (CONST_INT_P (x))
211 return plus_constant (mode, y, INTVAL (x));
212 else if (CONST_INT_P (y))
213 return plus_constant (mode, x, INTVAL (y));
214 else if (CONSTANT_P (x))
215 std::swap (x, y);
217 if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
218 return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
220 /* Note that if the operands of Y are specified in the opposite
221 order in the recursive calls below, infinite recursion will
222 occur. */
223 if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
224 return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
226 /* If both constant, encapsulate sum. Otherwise, just form sum. A
227 constant will have been placed second. */
228 if (CONSTANT_P (x) && CONSTANT_P (y))
230 if (GET_CODE (x) == CONST)
231 x = XEXP (x, 0);
232 if (GET_CODE (y) == CONST)
233 y = XEXP (y, 0);
235 return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y));
238 return gen_rtx_PLUS (mode, x, y);
241 /* Return the current substitution hard register of the elimination of
242 HARD_REGNO. If HARD_REGNO is not eliminable, return itself. */
244 lra_get_elimination_hard_regno (int hard_regno)
246 struct lra_elim_table *ep;
248 if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
249 return hard_regno;
250 if ((ep = elimination_map[hard_regno]) == NULL)
251 return hard_regno;
252 return ep->to;
255 /* Return elimination which will be used for hard reg REG, NULL
256 otherwise. */
257 static struct lra_elim_table *
258 get_elimination (rtx reg)
260 int hard_regno;
261 struct lra_elim_table *ep;
262 HOST_WIDE_INT offset;
264 lra_assert (REG_P (reg));
265 if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
266 return NULL;
267 if ((ep = elimination_map[hard_regno]) != NULL)
268 return ep->from_rtx != reg ? NULL : ep;
269 if ((offset = self_elim_offsets[hard_regno]) == 0)
270 return NULL;
271 /* This is an iteration to restore offsets just after HARD_REGNO
272 stopped to be eliminable. */
273 self_elim_table.from = self_elim_table.to = hard_regno;
274 self_elim_table.from_rtx
275 = self_elim_table.to_rtx
276 = eliminable_reg_rtx[hard_regno];
277 lra_assert (self_elim_table.from_rtx != NULL);
278 self_elim_table.offset = offset;
279 return &self_elim_table;
282 /* Transform (subreg (plus reg const)) to (plus (subreg reg) const)
283 when it is possible. Return X or the transformation result if the
284 transformation is done. */
285 static rtx
286 move_plus_up (rtx x)
288 rtx subreg_reg;
289 enum machine_mode x_mode, subreg_reg_mode;
291 if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x))
292 return x;
293 subreg_reg = SUBREG_REG (x);
294 x_mode = GET_MODE (x);
295 subreg_reg_mode = GET_MODE (subreg_reg);
296 if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS
297 && GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode)
298 && CONSTANT_P (XEXP (subreg_reg, 1))
299 && GET_MODE_CLASS (x_mode) == MODE_INT
300 && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT)
302 rtx cst = simplify_subreg (x_mode, XEXP (subreg_reg, 1), subreg_reg_mode,
303 subreg_lowpart_offset (x_mode,
304 subreg_reg_mode));
305 if (cst && CONSTANT_P (cst))
306 return gen_rtx_PLUS (x_mode, lowpart_subreg (x_mode, subreg_reg,
307 subreg_reg_mode), cst);
309 return x;
312 /* Scan X and replace any eliminable registers (such as fp) with a
313 replacement (such as sp) if SUBST_P, plus an offset. The offset is
314 a change in the offset between the eliminable register and its
315 substitution if UPDATE_P, or the full offset if FULL_P, or
316 otherwise zero. If FULL_P, we also use the SP offsets for
317 elimination to SP. If UPDATE_P, use UPDATE_SP_OFFSET for updating
318 offsets of register elimnable to SP. If UPDATE_SP_OFFSET is
319 non-zero, don't use difference of the offset and the previous
320 offset.
322 MEM_MODE is the mode of an enclosing MEM. We need this to know how
323 much to adjust a register for, e.g., PRE_DEC. Also, if we are
324 inside a MEM, we are allowed to replace a sum of a hard register
325 and the constant zero with the hard register, which we cannot do
326 outside a MEM. In addition, we need to record the fact that a
327 hard register is referenced outside a MEM.
329 If we make full substitution to SP for non-null INSN, add the insn
330 sp offset. */
332 lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
333 bool subst_p, bool update_p,
334 HOST_WIDE_INT update_sp_offset, bool full_p)
336 enum rtx_code code = GET_CODE (x);
337 struct lra_elim_table *ep;
338 rtx new_rtx;
339 int i, j;
340 const char *fmt;
341 int copied = 0;
343 lra_assert (!update_p || !full_p);
344 lra_assert (update_sp_offset == 0 || (!subst_p && update_p && !full_p));
345 if (! current_function_decl)
346 return x;
348 switch (code)
350 CASE_CONST_ANY:
351 case CONST:
352 case SYMBOL_REF:
353 case CODE_LABEL:
354 case PC:
355 case CC0:
356 case ASM_INPUT:
357 case ADDR_VEC:
358 case ADDR_DIFF_VEC:
359 case RETURN:
360 return x;
362 case REG:
363 /* First handle the case where we encounter a bare hard register
364 that is eliminable. Replace it with a PLUS. */
365 if ((ep = get_elimination (x)) != NULL)
367 rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
369 if (update_sp_offset != 0)
371 if (ep->to_rtx == stack_pointer_rtx)
372 return plus_constant (Pmode, to, update_sp_offset);
373 return to;
375 else if (update_p)
376 return plus_constant (Pmode, to, ep->offset - ep->previous_offset);
377 else if (full_p)
378 return plus_constant (Pmode, to,
379 ep->offset
380 - (insn != NULL_RTX
381 && ep->to_rtx == stack_pointer_rtx
382 ? lra_get_insn_recog_data (insn)->sp_offset
383 : 0));
384 else
385 return to;
387 return x;
389 case PLUS:
390 /* If this is the sum of an eliminable register and a constant, rework
391 the sum. */
392 if (REG_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
394 if ((ep = get_elimination (XEXP (x, 0))) != NULL)
396 HOST_WIDE_INT offset;
397 rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
399 if (! update_p && ! full_p)
400 return gen_rtx_PLUS (Pmode, to, XEXP (x, 1));
402 if (update_sp_offset != 0)
403 offset = ep->to_rtx == stack_pointer_rtx ? update_sp_offset : 0;
404 else
405 offset = (update_p
406 ? ep->offset - ep->previous_offset : ep->offset);
407 if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
408 offset -= lra_get_insn_recog_data (insn)->sp_offset;
409 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == -offset)
410 return to;
411 else
412 return gen_rtx_PLUS (Pmode, to,
413 plus_constant (Pmode,
414 XEXP (x, 1), offset));
417 /* If the hard register is not eliminable, we are done since
418 the other operand is a constant. */
419 return x;
422 /* If this is part of an address, we want to bring any constant
423 to the outermost PLUS. We will do this by doing hard
424 register replacement in our operands and seeing if a constant
425 shows up in one of them.
427 Note that there is no risk of modifying the structure of the
428 insn, since we only get called for its operands, thus we are
429 either modifying the address inside a MEM, or something like
430 an address operand of a load-address insn. */
433 rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
434 subst_p, update_p,
435 update_sp_offset, full_p);
436 rtx new1 = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
437 subst_p, update_p,
438 update_sp_offset, full_p);
440 new0 = move_plus_up (new0);
441 new1 = move_plus_up (new1);
442 if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
443 return form_sum (new0, new1);
445 return x;
447 case MULT:
448 /* If this is the product of an eliminable hard register and a
449 constant, apply the distribute law and move the constant out
450 so that we have (plus (mult ..) ..). This is needed in order
451 to keep load-address insns valid. This case is pathological.
452 We ignore the possibility of overflow here. */
453 if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1))
454 && (ep = get_elimination (XEXP (x, 0))) != NULL)
456 rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
458 if (update_sp_offset != 0)
460 if (ep->to_rtx == stack_pointer_rtx)
461 return plus_constant (Pmode,
462 gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
463 update_sp_offset * INTVAL (XEXP (x, 1)));
464 return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
466 else if (update_p)
467 return plus_constant (Pmode,
468 gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
469 (ep->offset - ep->previous_offset)
470 * INTVAL (XEXP (x, 1)));
471 else if (full_p)
473 HOST_WIDE_INT offset = ep->offset;
475 if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
476 offset -= lra_get_insn_recog_data (insn)->sp_offset;
477 return
478 plus_constant (Pmode,
479 gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
480 offset * INTVAL (XEXP (x, 1)));
482 else
483 return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
486 /* ... fall through ... */
488 case CALL:
489 case COMPARE:
490 /* See comments before PLUS about handling MINUS. */
491 case MINUS:
492 case DIV: case UDIV:
493 case MOD: case UMOD:
494 case AND: case IOR: case XOR:
495 case ROTATERT: case ROTATE:
496 case ASHIFTRT: case LSHIFTRT: case ASHIFT:
497 case NE: case EQ:
498 case GE: case GT: case GEU: case GTU:
499 case LE: case LT: case LEU: case LTU:
501 rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
502 subst_p, update_p,
503 update_sp_offset, full_p);
504 rtx new1 = XEXP (x, 1)
505 ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
506 subst_p, update_p,
507 update_sp_offset, full_p) : 0;
509 if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
510 return gen_rtx_fmt_ee (code, GET_MODE (x), new0, new1);
512 return x;
514 case EXPR_LIST:
515 /* If we have something in XEXP (x, 0), the usual case,
516 eliminate it. */
517 if (XEXP (x, 0))
519 new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
520 subst_p, update_p,
521 update_sp_offset, full_p);
522 if (new_rtx != XEXP (x, 0))
524 /* If this is a REG_DEAD note, it is not valid anymore.
525 Using the eliminated version could result in creating a
526 REG_DEAD note for the stack or frame pointer. */
527 if (REG_NOTE_KIND (x) == REG_DEAD)
528 return (XEXP (x, 1)
529 ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
530 subst_p, update_p,
531 update_sp_offset, full_p)
532 : NULL_RTX);
534 x = alloc_reg_note (REG_NOTE_KIND (x), new_rtx, XEXP (x, 1));
538 /* ... fall through ... */
540 case INSN_LIST:
541 case INT_LIST:
542 /* Now do eliminations in the rest of the chain. If this was
543 an EXPR_LIST, this might result in allocating more memory than is
544 strictly needed, but it simplifies the code. */
545 if (XEXP (x, 1))
547 new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
548 subst_p, update_p,
549 update_sp_offset, full_p);
550 if (new_rtx != XEXP (x, 1))
551 return
552 gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x),
553 XEXP (x, 0), new_rtx);
555 return x;
557 case PRE_INC:
558 case POST_INC:
559 case PRE_DEC:
560 case POST_DEC:
561 /* We do not support elimination of a register that is modified.
562 elimination_effects has already make sure that this does not
563 happen. */
564 return x;
566 case PRE_MODIFY:
567 case POST_MODIFY:
568 /* We do not support elimination of a hard register that is
569 modified. LRA has already make sure that this does not
570 happen. The only remaining case we need to consider here is
571 that the increment value may be an eliminable register. */
572 if (GET_CODE (XEXP (x, 1)) == PLUS
573 && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
575 rtx new_rtx = lra_eliminate_regs_1 (insn, XEXP (XEXP (x, 1), 1),
576 mem_mode, subst_p, update_p,
577 update_sp_offset, full_p);
579 if (new_rtx != XEXP (XEXP (x, 1), 1))
580 return gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (x, 0),
581 gen_rtx_PLUS (GET_MODE (x),
582 XEXP (x, 0), new_rtx));
584 return x;
586 case STRICT_LOW_PART:
587 case NEG: case NOT:
588 case SIGN_EXTEND: case ZERO_EXTEND:
589 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE:
590 case FLOAT: case FIX:
591 case UNSIGNED_FIX: case UNSIGNED_FLOAT:
592 case ABS:
593 case SQRT:
594 case FFS:
595 case CLZ:
596 case CTZ:
597 case POPCOUNT:
598 case PARITY:
599 case BSWAP:
600 new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
601 subst_p, update_p,
602 update_sp_offset, full_p);
603 if (new_rtx != XEXP (x, 0))
604 return gen_rtx_fmt_e (code, GET_MODE (x), new_rtx);
605 return x;
607 case SUBREG:
608 new_rtx = lra_eliminate_regs_1 (insn, SUBREG_REG (x), mem_mode,
609 subst_p, update_p,
610 update_sp_offset, full_p);
612 if (new_rtx != SUBREG_REG (x))
614 int x_size = GET_MODE_SIZE (GET_MODE (x));
615 int new_size = GET_MODE_SIZE (GET_MODE (new_rtx));
617 if (MEM_P (new_rtx) && x_size <= new_size)
619 SUBREG_REG (x) = new_rtx;
620 alter_subreg (&x, false);
621 return x;
623 else if (! subst_p)
625 /* LRA can transform subregs itself. So don't call
626 simplify_gen_subreg until LRA transformations are
627 finished. Function simplify_gen_subreg can do
628 non-trivial transformations (like truncation) which
629 might make LRA work to fail. */
630 SUBREG_REG (x) = new_rtx;
631 return x;
633 else
634 return simplify_gen_subreg (GET_MODE (x), new_rtx,
635 GET_MODE (new_rtx), SUBREG_BYTE (x));
638 return x;
640 case MEM:
641 /* Our only special processing is to pass the mode of the MEM to our
642 recursive call and copy the flags. While we are here, handle this
643 case more efficiently. */
644 return
645 replace_equiv_address_nv
647 lra_eliminate_regs_1 (insn, XEXP (x, 0), GET_MODE (x),
648 subst_p, update_p, update_sp_offset, full_p));
650 case USE:
651 /* Handle insn_list USE that a call to a pure function may generate. */
652 new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), VOIDmode,
653 subst_p, update_p, update_sp_offset, full_p);
654 if (new_rtx != XEXP (x, 0))
655 return gen_rtx_USE (GET_MODE (x), new_rtx);
656 return x;
658 case CLOBBER:
659 case SET:
660 gcc_unreachable ();
662 default:
663 break;
666 /* Process each of our operands recursively. If any have changed, make a
667 copy of the rtx. */
668 fmt = GET_RTX_FORMAT (code);
669 for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
671 if (*fmt == 'e')
673 new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, i), mem_mode,
674 subst_p, update_p,
675 update_sp_offset, full_p);
676 if (new_rtx != XEXP (x, i) && ! copied)
678 x = shallow_copy_rtx (x);
679 copied = 1;
681 XEXP (x, i) = new_rtx;
683 else if (*fmt == 'E')
685 int copied_vec = 0;
686 for (j = 0; j < XVECLEN (x, i); j++)
688 new_rtx = lra_eliminate_regs_1 (insn, XVECEXP (x, i, j), mem_mode,
689 subst_p, update_p,
690 update_sp_offset, full_p);
691 if (new_rtx != XVECEXP (x, i, j) && ! copied_vec)
693 rtvec new_v = gen_rtvec_v (XVECLEN (x, i),
694 XVEC (x, i)->elem);
695 if (! copied)
697 x = shallow_copy_rtx (x);
698 copied = 1;
700 XVEC (x, i) = new_v;
701 copied_vec = 1;
703 XVECEXP (x, i, j) = new_rtx;
708 return x;
711 /* This function is used externally in subsequent passes of GCC. It
712 always does a full elimination of X. */
714 lra_eliminate_regs (rtx x, machine_mode mem_mode,
715 rtx insn ATTRIBUTE_UNUSED)
717 return lra_eliminate_regs_1 (NULL, x, mem_mode, true, false, 0, true);
720 /* Stack pointer offset before the current insn relative to one at the
721 func start. RTL insns can change SP explicitly. We keep the
722 changes from one insn to another through this variable. */
723 static HOST_WIDE_INT curr_sp_change;
725 /* Scan rtx X for references to elimination source or target registers
726 in contexts that would prevent the elimination from happening.
727 Update the table of eliminables to reflect the changed state.
728 MEM_MODE is the mode of an enclosing MEM rtx, or VOIDmode if not
729 within a MEM. */
730 static void
731 mark_not_eliminable (rtx x, machine_mode mem_mode)
733 enum rtx_code code = GET_CODE (x);
734 struct lra_elim_table *ep;
735 int i, j;
736 const char *fmt;
738 switch (code)
740 case PRE_INC:
741 case POST_INC:
742 case PRE_DEC:
743 case POST_DEC:
744 case POST_MODIFY:
745 case PRE_MODIFY:
746 if (XEXP (x, 0) == stack_pointer_rtx
747 && ((code != PRE_MODIFY && code != POST_MODIFY)
748 || (GET_CODE (XEXP (x, 1)) == PLUS
749 && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
750 && CONST_INT_P (XEXP (XEXP (x, 1), 1)))))
752 int size = GET_MODE_SIZE (mem_mode);
754 #ifdef PUSH_ROUNDING
755 /* If more bytes than MEM_MODE are pushed, account for
756 them. */
757 size = PUSH_ROUNDING (size);
758 #endif
759 if (code == PRE_DEC || code == POST_DEC)
760 curr_sp_change -= size;
761 else if (code == PRE_INC || code == POST_INC)
762 curr_sp_change += size;
763 else if (code == PRE_MODIFY || code == POST_MODIFY)
764 curr_sp_change += INTVAL (XEXP (XEXP (x, 1), 1));
766 else if (REG_P (XEXP (x, 0))
767 && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER)
769 /* If we modify the source of an elimination rule, disable
770 it. Do the same if it is the destination and not the
771 hard frame register. */
772 for (ep = reg_eliminate;
773 ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
774 ep++)
775 if (ep->from_rtx == XEXP (x, 0)
776 || (ep->to_rtx == XEXP (x, 0)
777 && ep->to_rtx != hard_frame_pointer_rtx))
778 setup_can_eliminate (ep, false);
780 return;
782 case USE:
783 if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
784 /* If using a hard register that is the source of an eliminate
785 we still think can be performed, note it cannot be
786 performed since we don't know how this hard register is
787 used. */
788 for (ep = reg_eliminate;
789 ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
790 ep++)
791 if (ep->from_rtx == XEXP (x, 0)
792 && ep->to_rtx != hard_frame_pointer_rtx)
793 setup_can_eliminate (ep, false);
794 return;
796 case CLOBBER:
797 if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
798 /* If clobbering a hard register that is the replacement
799 register for an elimination we still think can be
800 performed, note that it cannot be performed. Otherwise, we
801 need not be concerned about it. */
802 for (ep = reg_eliminate;
803 ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
804 ep++)
805 if (ep->to_rtx == XEXP (x, 0)
806 && ep->to_rtx != hard_frame_pointer_rtx)
807 setup_can_eliminate (ep, false);
808 return;
810 case SET:
811 if (SET_DEST (x) == stack_pointer_rtx
812 && GET_CODE (SET_SRC (x)) == PLUS
813 && XEXP (SET_SRC (x), 0) == SET_DEST (x)
814 && CONST_INT_P (XEXP (SET_SRC (x), 1)))
816 curr_sp_change += INTVAL (XEXP (SET_SRC (x), 1));
817 return;
819 if (! REG_P (SET_DEST (x))
820 || REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER)
821 mark_not_eliminable (SET_DEST (x), mem_mode);
822 else
824 /* See if this is setting the replacement hard register for
825 an elimination.
827 If DEST is the hard frame pointer, we do nothing because
828 we assume that all assignments to the frame pointer are
829 for non-local gotos and are being done at a time when
830 they are valid and do not disturb anything else. Some
831 machines want to eliminate a fake argument pointer (or
832 even a fake frame pointer) with either the real frame
833 pointer or the stack pointer. Assignments to the hard
834 frame pointer must not prevent this elimination. */
835 for (ep = reg_eliminate;
836 ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
837 ep++)
838 if (ep->to_rtx == SET_DEST (x)
839 && SET_DEST (x) != hard_frame_pointer_rtx)
840 setup_can_eliminate (ep, false);
843 mark_not_eliminable (SET_SRC (x), mem_mode);
844 return;
846 case MEM:
847 /* Our only special processing is to pass the mode of the MEM to
848 our recursive call. */
849 mark_not_eliminable (XEXP (x, 0), GET_MODE (x));
850 return;
852 default:
853 break;
856 fmt = GET_RTX_FORMAT (code);
857 for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
859 if (*fmt == 'e')
860 mark_not_eliminable (XEXP (x, i), mem_mode);
861 else if (*fmt == 'E')
862 for (j = 0; j < XVECLEN (x, i); j++)
863 mark_not_eliminable (XVECEXP (x, i, j), mem_mode);
869 #ifdef HARD_FRAME_POINTER_REGNUM
871 /* Find offset equivalence note for reg WHAT in INSN and return the
872 found elmination offset. If the note is not found, return NULL.
873 Remove the found note. */
874 static rtx
875 remove_reg_equal_offset_note (rtx_insn *insn, rtx what)
877 rtx link, *link_loc;
879 for (link_loc = &REG_NOTES (insn);
880 (link = *link_loc) != NULL_RTX;
881 link_loc = &XEXP (link, 1))
882 if (REG_NOTE_KIND (link) == REG_EQUAL
883 && GET_CODE (XEXP (link, 0)) == PLUS
884 && XEXP (XEXP (link, 0), 0) == what
885 && CONST_INT_P (XEXP (XEXP (link, 0), 1)))
887 *link_loc = XEXP (link, 1);
888 return XEXP (XEXP (link, 0), 1);
890 return NULL_RTX;
893 #endif
895 /* Scan INSN and eliminate all eliminable hard registers in it.
897 If REPLACE_P is true, do the replacement destructively. Also
898 delete the insn as dead it if it is setting an eliminable register.
900 If REPLACE_P is false, just update the offsets while keeping the
901 base register the same. If FIRST_P, use the sp offset for
902 elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this. If
903 UPDATE_SP_OFFSET is non-zero, don't use difference of the offset
904 and the previous offset. Attach the note about used elimination
905 for insns setting frame pointer to update elimination easy (without
906 parsing already generated elimination insns to find offset
907 previously used) in future. */
909 void
910 eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
911 HOST_WIDE_INT update_sp_offset)
913 int icode = recog_memoized (insn);
914 rtx old_set = single_set (insn);
915 bool validate_p;
916 int i;
917 rtx substed_operand[MAX_RECOG_OPERANDS];
918 rtx orig_operand[MAX_RECOG_OPERANDS];
919 struct lra_elim_table *ep;
920 rtx plus_src, plus_cst_src;
921 lra_insn_recog_data_t id;
922 struct lra_static_insn_data *static_id;
924 if (icode < 0 && asm_noperands (PATTERN (insn)) < 0 && ! DEBUG_INSN_P (insn))
926 lra_assert (GET_CODE (PATTERN (insn)) == USE
927 || GET_CODE (PATTERN (insn)) == CLOBBER
928 || GET_CODE (PATTERN (insn)) == ASM_INPUT);
929 return;
932 /* Check for setting an eliminable register. */
933 if (old_set != 0 && REG_P (SET_DEST (old_set))
934 && (ep = get_elimination (SET_DEST (old_set))) != NULL)
936 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
937 if (ep->from_rtx == SET_DEST (old_set) && ep->can_eliminate)
939 bool delete_p = replace_p;
941 #ifdef HARD_FRAME_POINTER_REGNUM
942 if (ep->from == FRAME_POINTER_REGNUM
943 && ep->to == HARD_FRAME_POINTER_REGNUM)
944 /* If this is setting the frame pointer register to the
945 hardware frame pointer register and this is an
946 elimination that will be done (tested above), this
947 insn is really adjusting the frame pointer downward
948 to compensate for the adjustment done before a
949 nonlocal goto. */
951 rtx src = SET_SRC (old_set);
952 rtx off = remove_reg_equal_offset_note (insn, ep->to_rtx);
954 /* We should never process such insn with non-zero
955 UPDATE_SP_OFFSET. */
956 lra_assert (update_sp_offset == 0);
958 if (off != NULL_RTX
959 || src == ep->to_rtx
960 || (GET_CODE (src) == PLUS
961 && XEXP (src, 0) == ep->to_rtx
962 && CONST_INT_P (XEXP (src, 1))))
964 HOST_WIDE_INT offset;
966 if (replace_p)
968 SET_DEST (old_set) = ep->to_rtx;
969 lra_update_insn_recog_data (insn);
970 return;
972 offset = (off != NULL_RTX ? INTVAL (off)
973 : src == ep->to_rtx ? 0 : INTVAL (XEXP (src, 1)));
974 offset -= (ep->offset - ep->previous_offset);
975 src = plus_constant (Pmode, ep->to_rtx, offset);
977 /* First see if this insn remains valid when we
978 make the change. If not, keep the INSN_CODE
979 the same and let the constraint pass fit it
980 up. */
981 validate_change (insn, &SET_SRC (old_set), src, 1);
982 validate_change (insn, &SET_DEST (old_set),
983 ep->from_rtx, 1);
984 if (! apply_change_group ())
986 SET_SRC (old_set) = src;
987 SET_DEST (old_set) = ep->from_rtx;
989 lra_update_insn_recog_data (insn);
990 /* Add offset note for future updates. */
991 add_reg_note (insn, REG_EQUAL, src);
992 return;
995 #endif
997 /* This insn isn't serving a useful purpose. We delete it
998 when REPLACE is set. */
999 if (delete_p)
1000 lra_delete_dead_insn (insn);
1001 return;
1005 /* We allow one special case which happens to work on all machines we
1006 currently support: a single set with the source or a REG_EQUAL
1007 note being a PLUS of an eliminable register and a constant. */
1008 plus_src = plus_cst_src = 0;
1009 if (old_set && REG_P (SET_DEST (old_set)))
1011 if (GET_CODE (SET_SRC (old_set)) == PLUS)
1012 plus_src = SET_SRC (old_set);
1013 /* First see if the source is of the form (plus (...) CST). */
1014 if (plus_src
1015 && CONST_INT_P (XEXP (plus_src, 1)))
1016 plus_cst_src = plus_src;
1017 /* Check that the first operand of the PLUS is a hard reg or
1018 the lowpart subreg of one. */
1019 if (plus_cst_src)
1021 rtx reg = XEXP (plus_cst_src, 0);
1023 if (GET_CODE (reg) == SUBREG && subreg_lowpart_p (reg))
1024 reg = SUBREG_REG (reg);
1026 if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
1027 plus_cst_src = 0;
1030 if (plus_cst_src)
1032 rtx reg = XEXP (plus_cst_src, 0);
1033 HOST_WIDE_INT offset = INTVAL (XEXP (plus_cst_src, 1));
1035 if (GET_CODE (reg) == SUBREG)
1036 reg = SUBREG_REG (reg);
1038 if (REG_P (reg) && (ep = get_elimination (reg)) != NULL)
1040 rtx to_rtx = replace_p ? ep->to_rtx : ep->from_rtx;
1042 if (! replace_p)
1044 if (update_sp_offset == 0)
1045 offset += (ep->offset - ep->previous_offset);
1046 if (ep->to_rtx == stack_pointer_rtx)
1048 if (first_p)
1049 offset -= lra_get_insn_recog_data (insn)->sp_offset;
1050 else
1051 offset += update_sp_offset;
1053 offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src));
1056 if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG)
1057 to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)), to_rtx);
1058 /* If we have a nonzero offset, and the source is already a
1059 simple REG, the following transformation would increase
1060 the cost of the insn by replacing a simple REG with (plus
1061 (reg sp) CST). So try only when we already had a PLUS
1062 before. */
1063 if (offset == 0 || plus_src)
1065 rtx new_src = plus_constant (GET_MODE (to_rtx), to_rtx, offset);
1067 old_set = single_set (insn);
1069 /* First see if this insn remains valid when we make the
1070 change. If not, try to replace the whole pattern
1071 with a simple set (this may help if the original insn
1072 was a PARALLEL that was only recognized as single_set
1073 due to REG_UNUSED notes). If this isn't valid
1074 either, keep the INSN_CODE the same and let the
1075 constraint pass fix it up. */
1076 if (! validate_change (insn, &SET_SRC (old_set), new_src, 0))
1078 rtx new_pat = gen_rtx_SET (SET_DEST (old_set), new_src);
1080 if (! validate_change (insn, &PATTERN (insn), new_pat, 0))
1081 SET_SRC (old_set) = new_src;
1083 lra_update_insn_recog_data (insn);
1084 /* This can't have an effect on elimination offsets, so skip
1085 right to the end. */
1086 return;
1091 /* Eliminate all eliminable registers occurring in operands that
1092 can be handled by the constraint pass. */
1093 id = lra_get_insn_recog_data (insn);
1094 static_id = id->insn_static_data;
1095 validate_p = false;
1096 for (i = 0; i < static_id->n_operands; i++)
1098 orig_operand[i] = *id->operand_loc[i];
1099 substed_operand[i] = *id->operand_loc[i];
1101 /* For an asm statement, every operand is eliminable. */
1102 if (icode < 0 || insn_data[icode].operand[i].eliminable)
1104 /* Check for setting a hard register that we know about. */
1105 if (static_id->operand[i].type != OP_IN
1106 && REG_P (orig_operand[i]))
1108 /* If we are assigning to a hard register that can be
1109 eliminated, it must be as part of a PARALLEL, since
1110 the code above handles single SETs. This reg can not
1111 be longer eliminated -- it is forced by
1112 mark_not_eliminable. */
1113 for (ep = reg_eliminate;
1114 ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
1115 ep++)
1116 lra_assert (ep->from_rtx != orig_operand[i]
1117 || ! ep->can_eliminate);
1120 /* Companion to the above plus substitution, we can allow
1121 invariants as the source of a plain move. */
1122 substed_operand[i]
1123 = lra_eliminate_regs_1 (insn, *id->operand_loc[i], VOIDmode,
1124 replace_p, ! replace_p && ! first_p,
1125 update_sp_offset, first_p);
1126 if (substed_operand[i] != orig_operand[i])
1127 validate_p = true;
1131 if (! validate_p)
1132 return;
1134 /* Substitute the operands; the new values are in the substed_operand
1135 array. */
1136 for (i = 0; i < static_id->n_operands; i++)
1137 *id->operand_loc[i] = substed_operand[i];
1138 for (i = 0; i < static_id->n_dups; i++)
1139 *id->dup_loc[i] = substed_operand[(int) static_id->dup_num[i]];
1141 /* If we had a move insn but now we don't, re-recognize it.
1142 This will cause spurious re-recognition if the old move had a
1143 PARALLEL since the new one still will, but we can't call
1144 single_set without having put new body into the insn and the
1145 re-recognition won't hurt in this rare case. */
1146 id = lra_update_insn_recog_data (insn);
1147 static_id = id->insn_static_data;
1150 /* Spill pseudos which are assigned to hard registers in SET. Add
1151 affected insns for processing in the subsequent constraint
1152 pass. */
1153 static void
1154 spill_pseudos (HARD_REG_SET set)
1156 int i;
1157 bitmap_head to_process;
1158 rtx_insn *insn;
1160 if (hard_reg_set_empty_p (set))
1161 return;
1162 if (lra_dump_file != NULL)
1164 fprintf (lra_dump_file, " Spilling non-eliminable hard regs:");
1165 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1166 if (TEST_HARD_REG_BIT (set, i))
1167 fprintf (lra_dump_file, " %d", i);
1168 fprintf (lra_dump_file, "\n");
1170 bitmap_initialize (&to_process, &reg_obstack);
1171 for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
1172 if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
1173 && overlaps_hard_reg_set_p (set,
1174 PSEUDO_REGNO_MODE (i), reg_renumber[i]))
1176 if (lra_dump_file != NULL)
1177 fprintf (lra_dump_file, " Spilling r%d(%d)\n",
1178 i, reg_renumber[i]);
1179 reg_renumber[i] = -1;
1180 bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap);
1182 IOR_HARD_REG_SET (lra_no_alloc_regs, set);
1183 for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
1184 if (bitmap_bit_p (&to_process, INSN_UID (insn)))
1186 lra_push_insn (insn);
1187 lra_set_used_insn_alternative (insn, -1);
1189 bitmap_clear (&to_process);
1192 /* Update all offsets and possibility for elimination on eliminable
1193 registers. Spill pseudos assigned to registers which are
1194 uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET. Add
1195 insns to INSNS_WITH_CHANGED_OFFSETS containing eliminable hard
1196 registers whose offsets should be changed. Return true if any
1197 elimination offset changed. */
1198 static bool
1199 update_reg_eliminate (bitmap insns_with_changed_offsets)
1201 bool prev, result;
1202 struct lra_elim_table *ep, *ep1;
1203 HARD_REG_SET temp_hard_reg_set;
1205 /* Clear self elimination offsets. */
1206 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1207 self_elim_offsets[ep->from] = 0;
1208 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1210 /* If it is a currently used elimination: update the previous
1211 offset. */
1212 if (elimination_map[ep->from] == ep)
1213 ep->previous_offset = ep->offset;
1215 prev = ep->prev_can_eliminate;
1216 setup_can_eliminate (ep, targetm.can_eliminate (ep->from, ep->to));
1217 if (ep->can_eliminate && ! prev)
1219 /* It is possible that not eliminable register becomes
1220 eliminable because we took other reasons into account to
1221 set up eliminable regs in the initial set up. Just
1222 ignore new eliminable registers. */
1223 setup_can_eliminate (ep, false);
1224 continue;
1226 if (ep->can_eliminate != prev && elimination_map[ep->from] == ep)
1228 /* We cannot use this elimination anymore -- find another
1229 one. */
1230 if (lra_dump_file != NULL)
1231 fprintf (lra_dump_file,
1232 " Elimination %d to %d is not possible anymore\n",
1233 ep->from, ep->to);
1234 /* If after processing RTL we decides that SP can be used as
1235 a result of elimination, it can not be changed. */
1236 gcc_assert ((ep->to_rtx != stack_pointer_rtx)
1237 || (ep->from < FIRST_PSEUDO_REGISTER
1238 && fixed_regs [ep->from]));
1239 /* Mark that is not eliminable anymore. */
1240 elimination_map[ep->from] = NULL;
1241 for (ep1 = ep + 1; ep1 < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep1++)
1242 if (ep1->can_eliminate && ep1->from == ep->from)
1243 break;
1244 if (ep1 < &reg_eliminate[NUM_ELIMINABLE_REGS])
1246 if (lra_dump_file != NULL)
1247 fprintf (lra_dump_file, " Using elimination %d to %d now\n",
1248 ep1->from, ep1->to);
1249 lra_assert (ep1->previous_offset == 0);
1250 ep1->previous_offset = ep->offset;
1252 else
1254 /* There is no elimination anymore just use the hard
1255 register `from' itself. Setup self elimination
1256 offset to restore the original offset values. */
1257 if (lra_dump_file != NULL)
1258 fprintf (lra_dump_file, " %d is not eliminable at all\n",
1259 ep->from);
1260 self_elim_offsets[ep->from] = -ep->offset;
1261 if (ep->offset != 0)
1262 bitmap_ior_into (insns_with_changed_offsets,
1263 &lra_reg_info[ep->from].insn_bitmap);
1267 #ifdef ELIMINABLE_REGS
1268 INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->offset);
1269 #else
1270 INITIAL_FRAME_POINTER_OFFSET (ep->offset);
1271 #endif
1273 setup_elimination_map ();
1274 result = false;
1275 CLEAR_HARD_REG_SET (temp_hard_reg_set);
1276 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1277 if (elimination_map[ep->from] == NULL)
1278 SET_HARD_REG_BIT (temp_hard_reg_set, ep->from);
1279 else if (elimination_map[ep->from] == ep)
1281 /* Prevent the hard register into which we eliminate from
1282 the usage for pseudos. */
1283 if (ep->from != ep->to)
1284 SET_HARD_REG_BIT (temp_hard_reg_set, ep->to);
1285 if (ep->previous_offset != ep->offset)
1287 bitmap_ior_into (insns_with_changed_offsets,
1288 &lra_reg_info[ep->from].insn_bitmap);
1290 /* Update offset when the eliminate offset have been
1291 changed. */
1292 lra_update_reg_val_offset (lra_reg_info[ep->from].val,
1293 ep->offset - ep->previous_offset);
1294 result = true;
1297 IOR_HARD_REG_SET (lra_no_alloc_regs, temp_hard_reg_set);
1298 AND_COMPL_HARD_REG_SET (eliminable_regset, temp_hard_reg_set);
1299 spill_pseudos (temp_hard_reg_set);
1300 return result;
1303 /* Initialize the table of hard registers to eliminate.
1304 Pre-condition: global flag frame_pointer_needed has been set before
1305 calling this function. */
1306 static void
1307 init_elim_table (void)
1309 struct lra_elim_table *ep;
1310 #ifdef ELIMINABLE_REGS
1311 bool value_p;
1312 const struct elim_table_1 *ep1;
1313 #endif
1315 if (!reg_eliminate)
1316 reg_eliminate = XCNEWVEC (struct lra_elim_table, NUM_ELIMINABLE_REGS);
1318 memset (self_elim_offsets, 0, sizeof (self_elim_offsets));
1319 /* Initiate member values which will be never changed. */
1320 self_elim_table.can_eliminate = self_elim_table.prev_can_eliminate = true;
1321 self_elim_table.previous_offset = 0;
1322 #ifdef ELIMINABLE_REGS
1323 for (ep = reg_eliminate, ep1 = reg_eliminate_1;
1324 ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++)
1326 ep->offset = ep->previous_offset = 0;
1327 ep->from = ep1->from;
1328 ep->to = ep1->to;
1329 value_p = (targetm.can_eliminate (ep->from, ep->to)
1330 && ! (ep->to == STACK_POINTER_REGNUM
1331 && frame_pointer_needed
1332 && (! SUPPORTS_STACK_ALIGNMENT
1333 || ! stack_realign_fp)));
1334 setup_can_eliminate (ep, value_p);
1336 #else
1337 reg_eliminate[0].offset = reg_eliminate[0].previous_offset = 0;
1338 reg_eliminate[0].from = reg_eliminate_1[0].from;
1339 reg_eliminate[0].to = reg_eliminate_1[0].to;
1340 setup_can_eliminate (&reg_eliminate[0], ! frame_pointer_needed);
1341 #endif
1343 /* Build the FROM and TO REG rtx's. Note that code in gen_rtx_REG
1344 will cause, e.g., gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to
1345 equal stack_pointer_rtx. We depend on this. Threfore we switch
1346 off that we are in LRA temporarily. */
1347 lra_in_progress = 0;
1348 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1350 ep->from_rtx = gen_rtx_REG (Pmode, ep->from);
1351 ep->to_rtx = gen_rtx_REG (Pmode, ep->to);
1352 eliminable_reg_rtx[ep->from] = ep->from_rtx;
1354 lra_in_progress = 1;
1357 /* Function for initialization of elimination once per function. It
1358 sets up sp offset for each insn. */
1359 static void
1360 init_elimination (void)
1362 bool stop_to_sp_elimination_p;
1363 basic_block bb;
1364 rtx_insn *insn;
1365 struct lra_elim_table *ep;
1367 init_elim_table ();
1368 FOR_EACH_BB_FN (bb, cfun)
1370 curr_sp_change = 0;
1371 stop_to_sp_elimination_p = false;
1372 FOR_BB_INSNS (bb, insn)
1373 if (INSN_P (insn))
1375 lra_get_insn_recog_data (insn)->sp_offset = curr_sp_change;
1376 if (NONDEBUG_INSN_P (insn))
1378 mark_not_eliminable (PATTERN (insn), VOIDmode);
1379 if (curr_sp_change != 0
1380 && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX))
1381 stop_to_sp_elimination_p = true;
1384 if (! frame_pointer_needed
1385 && (curr_sp_change != 0 || stop_to_sp_elimination_p)
1386 && bb->succs && bb->succs->length () != 0)
1387 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1388 if (ep->to == STACK_POINTER_REGNUM)
1389 setup_can_eliminate (ep, false);
1391 setup_elimination_map ();
1394 /* Eliminate hard reg given by its location LOC. */
1395 void
1396 lra_eliminate_reg_if_possible (rtx *loc)
1398 int regno;
1399 struct lra_elim_table *ep;
1401 lra_assert (REG_P (*loc));
1402 if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
1403 || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno))
1404 return;
1405 if ((ep = get_elimination (*loc)) != NULL)
1406 *loc = ep->to_rtx;
1409 /* Do (final if FINAL_P or first if FIRST_P) elimination in INSN. Add
1410 the insn for subsequent processing in the constraint pass, update
1411 the insn info. */
1412 static void
1413 process_insn_for_elimination (rtx_insn *insn, bool final_p, bool first_p)
1415 eliminate_regs_in_insn (insn, final_p, first_p, 0);
1416 if (! final_p)
1418 /* Check that insn changed its code. This is a case when a move
1419 insn becomes an add insn and we do not want to process the
1420 insn as a move anymore. */
1421 int icode = recog (PATTERN (insn), insn, 0);
1423 if (icode >= 0 && icode != INSN_CODE (insn))
1425 INSN_CODE (insn) = icode;
1426 lra_update_insn_recog_data (insn);
1428 lra_update_insn_regno_info (insn);
1429 lra_push_insn (insn);
1430 lra_set_used_insn_alternative (insn, -1);
1434 /* Entry function to do final elimination if FINAL_P or to update
1435 elimination register offsets (FIRST_P if we are doing it the first
1436 time). */
1437 void
1438 lra_eliminate (bool final_p, bool first_p)
1440 unsigned int uid;
1441 bitmap_head insns_with_changed_offsets;
1442 bitmap_iterator bi;
1443 struct lra_elim_table *ep;
1445 gcc_assert (! final_p || ! first_p);
1447 timevar_push (TV_LRA_ELIMINATE);
1449 if (first_p)
1450 init_elimination ();
1452 bitmap_initialize (&insns_with_changed_offsets, &reg_obstack);
1453 if (final_p)
1455 if (flag_checking)
1457 update_reg_eliminate (&insns_with_changed_offsets);
1458 gcc_assert (bitmap_empty_p (&insns_with_changed_offsets));
1460 /* We change eliminable hard registers in insns so we should do
1461 this for all insns containing any eliminable hard
1462 register. */
1463 for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
1464 if (elimination_map[ep->from] != NULL)
1465 bitmap_ior_into (&insns_with_changed_offsets,
1466 &lra_reg_info[ep->from].insn_bitmap);
1468 else if (! update_reg_eliminate (&insns_with_changed_offsets))
1469 goto lra_eliminate_done;
1470 if (lra_dump_file != NULL)
1472 fprintf (lra_dump_file, "New elimination table:\n");
1473 print_elim_table (lra_dump_file);
1475 EXECUTE_IF_SET_IN_BITMAP (&insns_with_changed_offsets, 0, uid, bi)
1476 /* A dead insn can be deleted in process_insn_for_elimination. */
1477 if (lra_insn_recog_data[uid] != NULL)
1478 process_insn_for_elimination (lra_insn_recog_data[uid]->insn,
1479 final_p, first_p);
1480 bitmap_clear (&insns_with_changed_offsets);
1482 lra_eliminate_done:
1483 timevar_pop (TV_LRA_ELIMINATE);