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