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