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