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
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
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
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
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
56 #include "coretypes.h"
68 #include "rtl-error.h"
71 /* This structure is used to record information about hard register
75 /* Hard register number to be eliminated. */
77 /* Hard register number used as replacement. */
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. */
84 /* Nonzero if this elimination can be done. */
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
93 /* REG rtx for the replacement. */
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
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
118 {{ FRAME_POINTER_REGNUM
, STACK_POINTER_REGNUM
}};
121 #define NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1)
123 /* Print info about elimination table to file F. */
125 print_elim_table (FILE *f
)
127 struct lra_elim_table
*ep
;
129 for (ep
= reg_eliminate
; ep
< ®_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. */
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. */
147 setup_can_eliminate (struct lra_elim_table
*ep
, bool value
)
149 ep
->can_eliminate
= ep
->prev_can_eliminate
= 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
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,
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. */
179 setup_elimination_map (void)
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
< ®_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. */
200 form_sum (rtx x
, rtx y
)
202 machine_mode mode
= GET_MODE (x
);
204 if (mode
== VOIDmode
)
207 if (mode
== VOIDmode
)
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
))
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
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
)
232 if (GET_CODE (y
) == CONST
)
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
)
250 if ((ep
= elimination_map
[hard_regno
]) == NULL
)
255 /* Return elimination which will be used for hard reg REG, NULL
257 static struct lra_elim_table
*
258 get_elimination (rtx reg
)
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
)
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)
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. */
289 enum machine_mode x_mode
, subreg_reg_mode
;
291 if (GET_CODE (x
) != SUBREG
|| !subreg_lowpart_p (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
,
305 if (cst
&& CONSTANT_P (cst
))
306 return gen_rtx_PLUS (x_mode
, lowpart_subreg (x_mode
, subreg_reg
,
307 subreg_reg_mode
), cst
);
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
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
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
;
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
)
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
);
376 return plus_constant (Pmode
, to
, ep
->offset
- ep
->previous_offset
);
378 return plus_constant (Pmode
, to
,
381 && ep
->to_rtx
== stack_pointer_rtx
382 ? lra_get_insn_recog_data (insn
)->sp_offset
390 /* If this is the sum of an eliminable register and a constant, rework
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;
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
)
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. */
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
,
435 update_sp_offset
, full_p
);
436 rtx new1
= lra_eliminate_regs_1 (insn
, XEXP (x
, 1), mem_mode
,
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
);
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));
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)));
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
;
478 plus_constant (Pmode
,
479 gen_rtx_MULT (Pmode
, to
, XEXP (x
, 1)),
480 offset
* INTVAL (XEXP (x
, 1)));
483 return gen_rtx_MULT (Pmode
, to
, XEXP (x
, 1));
486 /* ... fall through ... */
490 /* See comments before PLUS about handling MINUS. */
494 case AND
: case IOR
: case XOR
:
495 case ROTATERT
: case ROTATE
:
496 case ASHIFTRT
: case LSHIFTRT
: case ASHIFT
:
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
,
503 update_sp_offset
, full_p
);
504 rtx new1
= XEXP (x
, 1)
505 ? lra_eliminate_regs_1 (insn
, XEXP (x
, 1), mem_mode
,
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
);
515 /* If we have something in XEXP (x, 0), the usual case,
519 new_rtx
= lra_eliminate_regs_1 (insn
, XEXP (x
, 0), mem_mode
,
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
)
529 ? lra_eliminate_regs_1 (insn
, XEXP (x
, 1), mem_mode
,
531 update_sp_offset
, full_p
)
534 x
= alloc_reg_note (REG_NOTE_KIND (x
), new_rtx
, XEXP (x
, 1));
538 /* ... fall through ... */
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. */
547 new_rtx
= lra_eliminate_regs_1 (insn
, XEXP (x
, 1), mem_mode
,
549 update_sp_offset
, full_p
);
550 if (new_rtx
!= XEXP (x
, 1))
552 gen_rtx_fmt_ee (GET_CODE (x
), GET_MODE (x
),
553 XEXP (x
, 0), new_rtx
);
561 /* We do not support elimination of a register that is modified.
562 elimination_effects has already make sure that this does not
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
));
586 case STRICT_LOW_PART
:
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
:
600 new_rtx
= lra_eliminate_regs_1 (insn
, XEXP (x
, 0), mem_mode
,
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
);
608 new_rtx
= lra_eliminate_regs_1 (insn
, SUBREG_REG (x
), mem_mode
,
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);
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
;
634 return simplify_gen_subreg (GET_MODE (x
), new_rtx
,
635 GET_MODE (new_rtx
), SUBREG_BYTE (x
));
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. */
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
));
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
);
666 /* Process each of our operands recursively. If any have changed, make a
668 fmt
= GET_RTX_FORMAT (code
);
669 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++, fmt
++)
673 new_rtx
= lra_eliminate_regs_1 (insn
, XEXP (x
, i
), mem_mode
,
675 update_sp_offset
, full_p
);
676 if (new_rtx
!= XEXP (x
, i
) && ! copied
)
678 x
= shallow_copy_rtx (x
);
681 XEXP (x
, i
) = new_rtx
;
683 else if (*fmt
== 'E')
686 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
688 new_rtx
= lra_eliminate_regs_1 (insn
, XVECEXP (x
, i
, j
), mem_mode
,
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
),
697 x
= shallow_copy_rtx (x
);
703 XVECEXP (x
, i
, j
) = new_rtx
;
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
731 mark_not_eliminable (rtx x
, machine_mode mem_mode
)
733 enum rtx_code code
= GET_CODE (x
);
734 struct lra_elim_table
*ep
;
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
);
755 /* If more bytes than MEM_MODE are pushed, account for
757 size
= PUSH_ROUNDING (size
);
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
< ®_eliminate
[NUM_ELIMINABLE_REGS
];
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);
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
788 for (ep
= reg_eliminate
;
789 ep
< ®_eliminate
[NUM_ELIMINABLE_REGS
];
791 if (ep
->from_rtx
== XEXP (x
, 0)
792 && ep
->to_rtx
!= hard_frame_pointer_rtx
)
793 setup_can_eliminate (ep
, false);
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
< ®_eliminate
[NUM_ELIMINABLE_REGS
];
805 if (ep
->to_rtx
== XEXP (x
, 0)
806 && ep
->to_rtx
!= hard_frame_pointer_rtx
)
807 setup_can_eliminate (ep
, false);
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));
819 if (! REG_P (SET_DEST (x
))
820 || REGNO (SET_DEST (x
)) >= FIRST_PSEUDO_REGISTER
)
821 mark_not_eliminable (SET_DEST (x
), mem_mode
);
824 /* See if this is setting the replacement hard register for
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
< ®_eliminate
[NUM_ELIMINABLE_REGS
];
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
);
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
));
856 fmt
= GET_RTX_FORMAT (code
);
857 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++, fmt
++)
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. */
875 remove_reg_equal_offset_note (rtx_insn
*insn
, rtx what
)
879 for (link_loc
= ®_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);
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. */
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
);
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
);
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
< ®_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
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
956 lra_assert (update_sp_offset
== 0);
960 || (GET_CODE (src
) == PLUS
961 && XEXP (src
, 0) == ep
->to_rtx
962 && CONST_INT_P (XEXP (src
, 1))))
964 HOST_WIDE_INT offset
;
968 SET_DEST (old_set
) = ep
->to_rtx
;
969 lra_update_insn_recog_data (insn
);
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
981 validate_change (insn
, &SET_SRC (old_set
), src
, 1);
982 validate_change (insn
, &SET_DEST (old_set
),
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
);
997 /* This insn isn't serving a useful purpose. We delete it
998 when REPLACE is set. */
1000 lra_delete_dead_insn (insn
);
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). */
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. */
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
)
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
;
1044 if (update_sp_offset
== 0)
1045 offset
+= (ep
->offset
- ep
->previous_offset
);
1046 if (ep
->to_rtx
== stack_pointer_rtx
)
1049 offset
-= lra_get_insn_recog_data (insn
)->sp_offset
;
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
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. */
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
;
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
< ®_eliminate
[NUM_ELIMINABLE_REGS
];
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. */
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
])
1134 /* Substitute the operands; the new values are in the substed_operand
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
1154 spill_pseudos (HARD_REG_SET set
)
1157 bitmap_head to_process
;
1160 if (hard_reg_set_empty_p (set
))
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
, ®_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. */
1199 update_reg_eliminate (bitmap insns_with_changed_offsets
)
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
< ®_eliminate
[NUM_ELIMINABLE_REGS
]; ep
++)
1207 self_elim_offsets
[ep
->from
] = 0;
1208 for (ep
= reg_eliminate
; ep
< ®_eliminate
[NUM_ELIMINABLE_REGS
]; ep
++)
1210 /* If it is a currently used elimination: update the previous
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);
1226 if (ep
->can_eliminate
!= prev
&& elimination_map
[ep
->from
] == ep
)
1228 /* We cannot use this elimination anymore -- find another
1230 if (lra_dump_file
!= NULL
)
1231 fprintf (lra_dump_file
,
1232 " Elimination %d to %d is not possible anymore\n",
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
< ®_eliminate
[NUM_ELIMINABLE_REGS
]; ep1
++)
1242 if (ep1
->can_eliminate
&& ep1
->from
== ep
->from
)
1244 if (ep1
< ®_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
;
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",
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
);
1270 INITIAL_FRAME_POINTER_OFFSET (ep
->offset
);
1273 setup_elimination_map ();
1275 CLEAR_HARD_REG_SET (temp_hard_reg_set
);
1276 for (ep
= reg_eliminate
; ep
< ®_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
1292 lra_update_reg_val_offset (lra_reg_info
[ep
->from
].val
,
1293 ep
->offset
- ep
->previous_offset
);
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
);
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. */
1307 init_elim_table (void)
1309 struct lra_elim_table
*ep
;
1310 #ifdef ELIMINABLE_REGS
1312 const struct elim_table_1
*ep1
;
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
< ®_eliminate
[NUM_ELIMINABLE_REGS
]; ep
++, ep1
++)
1326 ep
->offset
= ep
->previous_offset
= 0;
1327 ep
->from
= ep1
->from
;
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
);
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 (®_eliminate
[0], ! frame_pointer_needed
);
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
< ®_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. */
1360 init_elimination (void)
1362 bool stop_to_sp_elimination_p
;
1365 struct lra_elim_table
*ep
;
1368 FOR_EACH_BB_FN (bb
, cfun
)
1371 stop_to_sp_elimination_p
= false;
1372 FOR_BB_INSNS (bb
, 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
< ®_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. */
1396 lra_eliminate_reg_if_possible (rtx
*loc
)
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
))
1405 if ((ep
= get_elimination (*loc
)) != NULL
)
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
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);
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
1438 lra_eliminate (bool final_p
, bool first_p
)
1441 bitmap_head insns_with_changed_offsets
;
1443 struct lra_elim_table
*ep
;
1445 gcc_assert (! final_p
|| ! first_p
);
1447 timevar_push (TV_LRA_ELIMINATE
);
1450 init_elimination ();
1452 bitmap_initialize (&insns_with_changed_offsets
, ®_obstack
);
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
1463 for (ep
= reg_eliminate
; ep
< ®_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
,
1480 bitmap_clear (&insns_with_changed_offsets
);
1483 timevar_pop (TV_LRA_ELIMINATE
);