xref: /dragonfly/contrib/gcc-8.0/gcc/lra.c (revision 58e805e6)
138fd1498Szrj /* LRA (local register allocator) driver and LRA utilities.
238fd1498Szrj    Copyright (C) 2010-2018 Free Software Foundation, Inc.
338fd1498Szrj    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
438fd1498Szrj 
538fd1498Szrj This file is part of GCC.
638fd1498Szrj 
738fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
838fd1498Szrj the terms of the GNU General Public License as published by the Free
938fd1498Szrj Software Foundation; either version 3, or (at your option) any later
1038fd1498Szrj version.
1138fd1498Szrj 
1238fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1338fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
1438fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1538fd1498Szrj for more details.
1638fd1498Szrj 
1738fd1498Szrj You should have received a copy of the GNU General Public License
1838fd1498Szrj along with GCC; see the file COPYING3.	If not see
1938fd1498Szrj <http://www.gnu.org/licenses/>.	 */
2038fd1498Szrj 
2138fd1498Szrj 
2238fd1498Szrj /* The Local Register Allocator (LRA) is a replacement of former
2338fd1498Szrj    reload pass.	 It is focused to simplify code solving the reload
2438fd1498Szrj    pass tasks, to make the code maintenance easier, and to implement new
2538fd1498Szrj    perspective optimizations.
2638fd1498Szrj 
2738fd1498Szrj    The major LRA design solutions are:
2838fd1498Szrj      o division small manageable, separated sub-tasks
2938fd1498Szrj      o reflection of all transformations and decisions in RTL as more
3038fd1498Szrj        as possible
3138fd1498Szrj      o insn constraints as a primary source of the info (minimizing
3238fd1498Szrj        number of target-depended macros/hooks)
3338fd1498Szrj 
3438fd1498Szrj    In brief LRA works by iterative insn process with the final goal is
3538fd1498Szrj    to satisfy all insn and address constraints:
3638fd1498Szrj      o New reload insns (in brief reloads) and reload pseudos might be
3738fd1498Szrj        generated;
3838fd1498Szrj      o Some pseudos might be spilled to assign hard registers to
3938fd1498Szrj        new reload pseudos;
4038fd1498Szrj      o Recalculating spilled pseudo values (rematerialization);
4138fd1498Szrj      o Changing spilled pseudos to stack memory or their equivalences;
4238fd1498Szrj      o Allocation stack memory changes the address displacement and
4338fd1498Szrj        new iteration is needed.
4438fd1498Szrj 
4538fd1498Szrj    Here is block diagram of LRA passes:
4638fd1498Szrj 
4738fd1498Szrj                                 ------------------------
4838fd1498Szrj            ---------------     | Undo inheritance for   |     ---------------
4938fd1498Szrj           | Memory-memory |    | spilled pseudos,       |    | New (and old) |
5038fd1498Szrj           | move coalesce |<---| splits for pseudos got |<-- |   pseudos     |
5138fd1498Szrj            ---------------     | the same hard regs,    |    |  assignment   |
5238fd1498Szrj   Start           |            | and optional reloads   |     ---------------
5338fd1498Szrj     |             |             ------------------------            ^
5438fd1498Szrj     V             |              ----------------                   |
5538fd1498Szrj  -----------      V             | Update virtual |                  |
5638fd1498Szrj |  Remove   |----> ------------>|    register    |                  |
5738fd1498Szrj | scratches |     ^             |  displacements |                  |
5838fd1498Szrj  -----------      |              ----------------                   |
5938fd1498Szrj                   |                      |                          |
6038fd1498Szrj                   |                      V         New              |
6138fd1498Szrj                   |                 ------------  pseudos   -------------------
6238fd1498Szrj                   |                |Constraints:| or insns | Inheritance/split |
6338fd1498Szrj                   |                |    RTL     |--------->|  transformations  |
6438fd1498Szrj                   |                | transfor-  |          |    in EBB scope   |
6538fd1498Szrj                   | substi-        |  mations   |           -------------------
6638fd1498Szrj                   | tutions         ------------
6738fd1498Szrj                   |                     | No change
6838fd1498Szrj           ----------------              V
6938fd1498Szrj          | Spilled pseudo |      -------------------
7038fd1498Szrj          |    to memory   |<----| Rematerialization |
7138fd1498Szrj          |  substitution  |      -------------------
7238fd1498Szrj           ----------------
7338fd1498Szrj                   | No susbtitions
7438fd1498Szrj                   V
7538fd1498Szrj       -------------------------
7638fd1498Szrj      | Hard regs substitution, |
7738fd1498Szrj      |  devirtalization, and   |------> Finish
7838fd1498Szrj      | restoring scratches got |
7938fd1498Szrj      |         memory          |
8038fd1498Szrj       -------------------------
8138fd1498Szrj 
8238fd1498Szrj    To speed up the process:
8338fd1498Szrj      o We process only insns affected by changes on previous
8438fd1498Szrj        iterations;
8538fd1498Szrj      o We don't use DFA-infrastructure because it results in much slower
8638fd1498Szrj        compiler speed than a special IR described below does;
8738fd1498Szrj      o We use a special insn representation for quick access to insn
8838fd1498Szrj        info which is always *synchronized* with the current RTL;
8938fd1498Szrj        o Insn IR is minimized by memory.  It is divided on three parts:
9038fd1498Szrj 	 o one specific for each insn in RTL (only operand locations);
9138fd1498Szrj 	 o one common for all insns in RTL with the same insn code
9238fd1498Szrj 	   (different operand attributes from machine descriptions);
9338fd1498Szrj 	 o one oriented for maintenance of live info (list of pseudos).
9438fd1498Szrj        o Pseudo data:
9538fd1498Szrj 	 o all insns where the pseudo is referenced;
9638fd1498Szrj 	 o live info (conflicting hard regs, live ranges, # of
9738fd1498Szrj 	   references etc);
9838fd1498Szrj 	 o data used for assigning (preferred hard regs, costs etc).
9938fd1498Szrj 
10038fd1498Szrj    This file contains LRA driver, LRA utility functions and data, and
10138fd1498Szrj    code for dealing with scratches.  */
10238fd1498Szrj 
10338fd1498Szrj #include "config.h"
10438fd1498Szrj #include "system.h"
10538fd1498Szrj #include "coretypes.h"
10638fd1498Szrj #include "backend.h"
10738fd1498Szrj #include "target.h"
10838fd1498Szrj #include "rtl.h"
10938fd1498Szrj #include "tree.h"
11038fd1498Szrj #include "predict.h"
11138fd1498Szrj #include "df.h"
11238fd1498Szrj #include "memmodel.h"
11338fd1498Szrj #include "tm_p.h"
11438fd1498Szrj #include "optabs.h"
11538fd1498Szrj #include "regs.h"
11638fd1498Szrj #include "ira.h"
11738fd1498Szrj #include "recog.h"
11838fd1498Szrj #include "expr.h"
11938fd1498Szrj #include "cfgrtl.h"
12038fd1498Szrj #include "cfgbuild.h"
12138fd1498Szrj #include "lra.h"
12238fd1498Szrj #include "lra-int.h"
12338fd1498Szrj #include "print-rtl.h"
12438fd1498Szrj 
12538fd1498Szrj /* Dump bitmap SET with TITLE and BB INDEX.  */
12638fd1498Szrj void
lra_dump_bitmap_with_title(const char * title,bitmap set,int index)12738fd1498Szrj lra_dump_bitmap_with_title (const char *title, bitmap set, int index)
12838fd1498Szrj {
12938fd1498Szrj   unsigned int i;
13038fd1498Szrj   int count;
13138fd1498Szrj   bitmap_iterator bi;
13238fd1498Szrj   static const int max_nums_on_line = 10;
13338fd1498Szrj 
13438fd1498Szrj   if (bitmap_empty_p (set))
13538fd1498Szrj     return;
13638fd1498Szrj   fprintf (lra_dump_file, "  %s %d:", title, index);
13738fd1498Szrj   fprintf (lra_dump_file, "\n");
13838fd1498Szrj   count = max_nums_on_line + 1;
13938fd1498Szrj   EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
14038fd1498Szrj     {
14138fd1498Szrj       if (count > max_nums_on_line)
14238fd1498Szrj 	{
14338fd1498Szrj 	  fprintf (lra_dump_file, "\n    ");
14438fd1498Szrj 	  count = 0;
14538fd1498Szrj 	}
14638fd1498Szrj       fprintf (lra_dump_file, " %4u", i);
14738fd1498Szrj       count++;
14838fd1498Szrj     }
14938fd1498Szrj   fprintf (lra_dump_file, "\n");
15038fd1498Szrj }
15138fd1498Szrj 
15238fd1498Szrj /* Hard registers currently not available for allocation.  It can
15338fd1498Szrj    changed after some hard  registers become not eliminable.  */
15438fd1498Szrj HARD_REG_SET lra_no_alloc_regs;
15538fd1498Szrj 
15638fd1498Szrj static int get_new_reg_value (void);
15738fd1498Szrj static void expand_reg_info (void);
15838fd1498Szrj static void invalidate_insn_recog_data (int);
15938fd1498Szrj static int get_insn_freq (rtx_insn *);
16038fd1498Szrj static void invalidate_insn_data_regno_info (lra_insn_recog_data_t,
16138fd1498Szrj 					     rtx_insn *, int);
16238fd1498Szrj 
16338fd1498Szrj /* Expand all regno related info needed for LRA.  */
16438fd1498Szrj static void
expand_reg_data(int old)16538fd1498Szrj expand_reg_data (int old)
16638fd1498Szrj {
16738fd1498Szrj   resize_reg_info ();
16838fd1498Szrj   expand_reg_info ();
16938fd1498Szrj   ira_expand_reg_equiv ();
17038fd1498Szrj   for (int i = (int) max_reg_num () - 1; i >= old; i--)
17138fd1498Szrj     lra_change_class (i, ALL_REGS, "      Set", true);
17238fd1498Szrj }
17338fd1498Szrj 
17438fd1498Szrj /* Create and return a new reg of ORIGINAL mode.  If ORIGINAL is NULL
17538fd1498Szrj    or of VOIDmode, use MD_MODE for the new reg.  Initialize its
17638fd1498Szrj    register class to RCLASS.  Print message about assigning class
17738fd1498Szrj    RCLASS containing new register name TITLE unless it is NULL.  Use
17838fd1498Szrj    attributes of ORIGINAL if it is a register.  The created register
17938fd1498Szrj    will have unique held value.  */
18038fd1498Szrj rtx
lra_create_new_reg_with_unique_value(machine_mode md_mode,rtx original,enum reg_class rclass,const char * title)18138fd1498Szrj lra_create_new_reg_with_unique_value (machine_mode md_mode, rtx original,
18238fd1498Szrj 				      enum reg_class rclass, const char *title)
18338fd1498Szrj {
18438fd1498Szrj   machine_mode mode;
18538fd1498Szrj   rtx new_reg;
18638fd1498Szrj 
18738fd1498Szrj   if (original == NULL_RTX || (mode = GET_MODE (original)) == VOIDmode)
18838fd1498Szrj     mode = md_mode;
18938fd1498Szrj   lra_assert (mode != VOIDmode);
19038fd1498Szrj   new_reg = gen_reg_rtx (mode);
19138fd1498Szrj   if (original == NULL_RTX || ! REG_P (original))
19238fd1498Szrj     {
19338fd1498Szrj       if (lra_dump_file != NULL)
19438fd1498Szrj 	fprintf (lra_dump_file, "      Creating newreg=%i", REGNO (new_reg));
19538fd1498Szrj     }
19638fd1498Szrj   else
19738fd1498Szrj     {
19838fd1498Szrj       if (ORIGINAL_REGNO (original) >= FIRST_PSEUDO_REGISTER)
19938fd1498Szrj 	ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original);
20038fd1498Szrj       REG_USERVAR_P (new_reg) = REG_USERVAR_P (original);
20138fd1498Szrj       REG_POINTER (new_reg) = REG_POINTER (original);
20238fd1498Szrj       REG_ATTRS (new_reg) = REG_ATTRS (original);
20338fd1498Szrj       if (lra_dump_file != NULL)
20438fd1498Szrj 	fprintf (lra_dump_file, "      Creating newreg=%i from oldreg=%i",
20538fd1498Szrj 		 REGNO (new_reg), REGNO (original));
20638fd1498Szrj     }
20738fd1498Szrj   if (lra_dump_file != NULL)
20838fd1498Szrj     {
20938fd1498Szrj       if (title != NULL)
21038fd1498Szrj 	fprintf (lra_dump_file, ", assigning class %s to%s%s r%d",
21138fd1498Szrj 		 reg_class_names[rclass], *title == '\0' ? "" : " ",
21238fd1498Szrj 		 title, REGNO (new_reg));
21338fd1498Szrj       fprintf (lra_dump_file, "\n");
21438fd1498Szrj     }
21538fd1498Szrj   expand_reg_data (max_reg_num ());
21638fd1498Szrj   setup_reg_classes (REGNO (new_reg), rclass, NO_REGS, rclass);
21738fd1498Szrj   return new_reg;
21838fd1498Szrj }
21938fd1498Szrj 
22038fd1498Szrj /* Analogous to the previous function but also inherits value of
22138fd1498Szrj    ORIGINAL.  */
22238fd1498Szrj rtx
lra_create_new_reg(machine_mode md_mode,rtx original,enum reg_class rclass,const char * title)22338fd1498Szrj lra_create_new_reg (machine_mode md_mode, rtx original,
22438fd1498Szrj 		    enum reg_class rclass, const char *title)
22538fd1498Szrj {
22638fd1498Szrj   rtx new_reg;
22738fd1498Szrj 
22838fd1498Szrj   new_reg
22938fd1498Szrj     = lra_create_new_reg_with_unique_value (md_mode, original, rclass, title);
23038fd1498Szrj   if (original != NULL_RTX && REG_P (original))
23138fd1498Szrj     lra_assign_reg_val (REGNO (original), REGNO (new_reg));
23238fd1498Szrj   return new_reg;
23338fd1498Szrj }
23438fd1498Szrj 
23538fd1498Szrj /* Set up for REGNO unique hold value.	*/
23638fd1498Szrj void
lra_set_regno_unique_value(int regno)23738fd1498Szrj lra_set_regno_unique_value (int regno)
23838fd1498Szrj {
23938fd1498Szrj   lra_reg_info[regno].val = get_new_reg_value ();
24038fd1498Szrj }
24138fd1498Szrj 
24238fd1498Szrj /* Invalidate INSN related info used by LRA.  The info should never be
24338fd1498Szrj    used after that.  */
24438fd1498Szrj void
lra_invalidate_insn_data(rtx_insn * insn)24538fd1498Szrj lra_invalidate_insn_data (rtx_insn *insn)
24638fd1498Szrj {
24738fd1498Szrj   lra_invalidate_insn_regno_info (insn);
24838fd1498Szrj   invalidate_insn_recog_data (INSN_UID (insn));
24938fd1498Szrj }
25038fd1498Szrj 
25138fd1498Szrj /* Mark INSN deleted and invalidate the insn related info used by
25238fd1498Szrj    LRA.	 */
25338fd1498Szrj void
lra_set_insn_deleted(rtx_insn * insn)25438fd1498Szrj lra_set_insn_deleted (rtx_insn *insn)
25538fd1498Szrj {
25638fd1498Szrj   lra_invalidate_insn_data (insn);
25738fd1498Szrj   SET_INSN_DELETED (insn);
25838fd1498Szrj }
25938fd1498Szrj 
26038fd1498Szrj /* Delete an unneeded INSN and any previous insns who sole purpose is
26138fd1498Szrj    loading data that is dead in INSN.  */
26238fd1498Szrj void
lra_delete_dead_insn(rtx_insn * insn)26338fd1498Szrj lra_delete_dead_insn (rtx_insn *insn)
26438fd1498Szrj {
26538fd1498Szrj   rtx_insn *prev = prev_real_insn (insn);
26638fd1498Szrj   rtx prev_dest;
26738fd1498Szrj 
26838fd1498Szrj   /* If the previous insn sets a register that dies in our insn,
26938fd1498Szrj      delete it too.  */
27038fd1498Szrj   if (prev && GET_CODE (PATTERN (prev)) == SET
27138fd1498Szrj       && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
27238fd1498Szrj       && reg_mentioned_p (prev_dest, PATTERN (insn))
27338fd1498Szrj       && find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
27438fd1498Szrj       && ! side_effects_p (SET_SRC (PATTERN (prev))))
27538fd1498Szrj     lra_delete_dead_insn (prev);
27638fd1498Szrj 
27738fd1498Szrj   lra_set_insn_deleted (insn);
27838fd1498Szrj }
27938fd1498Szrj 
28038fd1498Szrj /* Emit insn x = y + z.  Return NULL if we failed to do it.
28138fd1498Szrj    Otherwise, return the insn.  We don't use gen_add3_insn as it might
28238fd1498Szrj    clobber CC.  */
28338fd1498Szrj static rtx_insn *
emit_add3_insn(rtx x,rtx y,rtx z)28438fd1498Szrj emit_add3_insn (rtx x, rtx y, rtx z)
28538fd1498Szrj {
28638fd1498Szrj   rtx_insn *last;
28738fd1498Szrj 
28838fd1498Szrj   last = get_last_insn ();
28938fd1498Szrj 
29038fd1498Szrj   if (have_addptr3_insn (x, y, z))
29138fd1498Szrj     {
29238fd1498Szrj       rtx_insn *insn = gen_addptr3_insn (x, y, z);
29338fd1498Szrj 
29438fd1498Szrj       /* If the target provides an "addptr" pattern it hopefully does
29538fd1498Szrj 	 for a reason.  So falling back to the normal add would be
29638fd1498Szrj 	 a bug.  */
29738fd1498Szrj       lra_assert (insn != NULL_RTX);
29838fd1498Szrj       emit_insn (insn);
29938fd1498Szrj       return insn;
30038fd1498Szrj     }
30138fd1498Szrj 
30238fd1498Szrj   rtx_insn *insn = emit_insn (gen_rtx_SET (x, gen_rtx_PLUS (GET_MODE (y),
30338fd1498Szrj 							    y, z)));
30438fd1498Szrj   if (recog_memoized (insn) < 0)
30538fd1498Szrj     {
30638fd1498Szrj       delete_insns_since (last);
30738fd1498Szrj       insn = NULL;
30838fd1498Szrj     }
30938fd1498Szrj   return insn;
31038fd1498Szrj }
31138fd1498Szrj 
31238fd1498Szrj /* Emit insn x = x + y.  Return the insn.  We use gen_add2_insn as the
31338fd1498Szrj    last resort.  */
31438fd1498Szrj static rtx_insn *
emit_add2_insn(rtx x,rtx y)31538fd1498Szrj emit_add2_insn (rtx x, rtx y)
31638fd1498Szrj {
31738fd1498Szrj   rtx_insn *insn = emit_add3_insn (x, x, y);
31838fd1498Szrj   if (insn == NULL_RTX)
31938fd1498Szrj     {
32038fd1498Szrj       insn = gen_add2_insn (x, y);
32138fd1498Szrj       if (insn != NULL_RTX)
32238fd1498Szrj 	emit_insn (insn);
32338fd1498Szrj     }
32438fd1498Szrj   return insn;
32538fd1498Szrj }
32638fd1498Szrj 
32738fd1498Szrj /* Target checks operands through operand predicates to recognize an
32838fd1498Szrj    insn.  We should have a special precaution to generate add insns
32938fd1498Szrj    which are frequent results of elimination.
33038fd1498Szrj 
33138fd1498Szrj    Emit insns for x = y + z.  X can be used to store intermediate
33238fd1498Szrj    values and should be not in Y and Z when we use X to store an
33338fd1498Szrj    intermediate value.  Y + Z should form [base] [+ index[ * scale]] [
33438fd1498Szrj    + disp] where base and index are registers, disp and scale are
33538fd1498Szrj    constants.  Y should contain base if it is present, Z should
33638fd1498Szrj    contain disp if any.  index[*scale] can be part of Y or Z.  */
33738fd1498Szrj void
lra_emit_add(rtx x,rtx y,rtx z)33838fd1498Szrj lra_emit_add (rtx x, rtx y, rtx z)
33938fd1498Szrj {
34038fd1498Szrj   int old;
34138fd1498Szrj   rtx_insn *last;
34238fd1498Szrj   rtx a1, a2, base, index, disp, scale, index_scale;
34338fd1498Szrj   bool ok_p;
34438fd1498Szrj 
34538fd1498Szrj   rtx_insn *add3_insn = emit_add3_insn (x, y, z);
34638fd1498Szrj   old = max_reg_num ();
34738fd1498Szrj   if (add3_insn != NULL)
34838fd1498Szrj     ;
34938fd1498Szrj   else
35038fd1498Szrj     {
35138fd1498Szrj       disp = a2 = NULL_RTX;
35238fd1498Szrj       if (GET_CODE (y) == PLUS)
35338fd1498Szrj 	{
35438fd1498Szrj 	  a1 = XEXP (y, 0);
35538fd1498Szrj 	  a2 = XEXP (y, 1);
35638fd1498Szrj 	  disp = z;
35738fd1498Szrj 	}
35838fd1498Szrj       else
35938fd1498Szrj 	{
36038fd1498Szrj 	  a1 = y;
36138fd1498Szrj 	  if (CONSTANT_P (z))
36238fd1498Szrj 	    disp = z;
36338fd1498Szrj 	  else
36438fd1498Szrj 	    a2 = z;
36538fd1498Szrj 	}
36638fd1498Szrj       index_scale = scale = NULL_RTX;
36738fd1498Szrj       if (GET_CODE (a1) == MULT)
36838fd1498Szrj 	{
36938fd1498Szrj 	  index_scale = a1;
37038fd1498Szrj 	  index = XEXP (a1, 0);
37138fd1498Szrj 	  scale = XEXP (a1, 1);
37238fd1498Szrj 	  base = a2;
37338fd1498Szrj 	}
37438fd1498Szrj       else if (a2 != NULL_RTX && GET_CODE (a2) == MULT)
37538fd1498Szrj 	{
37638fd1498Szrj 	  index_scale = a2;
37738fd1498Szrj 	  index = XEXP (a2, 0);
37838fd1498Szrj 	  scale = XEXP (a2, 1);
37938fd1498Szrj 	  base = a1;
38038fd1498Szrj 	}
38138fd1498Szrj       else
38238fd1498Szrj 	{
38338fd1498Szrj 	  base = a1;
38438fd1498Szrj 	  index = a2;
38538fd1498Szrj 	}
38638fd1498Szrj       if ((base != NULL_RTX && ! (REG_P (base) || GET_CODE (base) == SUBREG))
38738fd1498Szrj 	  || (index != NULL_RTX
38838fd1498Szrj 	      && ! (REG_P (index) || GET_CODE (index) == SUBREG))
38938fd1498Szrj 	  || (disp != NULL_RTX && ! CONSTANT_P (disp))
39038fd1498Szrj 	  || (scale != NULL_RTX && ! CONSTANT_P (scale)))
39138fd1498Szrj 	{
39238fd1498Szrj 	  /* Probably we have no 3 op add.  Last chance is to use 2-op
39338fd1498Szrj 	     add insn.  To succeed, don't move Z to X as an address
39438fd1498Szrj 	     segment always comes in Y.  Otherwise, we might fail when
39538fd1498Szrj 	     adding the address segment to register.  */
39638fd1498Szrj 	  lra_assert (x != y && x != z);
39738fd1498Szrj 	  emit_move_insn (x, y);
39838fd1498Szrj 	  rtx_insn *insn = emit_add2_insn (x, z);
39938fd1498Szrj 	  lra_assert (insn != NULL_RTX);
40038fd1498Szrj 	}
40138fd1498Szrj       else
40238fd1498Szrj 	{
40338fd1498Szrj 	  if (index_scale == NULL_RTX)
40438fd1498Szrj 	    index_scale = index;
40538fd1498Szrj 	  if (disp == NULL_RTX)
40638fd1498Szrj 	    {
40738fd1498Szrj 	      /* Generate x = index_scale; x = x + base.  */
40838fd1498Szrj 	      lra_assert (index_scale != NULL_RTX && base != NULL_RTX);
40938fd1498Szrj 	      emit_move_insn (x, index_scale);
41038fd1498Szrj 	      rtx_insn *insn = emit_add2_insn (x, base);
41138fd1498Szrj 	      lra_assert (insn != NULL_RTX);
41238fd1498Szrj 	    }
41338fd1498Szrj 	  else if (scale == NULL_RTX)
41438fd1498Szrj 	    {
41538fd1498Szrj 	      /* Try x = base + disp.  */
41638fd1498Szrj 	      lra_assert (base != NULL_RTX);
41738fd1498Szrj 	      last = get_last_insn ();
41838fd1498Szrj 	      rtx_insn *move_insn =
41938fd1498Szrj 		emit_move_insn (x, gen_rtx_PLUS (GET_MODE (base), base, disp));
42038fd1498Szrj 	      if (recog_memoized (move_insn) < 0)
42138fd1498Szrj 		{
42238fd1498Szrj 		  delete_insns_since (last);
42338fd1498Szrj 		  /* Generate x = disp; x = x + base.  */
42438fd1498Szrj 		  emit_move_insn (x, disp);
42538fd1498Szrj 		  rtx_insn *add2_insn = emit_add2_insn (x, base);
42638fd1498Szrj 		  lra_assert (add2_insn != NULL_RTX);
42738fd1498Szrj 		}
42838fd1498Szrj 	      /* Generate x = x + index.  */
42938fd1498Szrj 	      if (index != NULL_RTX)
43038fd1498Szrj 		{
43138fd1498Szrj 		  rtx_insn *insn = emit_add2_insn (x, index);
43238fd1498Szrj 		  lra_assert (insn != NULL_RTX);
43338fd1498Szrj 		}
43438fd1498Szrj 	    }
43538fd1498Szrj 	  else
43638fd1498Szrj 	    {
43738fd1498Szrj 	      /* Try x = index_scale; x = x + disp; x = x + base.  */
43838fd1498Szrj 	      last = get_last_insn ();
43938fd1498Szrj 	      rtx_insn *move_insn = emit_move_insn (x, index_scale);
44038fd1498Szrj 	      ok_p = false;
44138fd1498Szrj 	      if (recog_memoized (move_insn) >= 0)
44238fd1498Szrj 		{
44338fd1498Szrj 		  rtx_insn *insn = emit_add2_insn (x, disp);
44438fd1498Szrj 		  if (insn != NULL_RTX)
44538fd1498Szrj 		    {
44638fd1498Szrj 		      if (base == NULL_RTX)
44738fd1498Szrj 			ok_p = true;
44838fd1498Szrj 		      else
44938fd1498Szrj 			{
45038fd1498Szrj 			  insn = emit_add2_insn (x, base);
45138fd1498Szrj 			  if (insn != NULL_RTX)
45238fd1498Szrj 			    ok_p = true;
45338fd1498Szrj 			}
45438fd1498Szrj 		    }
45538fd1498Szrj 		}
45638fd1498Szrj 	      if (! ok_p)
45738fd1498Szrj 		{
45838fd1498Szrj 		  rtx_insn *insn;
45938fd1498Szrj 
46038fd1498Szrj 		  delete_insns_since (last);
46138fd1498Szrj 		  /* Generate x = disp; x = x + base; x = x + index_scale.  */
46238fd1498Szrj 		  emit_move_insn (x, disp);
46338fd1498Szrj 		  if (base != NULL_RTX)
46438fd1498Szrj 		    {
46538fd1498Szrj 		      insn = emit_add2_insn (x, base);
46638fd1498Szrj 		      lra_assert (insn != NULL_RTX);
46738fd1498Szrj 		    }
46838fd1498Szrj 		  insn = emit_add2_insn (x, index_scale);
46938fd1498Szrj 		  lra_assert (insn != NULL_RTX);
47038fd1498Szrj 		}
47138fd1498Szrj 	    }
47238fd1498Szrj 	}
47338fd1498Szrj     }
47438fd1498Szrj   /* Functions emit_... can create pseudos -- so expand the pseudo
47538fd1498Szrj      data.  */
47638fd1498Szrj   if (old != max_reg_num ())
47738fd1498Szrj     expand_reg_data (old);
47838fd1498Szrj }
47938fd1498Szrj 
48038fd1498Szrj /* The number of emitted reload insns so far.  */
48138fd1498Szrj int lra_curr_reload_num;
48238fd1498Szrj 
48338fd1498Szrj /* Emit x := y, processing special case when y = u + v or y = u + v *
48438fd1498Szrj    scale + w through emit_add (Y can be an address which is base +
48538fd1498Szrj    index reg * scale + displacement in general case).  X may be used
48638fd1498Szrj    as intermediate result therefore it should be not in Y.  */
48738fd1498Szrj void
lra_emit_move(rtx x,rtx y)48838fd1498Szrj lra_emit_move (rtx x, rtx y)
48938fd1498Szrj {
49038fd1498Szrj   int old;
49138fd1498Szrj 
49238fd1498Szrj   if (GET_CODE (y) != PLUS)
49338fd1498Szrj     {
49438fd1498Szrj       if (rtx_equal_p (x, y))
49538fd1498Szrj 	return;
49638fd1498Szrj       old = max_reg_num ();
49738fd1498Szrj       emit_move_insn (x, y);
49838fd1498Szrj       if (REG_P (x))
49938fd1498Szrj 	lra_reg_info[ORIGINAL_REGNO (x)].last_reload = ++lra_curr_reload_num;
50038fd1498Szrj       /* Function emit_move can create pseudos -- so expand the pseudo
50138fd1498Szrj 	 data.	*/
50238fd1498Szrj       if (old != max_reg_num ())
50338fd1498Szrj 	expand_reg_data (old);
50438fd1498Szrj       return;
50538fd1498Szrj     }
50638fd1498Szrj   lra_emit_add (x, XEXP (y, 0), XEXP (y, 1));
50738fd1498Szrj }
50838fd1498Szrj 
50938fd1498Szrj /* Update insn operands which are duplication of operands whose
51038fd1498Szrj    numbers are in array of NOPS (with end marker -1).  The insn is
51138fd1498Szrj    represented by its LRA internal representation ID.  */
51238fd1498Szrj void
lra_update_dups(lra_insn_recog_data_t id,signed char * nops)51338fd1498Szrj lra_update_dups (lra_insn_recog_data_t id, signed char *nops)
51438fd1498Szrj {
51538fd1498Szrj   int i, j, nop;
51638fd1498Szrj   struct lra_static_insn_data *static_id = id->insn_static_data;
51738fd1498Szrj 
51838fd1498Szrj   for (i = 0; i < static_id->n_dups; i++)
51938fd1498Szrj     for (j = 0; (nop = nops[j]) >= 0; j++)
52038fd1498Szrj       if (static_id->dup_num[i] == nop)
52138fd1498Szrj 	*id->dup_loc[i] = *id->operand_loc[nop];
52238fd1498Szrj }
52338fd1498Szrj 
52438fd1498Szrj 
52538fd1498Szrj 
52638fd1498Szrj /* This page contains code dealing with info about registers in the
52738fd1498Szrj    insns.  */
52838fd1498Szrj 
52938fd1498Szrj /* Pools for insn reg info.  */
53038fd1498Szrj object_allocator<lra_insn_reg> lra_insn_reg_pool ("insn regs");
53138fd1498Szrj 
53238fd1498Szrj /* Create LRA insn related info about a reference to REGNO in INSN
53338fd1498Szrj    with TYPE (in/out/inout), biggest reference mode MODE, flag that it
53438fd1498Szrj    is reference through subreg (SUBREG_P), flag that is early
53538fd1498Szrj    clobbered in the insn (EARLY_CLOBBER), and reference to the next
53638fd1498Szrj    insn reg info (NEXT).  If REGNO can be early clobbered,
53738fd1498Szrj    alternatives in which it can be early clobbered are given by
53838fd1498Szrj    EARLY_CLOBBER_ALTS.  */
53938fd1498Szrj static struct lra_insn_reg *
new_insn_reg(rtx_insn * insn,int regno,enum op_type type,machine_mode mode,bool subreg_p,bool early_clobber,alternative_mask early_clobber_alts,struct lra_insn_reg * next)54038fd1498Szrj new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
54138fd1498Szrj 	      machine_mode mode,
54238fd1498Szrj 	      bool subreg_p, bool early_clobber,
54338fd1498Szrj 	      alternative_mask early_clobber_alts,
54438fd1498Szrj 	      struct lra_insn_reg *next)
54538fd1498Szrj {
54638fd1498Szrj   lra_insn_reg *ir = lra_insn_reg_pool.allocate ();
54738fd1498Szrj   ir->type = type;
54838fd1498Szrj   ir->biggest_mode = mode;
54938fd1498Szrj   if (NONDEBUG_INSN_P (insn)
55038fd1498Szrj       && partial_subreg_p (lra_reg_info[regno].biggest_mode, mode))
55138fd1498Szrj     lra_reg_info[regno].biggest_mode = mode;
55238fd1498Szrj   ir->subreg_p = subreg_p;
55338fd1498Szrj   ir->early_clobber = early_clobber;
55438fd1498Szrj   ir->early_clobber_alts = early_clobber_alts;
55538fd1498Szrj   ir->regno = regno;
55638fd1498Szrj   ir->next = next;
55738fd1498Szrj   return ir;
55838fd1498Szrj }
55938fd1498Szrj 
56038fd1498Szrj /* Free insn reg info list IR.	*/
56138fd1498Szrj static void
free_insn_regs(struct lra_insn_reg * ir)56238fd1498Szrj free_insn_regs (struct lra_insn_reg *ir)
56338fd1498Szrj {
56438fd1498Szrj   struct lra_insn_reg *next_ir;
56538fd1498Szrj 
56638fd1498Szrj   for (; ir != NULL; ir = next_ir)
56738fd1498Szrj     {
56838fd1498Szrj       next_ir = ir->next;
56938fd1498Szrj       lra_insn_reg_pool.remove (ir);
57038fd1498Szrj     }
57138fd1498Szrj }
57238fd1498Szrj 
57338fd1498Szrj /* Finish pool for insn reg info.  */
57438fd1498Szrj static void
finish_insn_regs(void)57538fd1498Szrj finish_insn_regs (void)
57638fd1498Szrj {
57738fd1498Szrj   lra_insn_reg_pool.release ();
57838fd1498Szrj }
57938fd1498Szrj 
58038fd1498Szrj 
58138fd1498Szrj 
58238fd1498Szrj /* This page contains code dealing LRA insn info (or in other words
58338fd1498Szrj    LRA internal insn representation).  */
58438fd1498Szrj 
58538fd1498Szrj /* Map INSN_CODE -> the static insn data.  This info is valid during
58638fd1498Szrj    all translation unit.  */
58738fd1498Szrj struct lra_static_insn_data *insn_code_data[NUM_INSN_CODES];
58838fd1498Szrj 
58938fd1498Szrj /* Debug insns are represented as a special insn with one input
59038fd1498Szrj    operand which is RTL expression in var_location.  */
59138fd1498Szrj 
59238fd1498Szrj /* The following data are used as static insn operand data for all
59338fd1498Szrj    debug insns.	 If structure lra_operand_data is changed, the
59438fd1498Szrj    initializer should be changed too.  */
59538fd1498Szrj static struct lra_operand_data debug_operand_data =
59638fd1498Szrj   {
59738fd1498Szrj     NULL, /* alternative  */
59838fd1498Szrj     0, /* early_clobber_alts */
59938fd1498Szrj     E_VOIDmode, /* We are not interesting in the operand mode.  */
60038fd1498Szrj     OP_IN,
60138fd1498Szrj     0, 0, 0, 0
60238fd1498Szrj   };
60338fd1498Szrj 
60438fd1498Szrj /* The following data are used as static insn data for all debug
60538fd1498Szrj    bind insns.  If structure lra_static_insn_data is changed, the
60638fd1498Szrj    initializer should be changed too.  */
60738fd1498Szrj static struct lra_static_insn_data debug_bind_static_data =
60838fd1498Szrj   {
60938fd1498Szrj     &debug_operand_data,
61038fd1498Szrj     0,	/* Duplication operands #.  */
61138fd1498Szrj     -1, /* Commutative operand #.  */
61238fd1498Szrj     1,	/* Operands #.	There is only one operand which is debug RTL
61338fd1498Szrj 	   expression.	*/
61438fd1498Szrj     0,	/* Duplications #.  */
61538fd1498Szrj     0,	/* Alternatives #.  We are not interesting in alternatives
61638fd1498Szrj 	   because we does not proceed debug_insns for reloads.	 */
61738fd1498Szrj     NULL, /* Hard registers referenced in machine description.	*/
61838fd1498Szrj     NULL  /* Descriptions of operands in alternatives.	*/
61938fd1498Szrj   };
62038fd1498Szrj 
62138fd1498Szrj /* The following data are used as static insn data for all debug
62238fd1498Szrj    marker insns.  If structure lra_static_insn_data is changed, the
62338fd1498Szrj    initializer should be changed too.  */
62438fd1498Szrj static struct lra_static_insn_data debug_marker_static_data =
62538fd1498Szrj   {
62638fd1498Szrj     &debug_operand_data,
62738fd1498Szrj     0,	/* Duplication operands #.  */
62838fd1498Szrj     -1, /* Commutative operand #.  */
62938fd1498Szrj     0,	/* Operands #.	There isn't any operand.  */
63038fd1498Szrj     0,	/* Duplications #.  */
63138fd1498Szrj     0,	/* Alternatives #.  We are not interesting in alternatives
63238fd1498Szrj 	   because we does not proceed debug_insns for reloads.	 */
63338fd1498Szrj     NULL, /* Hard registers referenced in machine description.	*/
63438fd1498Szrj     NULL  /* Descriptions of operands in alternatives.	*/
63538fd1498Szrj   };
63638fd1498Szrj 
63738fd1498Szrj /* Called once per compiler work to initialize some LRA data related
63838fd1498Szrj    to insns.  */
63938fd1498Szrj static void
init_insn_code_data_once(void)64038fd1498Szrj init_insn_code_data_once (void)
64138fd1498Szrj {
64238fd1498Szrj   memset (insn_code_data, 0, sizeof (insn_code_data));
64338fd1498Szrj }
64438fd1498Szrj 
64538fd1498Szrj /* Called once per compiler work to finalize some LRA data related to
64638fd1498Szrj    insns.  */
64738fd1498Szrj static void
finish_insn_code_data_once(void)64838fd1498Szrj finish_insn_code_data_once (void)
64938fd1498Szrj {
65038fd1498Szrj   for (unsigned int i = 0; i < NUM_INSN_CODES; i++)
65138fd1498Szrj     {
65238fd1498Szrj       if (insn_code_data[i] != NULL)
65338fd1498Szrj 	free (insn_code_data[i]);
65438fd1498Szrj     }
65538fd1498Szrj }
65638fd1498Szrj 
65738fd1498Szrj /* Return static insn data, allocate and setup if necessary.  Although
65838fd1498Szrj    dup_num is static data (it depends only on icode), to set it up we
65938fd1498Szrj    need to extract insn first.	So recog_data should be valid for
66038fd1498Szrj    normal insn (ICODE >= 0) before the call.  */
66138fd1498Szrj static struct lra_static_insn_data *
get_static_insn_data(int icode,int nop,int ndup,int nalt)66238fd1498Szrj get_static_insn_data (int icode, int nop, int ndup, int nalt)
66338fd1498Szrj {
66438fd1498Szrj   struct lra_static_insn_data *data;
66538fd1498Szrj   size_t n_bytes;
66638fd1498Szrj 
66738fd1498Szrj   lra_assert (icode < (int) NUM_INSN_CODES);
66838fd1498Szrj   if (icode >= 0 && (data = insn_code_data[icode]) != NULL)
66938fd1498Szrj     return data;
67038fd1498Szrj   lra_assert (nop >= 0 && ndup >= 0 && nalt >= 0);
67138fd1498Szrj   n_bytes = sizeof (struct lra_static_insn_data)
67238fd1498Szrj 	    + sizeof (struct lra_operand_data) * nop
67338fd1498Szrj 	    + sizeof (int) * ndup;
67438fd1498Szrj   data = XNEWVAR (struct lra_static_insn_data, n_bytes);
67538fd1498Szrj   data->operand_alternative = NULL;
67638fd1498Szrj   data->n_operands = nop;
67738fd1498Szrj   data->n_dups = ndup;
67838fd1498Szrj   data->n_alternatives = nalt;
67938fd1498Szrj   data->operand = ((struct lra_operand_data *)
68038fd1498Szrj 		   ((char *) data + sizeof (struct lra_static_insn_data)));
68138fd1498Szrj   data->dup_num = ((int *) ((char *) data->operand
68238fd1498Szrj 			    + sizeof (struct lra_operand_data) * nop));
68338fd1498Szrj   if (icode >= 0)
68438fd1498Szrj     {
68538fd1498Szrj       int i;
68638fd1498Szrj 
68738fd1498Szrj       insn_code_data[icode] = data;
68838fd1498Szrj       for (i = 0; i < nop; i++)
68938fd1498Szrj 	{
69038fd1498Szrj 	  data->operand[i].constraint
69138fd1498Szrj 	    = insn_data[icode].operand[i].constraint;
69238fd1498Szrj 	  data->operand[i].mode = insn_data[icode].operand[i].mode;
69338fd1498Szrj 	  data->operand[i].strict_low = insn_data[icode].operand[i].strict_low;
69438fd1498Szrj 	  data->operand[i].is_operator
69538fd1498Szrj 	    = insn_data[icode].operand[i].is_operator;
69638fd1498Szrj 	  data->operand[i].type
69738fd1498Szrj 	    = (data->operand[i].constraint[0] == '=' ? OP_OUT
69838fd1498Szrj 	       : data->operand[i].constraint[0] == '+' ? OP_INOUT
69938fd1498Szrj 	       : OP_IN);
70038fd1498Szrj 	  data->operand[i].is_address = false;
70138fd1498Szrj 	}
70238fd1498Szrj       for (i = 0; i < ndup; i++)
70338fd1498Szrj 	data->dup_num[i] = recog_data.dup_num[i];
70438fd1498Szrj     }
70538fd1498Szrj   return data;
70638fd1498Szrj }
70738fd1498Szrj 
70838fd1498Szrj /* The current length of the following array.  */
70938fd1498Szrj int lra_insn_recog_data_len;
71038fd1498Szrj 
71138fd1498Szrj /* Map INSN_UID -> the insn recog data (NULL if unknown).  */
71238fd1498Szrj lra_insn_recog_data_t *lra_insn_recog_data;
71338fd1498Szrj 
71438fd1498Szrj /* Initialize LRA data about insns.  */
71538fd1498Szrj static void
init_insn_recog_data(void)71638fd1498Szrj init_insn_recog_data (void)
71738fd1498Szrj {
71838fd1498Szrj   lra_insn_recog_data_len = 0;
71938fd1498Szrj   lra_insn_recog_data = NULL;
72038fd1498Szrj }
72138fd1498Szrj 
72238fd1498Szrj /* Expand, if necessary, LRA data about insns.	*/
72338fd1498Szrj static void
check_and_expand_insn_recog_data(int index)72438fd1498Szrj check_and_expand_insn_recog_data (int index)
72538fd1498Szrj {
72638fd1498Szrj   int i, old;
72738fd1498Szrj 
72838fd1498Szrj   if (lra_insn_recog_data_len > index)
72938fd1498Szrj     return;
73038fd1498Szrj   old = lra_insn_recog_data_len;
73138fd1498Szrj   lra_insn_recog_data_len = index * 3 / 2 + 1;
73238fd1498Szrj   lra_insn_recog_data = XRESIZEVEC (lra_insn_recog_data_t,
73338fd1498Szrj 				    lra_insn_recog_data,
73438fd1498Szrj 				    lra_insn_recog_data_len);
73538fd1498Szrj   for (i = old; i < lra_insn_recog_data_len; i++)
73638fd1498Szrj     lra_insn_recog_data[i] = NULL;
73738fd1498Szrj }
73838fd1498Szrj 
73938fd1498Szrj /* Finish LRA DATA about insn.	*/
74038fd1498Szrj static void
free_insn_recog_data(lra_insn_recog_data_t data)74138fd1498Szrj free_insn_recog_data (lra_insn_recog_data_t data)
74238fd1498Szrj {
74338fd1498Szrj   if (data->operand_loc != NULL)
74438fd1498Szrj     free (data->operand_loc);
74538fd1498Szrj   if (data->dup_loc != NULL)
74638fd1498Szrj     free (data->dup_loc);
74738fd1498Szrj   if (data->arg_hard_regs != NULL)
74838fd1498Szrj     free (data->arg_hard_regs);
74938fd1498Szrj   if (data->icode < 0 && NONDEBUG_INSN_P (data->insn))
75038fd1498Szrj     {
75138fd1498Szrj       if (data->insn_static_data->operand_alternative != NULL)
75238fd1498Szrj 	free (const_cast <operand_alternative *>
75338fd1498Szrj 	      (data->insn_static_data->operand_alternative));
75438fd1498Szrj       free_insn_regs (data->insn_static_data->hard_regs);
75538fd1498Szrj       free (data->insn_static_data);
75638fd1498Szrj     }
75738fd1498Szrj   free_insn_regs (data->regs);
75838fd1498Szrj   data->regs = NULL;
75938fd1498Szrj   free (data);
76038fd1498Szrj }
76138fd1498Szrj 
76238fd1498Szrj /* Pools for copies.  */
76338fd1498Szrj static object_allocator<lra_copy> lra_copy_pool ("lra copies");
76438fd1498Szrj 
76538fd1498Szrj /* Finish LRA data about all insns.  */
76638fd1498Szrj static void
finish_insn_recog_data(void)76738fd1498Szrj finish_insn_recog_data (void)
76838fd1498Szrj {
76938fd1498Szrj   int i;
77038fd1498Szrj   lra_insn_recog_data_t data;
77138fd1498Szrj 
77238fd1498Szrj   for (i = 0; i < lra_insn_recog_data_len; i++)
77338fd1498Szrj     if ((data = lra_insn_recog_data[i]) != NULL)
77438fd1498Szrj       free_insn_recog_data (data);
77538fd1498Szrj   finish_insn_regs ();
77638fd1498Szrj   lra_copy_pool.release ();
77738fd1498Szrj   lra_insn_reg_pool.release ();
77838fd1498Szrj   free (lra_insn_recog_data);
77938fd1498Szrj }
78038fd1498Szrj 
78138fd1498Szrj /* Setup info about operands in alternatives of LRA DATA of insn.  */
78238fd1498Szrj static void
setup_operand_alternative(lra_insn_recog_data_t data,const operand_alternative * op_alt)78338fd1498Szrj setup_operand_alternative (lra_insn_recog_data_t data,
78438fd1498Szrj 			   const operand_alternative *op_alt)
78538fd1498Szrj {
78638fd1498Szrj   int i, j, nop, nalt;
78738fd1498Szrj   int icode = data->icode;
78838fd1498Szrj   struct lra_static_insn_data *static_data = data->insn_static_data;
78938fd1498Szrj 
79038fd1498Szrj   static_data->commutative = -1;
79138fd1498Szrj   nop = static_data->n_operands;
79238fd1498Szrj   nalt = static_data->n_alternatives;
79338fd1498Szrj   static_data->operand_alternative = op_alt;
79438fd1498Szrj   for (i = 0; i < nop; i++)
79538fd1498Szrj     {
79638fd1498Szrj       static_data->operand[i].early_clobber_alts = 0;
79738fd1498Szrj       static_data->operand[i].early_clobber = false;
79838fd1498Szrj       static_data->operand[i].is_address = false;
79938fd1498Szrj       if (static_data->operand[i].constraint[0] == '%')
80038fd1498Szrj 	{
80138fd1498Szrj 	  /* We currently only support one commutative pair of operands.  */
80238fd1498Szrj 	  if (static_data->commutative < 0)
80338fd1498Szrj 	    static_data->commutative = i;
80438fd1498Szrj 	  else
80538fd1498Szrj 	    lra_assert (icode < 0); /* Asm  */
80638fd1498Szrj 	  /* The last operand should not be marked commutative.  */
80738fd1498Szrj 	  lra_assert (i != nop - 1);
80838fd1498Szrj 	}
80938fd1498Szrj     }
81038fd1498Szrj   for (j = 0; j < nalt; j++)
81138fd1498Szrj     for (i = 0; i < nop; i++, op_alt++)
81238fd1498Szrj       {
81338fd1498Szrj 	static_data->operand[i].early_clobber |= op_alt->earlyclobber;
81438fd1498Szrj 	if (op_alt->earlyclobber)
81538fd1498Szrj 	  static_data->operand[i].early_clobber_alts |= (alternative_mask) 1 << j;
81638fd1498Szrj 	static_data->operand[i].is_address |= op_alt->is_address;
81738fd1498Szrj       }
81838fd1498Szrj }
81938fd1498Szrj 
82038fd1498Szrj /* Recursively process X and collect info about registers, which are
82138fd1498Szrj    not the insn operands, in X with TYPE (in/out/inout) and flag that
82238fd1498Szrj    it is early clobbered in the insn (EARLY_CLOBBER) and add the info
82338fd1498Szrj    to LIST.  X is a part of insn given by DATA.	 Return the result
82438fd1498Szrj    list.  */
82538fd1498Szrj static struct lra_insn_reg *
collect_non_operand_hard_regs(rtx_insn * insn,rtx * x,lra_insn_recog_data_t data,struct lra_insn_reg * list,enum op_type type,bool early_clobber)82638fd1498Szrj collect_non_operand_hard_regs (rtx_insn *insn, rtx *x,
82738fd1498Szrj 			       lra_insn_recog_data_t data,
82838fd1498Szrj 			       struct lra_insn_reg *list,
82938fd1498Szrj 			       enum op_type type, bool early_clobber)
83038fd1498Szrj {
83138fd1498Szrj   int i, j, regno, last;
83238fd1498Szrj   bool subreg_p;
83338fd1498Szrj   machine_mode mode;
83438fd1498Szrj   struct lra_insn_reg *curr;
83538fd1498Szrj   rtx op = *x;
83638fd1498Szrj   enum rtx_code code = GET_CODE (op);
83738fd1498Szrj   const char *fmt = GET_RTX_FORMAT (code);
83838fd1498Szrj 
83938fd1498Szrj   for (i = 0; i < data->insn_static_data->n_operands; i++)
84038fd1498Szrj     if (! data->insn_static_data->operand[i].is_operator
84138fd1498Szrj 	&& x == data->operand_loc[i])
84238fd1498Szrj       /* It is an operand loc. Stop here.  */
84338fd1498Szrj       return list;
84438fd1498Szrj   for (i = 0; i < data->insn_static_data->n_dups; i++)
84538fd1498Szrj     if (x == data->dup_loc[i])
84638fd1498Szrj       /* It is a dup loc. Stop here.  */
84738fd1498Szrj       return list;
84838fd1498Szrj   mode = GET_MODE (op);
84938fd1498Szrj   subreg_p = false;
85038fd1498Szrj   if (code == SUBREG)
85138fd1498Szrj     {
85238fd1498Szrj       mode = wider_subreg_mode (op);
85338fd1498Szrj       if (read_modify_subreg_p (op))
85438fd1498Szrj 	subreg_p = true;
85538fd1498Szrj       op = SUBREG_REG (op);
85638fd1498Szrj       code = GET_CODE (op);
85738fd1498Szrj     }
85838fd1498Szrj   if (REG_P (op))
85938fd1498Szrj     {
86038fd1498Szrj       if ((regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER)
86138fd1498Szrj 	return list;
86238fd1498Szrj       /* Process all regs even unallocatable ones as we need info
86338fd1498Szrj 	 about all regs for rematerialization pass.  */
86438fd1498Szrj       for (last = end_hard_regno (mode, regno); regno < last; regno++)
86538fd1498Szrj 	{
86638fd1498Szrj 	  for (curr = list; curr != NULL; curr = curr->next)
86738fd1498Szrj 	    if (curr->regno == regno && curr->subreg_p == subreg_p
86838fd1498Szrj 		&& curr->biggest_mode == mode)
86938fd1498Szrj 	      {
87038fd1498Szrj 		if (curr->type != type)
87138fd1498Szrj 		  curr->type = OP_INOUT;
87238fd1498Szrj 		if (early_clobber)
87338fd1498Szrj 		  {
87438fd1498Szrj 		    curr->early_clobber = true;
87538fd1498Szrj 		    curr->early_clobber_alts = ALL_ALTERNATIVES;
87638fd1498Szrj 		  }
87738fd1498Szrj 		break;
87838fd1498Szrj 	      }
87938fd1498Szrj 	  if (curr == NULL)
88038fd1498Szrj 	    {
88138fd1498Szrj 	      /* This is a new hard regno or the info can not be
88238fd1498Szrj 		 integrated into the found structure.	 */
88338fd1498Szrj #ifdef STACK_REGS
88438fd1498Szrj 	      early_clobber
88538fd1498Szrj 		= (early_clobber
88638fd1498Szrj 		   /* This clobber is to inform popping floating
88738fd1498Szrj 		      point stack only.  */
88838fd1498Szrj 		   && ! (FIRST_STACK_REG <= regno
88938fd1498Szrj 			 && regno <= LAST_STACK_REG));
89038fd1498Szrj #endif
89138fd1498Szrj 	      list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
89238fd1498Szrj 				   early_clobber,
89338fd1498Szrj 				   early_clobber ? ALL_ALTERNATIVES : 0, list);
89438fd1498Szrj 	    }
89538fd1498Szrj 	}
89638fd1498Szrj       return list;
89738fd1498Szrj     }
89838fd1498Szrj   switch (code)
89938fd1498Szrj     {
90038fd1498Szrj     case SET:
90138fd1498Szrj       list = collect_non_operand_hard_regs (insn, &SET_DEST (op), data,
90238fd1498Szrj 					    list, OP_OUT, false);
90338fd1498Szrj       list = collect_non_operand_hard_regs (insn, &SET_SRC (op), data,
90438fd1498Szrj 					    list, OP_IN, false);
90538fd1498Szrj       break;
90638fd1498Szrj     case CLOBBER:
90738fd1498Szrj       /* We treat clobber of non-operand hard registers as early clobber.  */
90838fd1498Szrj       list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
90938fd1498Szrj 					    list, OP_OUT, true);
91038fd1498Szrj       break;
91138fd1498Szrj     case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
91238fd1498Szrj       list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
91338fd1498Szrj 					    list, OP_INOUT, false);
91438fd1498Szrj       break;
91538fd1498Szrj     case PRE_MODIFY: case POST_MODIFY:
91638fd1498Szrj       list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
91738fd1498Szrj 					    list, OP_INOUT, false);
91838fd1498Szrj       list = collect_non_operand_hard_regs (insn, &XEXP (op, 1), data,
91938fd1498Szrj 					    list, OP_IN, false);
92038fd1498Szrj       break;
92138fd1498Szrj     default:
92238fd1498Szrj       fmt = GET_RTX_FORMAT (code);
92338fd1498Szrj       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
92438fd1498Szrj 	{
92538fd1498Szrj 	  if (fmt[i] == 'e')
92638fd1498Szrj 	    list = collect_non_operand_hard_regs (insn, &XEXP (op, i), data,
92738fd1498Szrj 						  list, OP_IN, false);
92838fd1498Szrj 	  else if (fmt[i] == 'E')
92938fd1498Szrj 	    for (j = XVECLEN (op, i) - 1; j >= 0; j--)
93038fd1498Szrj 	      list = collect_non_operand_hard_regs (insn, &XVECEXP (op, i, j),
93138fd1498Szrj 						    data, list, OP_IN, false);
93238fd1498Szrj 	}
93338fd1498Szrj     }
93438fd1498Szrj   return list;
93538fd1498Szrj }
93638fd1498Szrj 
93738fd1498Szrj /* Set up and return info about INSN.  Set up the info if it is not set up
93838fd1498Szrj    yet.	 */
93938fd1498Szrj lra_insn_recog_data_t
lra_set_insn_recog_data(rtx_insn * insn)94038fd1498Szrj lra_set_insn_recog_data (rtx_insn *insn)
94138fd1498Szrj {
94238fd1498Szrj   lra_insn_recog_data_t data;
94338fd1498Szrj   int i, n, icode;
94438fd1498Szrj   rtx **locs;
94538fd1498Szrj   unsigned int uid = INSN_UID (insn);
94638fd1498Szrj   struct lra_static_insn_data *insn_static_data;
94738fd1498Szrj 
94838fd1498Szrj   check_and_expand_insn_recog_data (uid);
94938fd1498Szrj   if (DEBUG_INSN_P (insn))
95038fd1498Szrj     icode = -1;
95138fd1498Szrj   else
95238fd1498Szrj     {
95338fd1498Szrj       icode = INSN_CODE (insn);
95438fd1498Szrj       if (icode < 0)
95538fd1498Szrj 	/* It might be a new simple insn which is not recognized yet.  */
95638fd1498Szrj 	INSN_CODE (insn) = icode = recog_memoized (insn);
95738fd1498Szrj     }
95838fd1498Szrj   data = XNEW (struct lra_insn_recog_data);
95938fd1498Szrj   lra_insn_recog_data[uid] = data;
96038fd1498Szrj   data->insn = insn;
96138fd1498Szrj   data->used_insn_alternative = LRA_UNKNOWN_ALT;
96238fd1498Szrj   data->icode = icode;
96338fd1498Szrj   data->regs = NULL;
96438fd1498Szrj   if (DEBUG_INSN_P (insn))
96538fd1498Szrj     {
96638fd1498Szrj       data->dup_loc = NULL;
96738fd1498Szrj       data->arg_hard_regs = NULL;
96838fd1498Szrj       data->preferred_alternatives = ALL_ALTERNATIVES;
96938fd1498Szrj       if (DEBUG_BIND_INSN_P (insn))
97038fd1498Szrj 	{
97138fd1498Szrj 	  data->insn_static_data = &debug_bind_static_data;
97238fd1498Szrj 	  data->operand_loc = XNEWVEC (rtx *, 1);
97338fd1498Szrj 	  data->operand_loc[0] = &INSN_VAR_LOCATION_LOC (insn);
97438fd1498Szrj 	}
97538fd1498Szrj       else if (DEBUG_MARKER_INSN_P (insn))
97638fd1498Szrj 	{
97738fd1498Szrj 	  data->insn_static_data = &debug_marker_static_data;
97838fd1498Szrj 	  data->operand_loc = NULL;
97938fd1498Szrj 	}
98038fd1498Szrj       return data;
98138fd1498Szrj     }
98238fd1498Szrj   if (icode < 0)
98338fd1498Szrj     {
98438fd1498Szrj       int nop, nalt;
98538fd1498Szrj       machine_mode operand_mode[MAX_RECOG_OPERANDS];
98638fd1498Szrj       const char *constraints[MAX_RECOG_OPERANDS];
98738fd1498Szrj 
98838fd1498Szrj       nop = asm_noperands (PATTERN (insn));
98938fd1498Szrj       data->operand_loc = data->dup_loc = NULL;
99038fd1498Szrj       nalt = 1;
99138fd1498Szrj       if (nop < 0)
99238fd1498Szrj 	{
99338fd1498Szrj 	  /* It is a special insn like USE or CLOBBER.  We should
99438fd1498Szrj 	     recognize any regular insn otherwise LRA can do nothing
99538fd1498Szrj 	     with this insn.  */
99638fd1498Szrj 	  gcc_assert (GET_CODE (PATTERN (insn)) == USE
99738fd1498Szrj 		      || GET_CODE (PATTERN (insn)) == CLOBBER
99838fd1498Szrj 		      || GET_CODE (PATTERN (insn)) == ASM_INPUT);
99938fd1498Szrj 	  data->insn_static_data = insn_static_data
100038fd1498Szrj 	    = get_static_insn_data (-1, 0, 0, nalt);
100138fd1498Szrj 	}
100238fd1498Szrj       else
100338fd1498Szrj 	{
100438fd1498Szrj 	  /* expand_asm_operands makes sure there aren't too many
100538fd1498Szrj 	     operands.	*/
100638fd1498Szrj 	  lra_assert (nop <= MAX_RECOG_OPERANDS);
100738fd1498Szrj 	  if (nop != 0)
100838fd1498Szrj 	    data->operand_loc = XNEWVEC (rtx *, nop);
100938fd1498Szrj 	  /* Now get the operand values and constraints out of the
101038fd1498Szrj 	     insn.  */
101138fd1498Szrj 	  decode_asm_operands (PATTERN (insn), NULL,
101238fd1498Szrj 			       data->operand_loc,
101338fd1498Szrj 			       constraints, operand_mode, NULL);
101438fd1498Szrj 	  if (nop > 0)
101538fd1498Szrj 	    {
101638fd1498Szrj 	      const char *p =  recog_data.constraints[0];
101738fd1498Szrj 
101838fd1498Szrj 	      for (p =	constraints[0]; *p; p++)
101938fd1498Szrj 		nalt += *p == ',';
102038fd1498Szrj 	    }
102138fd1498Szrj 	  data->insn_static_data = insn_static_data
102238fd1498Szrj 	    = get_static_insn_data (-1, nop, 0, nalt);
102338fd1498Szrj 	  for (i = 0; i < nop; i++)
102438fd1498Szrj 	    {
102538fd1498Szrj 	      insn_static_data->operand[i].mode = operand_mode[i];
102638fd1498Szrj 	      insn_static_data->operand[i].constraint = constraints[i];
102738fd1498Szrj 	      insn_static_data->operand[i].strict_low = false;
102838fd1498Szrj 	      insn_static_data->operand[i].is_operator = false;
102938fd1498Szrj 	      insn_static_data->operand[i].is_address = false;
103038fd1498Szrj 	    }
103138fd1498Szrj 	}
103238fd1498Szrj       for (i = 0; i < insn_static_data->n_operands; i++)
103338fd1498Szrj 	insn_static_data->operand[i].type
103438fd1498Szrj 	  = (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT
103538fd1498Szrj 	     : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
103638fd1498Szrj 	     : OP_IN);
103738fd1498Szrj       data->preferred_alternatives = ALL_ALTERNATIVES;
103838fd1498Szrj       if (nop > 0)
103938fd1498Szrj 	{
104038fd1498Szrj 	  operand_alternative *op_alt = XCNEWVEC (operand_alternative,
104138fd1498Szrj 						  nalt * nop);
104238fd1498Szrj 	  preprocess_constraints (nop, nalt, constraints, op_alt,
104338fd1498Szrj 				  data->operand_loc);
104438fd1498Szrj 	  setup_operand_alternative (data, op_alt);
104538fd1498Szrj 	}
104638fd1498Szrj     }
104738fd1498Szrj   else
104838fd1498Szrj     {
104938fd1498Szrj       insn_extract (insn);
105038fd1498Szrj       data->insn_static_data = insn_static_data
105138fd1498Szrj 	= get_static_insn_data (icode, insn_data[icode].n_operands,
105238fd1498Szrj 				insn_data[icode].n_dups,
105338fd1498Szrj 				insn_data[icode].n_alternatives);
105438fd1498Szrj       n = insn_static_data->n_operands;
105538fd1498Szrj       if (n == 0)
105638fd1498Szrj 	locs = NULL;
105738fd1498Szrj       else
105838fd1498Szrj 	{
105938fd1498Szrj 	  locs = XNEWVEC (rtx *, n);
106038fd1498Szrj 	  memcpy (locs, recog_data.operand_loc, n * sizeof (rtx *));
106138fd1498Szrj 	}
106238fd1498Szrj       data->operand_loc = locs;
106338fd1498Szrj       n = insn_static_data->n_dups;
106438fd1498Szrj       if (n == 0)
106538fd1498Szrj 	locs = NULL;
106638fd1498Szrj       else
106738fd1498Szrj 	{
106838fd1498Szrj 	  locs = XNEWVEC (rtx *, n);
106938fd1498Szrj 	  memcpy (locs, recog_data.dup_loc, n * sizeof (rtx *));
107038fd1498Szrj 	}
107138fd1498Szrj       data->dup_loc = locs;
107238fd1498Szrj       data->preferred_alternatives = get_preferred_alternatives (insn);
107338fd1498Szrj       const operand_alternative *op_alt = preprocess_insn_constraints (icode);
107438fd1498Szrj       if (!insn_static_data->operand_alternative)
107538fd1498Szrj 	setup_operand_alternative (data, op_alt);
107638fd1498Szrj       else if (op_alt != insn_static_data->operand_alternative)
107738fd1498Szrj 	insn_static_data->operand_alternative = op_alt;
107838fd1498Szrj     }
107938fd1498Szrj   if (GET_CODE (PATTERN (insn)) == CLOBBER || GET_CODE (PATTERN (insn)) == USE)
108038fd1498Szrj     insn_static_data->hard_regs = NULL;
108138fd1498Szrj   else
108238fd1498Szrj     insn_static_data->hard_regs
108338fd1498Szrj       = collect_non_operand_hard_regs (insn, &PATTERN (insn), data,
108438fd1498Szrj 				       NULL, OP_IN, false);
108538fd1498Szrj   data->arg_hard_regs = NULL;
108638fd1498Szrj   if (CALL_P (insn))
108738fd1498Szrj     {
108838fd1498Szrj       bool use_p;
108938fd1498Szrj       rtx link;
109038fd1498Szrj       int n_hard_regs, regno, arg_hard_regs[FIRST_PSEUDO_REGISTER];
109138fd1498Szrj 
109238fd1498Szrj       n_hard_regs = 0;
109338fd1498Szrj       /* Finding implicit hard register usage.	We believe it will be
109438fd1498Szrj 	 not changed whatever transformations are used.	 Call insns
109538fd1498Szrj 	 are such example.  */
109638fd1498Szrj       for (link = CALL_INSN_FUNCTION_USAGE (insn);
109738fd1498Szrj 	   link != NULL_RTX;
109838fd1498Szrj 	   link = XEXP (link, 1))
109938fd1498Szrj 	if (((use_p = GET_CODE (XEXP (link, 0)) == USE)
110038fd1498Szrj 	     || GET_CODE (XEXP (link, 0)) == CLOBBER)
110138fd1498Szrj 	    && REG_P (XEXP (XEXP (link, 0), 0)))
110238fd1498Szrj 	  {
110338fd1498Szrj 	    regno = REGNO (XEXP (XEXP (link, 0), 0));
110438fd1498Szrj 	    lra_assert (regno < FIRST_PSEUDO_REGISTER);
110538fd1498Szrj 	    /* It is an argument register.  */
110638fd1498Szrj 	    for (i = REG_NREGS (XEXP (XEXP (link, 0), 0)) - 1; i >= 0; i--)
110738fd1498Szrj 	      arg_hard_regs[n_hard_regs++]
110838fd1498Szrj 		= regno + i + (use_p ? 0 : FIRST_PSEUDO_REGISTER);
110938fd1498Szrj 	  }
111038fd1498Szrj       if (n_hard_regs != 0)
111138fd1498Szrj 	{
111238fd1498Szrj 	  arg_hard_regs[n_hard_regs++] = -1;
111338fd1498Szrj 	  data->arg_hard_regs = XNEWVEC (int, n_hard_regs);
111438fd1498Szrj 	  memcpy (data->arg_hard_regs, arg_hard_regs,
111538fd1498Szrj 		  sizeof (int) * n_hard_regs);
111638fd1498Szrj 	}
111738fd1498Szrj     }
111838fd1498Szrj   /* Some output operand can be recognized only from the context not
111938fd1498Szrj      from the constraints which are empty in this case.	 Call insn may
112038fd1498Szrj      contain a hard register in set destination with empty constraint
112138fd1498Szrj      and extract_insn treats them as an input.	*/
112238fd1498Szrj   for (i = 0; i < insn_static_data->n_operands; i++)
112338fd1498Szrj     {
112438fd1498Szrj       int j;
112538fd1498Szrj       rtx pat, set;
112638fd1498Szrj       struct lra_operand_data *operand = &insn_static_data->operand[i];
112738fd1498Szrj 
112838fd1498Szrj       /* ??? Should we treat 'X' the same way.	It looks to me that
112938fd1498Szrj 	 'X' means anything and empty constraint means we do not
113038fd1498Szrj 	 care.	*/
113138fd1498Szrj       if (operand->type != OP_IN || *operand->constraint != '\0'
113238fd1498Szrj 	  || operand->is_operator)
113338fd1498Szrj 	continue;
113438fd1498Szrj       pat = PATTERN (insn);
113538fd1498Szrj       if (GET_CODE (pat) == SET)
113638fd1498Szrj 	{
113738fd1498Szrj 	  if (data->operand_loc[i] != &SET_DEST (pat))
113838fd1498Szrj 	    continue;
113938fd1498Szrj 	}
114038fd1498Szrj       else if (GET_CODE (pat) == PARALLEL)
114138fd1498Szrj 	{
114238fd1498Szrj 	  for (j = XVECLEN (pat, 0) - 1; j >= 0; j--)
114338fd1498Szrj 	    {
114438fd1498Szrj 	      set = XVECEXP (PATTERN (insn), 0, j);
114538fd1498Szrj 	      if (GET_CODE (set) == SET
114638fd1498Szrj 		  && &SET_DEST (set) == data->operand_loc[i])
114738fd1498Szrj 		break;
114838fd1498Szrj 	    }
114938fd1498Szrj 	  if (j < 0)
115038fd1498Szrj 	    continue;
115138fd1498Szrj 	}
115238fd1498Szrj       else
115338fd1498Szrj 	continue;
115438fd1498Szrj       operand->type = OP_OUT;
115538fd1498Szrj     }
115638fd1498Szrj   return data;
115738fd1498Szrj }
115838fd1498Szrj 
115938fd1498Szrj /* Return info about insn give by UID.	The info should be already set
116038fd1498Szrj    up.	*/
116138fd1498Szrj static lra_insn_recog_data_t
get_insn_recog_data_by_uid(int uid)116238fd1498Szrj get_insn_recog_data_by_uid (int uid)
116338fd1498Szrj {
116438fd1498Szrj   lra_insn_recog_data_t data;
116538fd1498Szrj 
116638fd1498Szrj   data = lra_insn_recog_data[uid];
116738fd1498Szrj   lra_assert (data != NULL);
116838fd1498Szrj   return data;
116938fd1498Szrj }
117038fd1498Szrj 
117138fd1498Szrj /* Invalidate all info about insn given by its UID.  */
117238fd1498Szrj static void
invalidate_insn_recog_data(int uid)117338fd1498Szrj invalidate_insn_recog_data (int uid)
117438fd1498Szrj {
117538fd1498Szrj   lra_insn_recog_data_t data;
117638fd1498Szrj 
117738fd1498Szrj   data = lra_insn_recog_data[uid];
117838fd1498Szrj   lra_assert (data != NULL);
117938fd1498Szrj   free_insn_recog_data (data);
118038fd1498Szrj   lra_insn_recog_data[uid] = NULL;
118138fd1498Szrj }
118238fd1498Szrj 
118338fd1498Szrj /* Update all the insn info about INSN.	 It is usually called when
118438fd1498Szrj    something in the insn was changed.  Return the updated info.	 */
118538fd1498Szrj lra_insn_recog_data_t
lra_update_insn_recog_data(rtx_insn * insn)118638fd1498Szrj lra_update_insn_recog_data (rtx_insn *insn)
118738fd1498Szrj {
118838fd1498Szrj   lra_insn_recog_data_t data;
118938fd1498Szrj   int n;
119038fd1498Szrj   unsigned int uid = INSN_UID (insn);
119138fd1498Szrj   struct lra_static_insn_data *insn_static_data;
119238fd1498Szrj   poly_int64 sp_offset = 0;
119338fd1498Szrj 
119438fd1498Szrj   check_and_expand_insn_recog_data (uid);
119538fd1498Szrj   if ((data = lra_insn_recog_data[uid]) != NULL
119638fd1498Szrj       && data->icode != INSN_CODE (insn))
119738fd1498Szrj     {
119838fd1498Szrj       sp_offset = data->sp_offset;
119938fd1498Szrj       invalidate_insn_data_regno_info (data, insn, get_insn_freq (insn));
120038fd1498Szrj       invalidate_insn_recog_data (uid);
120138fd1498Szrj       data = NULL;
120238fd1498Szrj     }
120338fd1498Szrj   if (data == NULL)
120438fd1498Szrj     {
120538fd1498Szrj       data = lra_get_insn_recog_data (insn);
120638fd1498Szrj       /* Initiate or restore SP offset.  */
120738fd1498Szrj       data->sp_offset = sp_offset;
120838fd1498Szrj       return data;
120938fd1498Szrj     }
121038fd1498Szrj   insn_static_data = data->insn_static_data;
121138fd1498Szrj   data->used_insn_alternative = LRA_UNKNOWN_ALT;
121238fd1498Szrj   if (DEBUG_INSN_P (insn))
121338fd1498Szrj     return data;
121438fd1498Szrj   if (data->icode < 0)
121538fd1498Szrj     {
121638fd1498Szrj       int nop;
121738fd1498Szrj       machine_mode operand_mode[MAX_RECOG_OPERANDS];
121838fd1498Szrj       const char *constraints[MAX_RECOG_OPERANDS];
121938fd1498Szrj 
122038fd1498Szrj       nop = asm_noperands (PATTERN (insn));
122138fd1498Szrj       if (nop >= 0)
122238fd1498Szrj 	{
122338fd1498Szrj 	  lra_assert (nop == data->insn_static_data->n_operands);
122438fd1498Szrj 	  /* Now get the operand values and constraints out of the
122538fd1498Szrj 	     insn.  */
122638fd1498Szrj 	  decode_asm_operands (PATTERN (insn), NULL,
122738fd1498Szrj 			       data->operand_loc,
122838fd1498Szrj 			       constraints, operand_mode, NULL);
122938fd1498Szrj 
123038fd1498Szrj 	  if (flag_checking)
123138fd1498Szrj 	    for (int i = 0; i < nop; i++)
123238fd1498Szrj 	      lra_assert
123338fd1498Szrj 		(insn_static_data->operand[i].mode == operand_mode[i]
123438fd1498Szrj 		 && insn_static_data->operand[i].constraint == constraints[i]
123538fd1498Szrj 		 && ! insn_static_data->operand[i].is_operator);
123638fd1498Szrj 	}
123738fd1498Szrj 
123838fd1498Szrj       if (flag_checking)
123938fd1498Szrj 	for (int i = 0; i < insn_static_data->n_operands; i++)
124038fd1498Szrj 	  lra_assert
124138fd1498Szrj 	    (insn_static_data->operand[i].type
124238fd1498Szrj 	     == (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT
124338fd1498Szrj 		 : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
124438fd1498Szrj 		 : OP_IN));
124538fd1498Szrj     }
124638fd1498Szrj   else
124738fd1498Szrj     {
124838fd1498Szrj       insn_extract (insn);
124938fd1498Szrj       n = insn_static_data->n_operands;
125038fd1498Szrj       if (n != 0)
125138fd1498Szrj 	memcpy (data->operand_loc, recog_data.operand_loc, n * sizeof (rtx *));
125238fd1498Szrj       n = insn_static_data->n_dups;
125338fd1498Szrj       if (n != 0)
125438fd1498Szrj 	memcpy (data->dup_loc, recog_data.dup_loc, n * sizeof (rtx *));
125538fd1498Szrj       lra_assert (check_bool_attrs (insn));
125638fd1498Szrj     }
125738fd1498Szrj   return data;
125838fd1498Szrj }
125938fd1498Szrj 
126038fd1498Szrj /* Set up that INSN is using alternative ALT now.  */
126138fd1498Szrj void
lra_set_used_insn_alternative(rtx_insn * insn,int alt)126238fd1498Szrj lra_set_used_insn_alternative (rtx_insn *insn, int alt)
126338fd1498Szrj {
126438fd1498Szrj   lra_insn_recog_data_t data;
126538fd1498Szrj 
126638fd1498Szrj   data = lra_get_insn_recog_data (insn);
126738fd1498Szrj   data->used_insn_alternative = alt;
126838fd1498Szrj }
126938fd1498Szrj 
127038fd1498Szrj /* Set up that insn with UID is using alternative ALT now.  The insn
127138fd1498Szrj    info should be already set up.  */
127238fd1498Szrj void
lra_set_used_insn_alternative_by_uid(int uid,int alt)127338fd1498Szrj lra_set_used_insn_alternative_by_uid (int uid, int alt)
127438fd1498Szrj {
127538fd1498Szrj   lra_insn_recog_data_t data;
127638fd1498Szrj 
127738fd1498Szrj   check_and_expand_insn_recog_data (uid);
127838fd1498Szrj   data = lra_insn_recog_data[uid];
127938fd1498Szrj   lra_assert (data != NULL);
128038fd1498Szrj   data->used_insn_alternative = alt;
128138fd1498Szrj }
128238fd1498Szrj 
128338fd1498Szrj 
128438fd1498Szrj 
128538fd1498Szrj /* This page contains code dealing with common register info and
128638fd1498Szrj    pseudo copies.  */
128738fd1498Szrj 
128838fd1498Szrj /* The size of the following array.  */
128938fd1498Szrj static int reg_info_size;
129038fd1498Szrj /* Common info about each register.  */
129138fd1498Szrj struct lra_reg *lra_reg_info;
129238fd1498Szrj 
129338fd1498Szrj HARD_REG_SET hard_regs_spilled_into;
129438fd1498Szrj 
129538fd1498Szrj /* Last register value.	 */
129638fd1498Szrj static int last_reg_value;
129738fd1498Szrj 
129838fd1498Szrj /* Return new register value.  */
129938fd1498Szrj static int
get_new_reg_value(void)130038fd1498Szrj get_new_reg_value (void)
130138fd1498Szrj {
130238fd1498Szrj   return ++last_reg_value;
130338fd1498Szrj }
130438fd1498Szrj 
130538fd1498Szrj /* Vec referring to pseudo copies.  */
130638fd1498Szrj static vec<lra_copy_t> copy_vec;
130738fd1498Szrj 
130838fd1498Szrj /* Initialize I-th element of lra_reg_info.  */
130938fd1498Szrj static inline void
initialize_lra_reg_info_element(int i)131038fd1498Szrj initialize_lra_reg_info_element (int i)
131138fd1498Szrj {
131238fd1498Szrj   bitmap_initialize (&lra_reg_info[i].insn_bitmap, &reg_obstack);
131338fd1498Szrj #ifdef STACK_REGS
131438fd1498Szrj   lra_reg_info[i].no_stack_p = false;
131538fd1498Szrj #endif
131638fd1498Szrj   CLEAR_HARD_REG_SET (lra_reg_info[i].conflict_hard_regs);
131738fd1498Szrj   CLEAR_HARD_REG_SET (lra_reg_info[i].actual_call_used_reg_set);
131838fd1498Szrj   lra_reg_info[i].preferred_hard_regno1 = -1;
131938fd1498Szrj   lra_reg_info[i].preferred_hard_regno2 = -1;
132038fd1498Szrj   lra_reg_info[i].preferred_hard_regno_profit1 = 0;
132138fd1498Szrj   lra_reg_info[i].preferred_hard_regno_profit2 = 0;
132238fd1498Szrj   lra_reg_info[i].biggest_mode = VOIDmode;
132338fd1498Szrj   lra_reg_info[i].live_ranges = NULL;
132438fd1498Szrj   lra_reg_info[i].nrefs = lra_reg_info[i].freq = 0;
132538fd1498Szrj   lra_reg_info[i].last_reload = 0;
132638fd1498Szrj   lra_reg_info[i].restore_rtx = NULL_RTX;
132738fd1498Szrj   lra_reg_info[i].val = get_new_reg_value ();
132838fd1498Szrj   lra_reg_info[i].offset = 0;
132938fd1498Szrj   lra_reg_info[i].copies = NULL;
133038fd1498Szrj }
133138fd1498Szrj 
133238fd1498Szrj /* Initialize common reg info and copies.  */
133338fd1498Szrj static void
init_reg_info(void)133438fd1498Szrj init_reg_info (void)
133538fd1498Szrj {
133638fd1498Szrj   int i;
133738fd1498Szrj 
133838fd1498Szrj   last_reg_value = 0;
133938fd1498Szrj   reg_info_size = max_reg_num () * 3 / 2 + 1;
134038fd1498Szrj   lra_reg_info = XNEWVEC (struct lra_reg, reg_info_size);
134138fd1498Szrj   for (i = 0; i < reg_info_size; i++)
134238fd1498Szrj     initialize_lra_reg_info_element (i);
134338fd1498Szrj   copy_vec.truncate (0);
134438fd1498Szrj   CLEAR_HARD_REG_SET (hard_regs_spilled_into);
134538fd1498Szrj }
134638fd1498Szrj 
134738fd1498Szrj 
134838fd1498Szrj /* Finish common reg info and copies.  */
134938fd1498Szrj static void
finish_reg_info(void)135038fd1498Szrj finish_reg_info (void)
135138fd1498Szrj {
135238fd1498Szrj   int i;
135338fd1498Szrj 
135438fd1498Szrj   for (i = 0; i < reg_info_size; i++)
135538fd1498Szrj     bitmap_clear (&lra_reg_info[i].insn_bitmap);
135638fd1498Szrj   free (lra_reg_info);
135738fd1498Szrj   reg_info_size = 0;
135838fd1498Szrj }
135938fd1498Szrj 
136038fd1498Szrj /* Expand common reg info if it is necessary.  */
136138fd1498Szrj static void
expand_reg_info(void)136238fd1498Szrj expand_reg_info (void)
136338fd1498Szrj {
136438fd1498Szrj   int i, old = reg_info_size;
136538fd1498Szrj 
136638fd1498Szrj   if (reg_info_size > max_reg_num ())
136738fd1498Szrj     return;
136838fd1498Szrj   reg_info_size = max_reg_num () * 3 / 2 + 1;
136938fd1498Szrj   lra_reg_info = XRESIZEVEC (struct lra_reg, lra_reg_info, reg_info_size);
137038fd1498Szrj   for (i = old; i < reg_info_size; i++)
137138fd1498Szrj     initialize_lra_reg_info_element (i);
137238fd1498Szrj }
137338fd1498Szrj 
137438fd1498Szrj /* Free all copies.  */
137538fd1498Szrj void
lra_free_copies(void)137638fd1498Szrj lra_free_copies (void)
137738fd1498Szrj {
137838fd1498Szrj   lra_copy_t cp;
137938fd1498Szrj 
138038fd1498Szrj   while (copy_vec.length () != 0)
138138fd1498Szrj     {
138238fd1498Szrj       cp = copy_vec.pop ();
138338fd1498Szrj       lra_reg_info[cp->regno1].copies = lra_reg_info[cp->regno2].copies = NULL;
138438fd1498Szrj       lra_copy_pool.remove (cp);
138538fd1498Szrj     }
138638fd1498Szrj }
138738fd1498Szrj 
138838fd1498Szrj /* Create copy of two pseudos REGNO1 and REGNO2.  The copy execution
138938fd1498Szrj    frequency is FREQ.  */
139038fd1498Szrj void
lra_create_copy(int regno1,int regno2,int freq)139138fd1498Szrj lra_create_copy (int regno1, int regno2, int freq)
139238fd1498Szrj {
139338fd1498Szrj   bool regno1_dest_p;
139438fd1498Szrj   lra_copy_t cp;
139538fd1498Szrj 
139638fd1498Szrj   lra_assert (regno1 != regno2);
139738fd1498Szrj   regno1_dest_p = true;
139838fd1498Szrj   if (regno1 > regno2)
139938fd1498Szrj     {
140038fd1498Szrj       std::swap (regno1, regno2);
140138fd1498Szrj       regno1_dest_p = false;
140238fd1498Szrj     }
140338fd1498Szrj   cp = lra_copy_pool.allocate ();
140438fd1498Szrj   copy_vec.safe_push (cp);
140538fd1498Szrj   cp->regno1_dest_p = regno1_dest_p;
140638fd1498Szrj   cp->freq = freq;
140738fd1498Szrj   cp->regno1 = regno1;
140838fd1498Szrj   cp->regno2 = regno2;
140938fd1498Szrj   cp->regno1_next = lra_reg_info[regno1].copies;
141038fd1498Szrj   lra_reg_info[regno1].copies = cp;
141138fd1498Szrj   cp->regno2_next = lra_reg_info[regno2].copies;
141238fd1498Szrj   lra_reg_info[regno2].copies = cp;
141338fd1498Szrj   if (lra_dump_file != NULL)
141438fd1498Szrj     fprintf (lra_dump_file, "	   Creating copy r%d%sr%d@%d\n",
141538fd1498Szrj 	     regno1, regno1_dest_p ? "<-" : "->", regno2, freq);
141638fd1498Szrj }
141738fd1498Szrj 
141838fd1498Szrj /* Return N-th (0, 1, ...) copy.  If there is no copy, return
141938fd1498Szrj    NULL.  */
142038fd1498Szrj lra_copy_t
lra_get_copy(int n)142138fd1498Szrj lra_get_copy (int n)
142238fd1498Szrj {
142338fd1498Szrj   if (n >= (int) copy_vec.length ())
142438fd1498Szrj     return NULL;
142538fd1498Szrj   return copy_vec[n];
142638fd1498Szrj }
142738fd1498Szrj 
142838fd1498Szrj 
142938fd1498Szrj 
143038fd1498Szrj /* This page contains code dealing with info about registers in
143138fd1498Szrj    insns.  */
143238fd1498Szrj 
143338fd1498Szrj /* Process X of INSN recursively and add info (operand type is
143438fd1498Szrj    given by TYPE, flag of that it is early clobber is EARLY_CLOBBER)
143538fd1498Szrj    about registers in X to the insn DATA.  If X can be early clobbered,
143638fd1498Szrj    alternatives in which it can be early clobbered are given by
143738fd1498Szrj    EARLY_CLOBBER_ALTS.  */
143838fd1498Szrj static void
add_regs_to_insn_regno_info(lra_insn_recog_data_t data,rtx x,rtx_insn * insn,enum op_type type,bool early_clobber,alternative_mask early_clobber_alts)143938fd1498Szrj add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
144038fd1498Szrj 			     rtx_insn *insn,
144138fd1498Szrj 			     enum op_type type, bool early_clobber,
144238fd1498Szrj 			     alternative_mask early_clobber_alts)
144338fd1498Szrj {
144438fd1498Szrj   int i, j, regno;
144538fd1498Szrj   bool subreg_p;
144638fd1498Szrj   machine_mode mode;
144738fd1498Szrj   const char *fmt;
144838fd1498Szrj   enum rtx_code code;
144938fd1498Szrj   struct lra_insn_reg *curr;
145038fd1498Szrj 
145138fd1498Szrj   code = GET_CODE (x);
145238fd1498Szrj   mode = GET_MODE (x);
145338fd1498Szrj   subreg_p = false;
145438fd1498Szrj   if (GET_CODE (x) == SUBREG)
145538fd1498Szrj     {
145638fd1498Szrj       mode = wider_subreg_mode (x);
145738fd1498Szrj       if (read_modify_subreg_p (x))
145838fd1498Szrj 	subreg_p = true;
145938fd1498Szrj       x = SUBREG_REG (x);
146038fd1498Szrj       code = GET_CODE (x);
146138fd1498Szrj     }
146238fd1498Szrj   if (REG_P (x))
146338fd1498Szrj     {
146438fd1498Szrj       regno = REGNO (x);
146538fd1498Szrj       /* Process all regs even unallocatable ones as we need info about
146638fd1498Szrj 	 all regs for rematerialization pass.  */
146738fd1498Szrj       expand_reg_info ();
146838fd1498Szrj       if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, INSN_UID (insn)))
146938fd1498Szrj 	{
147038fd1498Szrj 	  data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
147138fd1498Szrj 				     early_clobber, early_clobber_alts,
147238fd1498Szrj 				     data->regs);
147338fd1498Szrj 	  return;
147438fd1498Szrj 	}
147538fd1498Szrj       else
147638fd1498Szrj 	{
147738fd1498Szrj 	  for (curr = data->regs; curr != NULL; curr = curr->next)
147838fd1498Szrj 	    if (curr->regno == regno)
147938fd1498Szrj 	      {
148038fd1498Szrj 		if (curr->subreg_p != subreg_p || curr->biggest_mode != mode)
148138fd1498Szrj 		  /* The info can not be integrated into the found
148238fd1498Szrj 		     structure.  */
148338fd1498Szrj 		  data->regs = new_insn_reg (data->insn, regno, type, mode,
148438fd1498Szrj 					     subreg_p, early_clobber,
148538fd1498Szrj 					     early_clobber_alts, data->regs);
148638fd1498Szrj 		else
148738fd1498Szrj 		  {
148838fd1498Szrj 		    if (curr->type != type)
148938fd1498Szrj 		      curr->type = OP_INOUT;
149038fd1498Szrj 		    if (curr->early_clobber != early_clobber)
149138fd1498Szrj 		      curr->early_clobber = true;
149238fd1498Szrj 		    curr->early_clobber_alts |= early_clobber_alts;
149338fd1498Szrj 		  }
149438fd1498Szrj 		return;
149538fd1498Szrj 	      }
149638fd1498Szrj 	  gcc_unreachable ();
149738fd1498Szrj 	}
149838fd1498Szrj     }
149938fd1498Szrj 
150038fd1498Szrj   switch (code)
150138fd1498Szrj     {
150238fd1498Szrj     case SET:
150338fd1498Szrj       add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, false, 0);
150438fd1498Szrj       add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, false, 0);
150538fd1498Szrj       break;
150638fd1498Szrj     case CLOBBER:
150738fd1498Szrj       /* We treat clobber of non-operand hard registers as early
150838fd1498Szrj 	 clobber.  */
150938fd1498Szrj       add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT,
151038fd1498Szrj 				   true, ALL_ALTERNATIVES);
151138fd1498Szrj       break;
151238fd1498Szrj     case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
151338fd1498Szrj       add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
151438fd1498Szrj       break;
151538fd1498Szrj     case PRE_MODIFY: case POST_MODIFY:
151638fd1498Szrj       add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
151738fd1498Szrj       add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, false, 0);
151838fd1498Szrj       break;
151938fd1498Szrj     default:
152038fd1498Szrj       if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
152138fd1498Szrj 	/* Some targets place small structures in registers for return
152238fd1498Szrj 	   values of functions, and those registers are wrapped in
152338fd1498Szrj 	   PARALLEL that we may see as the destination of a SET.  Here
152438fd1498Szrj 	   is an example:
152538fd1498Szrj 
152638fd1498Szrj 	   (call_insn 13 12 14 2 (set (parallel:BLK [
152738fd1498Szrj 		(expr_list:REG_DEP_TRUE (reg:DI 0 ax)
152838fd1498Szrj 		    (const_int 0 [0]))
152938fd1498Szrj 		(expr_list:REG_DEP_TRUE (reg:DI 1 dx)
153038fd1498Szrj 		    (const_int 8 [0x8]))
153138fd1498Szrj 	       ])
153238fd1498Szrj 	     (call (mem:QI (symbol_ref:DI (...	*/
153338fd1498Szrj 	type = OP_IN;
153438fd1498Szrj       fmt = GET_RTX_FORMAT (code);
153538fd1498Szrj       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
153638fd1498Szrj 	{
153738fd1498Szrj 	  if (fmt[i] == 'e')
153838fd1498Szrj 	    add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, false, 0);
153938fd1498Szrj 	  else if (fmt[i] == 'E')
154038fd1498Szrj 	    {
154138fd1498Szrj 	      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
154238fd1498Szrj 		add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), insn,
154338fd1498Szrj 					     type, false, 0);
154438fd1498Szrj 	    }
154538fd1498Szrj 	}
154638fd1498Szrj     }
154738fd1498Szrj }
154838fd1498Szrj 
154938fd1498Szrj /* Return execution frequency of INSN.	*/
155038fd1498Szrj static int
get_insn_freq(rtx_insn * insn)155138fd1498Szrj get_insn_freq (rtx_insn *insn)
155238fd1498Szrj {
155338fd1498Szrj   basic_block bb = BLOCK_FOR_INSN (insn);
155438fd1498Szrj 
155538fd1498Szrj   gcc_checking_assert (bb != NULL);
155638fd1498Szrj   return REG_FREQ_FROM_BB (bb);
155738fd1498Szrj }
155838fd1498Szrj 
155938fd1498Szrj /* Invalidate all reg info of INSN with DATA and execution frequency
156038fd1498Szrj    FREQ.  Update common info about the invalidated registers.  */
156138fd1498Szrj static void
invalidate_insn_data_regno_info(lra_insn_recog_data_t data,rtx_insn * insn,int freq)156238fd1498Szrj invalidate_insn_data_regno_info (lra_insn_recog_data_t data, rtx_insn *insn,
156338fd1498Szrj 				 int freq)
156438fd1498Szrj {
156538fd1498Szrj   int uid;
156638fd1498Szrj   bool debug_p;
156738fd1498Szrj   unsigned int i;
156838fd1498Szrj   struct lra_insn_reg *ir, *next_ir;
156938fd1498Szrj 
157038fd1498Szrj   uid = INSN_UID (insn);
157138fd1498Szrj   debug_p = DEBUG_INSN_P (insn);
157238fd1498Szrj   for (ir = data->regs; ir != NULL; ir = next_ir)
157338fd1498Szrj     {
157438fd1498Szrj       i = ir->regno;
157538fd1498Szrj       next_ir = ir->next;
157638fd1498Szrj       lra_insn_reg_pool.remove (ir);
157738fd1498Szrj       bitmap_clear_bit (&lra_reg_info[i].insn_bitmap, uid);
157838fd1498Szrj       if (i >= FIRST_PSEUDO_REGISTER && ! debug_p)
157938fd1498Szrj 	{
158038fd1498Szrj 	  lra_reg_info[i].nrefs--;
158138fd1498Szrj 	  lra_reg_info[i].freq -= freq;
158238fd1498Szrj 	  lra_assert (lra_reg_info[i].nrefs >= 0 && lra_reg_info[i].freq >= 0);
158338fd1498Szrj 	}
158438fd1498Szrj     }
158538fd1498Szrj   data->regs = NULL;
158638fd1498Szrj }
158738fd1498Szrj 
158838fd1498Szrj /* Invalidate all reg info of INSN.  Update common info about the
158938fd1498Szrj    invalidated registers.  */
159038fd1498Szrj void
lra_invalidate_insn_regno_info(rtx_insn * insn)159138fd1498Szrj lra_invalidate_insn_regno_info (rtx_insn *insn)
159238fd1498Szrj {
159338fd1498Szrj   invalidate_insn_data_regno_info (lra_get_insn_recog_data (insn), insn,
159438fd1498Szrj 				   get_insn_freq (insn));
159538fd1498Szrj }
159638fd1498Szrj 
159738fd1498Szrj /* Update common reg info from reg info of insn given by its DATA and
159838fd1498Szrj    execution frequency FREQ.  */
159938fd1498Szrj static void
setup_insn_reg_info(lra_insn_recog_data_t data,int freq)160038fd1498Szrj setup_insn_reg_info (lra_insn_recog_data_t data, int freq)
160138fd1498Szrj {
160238fd1498Szrj   unsigned int i;
160338fd1498Szrj   struct lra_insn_reg *ir;
160438fd1498Szrj 
160538fd1498Szrj   for (ir = data->regs; ir != NULL; ir = ir->next)
160638fd1498Szrj     if ((i = ir->regno) >= FIRST_PSEUDO_REGISTER)
160738fd1498Szrj       {
160838fd1498Szrj 	lra_reg_info[i].nrefs++;
160938fd1498Szrj 	lra_reg_info[i].freq += freq;
161038fd1498Szrj       }
161138fd1498Szrj }
161238fd1498Szrj 
161338fd1498Szrj /* Set up insn reg info of INSN.  Update common reg info from reg info
161438fd1498Szrj    of INSN.  */
161538fd1498Szrj void
lra_update_insn_regno_info(rtx_insn * insn)161638fd1498Szrj lra_update_insn_regno_info (rtx_insn *insn)
161738fd1498Szrj {
161838fd1498Szrj   int i, freq;
161938fd1498Szrj   lra_insn_recog_data_t data;
162038fd1498Szrj   struct lra_static_insn_data *static_data;
162138fd1498Szrj   enum rtx_code code;
162238fd1498Szrj   rtx link;
162338fd1498Szrj 
162438fd1498Szrj   if (! INSN_P (insn))
162538fd1498Szrj     return;
162638fd1498Szrj   data = lra_get_insn_recog_data (insn);
162738fd1498Szrj   static_data = data->insn_static_data;
162838fd1498Szrj   freq = NONDEBUG_INSN_P (insn) ? get_insn_freq (insn) : 0;
162938fd1498Szrj   invalidate_insn_data_regno_info (data, insn, freq);
163038fd1498Szrj   for (i = static_data->n_operands - 1; i >= 0; i--)
163138fd1498Szrj     add_regs_to_insn_regno_info (data, *data->operand_loc[i], insn,
163238fd1498Szrj 				 static_data->operand[i].type,
163338fd1498Szrj 				 static_data->operand[i].early_clobber,
163438fd1498Szrj 				 static_data->operand[i].early_clobber_alts);
163538fd1498Szrj   if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE)
163638fd1498Szrj     add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), insn,
163738fd1498Szrj 				 code == USE ? OP_IN : OP_OUT, false, 0);
163838fd1498Szrj   if (CALL_P (insn))
163938fd1498Szrj     /* On some targets call insns can refer to pseudos in memory in
164038fd1498Szrj        CALL_INSN_FUNCTION_USAGE list.  Process them in order to
164138fd1498Szrj        consider their occurrences in calls for different
164238fd1498Szrj        transformations (e.g. inheritance) with given pseudos.  */
164338fd1498Szrj     for (link = CALL_INSN_FUNCTION_USAGE (insn);
164438fd1498Szrj 	 link != NULL_RTX;
164538fd1498Szrj 	 link = XEXP (link, 1))
164638fd1498Szrj       if (((code = GET_CODE (XEXP (link, 0))) == USE || code == CLOBBER)
164738fd1498Szrj 	  && MEM_P (XEXP (XEXP (link, 0), 0)))
164838fd1498Szrj 	add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), insn,
164938fd1498Szrj 				     code == USE ? OP_IN : OP_OUT, false, 0);
165038fd1498Szrj   if (NONDEBUG_INSN_P (insn))
165138fd1498Szrj     setup_insn_reg_info (data, freq);
165238fd1498Szrj }
165338fd1498Szrj 
165438fd1498Szrj /* Return reg info of insn given by it UID.  */
165538fd1498Szrj struct lra_insn_reg *
lra_get_insn_regs(int uid)165638fd1498Szrj lra_get_insn_regs (int uid)
165738fd1498Szrj {
165838fd1498Szrj   lra_insn_recog_data_t data;
165938fd1498Szrj 
166038fd1498Szrj   data = get_insn_recog_data_by_uid (uid);
166138fd1498Szrj   return data->regs;
166238fd1498Szrj }
166338fd1498Szrj 
166438fd1498Szrj 
166538fd1498Szrj 
166638fd1498Szrj /* Recursive hash function for RTL X.  */
166738fd1498Szrj hashval_t
lra_rtx_hash(rtx x)166838fd1498Szrj lra_rtx_hash (rtx x)
166938fd1498Szrj {
167038fd1498Szrj   int i, j;
167138fd1498Szrj   enum rtx_code code;
167238fd1498Szrj   const char *fmt;
167338fd1498Szrj   hashval_t val = 0;
167438fd1498Szrj 
167538fd1498Szrj   if (x == 0)
167638fd1498Szrj     return val;
167738fd1498Szrj 
167838fd1498Szrj   code = GET_CODE (x);
167938fd1498Szrj   val += (int) code + 4095;
168038fd1498Szrj 
168138fd1498Szrj   /* Some RTL can be compared nonrecursively.  */
168238fd1498Szrj   switch (code)
168338fd1498Szrj     {
168438fd1498Szrj     case REG:
168538fd1498Szrj       return val + REGNO (x);
168638fd1498Szrj 
168738fd1498Szrj     case LABEL_REF:
168838fd1498Szrj       return iterative_hash_object (XEXP (x, 0), val);
168938fd1498Szrj 
169038fd1498Szrj     case SYMBOL_REF:
169138fd1498Szrj       return iterative_hash_object (XSTR (x, 0), val);
169238fd1498Szrj 
169338fd1498Szrj     case SCRATCH:
169438fd1498Szrj     case CONST_DOUBLE:
169538fd1498Szrj     case CONST_VECTOR:
169638fd1498Szrj       return val;
169738fd1498Szrj 
1698*58e805e6Szrj     case CONST_INT:
1699*58e805e6Szrj       return val + UINTVAL (x);
1700*58e805e6Szrj 
170138fd1498Szrj     default:
170238fd1498Szrj       break;
170338fd1498Szrj     }
170438fd1498Szrj 
170538fd1498Szrj   /* Hash the elements.  */
170638fd1498Szrj   fmt = GET_RTX_FORMAT (code);
170738fd1498Szrj   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
170838fd1498Szrj     {
170938fd1498Szrj       switch (fmt[i])
171038fd1498Szrj 	{
171138fd1498Szrj 	case 'w':
171238fd1498Szrj 	  val += XWINT (x, i);
171338fd1498Szrj 	  break;
171438fd1498Szrj 
171538fd1498Szrj 	case 'n':
171638fd1498Szrj 	case 'i':
171738fd1498Szrj 	  val += XINT (x, i);
171838fd1498Szrj 	  break;
171938fd1498Szrj 
172038fd1498Szrj 	case 'V':
172138fd1498Szrj 	case 'E':
172238fd1498Szrj 	  val += XVECLEN (x, i);
172338fd1498Szrj 
172438fd1498Szrj 	  for (j = 0; j < XVECLEN (x, i); j++)
172538fd1498Szrj 	    val += lra_rtx_hash (XVECEXP (x, i, j));
172638fd1498Szrj 	  break;
172738fd1498Szrj 
172838fd1498Szrj 	case 'e':
172938fd1498Szrj 	  val += lra_rtx_hash (XEXP (x, i));
173038fd1498Szrj 	  break;
173138fd1498Szrj 
173238fd1498Szrj 	case 'S':
173338fd1498Szrj 	case 's':
173438fd1498Szrj 	  val += htab_hash_string (XSTR (x, i));
173538fd1498Szrj 	  break;
173638fd1498Szrj 
173738fd1498Szrj 	case 'u':
173838fd1498Szrj 	case '0':
173938fd1498Szrj 	case 't':
174038fd1498Szrj 	  break;
174138fd1498Szrj 
174238fd1498Szrj 	  /* It is believed that rtx's at this level will never
174338fd1498Szrj 	     contain anything but integers and other rtx's, except for
174438fd1498Szrj 	     within LABEL_REFs and SYMBOL_REFs.  */
174538fd1498Szrj 	default:
174638fd1498Szrj 	  abort ();
174738fd1498Szrj 	}
174838fd1498Szrj     }
174938fd1498Szrj   return val;
175038fd1498Szrj }
175138fd1498Szrj 
175238fd1498Szrj 
175338fd1498Szrj 
175438fd1498Szrj /* This page contains code dealing with stack of the insns which
175538fd1498Szrj    should be processed by the next constraint pass.  */
175638fd1498Szrj 
175738fd1498Szrj /* Bitmap used to put an insn on the stack only in one exemplar.  */
175838fd1498Szrj static sbitmap lra_constraint_insn_stack_bitmap;
175938fd1498Szrj 
176038fd1498Szrj /* The stack itself.  */
176138fd1498Szrj vec<rtx_insn *> lra_constraint_insn_stack;
176238fd1498Szrj 
176338fd1498Szrj /* Put INSN on the stack.  If ALWAYS_UPDATE is true, always update the reg
176438fd1498Szrj    info for INSN, otherwise only update it if INSN is not already on the
176538fd1498Szrj    stack.  */
176638fd1498Szrj static inline void
lra_push_insn_1(rtx_insn * insn,bool always_update)176738fd1498Szrj lra_push_insn_1 (rtx_insn *insn, bool always_update)
176838fd1498Szrj {
176938fd1498Szrj   unsigned int uid = INSN_UID (insn);
177038fd1498Szrj   if (always_update)
177138fd1498Szrj     lra_update_insn_regno_info (insn);
177238fd1498Szrj   if (uid >= SBITMAP_SIZE (lra_constraint_insn_stack_bitmap))
177338fd1498Szrj     lra_constraint_insn_stack_bitmap =
177438fd1498Szrj       sbitmap_resize (lra_constraint_insn_stack_bitmap, 3 * uid / 2, 0);
177538fd1498Szrj   if (bitmap_bit_p (lra_constraint_insn_stack_bitmap, uid))
177638fd1498Szrj     return;
177738fd1498Szrj   bitmap_set_bit (lra_constraint_insn_stack_bitmap, uid);
177838fd1498Szrj   if (! always_update)
177938fd1498Szrj     lra_update_insn_regno_info (insn);
178038fd1498Szrj   lra_constraint_insn_stack.safe_push (insn);
178138fd1498Szrj }
178238fd1498Szrj 
178338fd1498Szrj /* Put INSN on the stack.  */
178438fd1498Szrj void
lra_push_insn(rtx_insn * insn)178538fd1498Szrj lra_push_insn (rtx_insn *insn)
178638fd1498Szrj {
178738fd1498Szrj   lra_push_insn_1 (insn, false);
178838fd1498Szrj }
178938fd1498Szrj 
179038fd1498Szrj /* Put INSN on the stack and update its reg info.  */
179138fd1498Szrj void
lra_push_insn_and_update_insn_regno_info(rtx_insn * insn)179238fd1498Szrj lra_push_insn_and_update_insn_regno_info (rtx_insn *insn)
179338fd1498Szrj {
179438fd1498Szrj   lra_push_insn_1 (insn, true);
179538fd1498Szrj }
179638fd1498Szrj 
179738fd1498Szrj /* Put insn with UID on the stack.  */
179838fd1498Szrj void
lra_push_insn_by_uid(unsigned int uid)179938fd1498Szrj lra_push_insn_by_uid (unsigned int uid)
180038fd1498Szrj {
180138fd1498Szrj   lra_push_insn (lra_insn_recog_data[uid]->insn);
180238fd1498Szrj }
180338fd1498Szrj 
180438fd1498Szrj /* Take the last-inserted insns off the stack and return it.  */
180538fd1498Szrj rtx_insn *
lra_pop_insn(void)180638fd1498Szrj lra_pop_insn (void)
180738fd1498Szrj {
180838fd1498Szrj   rtx_insn *insn = lra_constraint_insn_stack.pop ();
180938fd1498Szrj   bitmap_clear_bit (lra_constraint_insn_stack_bitmap, INSN_UID (insn));
181038fd1498Szrj   return insn;
181138fd1498Szrj }
181238fd1498Szrj 
181338fd1498Szrj /* Return the current size of the insn stack.  */
181438fd1498Szrj unsigned int
lra_insn_stack_length(void)181538fd1498Szrj lra_insn_stack_length (void)
181638fd1498Szrj {
181738fd1498Szrj   return lra_constraint_insn_stack.length ();
181838fd1498Szrj }
181938fd1498Szrj 
182038fd1498Szrj /* Push insns FROM to TO (excluding it) going in reverse order.	 */
182138fd1498Szrj static void
push_insns(rtx_insn * from,rtx_insn * to)182238fd1498Szrj push_insns (rtx_insn *from, rtx_insn *to)
182338fd1498Szrj {
182438fd1498Szrj   rtx_insn *insn;
182538fd1498Szrj 
182638fd1498Szrj   if (from == NULL_RTX)
182738fd1498Szrj     return;
182838fd1498Szrj   for (insn = from; insn != to; insn = PREV_INSN (insn))
182938fd1498Szrj     if (INSN_P (insn))
183038fd1498Szrj       lra_push_insn (insn);
183138fd1498Szrj }
183238fd1498Szrj 
183338fd1498Szrj /* Set up sp offset for insn in range [FROM, LAST].  The offset is
183438fd1498Szrj    taken from the next BB insn after LAST or zero if there in such
183538fd1498Szrj    insn.  */
183638fd1498Szrj static void
setup_sp_offset(rtx_insn * from,rtx_insn * last)183738fd1498Szrj setup_sp_offset (rtx_insn *from, rtx_insn *last)
183838fd1498Szrj {
183938fd1498Szrj   rtx_insn *before = next_nonnote_nondebug_insn_bb (last);
184038fd1498Szrj   poly_int64 offset = (before == NULL_RTX || ! INSN_P (before)
184138fd1498Szrj 		       ? 0 : lra_get_insn_recog_data (before)->sp_offset);
184238fd1498Szrj 
184338fd1498Szrj   for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
184438fd1498Szrj     lra_get_insn_recog_data (insn)->sp_offset = offset;
184538fd1498Szrj }
184638fd1498Szrj 
184738fd1498Szrj /* Emit insns BEFORE before INSN and insns AFTER after INSN.  Put the
184838fd1498Szrj    insns onto the stack.  Print about emitting the insns with
184938fd1498Szrj    TITLE.  */
185038fd1498Szrj void
lra_process_new_insns(rtx_insn * insn,rtx_insn * before,rtx_insn * after,const char * title)185138fd1498Szrj lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after,
185238fd1498Szrj 		       const char *title)
185338fd1498Szrj {
185438fd1498Szrj   rtx_insn *last;
185538fd1498Szrj 
185638fd1498Szrj   if (before == NULL_RTX && after == NULL_RTX)
185738fd1498Szrj     return;
185838fd1498Szrj   if (lra_dump_file != NULL)
185938fd1498Szrj     {
186038fd1498Szrj       dump_insn_slim (lra_dump_file, insn);
186138fd1498Szrj       if (before != NULL_RTX)
186238fd1498Szrj 	{
186338fd1498Szrj 	  fprintf (lra_dump_file,"    %s before:\n", title);
186438fd1498Szrj 	  dump_rtl_slim (lra_dump_file, before, NULL, -1, 0);
186538fd1498Szrj 	}
186638fd1498Szrj       if (after != NULL_RTX)
186738fd1498Szrj 	{
186838fd1498Szrj 	  fprintf (lra_dump_file, "    %s after:\n", title);
186938fd1498Szrj 	  dump_rtl_slim (lra_dump_file, after, NULL, -1, 0);
187038fd1498Szrj 	}
187138fd1498Szrj       fprintf (lra_dump_file, "\n");
187238fd1498Szrj     }
187338fd1498Szrj   if (before != NULL_RTX)
187438fd1498Szrj     {
187538fd1498Szrj       if (cfun->can_throw_non_call_exceptions)
187638fd1498Szrj 	copy_reg_eh_region_note_forward (insn, before, NULL);
187738fd1498Szrj       emit_insn_before (before, insn);
187838fd1498Szrj       push_insns (PREV_INSN (insn), PREV_INSN (before));
187938fd1498Szrj       setup_sp_offset (before, PREV_INSN (insn));
188038fd1498Szrj     }
188138fd1498Szrj   if (after != NULL_RTX)
188238fd1498Szrj     {
188338fd1498Szrj       if (cfun->can_throw_non_call_exceptions)
188438fd1498Szrj 	copy_reg_eh_region_note_forward (insn, after, NULL);
188538fd1498Szrj       for (last = after; NEXT_INSN (last) != NULL_RTX; last = NEXT_INSN (last))
188638fd1498Szrj 	;
188738fd1498Szrj       emit_insn_after (after, insn);
188838fd1498Szrj       push_insns (last, insn);
188938fd1498Szrj       setup_sp_offset (after, last);
189038fd1498Szrj     }
189138fd1498Szrj   if (cfun->can_throw_non_call_exceptions)
189238fd1498Szrj     {
189338fd1498Szrj       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
189438fd1498Szrj       if (note && !insn_could_throw_p (insn))
189538fd1498Szrj 	remove_note (insn, note);
189638fd1498Szrj     }
189738fd1498Szrj }
189838fd1498Szrj 
189938fd1498Szrj 
190038fd1498Szrj /* Replace all references to register OLD_REGNO in *LOC with pseudo
190138fd1498Szrj    register NEW_REG.  Try to simplify subreg of constant if SUBREG_P.
190238fd1498Szrj    DEBUG_P is if LOC is within a DEBUG_INSN.  Return true if any
190338fd1498Szrj    change was made.  */
190438fd1498Szrj bool
lra_substitute_pseudo(rtx * loc,int old_regno,rtx new_reg,bool subreg_p,bool debug_p)190538fd1498Szrj lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p,
190638fd1498Szrj 		       bool debug_p)
190738fd1498Szrj {
190838fd1498Szrj   rtx x = *loc;
190938fd1498Szrj   bool result = false;
191038fd1498Szrj   enum rtx_code code;
191138fd1498Szrj   const char *fmt;
191238fd1498Szrj   int i, j;
191338fd1498Szrj 
191438fd1498Szrj   if (x == NULL_RTX)
191538fd1498Szrj     return false;
191638fd1498Szrj 
191738fd1498Szrj   code = GET_CODE (x);
191838fd1498Szrj   if (code == SUBREG && subreg_p)
191938fd1498Szrj     {
192038fd1498Szrj       rtx subst, inner = SUBREG_REG (x);
192138fd1498Szrj       /* Transform subreg of constant while we still have inner mode
192238fd1498Szrj 	 of the subreg.  The subreg internal should not be an insn
192338fd1498Szrj 	 operand.  */
192438fd1498Szrj       if (REG_P (inner) && (int) REGNO (inner) == old_regno
192538fd1498Szrj 	  && CONSTANT_P (new_reg)
192638fd1498Szrj 	  && (subst = simplify_subreg (GET_MODE (x), new_reg, GET_MODE (inner),
192738fd1498Szrj 				       SUBREG_BYTE (x))) != NULL_RTX)
192838fd1498Szrj 	{
192938fd1498Szrj 	  *loc = subst;
193038fd1498Szrj 	  return true;
193138fd1498Szrj 	}
193238fd1498Szrj 
193338fd1498Szrj     }
193438fd1498Szrj   else if (code == REG && (int) REGNO (x) == old_regno)
193538fd1498Szrj     {
193638fd1498Szrj       machine_mode mode = GET_MODE (x);
193738fd1498Szrj       machine_mode inner_mode = GET_MODE (new_reg);
193838fd1498Szrj 
193938fd1498Szrj       if (mode != inner_mode
194038fd1498Szrj 	  && ! (CONST_INT_P (new_reg) && SCALAR_INT_MODE_P (mode)))
194138fd1498Szrj 	{
194238fd1498Szrj 	  poly_uint64 offset = 0;
194338fd1498Szrj 	  if (partial_subreg_p (mode, inner_mode)
194438fd1498Szrj 	      && SCALAR_INT_MODE_P (inner_mode))
194538fd1498Szrj 	    offset = subreg_lowpart_offset (mode, inner_mode);
194638fd1498Szrj 	  if (debug_p)
194738fd1498Szrj 	    new_reg = gen_rtx_raw_SUBREG (mode, new_reg, offset);
194838fd1498Szrj 	  else
194938fd1498Szrj 	    new_reg = gen_rtx_SUBREG (mode, new_reg, offset);
195038fd1498Szrj 	}
195138fd1498Szrj       *loc = new_reg;
195238fd1498Szrj       return true;
195338fd1498Szrj     }
195438fd1498Szrj 
195538fd1498Szrj   /* Scan all the operand sub-expressions.  */
195638fd1498Szrj   fmt = GET_RTX_FORMAT (code);
195738fd1498Szrj   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
195838fd1498Szrj     {
195938fd1498Szrj       if (fmt[i] == 'e')
196038fd1498Szrj 	{
196138fd1498Szrj 	  if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
196238fd1498Szrj 				     new_reg, subreg_p, debug_p))
196338fd1498Szrj 	    result = true;
196438fd1498Szrj 	}
196538fd1498Szrj       else if (fmt[i] == 'E')
196638fd1498Szrj 	{
196738fd1498Szrj 	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
196838fd1498Szrj 	    if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno,
196938fd1498Szrj 				       new_reg, subreg_p, debug_p))
197038fd1498Szrj 	      result = true;
197138fd1498Szrj 	}
197238fd1498Szrj     }
197338fd1498Szrj   return result;
197438fd1498Szrj }
197538fd1498Szrj 
197638fd1498Szrj /* Call lra_substitute_pseudo within an insn.  Try to simplify subreg
197738fd1498Szrj    of constant if SUBREG_P.  This won't update the insn ptr, just the
197838fd1498Szrj    contents of the insn.  */
197938fd1498Szrj bool
lra_substitute_pseudo_within_insn(rtx_insn * insn,int old_regno,rtx new_reg,bool subreg_p)198038fd1498Szrj lra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno,
198138fd1498Szrj 				   rtx new_reg, bool subreg_p)
198238fd1498Szrj {
198338fd1498Szrj   rtx loc = insn;
198438fd1498Szrj   return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p,
198538fd1498Szrj 				DEBUG_INSN_P (insn));
198638fd1498Szrj }
198738fd1498Szrj 
198838fd1498Szrj 
198938fd1498Szrj 
199038fd1498Szrj /* This page contains code dealing with scratches (changing them onto
199138fd1498Szrj    pseudos and restoring them from the pseudos).
199238fd1498Szrj 
199338fd1498Szrj    We change scratches into pseudos at the beginning of LRA to
199438fd1498Szrj    simplify dealing with them (conflicts, hard register assignments).
199538fd1498Szrj 
199638fd1498Szrj    If the pseudo denoting scratch was spilled it means that we do need
199738fd1498Szrj    a hard register for it.  Such pseudos are transformed back to
199838fd1498Szrj    scratches at the end of LRA.	 */
199938fd1498Szrj 
200038fd1498Szrj /* Description of location of a former scratch operand.	 */
200138fd1498Szrj struct sloc
200238fd1498Szrj {
200338fd1498Szrj   rtx_insn *insn; /* Insn where the scratch was.  */
200438fd1498Szrj   int nop;  /* Number of the operand which was a scratch.  */
200538fd1498Szrj };
200638fd1498Szrj 
200738fd1498Szrj typedef struct sloc *sloc_t;
200838fd1498Szrj 
200938fd1498Szrj /* Locations of the former scratches.  */
201038fd1498Szrj static vec<sloc_t> scratches;
201138fd1498Szrj 
201238fd1498Szrj /* Bitmap of scratch regnos.  */
201338fd1498Szrj static bitmap_head scratch_bitmap;
201438fd1498Szrj 
201538fd1498Szrj /* Bitmap of scratch operands.	*/
201638fd1498Szrj static bitmap_head scratch_operand_bitmap;
201738fd1498Szrj 
201838fd1498Szrj /* Return true if pseudo REGNO is made of SCRATCH.  */
201938fd1498Szrj bool
lra_former_scratch_p(int regno)202038fd1498Szrj lra_former_scratch_p (int regno)
202138fd1498Szrj {
202238fd1498Szrj   return bitmap_bit_p (&scratch_bitmap, regno);
202338fd1498Szrj }
202438fd1498Szrj 
202538fd1498Szrj /* Return true if the operand NOP of INSN is a former scratch.	*/
202638fd1498Szrj bool
lra_former_scratch_operand_p(rtx_insn * insn,int nop)202738fd1498Szrj lra_former_scratch_operand_p (rtx_insn *insn, int nop)
202838fd1498Szrj {
202938fd1498Szrj   return bitmap_bit_p (&scratch_operand_bitmap,
203038fd1498Szrj 		       INSN_UID (insn) * MAX_RECOG_OPERANDS + nop) != 0;
203138fd1498Szrj }
203238fd1498Szrj 
203338fd1498Szrj /* Register operand NOP in INSN as a former scratch.  It will be
203438fd1498Szrj    changed to scratch back, if it is necessary, at the LRA end.  */
203538fd1498Szrj void
lra_register_new_scratch_op(rtx_insn * insn,int nop)203638fd1498Szrj lra_register_new_scratch_op (rtx_insn *insn, int nop)
203738fd1498Szrj {
203838fd1498Szrj   lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
203938fd1498Szrj   rtx op = *id->operand_loc[nop];
204038fd1498Szrj   sloc_t loc = XNEW (struct sloc);
204138fd1498Szrj   lra_assert (REG_P (op));
204238fd1498Szrj   loc->insn = insn;
204338fd1498Szrj   loc->nop = nop;
204438fd1498Szrj   scratches.safe_push (loc);
204538fd1498Szrj   bitmap_set_bit (&scratch_bitmap, REGNO (op));
204638fd1498Szrj   bitmap_set_bit (&scratch_operand_bitmap,
204738fd1498Szrj 		  INSN_UID (insn) * MAX_RECOG_OPERANDS + nop);
204838fd1498Szrj   add_reg_note (insn, REG_UNUSED, op);
204938fd1498Szrj }
205038fd1498Szrj 
205138fd1498Szrj /* Change scratches onto pseudos and save their location.  */
205238fd1498Szrj static void
remove_scratches(void)205338fd1498Szrj remove_scratches (void)
205438fd1498Szrj {
205538fd1498Szrj   int i;
205638fd1498Szrj   bool insn_changed_p;
205738fd1498Szrj   basic_block bb;
205838fd1498Szrj   rtx_insn *insn;
205938fd1498Szrj   rtx reg;
206038fd1498Szrj   lra_insn_recog_data_t id;
206138fd1498Szrj   struct lra_static_insn_data *static_id;
206238fd1498Szrj 
206338fd1498Szrj   scratches.create (get_max_uid ());
206438fd1498Szrj   bitmap_initialize (&scratch_bitmap, &reg_obstack);
206538fd1498Szrj   bitmap_initialize (&scratch_operand_bitmap, &reg_obstack);
206638fd1498Szrj   FOR_EACH_BB_FN (bb, cfun)
206738fd1498Szrj     FOR_BB_INSNS (bb, insn)
206838fd1498Szrj     if (INSN_P (insn))
206938fd1498Szrj       {
207038fd1498Szrj 	id = lra_get_insn_recog_data (insn);
207138fd1498Szrj 	static_id = id->insn_static_data;
207238fd1498Szrj 	insn_changed_p = false;
207338fd1498Szrj 	for (i = 0; i < static_id->n_operands; i++)
207438fd1498Szrj 	  if (GET_CODE (*id->operand_loc[i]) == SCRATCH
207538fd1498Szrj 	      && GET_MODE (*id->operand_loc[i]) != VOIDmode)
207638fd1498Szrj 	    {
207738fd1498Szrj 	      insn_changed_p = true;
207838fd1498Szrj 	      *id->operand_loc[i] = reg
207938fd1498Szrj 		= lra_create_new_reg (static_id->operand[i].mode,
208038fd1498Szrj 				      *id->operand_loc[i], ALL_REGS, NULL);
208138fd1498Szrj 	      lra_register_new_scratch_op (insn, i);
208238fd1498Szrj 	      if (lra_dump_file != NULL)
208338fd1498Szrj 		fprintf (lra_dump_file,
208438fd1498Szrj 			 "Removing SCRATCH in insn #%u (nop %d)\n",
208538fd1498Szrj 			 INSN_UID (insn), i);
208638fd1498Szrj 	    }
208738fd1498Szrj 	if (insn_changed_p)
208838fd1498Szrj 	  /* Because we might use DF right after caller-saves sub-pass
208938fd1498Szrj 	     we need to keep DF info up to date.  */
209038fd1498Szrj 	  df_insn_rescan (insn);
209138fd1498Szrj       }
209238fd1498Szrj }
209338fd1498Szrj 
209438fd1498Szrj /* Changes pseudos created by function remove_scratches onto scratches.	 */
209538fd1498Szrj static void
restore_scratches(void)209638fd1498Szrj restore_scratches (void)
209738fd1498Szrj {
209838fd1498Szrj   int regno;
209938fd1498Szrj   unsigned i;
210038fd1498Szrj   sloc_t loc;
210138fd1498Szrj   rtx_insn *last = NULL;
210238fd1498Szrj   lra_insn_recog_data_t id = NULL;
210338fd1498Szrj 
210438fd1498Szrj   for (i = 0; scratches.iterate (i, &loc); i++)
210538fd1498Szrj     {
210638fd1498Szrj       /* Ignore already deleted insns.  */
210738fd1498Szrj       if (NOTE_P (loc->insn)
210838fd1498Szrj 	  && NOTE_KIND (loc->insn) == NOTE_INSN_DELETED)
210938fd1498Szrj 	continue;
211038fd1498Szrj       if (last != loc->insn)
211138fd1498Szrj 	{
211238fd1498Szrj 	  last = loc->insn;
211338fd1498Szrj 	  id = lra_get_insn_recog_data (last);
211438fd1498Szrj 	}
211538fd1498Szrj       if (REG_P (*id->operand_loc[loc->nop])
211638fd1498Szrj 	  && ((regno = REGNO (*id->operand_loc[loc->nop]))
211738fd1498Szrj 	      >= FIRST_PSEUDO_REGISTER)
211838fd1498Szrj 	  && lra_get_regno_hard_regno (regno) < 0)
211938fd1498Szrj 	{
212038fd1498Szrj 	  /* It should be only case when scratch register with chosen
212138fd1498Szrj 	     constraint 'X' did not get memory or hard register.  */
212238fd1498Szrj 	  lra_assert (lra_former_scratch_p (regno));
212338fd1498Szrj 	  *id->operand_loc[loc->nop]
212438fd1498Szrj 	    = gen_rtx_SCRATCH (GET_MODE (*id->operand_loc[loc->nop]));
212538fd1498Szrj 	  lra_update_dup (id, loc->nop);
212638fd1498Szrj 	  if (lra_dump_file != NULL)
212738fd1498Szrj 	    fprintf (lra_dump_file, "Restoring SCRATCH in insn #%u(nop %d)\n",
212838fd1498Szrj 		     INSN_UID (loc->insn), loc->nop);
212938fd1498Szrj 	}
213038fd1498Szrj     }
213138fd1498Szrj   for (i = 0; scratches.iterate (i, &loc); i++)
213238fd1498Szrj     free (loc);
213338fd1498Szrj   scratches.release ();
213438fd1498Szrj   bitmap_clear (&scratch_bitmap);
213538fd1498Szrj   bitmap_clear (&scratch_operand_bitmap);
213638fd1498Szrj }
213738fd1498Szrj 
213838fd1498Szrj 
213938fd1498Szrj 
214038fd1498Szrj /* Function checks RTL for correctness.	 If FINAL_P is true, it is
214138fd1498Szrj    done at the end of LRA and the check is more rigorous.  */
214238fd1498Szrj static void
check_rtl(bool final_p)214338fd1498Szrj check_rtl (bool final_p)
214438fd1498Szrj {
214538fd1498Szrj   basic_block bb;
214638fd1498Szrj   rtx_insn *insn;
214738fd1498Szrj 
214838fd1498Szrj   lra_assert (! final_p || reload_completed);
214938fd1498Szrj   FOR_EACH_BB_FN (bb, cfun)
215038fd1498Szrj     FOR_BB_INSNS (bb, insn)
215138fd1498Szrj     if (NONDEBUG_INSN_P (insn)
215238fd1498Szrj 	&& GET_CODE (PATTERN (insn)) != USE
215338fd1498Szrj 	&& GET_CODE (PATTERN (insn)) != CLOBBER
215438fd1498Szrj 	&& GET_CODE (PATTERN (insn)) != ASM_INPUT)
215538fd1498Szrj       {
215638fd1498Szrj 	if (final_p)
215738fd1498Szrj 	  {
215838fd1498Szrj 	    extract_constrain_insn (insn);
215938fd1498Szrj 	    continue;
216038fd1498Szrj 	  }
216138fd1498Szrj 	/* LRA code is based on assumption that all addresses can be
216238fd1498Szrj 	   correctly decomposed.  LRA can generate reloads for
216338fd1498Szrj 	   decomposable addresses.  The decomposition code checks the
216438fd1498Szrj 	   correctness of the addresses.  So we don't need to check
216538fd1498Szrj 	   the addresses here.  Don't call insn_invalid_p here, it can
216638fd1498Szrj 	   change the code at this stage.  */
216738fd1498Szrj 	if (recog_memoized (insn) < 0 && asm_noperands (PATTERN (insn)) < 0)
216838fd1498Szrj 	  fatal_insn_not_found (insn);
216938fd1498Szrj       }
217038fd1498Szrj }
217138fd1498Szrj 
217238fd1498Szrj /* Determine if the current function has an exception receiver block
217338fd1498Szrj    that reaches the exit block via non-exceptional edges  */
217438fd1498Szrj static bool
has_nonexceptional_receiver(void)217538fd1498Szrj has_nonexceptional_receiver (void)
217638fd1498Szrj {
217738fd1498Szrj   edge e;
217838fd1498Szrj   edge_iterator ei;
217938fd1498Szrj   basic_block *tos, *worklist, bb;
218038fd1498Szrj 
218138fd1498Szrj   /* If we're not optimizing, then just err on the safe side.  */
218238fd1498Szrj   if (!optimize)
218338fd1498Szrj     return true;
218438fd1498Szrj 
218538fd1498Szrj   /* First determine which blocks can reach exit via normal paths.  */
218638fd1498Szrj   tos = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) + 1);
218738fd1498Szrj 
218838fd1498Szrj   FOR_EACH_BB_FN (bb, cfun)
218938fd1498Szrj     bb->flags &= ~BB_REACHABLE;
219038fd1498Szrj 
219138fd1498Szrj   /* Place the exit block on our worklist.  */
219238fd1498Szrj   EXIT_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_REACHABLE;
219338fd1498Szrj   *tos++ = EXIT_BLOCK_PTR_FOR_FN (cfun);
219438fd1498Szrj 
219538fd1498Szrj   /* Iterate: find everything reachable from what we've already seen.  */
219638fd1498Szrj   while (tos != worklist)
219738fd1498Szrj     {
219838fd1498Szrj       bb = *--tos;
219938fd1498Szrj 
220038fd1498Szrj       FOR_EACH_EDGE (e, ei, bb->preds)
220138fd1498Szrj 	if (e->flags & EDGE_ABNORMAL)
220238fd1498Szrj 	  {
220338fd1498Szrj 	    free (worklist);
220438fd1498Szrj 	    return true;
220538fd1498Szrj 	  }
220638fd1498Szrj 	else
220738fd1498Szrj 	  {
220838fd1498Szrj 	    basic_block src = e->src;
220938fd1498Szrj 
221038fd1498Szrj 	    if (!(src->flags & BB_REACHABLE))
221138fd1498Szrj 	      {
221238fd1498Szrj 		src->flags |= BB_REACHABLE;
221338fd1498Szrj 		*tos++ = src;
221438fd1498Szrj 	      }
221538fd1498Szrj 	  }
221638fd1498Szrj     }
221738fd1498Szrj   free (worklist);
221838fd1498Szrj   /* No exceptional block reached exit unexceptionally.	 */
221938fd1498Szrj   return false;
222038fd1498Szrj }
222138fd1498Szrj 
222238fd1498Szrj 
222338fd1498Szrj /* Process recursively X of INSN and add REG_INC notes if necessary.  */
222438fd1498Szrj static void
add_auto_inc_notes(rtx_insn * insn,rtx x)222538fd1498Szrj add_auto_inc_notes (rtx_insn *insn, rtx x)
222638fd1498Szrj {
222738fd1498Szrj   enum rtx_code code = GET_CODE (x);
222838fd1498Szrj   const char *fmt;
222938fd1498Szrj   int i, j;
223038fd1498Szrj 
223138fd1498Szrj   if (code == MEM && auto_inc_p (XEXP (x, 0)))
223238fd1498Szrj     {
223338fd1498Szrj       add_reg_note (insn, REG_INC, XEXP (XEXP (x, 0), 0));
223438fd1498Szrj       return;
223538fd1498Szrj     }
223638fd1498Szrj 
223738fd1498Szrj   /* Scan all X sub-expressions.  */
223838fd1498Szrj   fmt = GET_RTX_FORMAT (code);
223938fd1498Szrj   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
224038fd1498Szrj     {
224138fd1498Szrj       if (fmt[i] == 'e')
224238fd1498Szrj 	add_auto_inc_notes (insn, XEXP (x, i));
224338fd1498Szrj       else if (fmt[i] == 'E')
224438fd1498Szrj 	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
224538fd1498Szrj 	  add_auto_inc_notes (insn, XVECEXP (x, i, j));
224638fd1498Szrj     }
224738fd1498Szrj }
224838fd1498Szrj 
224938fd1498Szrj 
225038fd1498Szrj /* Remove all REG_DEAD and REG_UNUSED notes and regenerate REG_INC.
225138fd1498Szrj    We change pseudos by hard registers without notification of DF and
225238fd1498Szrj    that can make the notes obsolete.  DF-infrastructure does not deal
225338fd1498Szrj    with REG_INC notes -- so we should regenerate them here.  */
225438fd1498Szrj static void
update_inc_notes(void)225538fd1498Szrj update_inc_notes (void)
225638fd1498Szrj {
225738fd1498Szrj   rtx *pnote;
225838fd1498Szrj   basic_block bb;
225938fd1498Szrj   rtx_insn *insn;
226038fd1498Szrj 
226138fd1498Szrj   FOR_EACH_BB_FN (bb, cfun)
226238fd1498Szrj     FOR_BB_INSNS (bb, insn)
226338fd1498Szrj     if (NONDEBUG_INSN_P (insn))
226438fd1498Szrj       {
226538fd1498Szrj 	pnote = &REG_NOTES (insn);
226638fd1498Szrj 	while (*pnote != 0)
226738fd1498Szrj 	  {
226838fd1498Szrj 	    if (REG_NOTE_KIND (*pnote) == REG_DEAD
226938fd1498Szrj                 || REG_NOTE_KIND (*pnote) == REG_UNUSED
227038fd1498Szrj                 || REG_NOTE_KIND (*pnote) == REG_INC)
227138fd1498Szrj 	      *pnote = XEXP (*pnote, 1);
227238fd1498Szrj 	    else
227338fd1498Szrj 	      pnote = &XEXP (*pnote, 1);
227438fd1498Szrj 	  }
227538fd1498Szrj 
227638fd1498Szrj 	if (AUTO_INC_DEC)
227738fd1498Szrj 	  add_auto_inc_notes (insn, PATTERN (insn));
227838fd1498Szrj       }
227938fd1498Szrj }
228038fd1498Szrj 
228138fd1498Szrj /* Set to 1 while in lra.  */
228238fd1498Szrj int lra_in_progress;
228338fd1498Szrj 
228438fd1498Szrj /* Start of pseudo regnos before the LRA.  */
228538fd1498Szrj int lra_new_regno_start;
228638fd1498Szrj 
228738fd1498Szrj /* Start of reload pseudo regnos before the new spill pass.  */
228838fd1498Szrj int lra_constraint_new_regno_start;
228938fd1498Szrj 
229038fd1498Szrj /* Avoid spilling pseudos with regno more than the following value if
229138fd1498Szrj    it is possible.  */
229238fd1498Szrj int lra_bad_spill_regno_start;
229338fd1498Szrj 
229438fd1498Szrj /* Inheritance pseudo regnos before the new spill pass.	 */
229538fd1498Szrj bitmap_head lra_inheritance_pseudos;
229638fd1498Szrj 
229738fd1498Szrj /* Split regnos before the new spill pass.  */
229838fd1498Szrj bitmap_head lra_split_regs;
229938fd1498Szrj 
230038fd1498Szrj /* Reload pseudo regnos before the new assignment pass which still can
230138fd1498Szrj    be spilled after the assignment pass as memory is also accepted in
230238fd1498Szrj    insns for the reload pseudos.  */
230338fd1498Szrj bitmap_head lra_optional_reload_pseudos;
230438fd1498Szrj 
230538fd1498Szrj /* Pseudo regnos used for subreg reloads before the new assignment
230638fd1498Szrj    pass.  Such pseudos still can be spilled after the assignment
230738fd1498Szrj    pass.  */
230838fd1498Szrj bitmap_head lra_subreg_reload_pseudos;
230938fd1498Szrj 
231038fd1498Szrj /* File used for output of LRA debug information.  */
231138fd1498Szrj FILE *lra_dump_file;
231238fd1498Szrj 
231338fd1498Szrj /* True if we should try spill into registers of different classes
231438fd1498Szrj    instead of memory.  */
231538fd1498Szrj bool lra_reg_spill_p;
231638fd1498Szrj 
231738fd1498Szrj /* Set up value LRA_REG_SPILL_P.  */
231838fd1498Szrj static void
setup_reg_spill_flag(void)231938fd1498Szrj setup_reg_spill_flag (void)
232038fd1498Szrj {
232138fd1498Szrj   int cl, mode;
232238fd1498Szrj 
232338fd1498Szrj   if (targetm.spill_class != NULL)
232438fd1498Szrj     for (cl = 0; cl < (int) LIM_REG_CLASSES; cl++)
232538fd1498Szrj       for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
232638fd1498Szrj 	if (targetm.spill_class ((enum reg_class) cl,
232738fd1498Szrj 				 (machine_mode) mode) != NO_REGS)
232838fd1498Szrj 	  {
232938fd1498Szrj 	    lra_reg_spill_p = true;
233038fd1498Szrj 	    return;
233138fd1498Szrj 	  }
233238fd1498Szrj   lra_reg_spill_p = false;
233338fd1498Szrj }
233438fd1498Szrj 
233538fd1498Szrj /* True if the current function is too big to use regular algorithms
233638fd1498Szrj    in LRA. In other words, we should use simpler and faster algorithms
233738fd1498Szrj    in LRA.  It also means we should not worry about generation code
233838fd1498Szrj    for caller saves.  The value is set up in IRA.  */
233938fd1498Szrj bool lra_simple_p;
234038fd1498Szrj 
234138fd1498Szrj /* Major LRA entry function.  F is a file should be used to dump LRA
234238fd1498Szrj    debug info.  */
234338fd1498Szrj void
lra(FILE * f)234438fd1498Szrj lra (FILE *f)
234538fd1498Szrj {
234638fd1498Szrj   int i;
234738fd1498Szrj   bool live_p, inserted_p;
234838fd1498Szrj 
234938fd1498Szrj   lra_dump_file = f;
235038fd1498Szrj 
235138fd1498Szrj   timevar_push (TV_LRA);
235238fd1498Szrj 
235338fd1498Szrj   /* Make sure that the last insn is a note.  Some subsequent passes
235438fd1498Szrj      need it.  */
235538fd1498Szrj   emit_note (NOTE_INSN_DELETED);
235638fd1498Szrj 
235738fd1498Szrj   COPY_HARD_REG_SET (lra_no_alloc_regs, ira_no_alloc_regs);
235838fd1498Szrj 
235938fd1498Szrj   init_reg_info ();
236038fd1498Szrj   expand_reg_info ();
236138fd1498Szrj 
236238fd1498Szrj   init_insn_recog_data ();
236338fd1498Szrj 
236438fd1498Szrj   /* Some quick check on RTL generated by previous passes.  */
236538fd1498Szrj   if (flag_checking)
236638fd1498Szrj     check_rtl (false);
236738fd1498Szrj 
236838fd1498Szrj   lra_in_progress = 1;
236938fd1498Szrj 
237038fd1498Szrj   lra_live_range_iter = lra_coalesce_iter = lra_constraint_iter = 0;
237138fd1498Szrj   lra_assignment_iter = lra_assignment_iter_after_spill = 0;
237238fd1498Szrj   lra_inheritance_iter = lra_undo_inheritance_iter = 0;
237338fd1498Szrj   lra_rematerialization_iter = 0;
237438fd1498Szrj 
237538fd1498Szrj   setup_reg_spill_flag ();
237638fd1498Szrj 
237738fd1498Szrj   /* Function remove_scratches can creates new pseudos for clobbers --
237838fd1498Szrj      so set up lra_constraint_new_regno_start before its call to
237938fd1498Szrj      permit changing reg classes for pseudos created by this
238038fd1498Szrj      simplification.  */
238138fd1498Szrj   lra_constraint_new_regno_start = lra_new_regno_start = max_reg_num ();
238238fd1498Szrj   lra_bad_spill_regno_start = INT_MAX;
238338fd1498Szrj   remove_scratches ();
238438fd1498Szrj 
238538fd1498Szrj   /* A function that has a non-local label that can reach the exit
238638fd1498Szrj      block via non-exceptional paths must save all call-saved
238738fd1498Szrj      registers.	 */
238838fd1498Szrj   if (cfun->has_nonlocal_label && has_nonexceptional_receiver ())
238938fd1498Szrj     crtl->saves_all_registers = 1;
239038fd1498Szrj 
239138fd1498Szrj   if (crtl->saves_all_registers)
239238fd1498Szrj     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
239338fd1498Szrj       if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
239438fd1498Szrj 	df_set_regs_ever_live (i, true);
239538fd1498Szrj 
239638fd1498Szrj   /* We don't DF from now and avoid its using because it is to
239738fd1498Szrj      expensive when a lot of RTL changes are made.  */
239838fd1498Szrj   df_set_flags (DF_NO_INSN_RESCAN);
239938fd1498Szrj   lra_constraint_insn_stack.create (get_max_uid ());
240038fd1498Szrj   lra_constraint_insn_stack_bitmap = sbitmap_alloc (get_max_uid ());
240138fd1498Szrj   bitmap_clear (lra_constraint_insn_stack_bitmap);
240238fd1498Szrj   lra_live_ranges_init ();
240338fd1498Szrj   lra_constraints_init ();
240438fd1498Szrj   lra_curr_reload_num = 0;
240538fd1498Szrj   push_insns (get_last_insn (), NULL);
240638fd1498Szrj   /* It is needed for the 1st coalescing.  */
240738fd1498Szrj   bitmap_initialize (&lra_inheritance_pseudos, &reg_obstack);
240838fd1498Szrj   bitmap_initialize (&lra_split_regs, &reg_obstack);
240938fd1498Szrj   bitmap_initialize (&lra_optional_reload_pseudos, &reg_obstack);
241038fd1498Szrj   bitmap_initialize (&lra_subreg_reload_pseudos, &reg_obstack);
241138fd1498Szrj   live_p = false;
241238fd1498Szrj   if (maybe_ne (get_frame_size (), 0) && crtl->stack_alignment_needed)
241338fd1498Szrj     /* If we have a stack frame, we must align it now.  The stack size
241438fd1498Szrj        may be a part of the offset computation for register
241538fd1498Szrj        elimination.  */
241638fd1498Szrj     assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed);
241738fd1498Szrj   lra_init_equiv ();
241838fd1498Szrj   for (;;)
241938fd1498Szrj     {
242038fd1498Szrj       for (;;)
242138fd1498Szrj 	{
242238fd1498Szrj 	  bool reloads_p = lra_constraints (lra_constraint_iter == 0);
242338fd1498Szrj 	  /* Constraint transformations may result in that eliminable
242438fd1498Szrj 	     hard regs become uneliminable and pseudos which use them
242538fd1498Szrj 	     should be spilled.	 It is better to do it before pseudo
242638fd1498Szrj 	     assignments.
242738fd1498Szrj 
242838fd1498Szrj 	     For example, rs6000 can make
242938fd1498Szrj 	     RS6000_PIC_OFFSET_TABLE_REGNUM uneliminable if we started
243038fd1498Szrj 	     to use a constant pool.  */
243138fd1498Szrj 	  lra_eliminate (false, false);
243238fd1498Szrj 	  /* We should try to assign hard registers to scratches even
243338fd1498Szrj 	     if there were no RTL transformations in lra_constraints.
243438fd1498Szrj 	     Also we should check IRA assignments on the first
243538fd1498Szrj 	     iteration as they can be wrong because of early clobbers
243638fd1498Szrj 	     operands which are ignored in IRA.  */
243738fd1498Szrj 	  if (! reloads_p && lra_constraint_iter > 1)
243838fd1498Szrj 	    {
243938fd1498Szrj 	      /* Stack is not empty here only when there are changes
244038fd1498Szrj 		 during the elimination sub-pass.  */
244138fd1498Szrj 	      if (bitmap_empty_p (lra_constraint_insn_stack_bitmap))
244238fd1498Szrj 		break;
244338fd1498Szrj 	      else
244438fd1498Szrj 		/* If there are no reloads but changing due
244538fd1498Szrj 		   elimination, restart the constraint sub-pass
244638fd1498Szrj 		   first.  */
244738fd1498Szrj 		continue;
244838fd1498Szrj 	    }
244938fd1498Szrj 	  /* Do inheritance only for regular algorithms.  */
245038fd1498Szrj 	  if (! lra_simple_p)
245138fd1498Szrj 	    {
245238fd1498Szrj 	      if (flag_ipa_ra)
245338fd1498Szrj 		{
245438fd1498Szrj 		  if (live_p)
245538fd1498Szrj 		    lra_clear_live_ranges ();
245638fd1498Szrj 		  /* As a side-effect of lra_create_live_ranges, we calculate
245738fd1498Szrj 		     actual_call_used_reg_set,  which is needed during
245838fd1498Szrj 		     lra_inheritance.  */
245938fd1498Szrj 		  lra_create_live_ranges (true, true);
246038fd1498Szrj 		  live_p = true;
246138fd1498Szrj 		}
246238fd1498Szrj 	      lra_inheritance ();
246338fd1498Szrj 	    }
246438fd1498Szrj 	  if (live_p)
246538fd1498Szrj 	    lra_clear_live_ranges ();
246638fd1498Szrj 	  bool fails_p;
246738fd1498Szrj 	  do
246838fd1498Szrj 	    {
246938fd1498Szrj 	      /* We need live ranges for lra_assign -- so build them.
247038fd1498Szrj 		 But don't remove dead insns or change global live
247138fd1498Szrj 		 info as we can undo inheritance transformations after
247238fd1498Szrj 		 inheritance pseudo assigning.  */
247338fd1498Szrj 	      lra_create_live_ranges (true, false);
247438fd1498Szrj 	      live_p = true;
247538fd1498Szrj 	      /* If we don't spill non-reload and non-inheritance
247638fd1498Szrj 		 pseudos, there is no sense to run memory-memory move
247738fd1498Szrj 		 coalescing.  If inheritance pseudos were spilled, the
247838fd1498Szrj 		 memory-memory moves involving them will be removed by
247938fd1498Szrj 		 pass undoing inheritance.  */
248038fd1498Szrj 	      if (lra_simple_p)
248138fd1498Szrj 		lra_assign (fails_p);
248238fd1498Szrj 	      else
248338fd1498Szrj 		{
248438fd1498Szrj 		  bool spill_p = !lra_assign (fails_p);
248538fd1498Szrj 
248638fd1498Szrj 		  if (lra_undo_inheritance ())
248738fd1498Szrj 		    live_p = false;
248838fd1498Szrj 		  if (spill_p && ! fails_p)
248938fd1498Szrj 		    {
249038fd1498Szrj 		      if (! live_p)
249138fd1498Szrj 			{
249238fd1498Szrj 			  lra_create_live_ranges (true, true);
249338fd1498Szrj 			  live_p = true;
249438fd1498Szrj 			}
249538fd1498Szrj 		      if (lra_coalesce ())
249638fd1498Szrj 			live_p = false;
249738fd1498Szrj 		    }
249838fd1498Szrj 		  if (! live_p)
249938fd1498Szrj 		    lra_clear_live_ranges ();
250038fd1498Szrj 		}
250138fd1498Szrj 	      if (fails_p)
250238fd1498Szrj 		{
250338fd1498Szrj 		  /* It is a very rare case.  It is the last hope to
250438fd1498Szrj 		     split a hard regno live range for a reload
250538fd1498Szrj 		     pseudo.  */
250638fd1498Szrj 		  if (live_p)
250738fd1498Szrj 		    lra_clear_live_ranges ();
250838fd1498Szrj 		  live_p = false;
250938fd1498Szrj 		  if (! lra_split_hard_reg_for ())
251038fd1498Szrj 		    break;
251138fd1498Szrj 		}
251238fd1498Szrj 	    }
251338fd1498Szrj 	  while (fails_p);
251438fd1498Szrj 	}
251538fd1498Szrj       /* Don't clear optional reloads bitmap until all constraints are
251638fd1498Szrj 	 satisfied as we need to differ them from regular reloads.  */
251738fd1498Szrj       bitmap_clear (&lra_optional_reload_pseudos);
251838fd1498Szrj       bitmap_clear (&lra_subreg_reload_pseudos);
251938fd1498Szrj       bitmap_clear (&lra_inheritance_pseudos);
252038fd1498Szrj       bitmap_clear (&lra_split_regs);
252138fd1498Szrj       if (! live_p)
252238fd1498Szrj 	{
252338fd1498Szrj 	  /* We need full live info for spilling pseudos into
252438fd1498Szrj 	     registers instead of memory.  */
252538fd1498Szrj 	  lra_create_live_ranges (lra_reg_spill_p, true);
252638fd1498Szrj 	  live_p = true;
252738fd1498Szrj 	}
252838fd1498Szrj       /* We should check necessity for spilling here as the above live
252938fd1498Szrj 	 range pass can remove spilled pseudos.  */
253038fd1498Szrj       if (! lra_need_for_spills_p ())
253138fd1498Szrj 	break;
253238fd1498Szrj       /* Now we know what pseudos should be spilled.  Try to
253338fd1498Szrj 	 rematerialize them first.  */
253438fd1498Szrj       if (lra_remat ())
253538fd1498Szrj 	{
253638fd1498Szrj 	  /* We need full live info -- see the comment above.  */
253738fd1498Szrj 	  lra_create_live_ranges (lra_reg_spill_p, true);
253838fd1498Szrj 	  live_p = true;
253938fd1498Szrj 	  if (! lra_need_for_spills_p ())
254038fd1498Szrj 	    break;
254138fd1498Szrj 	}
254238fd1498Szrj       lra_spill ();
254338fd1498Szrj       /* Assignment of stack slots changes elimination offsets for
254438fd1498Szrj 	 some eliminations.  So update the offsets here.  */
254538fd1498Szrj       lra_eliminate (false, false);
254638fd1498Szrj       lra_constraint_new_regno_start = max_reg_num ();
254738fd1498Szrj       if (lra_bad_spill_regno_start == INT_MAX
254838fd1498Szrj 	  && lra_inheritance_iter > LRA_MAX_INHERITANCE_PASSES
254938fd1498Szrj 	  && lra_rematerialization_iter > LRA_MAX_REMATERIALIZATION_PASSES)
255038fd1498Szrj 	/* After switching off inheritance and rematerialization
255138fd1498Szrj 	   passes, avoid spilling reload pseudos will be created to
255238fd1498Szrj 	   prevent LRA cycling in some complicated cases.  */
255338fd1498Szrj 	lra_bad_spill_regno_start = lra_constraint_new_regno_start;
255438fd1498Szrj       lra_assignment_iter_after_spill = 0;
255538fd1498Szrj     }
255638fd1498Szrj   restore_scratches ();
255738fd1498Szrj   lra_eliminate (true, false);
255838fd1498Szrj   lra_final_code_change ();
255938fd1498Szrj   lra_in_progress = 0;
256038fd1498Szrj   if (live_p)
256138fd1498Szrj     lra_clear_live_ranges ();
256238fd1498Szrj   lra_live_ranges_finish ();
256338fd1498Szrj   lra_constraints_finish ();
256438fd1498Szrj   finish_reg_info ();
256538fd1498Szrj   sbitmap_free (lra_constraint_insn_stack_bitmap);
256638fd1498Szrj   lra_constraint_insn_stack.release ();
256738fd1498Szrj   finish_insn_recog_data ();
256838fd1498Szrj   regstat_free_n_sets_and_refs ();
256938fd1498Szrj   regstat_free_ri ();
257038fd1498Szrj   reload_completed = 1;
257138fd1498Szrj   update_inc_notes ();
257238fd1498Szrj 
257338fd1498Szrj   inserted_p = fixup_abnormal_edges ();
257438fd1498Szrj 
257538fd1498Szrj   /* We've possibly turned single trapping insn into multiple ones.  */
257638fd1498Szrj   if (cfun->can_throw_non_call_exceptions)
257738fd1498Szrj     {
257838fd1498Szrj       auto_sbitmap blocks (last_basic_block_for_fn (cfun));
257938fd1498Szrj       bitmap_ones (blocks);
258038fd1498Szrj       find_many_sub_basic_blocks (blocks);
258138fd1498Szrj     }
258238fd1498Szrj 
258338fd1498Szrj   if (inserted_p)
258438fd1498Szrj     commit_edge_insertions ();
258538fd1498Szrj 
258638fd1498Szrj   /* Replacing pseudos with their memory equivalents might have
258738fd1498Szrj      created shared rtx.  Subsequent passes would get confused
258838fd1498Szrj      by this, so unshare everything here.  */
258938fd1498Szrj   unshare_all_rtl_again (get_insns ());
259038fd1498Szrj 
259138fd1498Szrj   if (flag_checking)
259238fd1498Szrj     check_rtl (true);
259338fd1498Szrj 
259438fd1498Szrj   timevar_pop (TV_LRA);
259538fd1498Szrj }
259638fd1498Szrj 
259738fd1498Szrj /* Called once per compiler to initialize LRA data once.  */
259838fd1498Szrj void
lra_init_once(void)259938fd1498Szrj lra_init_once (void)
260038fd1498Szrj {
260138fd1498Szrj   init_insn_code_data_once ();
260238fd1498Szrj }
260338fd1498Szrj 
260438fd1498Szrj /* Called once per compiler to finish LRA data which are initialize
260538fd1498Szrj    once.  */
260638fd1498Szrj void
lra_finish_once(void)260738fd1498Szrj lra_finish_once (void)
260838fd1498Szrj {
260938fd1498Szrj   finish_insn_code_data_once ();
261038fd1498Szrj }
2611