1139804Simp/* LRA (local register allocator) driver and LRA utilities.
2185435Sbz   Copyright (C) 2010-2015 Free Software Foundation, Inc.
3185435Sbz   Contributed by Vladimir Makarov <vmakarov@redhat.com>.
4191673Sjamie
5185435SbzThis file is part of GCC.
6190466Sjamie
7185404SbzGCC is free software; you can redistribute it and/or modify it under
8185404Sbzthe terms of the GNU General Public License as published by the Free
9185404SbzSoftware Foundation; either version 3, or (at your option) any later
10185404Sbzversion.
11185404Sbz
12185404SbzGCC is distributed in the hope that it will be useful, but WITHOUT ANY
13185404SbzWARRANTY; without even the implied warranty of MERCHANTABILITY or
14185404SbzFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15185404Sbzfor more details.
16185404Sbz
17185404SbzYou should have received a copy of the GNU General Public License
18185404Sbzalong with GCC; see the file COPYING3.	If not see
19185404Sbz<http://www.gnu.org/licenses/>.	 */
20185404Sbz
21185404Sbz
22185404Sbz/* The Local Register Allocator (LRA) is a replacement of former
23185404Sbz   reload pass.	 It is focused to simplify code solving the reload
24185404Sbz   pass tasks, to make the code maintenance easier, and to implement new
25185404Sbz   perspective optimizations.
26185404Sbz
2746197Sphk   The major LRA design solutions are:
2846155Sphk     o division small manageable, separated sub-tasks
29116182Sobrien     o reflection of all transformations and decisions in RTL as more
30116182Sobrien       as possible
31116182Sobrien     o insn constraints as a primary source of the info (minimizing
32193066Sjamie       number of target-depended macros/hooks)
33185435Sbz
34185435Sbz   In brief LRA works by iterative insn process with the final goal is
35185435Sbz   to satisfy all insn and address constraints:
36131177Spjd     o New reload insns (in brief reloads) and reload pseudos might be
3746155Sphk       generated;
3846155Sphk     o Some pseudos might be spilled to assign hard registers to
3946155Sphk       new reload pseudos;
4046155Sphk     o Recalculating spilled pseudo values (rematerialization);
4146155Sphk     o Changing spilled pseudos to stack memory or their equivalences;
4246155Sphk     o Allocation stack memory changes the address displacement and
4346155Sphk       new iteration is needed.
44192895Sjamie
45164032Srwatson   Here is block diagram of LRA passes:
4646155Sphk
47124882Srwatson                                ------------------------
48177785Skib           ---------------     | Undo inheritance for   |     ---------------
4946155Sphk          | Memory-memory |    | spilled pseudos,       |    | New (and old) |
5087275Srwatson          | move coalesce |<---| splits for pseudos got |<-- |   pseudos     |
5187275Srwatson           ---------------     | the same hard regs,    |    |  assignment   |
52220137Strasz  Start           |            | and optional reloads   |     ---------------
53221362Strasz    |             |             ------------------------            ^
54168401Spjd    V             |              ----------------                   |
55193066Sjamie -----------      V             | Update virtual |                  |
56113275Smike|  Remove   |----> ------------>|    register    |                  |
57147185Spjd| scratches |     ^             |  displacements |                  |
58113275Smike -----------      |              ----------------                   |
5946155Sphk                  |                      |                          |
60113275Smike                  |                      V         New              |
6157163Srwatson                  |                 ------------  pseudos   -------------------
62113275Smike                  |                |Constraints:| or insns | Inheritance/split |
63196019Srwatson                  |                |    RTL     |--------->|  transformations  |
6446155Sphk                  |                | transfor-  |          |    in EBB scope   |
65196019Srwatson                  | substi-        |  mations   |           -------------------
66196019Srwatson                  | tutions         ------------
6746155Sphk                  |                     | No change
68196019Srwatson          ----------------              V
69185435Sbz         | Spilled pseudo |      -------------------
70185435Sbz         |    to memory   |<----| Rematerialization |
71185435Sbz         |  substitution  |      -------------------
72185435Sbz          ----------------
73185435Sbz                  | No susbtitions
74185435Sbz                  V
7546155Sphk      -------------------------
76163606Srwatson     | Hard regs substitution, |
77163606Srwatson     |  devirtalization, and   |------> Finish
78195944Sjamie     | restoring scratches got |
79195944Sjamie     |         memory          |
8046155Sphk      -------------------------
81227293Sed
8246155Sphk   To speed up the process:
83202468Sbz     o We process only insns affected by changes on previous
84202468Sbz       iterations;
85202468Sbz     o We don't use DFA-infrastructure because it results in much slower
86202468Sbz       compiler speed than a special IR described below does;
87202468Sbz     o We use a special insn representation for quick access to insn
88202468Sbz       info which is always *synchronized* with the current RTL;
89202468Sbz       o Insn IR is minimized by memory.  It is divided on three parts:
90202468Sbz	 o one specific for each insn in RTL (only operand locations);
91202468Sbz	 o one common for all insns in RTL with the same insn code
92202468Sbz	   (different operand attributes from machine descriptions);
93202468Sbz	 o one oriented for maintenance of live info (list of pseudos).
94202468Sbz       o Pseudo data:
95202468Sbz	 o all insns where the pseudo is referenced;
96202468Sbz	 o live info (conflicting hard regs, live ranges, # of
97202468Sbz	   references etc);
98192895Sjamie	 o data used for assigning (preferred hard regs, costs etc).
99192895Sjamie
100192895Sjamie   This file contains LRA driver, LRA utility functions and data, and
101192895Sjamie   code for dealing with scratches.  */
102192895Sjamie
103192895Sjamie#include "config.h"
104192895Sjamie#include "system.h"
105192895Sjamie#include "coretypes.h"
106231267Smm#include "tm.h"
107194762Sjamie#include "hard-reg-set.h"
108195944Sjamie#include "rtl.h"
109201145Santoine#include "tm_p.h"
110196176Sbz#include "regs.h"
111202468Sbz#include "insn-config.h"
112196176Sbz#include "insn-codes.h"
113202468Sbz#include "recog.h"
114196176Sbz#include "output.h"
115192895Sjamie#include "addresses.h"
116192895Sjamie#include "flags.h"
117192895Sjamie#include "hashtab.h"
11857163Srwatson#include "hash-set.h"
119221362Strasz#include "vec.h"
120168401Spjd#include "machmode.h"
121191673Sjamie#include "input.h"
122191673Sjamie#include "function.h"
123221362Strasz#include "symtab.h"
124179881Sdelphij#include "wide-int.h"
125113275Smike#include "inchash.h"
126191673Sjamie#include "tree.h"
127190466Sjamie#include "optabs.h"
128191673Sjamie#include "statistics.h"
129192895Sjamie#include "double-int.h"
130192895Sjamie#include "real.h"
131221362Strasz#include "fixed-value.h"
132221362Strasz#include "alias.h"
133232598Strasz#include "expmed.h"
134221362Strasz#include "dojump.h"
135221362Strasz#include "explow.h"
136185435Sbz#include "calls.h"
137190466Sjamie#include "emit-rtl.h"
138192895Sjamie#include "varasm.h"
139185435Sbz#include "stmt.h"
140185435Sbz#include "expr.h"
141190466Sjamie#include "predict.h"
142192895Sjamie#include "dominance.h"
143185435Sbz#include "cfg.h"
144113275Smike#include "cfgrtl.h"
145191673Sjamie#include "cfgbuild.h"
146191673Sjamie#include "basic-block.h"
147191673Sjamie#include "except.h"
148191673Sjamie#include "tree-pass.h"
149191673Sjamie#include "timevar.h"
150191673Sjamie#include "target.h"
151113275Smike#include "ira.h"
152192895Sjamie#include "lra-int.h"
153216861Sbz#include "df.h"
154216861Sbz
155216861Sbz/* Dump bitmap SET with TITLE and BB INDEX.  */
156192895Sjamievoid
157192895Sjamielra_dump_bitmap_with_title (const char *title, bitmap set, int index)
158192895Sjamie{
159202468Sbz  unsigned int i;
160202468Sbz  int count;
161202468Sbz  bitmap_iterator bi;
162202468Sbz  static const int max_nums_on_line = 10;
163202468Sbz
164202468Sbz  if (bitmap_empty_p (set))
165192895Sjamie    return;
166216861Sbz  fprintf (lra_dump_file, "  %s %d:", title, index);
167192895Sjamie  fprintf (lra_dump_file, "\n");
168192895Sjamie  count = max_nums_on_line + 1;
169192895Sjamie  EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
170202468Sbz    {
171202468Sbz      if (count > max_nums_on_line)
172202468Sbz	{
173202468Sbz	  fprintf (lra_dump_file, "\n    ");
174202468Sbz	  count = 0;
175202468Sbz	}
176195870Sjamie      fprintf (lra_dump_file, " %4u", i);
177216861Sbz      count++;
178195870Sjamie    }
179195870Sjamie  fprintf (lra_dump_file, "\n");
180195870Sjamie}
181195870Sjamie
182195870Sjamie/* Hard registers currently not available for allocation.  It can
183195870Sjamie   changed after some hard  registers become not eliminable.  */
184195870SjamieHARD_REG_SET lra_no_alloc_regs;
185195870Sjamie
186195870Sjamiestatic int get_new_reg_value (void);
187195870Sjamiestatic void expand_reg_info (void);
188192895Sjamiestatic void invalidate_insn_recog_data (int);
189195870Sjamiestatic int get_insn_freq (rtx_insn *);
190192895Sjamiestatic void invalidate_insn_data_regno_info (lra_insn_recog_data_t,
191192895Sjamie					     rtx_insn *, int);
192195870Sjamie
193192895Sjamie/* Expand all regno related info needed for LRA.  */
194192895Sjamiestatic void
195216861Sbzexpand_reg_data (int old)
196192895Sjamie{
197192895Sjamie  resize_reg_info ();
198192895Sjamie  expand_reg_info ();
199192895Sjamie  ira_expand_reg_equiv ();
200192895Sjamie  for (int i = (int) max_reg_num () - 1; i >= old; i--)
201192895Sjamie    lra_change_class (i, ALL_REGS, "      Set", true);
202192895Sjamie}
203192895Sjamie
204192895Sjamie/* Create and return a new reg of ORIGINAL mode.  If ORIGINAL is NULL
205232059Smm   or of VOIDmode, use MD_MODE for the new reg.  Initialize its
206232059Smm   register class to RCLASS.  Print message about assigning class
207232186Smm   RCLASS containing new register name TITLE unless it is NULL.  Use
208232278Smm   attributes of ORIGINAL if it is a register.  The created register
209254741Sdelphij   will have unique held value.  */
210277985Sjamiertx
211192895Sjamielra_create_new_reg_with_unique_value (machine_mode md_mode, rtx original,
212216861Sbz				      enum reg_class rclass, const char *title)
213192895Sjamie{
214192895Sjamie  machine_mode mode;
215192895Sjamie  rtx new_reg;
216192895Sjamie
217192895Sjamie  if (original == NULL_RTX || (mode = GET_MODE (original)) == VOIDmode)
218192895Sjamie    mode = md_mode;
219192895Sjamie  lra_assert (mode != VOIDmode);
220192895Sjamie  new_reg = gen_reg_rtx (mode);
221192895Sjamie  if (original == NULL_RTX || ! REG_P (original))
222232059Smm    {
223232059Smm      if (lra_dump_file != NULL)
224232186Smm	fprintf (lra_dump_file, "      Creating newreg=%i", REGNO (new_reg));
225232278Smm    }
226254741Sdelphij  else
227277985Sjamie    {
228192895Sjamie      if (ORIGINAL_REGNO (original) >= FIRST_PSEUDO_REGISTER)
229216861Sbz	ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original);
230192895Sjamie      REG_USERVAR_P (new_reg) = REG_USERVAR_P (original);
231196002Sjamie      REG_POINTER (new_reg) = REG_POINTER (original);
232196002Sjamie      REG_ATTRS (new_reg) = REG_ATTRS (original);
233232059Smm      if (lra_dump_file != NULL)
234192895Sjamie	fprintf (lra_dump_file, "      Creating newreg=%i from oldreg=%i",
235196002Sjamie		 REGNO (new_reg), REGNO (original));
236231267Smm    }
237192895Sjamie  if (lra_dump_file != NULL)
238193865Sjamie    {
239192895Sjamie      if (title != NULL)
240192895Sjamie	fprintf (lra_dump_file, ", assigning class %s to%s%s r%d",
241280632Sian		 reg_class_names[rclass], *title == '\0' ? "" : " ",
242280632Sian		 title, REGNO (new_reg));
243280632Sian      fprintf (lra_dump_file, "\n");
244280632Sian    }
245280632Sian  expand_reg_data (max_reg_num ());
246280632Sian  setup_reg_classes (REGNO (new_reg), rclass, NO_REGS, rclass);
247280632Sian  return new_reg;
248280632Sian}
249280632Sian
250280632Sian/* Analogous to the previous function but also inherits value of
251280632Sian   ORIGINAL.  */
252280632Sianrtx
253280632Sianlra_create_new_reg (machine_mode md_mode, rtx original,
254192895Sjamie		    enum reg_class rclass, const char *title)
255185435Sbz{
256185435Sbz  rtx new_reg;
257185435Sbz
258185435Sbz  new_reg
259185435Sbz    = lra_create_new_reg_with_unique_value (md_mode, original, rclass, title);
260185435Sbz  if (original != NULL_RTX && REG_P (original))
261185435Sbz    lra_assign_reg_val (REGNO (original), REGNO (new_reg));
262185435Sbz  return new_reg;
263185435Sbz}
264185435Sbz
265185435Sbz/* Set up for REGNO unique hold value.	*/
266185435Sbzvoid
267185435Sbzlra_set_regno_unique_value (int regno)
268185435Sbz{
269185435Sbz  lra_reg_info[regno].val = get_new_reg_value ();
270185435Sbz}
271185435Sbz
272185435Sbz/* Invalidate INSN related info used by LRA.  The info should never be
273185435Sbz   used after that.  */
274185435Sbzvoid
275185435Sbzlra_invalidate_insn_data (rtx_insn *insn)
276185435Sbz{
277185435Sbz  lra_invalidate_insn_regno_info (insn);
278185435Sbz  invalidate_insn_recog_data (INSN_UID (insn));
279185435Sbz}
280185435Sbz
281185435Sbz/* Mark INSN deleted and invalidate the insn related info used by
282185435Sbz   LRA.	 */
283185435Sbzvoid
284185435Sbzlra_set_insn_deleted (rtx_insn *insn)
285185435Sbz{
286185435Sbz  lra_invalidate_insn_data (insn);
287185435Sbz  SET_INSN_DELETED (insn);
288185435Sbz}
289185435Sbz
290185435Sbz/* Delete an unneeded INSN and any previous insns who sole purpose is
291185435Sbz   loading data that is dead in INSN.  */
292190466Sjamievoid
293185435Sbzlra_delete_dead_insn (rtx_insn *insn)
294185435Sbz{
295185435Sbz  rtx_insn *prev = prev_real_insn (insn);
296185435Sbz  rtx prev_dest;
297185435Sbz
298185435Sbz  /* If the previous insn sets a register that dies in our insn,
299185435Sbz     delete it too.  */
300185435Sbz  if (prev && GET_CODE (PATTERN (prev)) == SET
301185435Sbz      && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
302191673Sjamie      && reg_mentioned_p (prev_dest, PATTERN (insn))
303191673Sjamie      && find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
304191673Sjamie      && ! side_effects_p (SET_SRC (PATTERN (prev))))
305191673Sjamie    lra_delete_dead_insn (prev);
306191673Sjamie
307191673Sjamie  lra_set_insn_deleted (insn);
308225617Skmacy}
309185435Sbz
310191673Sjamie/* Emit insn x = y + z.  Return NULL if we failed to do it.
311191673Sjamie   Otherwise, return the insn.  We don't use gen_add3_insn as it might
312192895Sjamie   clobber CC.  */
313185435Sbzstatic rtx
314191673Sjamieemit_add3_insn (rtx x, rtx y, rtx z)
315191673Sjamie{
316191673Sjamie  rtx_insn *last;
317185435Sbz
318191673Sjamie  last = get_last_insn ();
319191673Sjamie
320191673Sjamie  if (have_addptr3_insn (x, y, z))
321191673Sjamie    {
322185435Sbz      rtx insn = gen_addptr3_insn (x, y, z);
323192895Sjamie
324192895Sjamie      /* If the target provides an "addptr" pattern it hopefully does
325191673Sjamie	 for a reason.  So falling back to the normal add would be
326191673Sjamie	 a bug.  */
327191673Sjamie      lra_assert (insn != NULL_RTX);
328192895Sjamie      emit_insn (insn);
329192895Sjamie      return insn;
330192895Sjamie    }
331258929Speter
332191673Sjamie  rtx_insn *insn = emit_insn (gen_rtx_SET (VOIDmode, x,
333191673Sjamie					   gen_rtx_PLUS (GET_MODE (y), y, z)));
334191673Sjamie  if (recog_memoized (insn) < 0)
335191673Sjamie    {
336185435Sbz      delete_insns_since (last);
337191673Sjamie      insn = NULL;
338191673Sjamie    }
339185435Sbz  return insn;
340191673Sjamie}
341185435Sbz
342191673Sjamie/* Emit insn x = x + y.  Return the insn.  We use gen_add2_insn as the
343191673Sjamie   last resort.  */
344191673Sjamiestatic rtx
345191673Sjamieemit_add2_insn (rtx x, rtx y)
346191673Sjamie{
347192895Sjamie  rtx insn;
348192895Sjamie
349192895Sjamie  insn = emit_add3_insn (x, x, y);
350192895Sjamie  if (insn == NULL_RTX)
351192895Sjamie    {
352192895Sjamie      insn = gen_add2_insn (x, y);
353192895Sjamie      if (insn != NULL_RTX)
354192895Sjamie	emit_insn (insn);
355192895Sjamie    }
356192895Sjamie  return insn;
357192895Sjamie}
358192895Sjamie
359193865Sjamie/* Target checks operands through operand predicates to recognize an
360193865Sjamie   insn.  We should have a special precaution to generate add insns
361193865Sjamie   which are frequent results of elimination.
362193865Sjamie
363193865Sjamie   Emit insns for x = y + z.  X can be used to store intermediate
364193865Sjamie   values and should be not in Y and Z when we use X to store an
365193865Sjamie   intermediate value.  Y + Z should form [base] [+ index[ * scale]] [
366193865Sjamie   + disp] where base and index are registers, disp and scale are
367193865Sjamie   constants.  Y should contain base if it is present, Z should
368192895Sjamie   contain disp if any.  index[*scale] can be part of Y or Z.  */
369192895Sjamievoid
370185435Sbzlra_emit_add (rtx x, rtx y, rtx z)
371193865Sjamie{
372192895Sjamie  int old;
373192895Sjamie  rtx_insn *last;
374192895Sjamie  rtx a1, a2, base, index, disp, scale, index_scale;
375192895Sjamie  bool ok_p;
376192895Sjamie
377192895Sjamie  rtx add3_insn = emit_add3_insn (x, y, z);
378192895Sjamie  old = max_reg_num ();
379192895Sjamie  if (add3_insn != NULL)
380192895Sjamie    ;
381192895Sjamie  else
382192895Sjamie    {
383192895Sjamie      disp = a2 = NULL_RTX;
384192895Sjamie      if (GET_CODE (y) == PLUS)
385192895Sjamie	{
386192895Sjamie	  a1 = XEXP (y, 0);
387192895Sjamie	  a2 = XEXP (y, 1);
388192895Sjamie	  disp = z;
389192895Sjamie	}
390192895Sjamie      else
391192895Sjamie	{
392192895Sjamie	  a1 = y;
393192895Sjamie	  if (CONSTANT_P (z))
394192895Sjamie	    disp = z;
395192895Sjamie	  else
396192895Sjamie	    a2 = z;
397192895Sjamie	}
398192895Sjamie      index_scale = scale = NULL_RTX;
399192895Sjamie      if (GET_CODE (a1) == MULT)
400192895Sjamie	{
401192895Sjamie	  index_scale = a1;
402192895Sjamie	  index = XEXP (a1, 0);
403192895Sjamie	  scale = XEXP (a1, 1);
404192895Sjamie	  base = a2;
405192895Sjamie	}
406192895Sjamie      else if (a2 != NULL_RTX && GET_CODE (a2) == MULT)
407192895Sjamie	{
408192895Sjamie	  index_scale = a2;
409192895Sjamie	  index = XEXP (a2, 0);
410192895Sjamie	  scale = XEXP (a2, 1);
411192895Sjamie	  base = a1;
412192895Sjamie	}
413192895Sjamie      else
414192895Sjamie	{
415191673Sjamie	  base = a1;
416192895Sjamie	  index = a2;
417192895Sjamie	}
418191673Sjamie      if (! (REG_P (base) || GET_CODE (base) == SUBREG)
419191673Sjamie	  || (index != NULL_RTX
420192895Sjamie	      && ! (REG_P (index) || GET_CODE (index) == SUBREG))
421192895Sjamie	  || (disp != NULL_RTX && ! CONSTANT_P (disp))
422192895Sjamie	  || (scale != NULL_RTX && ! CONSTANT_P (scale)))
423191673Sjamie	{
424192895Sjamie	  /* Probably we have no 3 op add.  Last chance is to use 2-op
425192895Sjamie	     add insn.  To succeed, don't move Z to X as an address
426191673Sjamie	     segment always comes in Y.  Otherwise, we might fail when
427192895Sjamie	     adding the address segment to register.  */
428192895Sjamie	  lra_assert (x != y && x != z);
429192895Sjamie	  emit_move_insn (x, y);
430191673Sjamie	  rtx insn = emit_add2_insn (x, z);
431192895Sjamie	  lra_assert (insn != NULL_RTX);
432191673Sjamie	}
433191673Sjamie      else
434191673Sjamie	{
435192895Sjamie	  if (index_scale == NULL_RTX)
436191673Sjamie	    index_scale = index;
437192895Sjamie	  if (disp == NULL_RTX)
438191673Sjamie	    {
439191673Sjamie	      /* Generate x = index_scale; x = x + base.  */
440192895Sjamie	      lra_assert (index_scale != NULL_RTX && base != NULL_RTX);
441192895Sjamie	      emit_move_insn (x, index_scale);
442192895Sjamie	      rtx insn = emit_add2_insn (x, base);
443192895Sjamie	      lra_assert (insn != NULL_RTX);
444192895Sjamie	    }
445192895Sjamie	  else if (scale == NULL_RTX)
446192895Sjamie	    {
447192895Sjamie	      /* Try x = base + disp.  */
448192895Sjamie	      lra_assert (base != NULL_RTX);
449192895Sjamie	      last = get_last_insn ();
450192895Sjamie	      rtx_insn *move_insn =
451192895Sjamie		emit_move_insn (x, gen_rtx_PLUS (GET_MODE (base), base, disp));
452192895Sjamie	      if (recog_memoized (move_insn) < 0)
453192895Sjamie		{
454192895Sjamie		  delete_insns_since (last);
455192895Sjamie		  /* Generate x = disp; x = x + base.  */
456192895Sjamie		  emit_move_insn (x, disp);
457192895Sjamie		  rtx add2_insn = emit_add2_insn (x, base);
458192895Sjamie		  lra_assert (add2_insn != NULL_RTX);
459192895Sjamie		}
460192895Sjamie	      /* Generate x = x + index.  */
461192895Sjamie	      if (index != NULL_RTX)
462192895Sjamie		{
463192895Sjamie		  rtx insn = emit_add2_insn (x, index);
464192895Sjamie		  lra_assert (insn != NULL_RTX);
465192895Sjamie		}
466192895Sjamie	    }
467192895Sjamie	  else
468192895Sjamie	    {
469191673Sjamie	      /* Try x = index_scale; x = x + disp; x = x + base.  */
470191673Sjamie	      last = get_last_insn ();
471191673Sjamie	      rtx_insn *move_insn = emit_move_insn (x, index_scale);
472191673Sjamie	      ok_p = false;
473192895Sjamie	      if (recog_memoized (move_insn) >= 0)
474192895Sjamie		{
475191673Sjamie		  rtx insn = emit_add2_insn (x, disp);
476192895Sjamie		  if (insn != NULL_RTX)
477192895Sjamie		    {
478192895Sjamie		      insn = emit_add2_insn (x, base);
479192895Sjamie		      if (insn != NULL_RTX)
480192895Sjamie			ok_p = true;
481192895Sjamie		    }
482192895Sjamie		}
483192895Sjamie	      if (! ok_p)
484192895Sjamie		{
485191673Sjamie		  delete_insns_since (last);
486191673Sjamie		  /* Generate x = disp; x = x + base; x = x + index_scale.  */
487191673Sjamie		  emit_move_insn (x, disp);
488191673Sjamie		  rtx insn = emit_add2_insn (x, base);
489192895Sjamie		  lra_assert (insn != NULL_RTX);
490192895Sjamie		  insn = emit_add2_insn (x, index_scale);
491185435Sbz		  lra_assert (insn != NULL_RTX);
492185435Sbz		}
493192895Sjamie	    }
494192895Sjamie	}
495192895Sjamie    }
496192895Sjamie  /* Functions emit_... can create pseudos -- so expand the pseudo
497192895Sjamie     data.  */
498192895Sjamie  if (old != max_reg_num ())
499192895Sjamie    expand_reg_data (old);
500192895Sjamie}
501192895Sjamie
502192895Sjamie/* The number of emitted reload insns so far.  */
503192895Sjamieint lra_curr_reload_num;
504185435Sbz
505192895Sjamie/* Emit x := y, processing special case when y = u + v or y = u + v *
506192895Sjamie   scale + w through emit_add (Y can be an address which is base +
507191673Sjamie   index reg * scale + displacement in general case).  X may be used
508191673Sjamie   as intermediate result therefore it should be not in Y.  */
509191673Sjamievoid
510185435Sbzlra_emit_move (rtx x, rtx y)
511185435Sbz{
512192895Sjamie  int old;
513191673Sjamie
514191673Sjamie  if (GET_CODE (y) != PLUS)
515191673Sjamie    {
516191673Sjamie      if (rtx_equal_p (x, y))
517191673Sjamie	return;
518191673Sjamie      old = max_reg_num ();
519191673Sjamie      emit_move_insn (x, y);
520191673Sjamie      if (REG_P (x))
521225617Skmacy	lra_reg_info[ORIGINAL_REGNO (x)].last_reload = ++lra_curr_reload_num;
522185435Sbz      /* Function emit_move can create pseudos -- so expand the pseudo
523191673Sjamie	 data.	*/
524191673Sjamie      if (old != max_reg_num ())
525191673Sjamie	expand_reg_data (old);
526191673Sjamie      return;
527191673Sjamie    }
528191673Sjamie  lra_emit_add (x, XEXP (y, 0), XEXP (y, 1));
529191673Sjamie}
530191673Sjamie
531191673Sjamie/* Update insn operands which are duplication of operands whose
532191673Sjamie   numbers are in array of NOPS (with end marker -1).  The insn is
533191673Sjamie   represented by its LRA internal representation ID.  */
534191673Sjamievoid
535191673Sjamielra_update_dups (lra_insn_recog_data_t id, signed char *nops)
536191673Sjamie{
537191673Sjamie  int i, j, nop;
538191673Sjamie  struct lra_static_insn_data *static_id = id->insn_static_data;
539191673Sjamie
540191673Sjamie  for (i = 0; i < static_id->n_dups; i++)
541191673Sjamie    for (j = 0; (nop = nops[j]) >= 0; j++)
542185435Sbz      if (static_id->dup_num[i] == nop)
543190466Sjamie	*id->dup_loc[i] = *id->operand_loc[nop];
544185435Sbz}
545185435Sbz
546185435Sbz
547185435Sbz
548191673Sjamie/* This page contains code dealing with info about registers in the
549191673Sjamie   insns.  */
550196135Sbz
551191673Sjamie/* Pools for insn reg info.  */
552196835Sjamiestatic alloc_pool insn_reg_pool;
553280632Sian
554192895Sjamie/* Initiate pool for insn reg info.  */
555196135Sbzstatic void
556191673Sjamieinit_insn_regs (void)
557192895Sjamie{
558193066Sjamie  insn_reg_pool
559192895Sjamie    = create_alloc_pool ("insn regs", sizeof (struct lra_insn_reg), 100);
560192895Sjamie}
561231267Smm
562195870Sjamie/* Create LRA insn related info about a reference to REGNO in INSN with
563280632Sian   TYPE (in/out/inout), biggest reference mode MODE, flag that it is
564230129Smm   reference through subreg (SUBREG_P), flag that is early clobbered
565191673Sjamie   in the insn (EARLY_CLOBBER), and reference to the next insn reg
566192895Sjamie   info (NEXT).	 */
567191673Sjamiestatic struct lra_insn_reg *
568191673Sjamienew_insn_reg (rtx_insn *insn, int regno, enum op_type type,
569195974Sjamie	      machine_mode mode,
570191673Sjamie	      bool subreg_p, bool early_clobber, struct lra_insn_reg *next)
571191673Sjamie{
572195974Sjamie  struct lra_insn_reg *ir;
573191673Sjamie
574224290Smckusick  ir = (struct lra_insn_reg *) pool_alloc (insn_reg_pool);
575224290Smckusick  ir->type = type;
576191673Sjamie  ir->biggest_mode = mode;
577185435Sbz  if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode)
578191673Sjamie      && NONDEBUG_INSN_P (insn))
579191673Sjamie    lra_reg_info[regno].biggest_mode = mode;
580191673Sjamie  ir->subreg_p = subreg_p;
581191673Sjamie  ir->early_clobber = early_clobber;
582191673Sjamie  ir->regno = regno;
583192895Sjamie  ir->next = next;
584194762Sjamie  return ir;
585192895Sjamie}
586191673Sjamie
587191673Sjamie/* Free insn reg info IR.  */
588191673Sjamiestatic void
589185435Sbzfree_insn_reg (struct lra_insn_reg *ir)
590191673Sjamie{
591191673Sjamie  pool_free (insn_reg_pool, ir);
592191673Sjamie}
593191673Sjamie
594185435Sbz/* Free insn reg info list IR.	*/
595191673Sjamiestatic void
596191673Sjamiefree_insn_regs (struct lra_insn_reg *ir)
597191673Sjamie{
598185435Sbz  struct lra_insn_reg *next_ir;
599191673Sjamie
600191673Sjamie  for (; ir != NULL; ir = next_ir)
601191673Sjamie    {
602185435Sbz      next_ir = ir->next;
603185435Sbz      free_insn_reg (ir);
604185435Sbz    }
605185435Sbz}
606185435Sbz
607185435Sbz/* Finish pool for insn reg info.  */
608230407Smmstatic void
609191673Sjamiefinish_insn_regs (void)
610191673Sjamie{
611191673Sjamie  free_alloc_pool (insn_reg_pool);
612191673Sjamie}
613191673Sjamie
614191673Sjamie
615191673Sjamie
616191673Sjamie/* This page contains code dealing LRA insn info (or in other words
617191673Sjamie   LRA internal insn representation).  */
618191673Sjamie
619191673Sjamie/* Map INSN_CODE -> the static insn data.  This info is valid during
620191673Sjamie   all translation unit.  */
621191673Sjamiestruct lra_static_insn_data *insn_code_data[LAST_INSN_CODE];
622191673Sjamie
623191673Sjamie/* Debug insns are represented as a special insn with one input
624194762Sjamie   operand which is RTL expression in var_location.  */
625194762Sjamie
626194762Sjamie/* The following data are used as static insn operand data for all
627194762Sjamie   debug insns.	 If structure lra_operand_data is changed, the
628194762Sjamie   initializer should be changed too.  */
629194762Sjamiestatic struct lra_operand_data debug_operand_data =
630194762Sjamie  {
631194762Sjamie    NULL, /* alternative  */
632194762Sjamie    VOIDmode, /* We are not interesting in the operand mode.  */
633192895Sjamie    OP_IN,
634212436Sjamie    0, 0, 0, 0
635212436Sjamie  };
636212436Sjamie
637192895Sjamie/* The following data are used as static insn data for all debug
638212436Sjamie   insns.  If structure lra_static_insn_data is changed, the
639212436Sjamie   initializer should be changed too.  */
640212436Sjamiestatic struct lra_static_insn_data debug_insn_static_data =
641212436Sjamie  {
642212436Sjamie    &debug_operand_data,
643192895Sjamie    0,	/* Duplication operands #.  */
644231267Smm    -1, /* Commutative operand #.  */
645231267Smm    1,	/* Operands #.	There is only one operand which is debug RTL
646231267Smm	   expression.	*/
647231267Smm    0,	/* Duplications #.  */
648231267Smm    0,	/* Alternatives #.  We are not interesting in alternatives
649231267Smm	   because we does not proceed debug_insns for reloads.	 */
650231267Smm    NULL, /* Hard registers referenced in machine description.	*/
651231267Smm    NULL  /* Descriptions of operands in alternatives.	*/
652191673Sjamie  };
653192895Sjamie
654192895Sjamie/* Called once per compiler work to initialize some LRA data related
655192895Sjamie   to insns.  */
656192895Sjamiestatic void
657192895Sjamieinit_insn_code_data_once (void)
658192895Sjamie{
659192895Sjamie  memset (insn_code_data, 0, sizeof (insn_code_data));
660191673Sjamie}
661195870Sjamie
662195870Sjamie/* Called once per compiler work to finalize some LRA data related to
663195870Sjamie   insns.  */
664195870Sjamiestatic void
665195870Sjamiefinish_insn_code_data_once (void)
666195870Sjamie{
667195870Sjamie  int i;
668195870Sjamie
669195870Sjamie  for (i = 0; i < LAST_INSN_CODE; i++)
670195870Sjamie    {
671195870Sjamie      if (insn_code_data[i] != NULL)
672195870Sjamie	free (insn_code_data[i]);
673195870Sjamie    }
674195870Sjamie}
675195870Sjamie
676195870Sjamie/* Return static insn data, allocate and setup if necessary.  Although
677195870Sjamie   dup_num is static data (it depends only on icode), to set it up we
678195870Sjamie   need to extract insn first.	So recog_data should be valid for
679195870Sjamie   normal insn (ICODE >= 0) before the call.  */
680195870Sjamiestatic struct lra_static_insn_data *
681195870Sjamieget_static_insn_data (int icode, int nop, int ndup, int nalt)
682195870Sjamie{
683195870Sjamie  struct lra_static_insn_data *data;
684195870Sjamie  size_t n_bytes;
685195870Sjamie
686195870Sjamie  lra_assert (icode < LAST_INSN_CODE);
687195870Sjamie  if (icode >= 0 && (data = insn_code_data[icode]) != NULL)
688195870Sjamie    return data;
689211085Sjamie  lra_assert (nop >= 0 && ndup >= 0 && nalt >= 0);
690211085Sjamie  n_bytes = sizeof (struct lra_static_insn_data)
691211085Sjamie	    + sizeof (struct lra_operand_data) * nop
692211085Sjamie	    + sizeof (int) * ndup;
693211085Sjamie  data = XNEWVAR (struct lra_static_insn_data, n_bytes);
694211085Sjamie  data->operand_alternative = NULL;
695194251Sjamie  data->n_operands = nop;
696194251Sjamie  data->n_dups = ndup;
697194251Sjamie  data->n_alternatives = nalt;
698194251Sjamie  data->operand = ((struct lra_operand_data *)
699194251Sjamie		   ((char *) data + sizeof (struct lra_static_insn_data)));
700194251Sjamie  data->dup_num = ((int *) ((char *) data->operand
701194251Sjamie			    + sizeof (struct lra_operand_data) * nop));
702195974Sjamie  if (icode >= 0)
703195974Sjamie    {
704195974Sjamie      int i;
705195974Sjamie
706195974Sjamie      insn_code_data[icode] = data;
707195974Sjamie      for (i = 0; i < nop; i++)
708195974Sjamie	{
709195974Sjamie	  data->operand[i].constraint
710195974Sjamie	    = insn_data[icode].operand[i].constraint;
711195974Sjamie	  data->operand[i].mode = insn_data[icode].operand[i].mode;
712195974Sjamie	  data->operand[i].strict_low = insn_data[icode].operand[i].strict_low;
713195974Sjamie	  data->operand[i].is_operator
714195974Sjamie	    = insn_data[icode].operand[i].is_operator;
715195974Sjamie	  data->operand[i].type
716191673Sjamie	    = (data->operand[i].constraint[0] == '=' ? OP_OUT
717192895Sjamie	       : data->operand[i].constraint[0] == '+' ? OP_INOUT
718192895Sjamie	       : OP_IN);
719192895Sjamie	  data->operand[i].is_address = false;
720192895Sjamie	}
721192895Sjamie      for (i = 0; i < ndup; i++)
722192895Sjamie	data->dup_num[i] = recog_data.dup_num[i];
723192895Sjamie    }
724192895Sjamie  return data;
725191673Sjamie}
726191673Sjamie
727191673Sjamie/* The current length of the following array.  */
728191673Sjamieint lra_insn_recog_data_len;
729191673Sjamie
730191673Sjamie/* Map INSN_UID -> the insn recog data (NULL if unknown).  */
731191673Sjamielra_insn_recog_data_t *lra_insn_recog_data;
732191673Sjamie
733191673Sjamie/* Initialize LRA data about insns.  */
734191673Sjamiestatic void
735191673Sjamieinit_insn_recog_data (void)
736191673Sjamie{
737191673Sjamie  lra_insn_recog_data_len = 0;
738191673Sjamie  lra_insn_recog_data = NULL;
739191673Sjamie  init_insn_regs ();
740191673Sjamie}
741191673Sjamie
742191673Sjamie/* Expand, if necessary, LRA data about insns.	*/
743191673Sjamiestatic void
744191673Sjamiecheck_and_expand_insn_recog_data (int index)
745191673Sjamie{
746191673Sjamie  int i, old;
747193066Sjamie
748193066Sjamie  if (lra_insn_recog_data_len > index)
749191673Sjamie    return;
750191673Sjamie  old = lra_insn_recog_data_len;
751191673Sjamie  lra_insn_recog_data_len = index * 3 / 2 + 1;
752191673Sjamie  lra_insn_recog_data = XRESIZEVEC (lra_insn_recog_data_t,
753191673Sjamie				    lra_insn_recog_data,
754191673Sjamie				    lra_insn_recog_data_len);
755191673Sjamie  for (i = old; i < lra_insn_recog_data_len; i++)
756191673Sjamie    lra_insn_recog_data[i] = NULL;
757191673Sjamie}
758191673Sjamie
759193066Sjamie/* Finish LRA DATA about insn.	*/
760193066Sjamiestatic void
761193066Sjamiefree_insn_recog_data (lra_insn_recog_data_t data)
762193066Sjamie{
763193066Sjamie  if (data->operand_loc != NULL)
764193066Sjamie    free (data->operand_loc);
765193066Sjamie  if (data->dup_loc != NULL)
766193066Sjamie    free (data->dup_loc);
767193066Sjamie  if (data->arg_hard_regs != NULL)
768193066Sjamie    free (data->arg_hard_regs);
769193066Sjamie  if (data->icode < 0 && NONDEBUG_INSN_P (data->insn))
770193066Sjamie    {
771193066Sjamie      if (data->insn_static_data->operand_alternative != NULL)
772193066Sjamie	free (const_cast <operand_alternative *>
773193066Sjamie	      (data->insn_static_data->operand_alternative));
774193066Sjamie      free_insn_regs (data->insn_static_data->hard_regs);
775193066Sjamie      free (data->insn_static_data);
776193066Sjamie    }
777193066Sjamie  free_insn_regs (data->regs);
778193066Sjamie  data->regs = NULL;
779193066Sjamie  free (data);
780193066Sjamie}
781193066Sjamie
782193066Sjamie/* Finish LRA data about all insns.  */
783193066Sjamiestatic void
784193066Sjamiefinish_insn_recog_data (void)
785193066Sjamie{
786193066Sjamie  int i;
787193066Sjamie  lra_insn_recog_data_t data;
788193066Sjamie
789193066Sjamie  for (i = 0; i < lra_insn_recog_data_len; i++)
790193066Sjamie    if ((data = lra_insn_recog_data[i]) != NULL)
791193066Sjamie      free_insn_recog_data (data);
792193066Sjamie  finish_insn_regs ();
793193066Sjamie  free (lra_insn_recog_data);
794193066Sjamie}
795205014Snwhitehorn
796217896Sdchagin/* Setup info about operands in alternatives of LRA DATA of insn.  */
797193066Sjamiestatic void
798193066Sjamiesetup_operand_alternative (lra_insn_recog_data_t data,
799193066Sjamie			   const operand_alternative *op_alt)
800193066Sjamie{
801193066Sjamie  int i, j, nop, nalt;
802193066Sjamie  int icode = data->icode;
803193066Sjamie  struct lra_static_insn_data *static_data = data->insn_static_data;
804193066Sjamie
805193066Sjamie  static_data->commutative = -1;
806193066Sjamie  nop = static_data->n_operands;
807193066Sjamie  nalt = static_data->n_alternatives;
808193066Sjamie  static_data->operand_alternative = op_alt;
809193066Sjamie  for (i = 0; i < nop; i++)
810193066Sjamie    {
811193066Sjamie      static_data->operand[i].early_clobber = false;
812193066Sjamie      static_data->operand[i].is_address = false;
813193066Sjamie      if (static_data->operand[i].constraint[0] == '%')
814185435Sbz	{
815191673Sjamie	  /* We currently only support one commutative pair of operands.  */
816191673Sjamie	  if (static_data->commutative < 0)
817277279Sjamie	    static_data->commutative = i;
818191673Sjamie	  else
819191673Sjamie	    lra_assert (icode < 0); /* Asm  */
820191673Sjamie	  /* The last operand should not be marked commutative.  */
821191673Sjamie	  lra_assert (i != nop - 1);
822191673Sjamie	}
823192895Sjamie    }
824195870Sjamie  for (j = 0; j < nalt; j++)
825195870Sjamie    for (i = 0; i < nop; i++, op_alt++)
826195870Sjamie      {
827195870Sjamie	static_data->operand[i].early_clobber |= op_alt->earlyclobber;
828195870Sjamie	static_data->operand[i].is_address |= op_alt->is_address;
829192895Sjamie      }
830192895Sjamie}
831185435Sbz
832192895Sjamie/* Recursively process X and collect info about registers, which are
833192895Sjamie   not the insn operands, in X with TYPE (in/out/inout) and flag that
834185435Sbz   it is early clobbered in the insn (EARLY_CLOBBER) and add the info
835195974Sjamie   to LIST.  X is a part of insn given by DATA.	 Return the result
836192895Sjamie   list.  */
837192895Sjamiestatic struct lra_insn_reg *
838192895Sjamiecollect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
839192895Sjamie			       struct lra_insn_reg *list,
840192895Sjamie			       enum op_type type, bool early_clobber)
841202116Sbz{
842202116Sbz  int i, j, regno, last;
843202116Sbz  bool subreg_p;
844192895Sjamie  machine_mode mode;
845192895Sjamie  struct lra_insn_reg *curr;
846192895Sjamie  rtx op = *x;
847192895Sjamie  enum rtx_code code = GET_CODE (op);
848192895Sjamie  const char *fmt = GET_RTX_FORMAT (code);
849192895Sjamie
850192895Sjamie  for (i = 0; i < data->insn_static_data->n_operands; i++)
851192895Sjamie    if (x == data->operand_loc[i])
852192895Sjamie      /* It is an operand loc. Stop here.  */
853192895Sjamie      return list;
854192895Sjamie  for (i = 0; i < data->insn_static_data->n_dups; i++)
855192895Sjamie    if (x == data->dup_loc[i])
856192895Sjamie      /* It is a dup loc. Stop here.  */
857192895Sjamie      return list;
858192895Sjamie  mode = GET_MODE (op);
859192895Sjamie  subreg_p = false;
860192895Sjamie  if (code == SUBREG)
861192895Sjamie    {
862192895Sjamie      op = SUBREG_REG (op);
863192895Sjamie      code = GET_CODE (op);
864192895Sjamie      if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (op)))
865192895Sjamie	{
866192895Sjamie	  mode = GET_MODE (op);
867192895Sjamie	  if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode))
868185435Sbz	    subreg_p = true;
869191673Sjamie	}
870191673Sjamie    }
871185435Sbz  if (REG_P (op))
872185435Sbz    {
873191673Sjamie      if ((regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER)
874191673Sjamie	return list;
875277279Sjamie      /* Process all regs even unallocatable ones as we need info
876191673Sjamie	 about all regs for rematerialization pass.  */
877191673Sjamie      for (last = regno + hard_regno_nregs[regno][mode];
878191673Sjamie	   regno < last;
879191673Sjamie	   regno++)
880191673Sjamie	{
881192895Sjamie	  for (curr = list; curr != NULL; curr = curr->next)
882195870Sjamie	    if (curr->regno == regno && curr->subreg_p == subreg_p
883195870Sjamie		&& curr->biggest_mode == mode)
884195870Sjamie	      {
885195870Sjamie		if (curr->type != type)
886195870Sjamie		  curr->type = OP_INOUT;
887192895Sjamie		if (curr->early_clobber != early_clobber)
888192895Sjamie		  curr->early_clobber = true;
889185435Sbz		break;
890192895Sjamie	      }
891192895Sjamie	  if (curr == NULL)
892185435Sbz	    {
893195974Sjamie	      /* This is a new hard regno or the info can not be
894192895Sjamie		 integrated into the found structure.	 */
895192895Sjamie#ifdef STACK_REGS
896192895Sjamie	      early_clobber
897192895Sjamie		= (early_clobber
898192895Sjamie		   /* This clobber is to inform popping floating
899192895Sjamie		      point stack only.  */
900192895Sjamie		   && ! (FIRST_STACK_REG <= regno
901192895Sjamie			 && regno <= LAST_STACK_REG));
902192895Sjamie#endif
903192895Sjamie	      list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
904192895Sjamie				   early_clobber, list);
905192895Sjamie	    }
906192895Sjamie	}
907192895Sjamie      return list;
908192895Sjamie    }
909192895Sjamie  switch (code)
910185435Sbz    {
911191673Sjamie    case SET:
912185435Sbz      list = collect_non_operand_hard_regs (&SET_DEST (op), data,
913185435Sbz					    list, OP_OUT, false);
914195945Sjamie      list = collect_non_operand_hard_regs (&SET_SRC (op), data,
915195945Sjamie					    list, OP_IN, false);
916195945Sjamie      break;
917195945Sjamie    case CLOBBER:
918195945Sjamie      /* We treat clobber of non-operand hard registers as early
919195945Sjamie	 clobber (the behavior is expected from asm).  */
920195945Sjamie      list = collect_non_operand_hard_regs (&XEXP (op, 0), data,
921195945Sjamie					    list, OP_OUT, true);
922195945Sjamie      break;
923230143Smm    case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
924191673Sjamie      list = collect_non_operand_hard_regs (&XEXP (op, 0), data,
925191673Sjamie					    list, OP_INOUT, false);
926191673Sjamie      break;
927191673Sjamie    case PRE_MODIFY: case POST_MODIFY:
928191673Sjamie      list = collect_non_operand_hard_regs (&XEXP (op, 0), data,
929191673Sjamie					    list, OP_INOUT, false);
930191673Sjamie      list = collect_non_operand_hard_regs (&XEXP (op, 1), data,
931191673Sjamie					    list, OP_IN, false);
932191673Sjamie      break;
933191673Sjamie    default:
934191673Sjamie      fmt = GET_RTX_FORMAT (code);
935191673Sjamie      for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
936191673Sjamie	{
937191673Sjamie	  if (fmt[i] == 'e')
938191673Sjamie	    list = collect_non_operand_hard_regs (&XEXP (op, i), data,
939191673Sjamie						  list, OP_IN, false);
940191673Sjamie	  else if (fmt[i] == 'E')
941241896Skib	    for (j = XVECLEN (op, i) - 1; j >= 0; j--)
942230129Smm	      list = collect_non_operand_hard_regs (&XVECEXP (op, i, j), data,
943230129Smm						    list, OP_IN, false);
944230129Smm	}
945230129Smm    }
946230129Smm  return list;
947230129Smm}
948230407Smm
949230407Smm/* Set up and return info about INSN.  Set up the info if it is not set up
950230407Smm   yet.	 */
951230407Smmlra_insn_recog_data_t
952230407Smmlra_set_insn_recog_data (rtx_insn *insn)
953230407Smm{
954230129Smm  lra_insn_recog_data_t data;
955230129Smm  int i, n, icode;
956230129Smm  rtx **locs;
957230129Smm  unsigned int uid = INSN_UID (insn);
958230407Smm  struct lra_static_insn_data *insn_static_data;
959230129Smm
960230129Smm  check_and_expand_insn_recog_data (uid);
961230129Smm  if (DEBUG_INSN_P (insn))
962230129Smm    icode = -1;
963230129Smm  else
964230129Smm    {
965230129Smm      icode = INSN_CODE (insn);
966230129Smm      if (icode < 0)
967230129Smm	/* It might be a new simple insn which is not recognized yet.  */
968230129Smm	INSN_CODE (insn) = icode = recog_memoized (insn);
969192895Sjamie    }
970192895Sjamie  data = XNEW (struct lra_insn_recog_data);
971192895Sjamie  lra_insn_recog_data[uid] = data;
972192895Sjamie  data->insn = insn;
973192895Sjamie  data->used_insn_alternative = -1;
974192895Sjamie  data->icode = icode;
975191673Sjamie  data->regs = NULL;
976191673Sjamie  if (DEBUG_INSN_P (insn))
977185435Sbz    {
978280632Sian      data->insn_static_data = &debug_insn_static_data;
979280632Sian      data->dup_loc = NULL;
980280632Sian      data->arg_hard_regs = NULL;
981280632Sian      data->preferred_alternatives = ALL_ALTERNATIVES;
982280632Sian      data->operand_loc = XNEWVEC (rtx *, 1);
983280632Sian      data->operand_loc[0] = &INSN_VAR_LOCATION_LOC (insn);
984280632Sian      return data;
985280632Sian    }
986280632Sian  if (icode < 0)
987280632Sian    {
988280632Sian      int nop, nalt;
989280632Sian      machine_mode operand_mode[MAX_RECOG_OPERANDS];
990280632Sian      const char *constraints[MAX_RECOG_OPERANDS];
991280632Sian
992280632Sian      nop = asm_noperands (PATTERN (insn));
993280632Sian      data->operand_loc = data->dup_loc = NULL;
994280632Sian      nalt = 1;
995280632Sian      if (nop < 0)
996280632Sian	{
997280632Sian	  /* It is a special insn like USE or CLOBBER.  We should
998280632Sian	     recognize any regular insn otherwise LRA can do nothing
999280632Sian	     with this insn.  */
1000280632Sian	  gcc_assert (GET_CODE (PATTERN (insn)) == USE
1001280632Sian		      || GET_CODE (PATTERN (insn)) == CLOBBER
1002280632Sian		      || GET_CODE (PATTERN (insn)) == ASM_INPUT);
1003280632Sian	  data->insn_static_data = insn_static_data
1004280632Sian	    = get_static_insn_data (-1, 0, 0, nalt);
1005280632Sian	}
1006280632Sian      else
1007280632Sian	{
1008280632Sian	  /* expand_asm_operands makes sure there aren't too many
1009280632Sian	     operands.	*/
1010280632Sian	  lra_assert (nop <= MAX_RECOG_OPERANDS);
1011280632Sian	  if (nop != 0)
1012280632Sian	    data->operand_loc = XNEWVEC (rtx *, nop);
1013280632Sian	  /* Now get the operand values and constraints out of the
1014280632Sian	     insn.  */
1015280632Sian	  decode_asm_operands (PATTERN (insn), NULL,
1016280632Sian			       data->operand_loc,
1017280632Sian			       constraints, operand_mode, NULL);
1018191673Sjamie	  if (nop > 0)
1019191673Sjamie	    {
1020191673Sjamie	      const char *p =  recog_data.constraints[0];
1021191673Sjamie
1022191673Sjamie	      for (p =	constraints[0]; *p; p++)
1023191673Sjamie		nalt += *p == ',';
1024191673Sjamie	    }
1025191673Sjamie	  data->insn_static_data = insn_static_data
1026191673Sjamie	    = get_static_insn_data (-1, nop, 0, nalt);
1027185435Sbz	  for (i = 0; i < nop; i++)
1028191673Sjamie	    {
1029191673Sjamie	      insn_static_data->operand[i].mode = operand_mode[i];
1030191673Sjamie	      insn_static_data->operand[i].constraint = constraints[i];
1031191673Sjamie	      insn_static_data->operand[i].strict_low = false;
1032191673Sjamie	      insn_static_data->operand[i].is_operator = false;
1033191673Sjamie	      insn_static_data->operand[i].is_address = false;
1034191673Sjamie	    }
1035191673Sjamie	}
1036191673Sjamie      for (i = 0; i < insn_static_data->n_operands; i++)
1037185435Sbz	insn_static_data->operand[i].type
1038191673Sjamie	  = (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT
1039191673Sjamie	     : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
1040185435Sbz	     : OP_IN);
1041191673Sjamie      data->preferred_alternatives = ALL_ALTERNATIVES;
1042191673Sjamie      if (nop > 0)
1043191673Sjamie	{
1044191673Sjamie	  operand_alternative *op_alt = XCNEWVEC (operand_alternative,
1045191673Sjamie						  nalt * nop);
1046191673Sjamie	  preprocess_constraints (nop, nalt, constraints, op_alt);
1047191673Sjamie	  setup_operand_alternative (data, op_alt);
1048196835Sjamie	}
1049196835Sjamie    }
1050196835Sjamie  else
1051196835Sjamie    {
1052196835Sjamie      insn_extract (insn);
1053196835Sjamie      data->insn_static_data = insn_static_data
1054196835Sjamie	= get_static_insn_data (icode, insn_data[icode].n_operands,
1055191673Sjamie				insn_data[icode].n_dups,
1056192895Sjamie				insn_data[icode].n_alternatives);
1057192895Sjamie      n = insn_static_data->n_operands;
1058192895Sjamie      if (n == 0)
1059192895Sjamie	locs = NULL;
1060192895Sjamie      else
1061192895Sjamie	{
1062192895Sjamie	  locs = XNEWVEC (rtx *, n);
1063191673Sjamie	  memcpy (locs, recog_data.operand_loc, n * sizeof (rtx *));
1064191673Sjamie	}
1065191673Sjamie      data->operand_loc = locs;
1066191673Sjamie      n = insn_static_data->n_dups;
1067191673Sjamie      if (n == 0)
1068191673Sjamie	locs = NULL;
1069191673Sjamie      else
1070192895Sjamie	{
1071191673Sjamie	  locs = XNEWVEC (rtx *, n);
1072191673Sjamie	  memcpy (locs, recog_data.dup_loc, n * sizeof (rtx *));
1073191673Sjamie	}
1074191673Sjamie      data->dup_loc = locs;
1075191673Sjamie      data->preferred_alternatives = get_preferred_alternatives (insn);
1076191673Sjamie      const operand_alternative *op_alt = preprocess_insn_constraints (icode);
1077191673Sjamie      if (!insn_static_data->operand_alternative)
1078191673Sjamie	setup_operand_alternative (data, op_alt);
1079192895Sjamie      else if (op_alt != insn_static_data->operand_alternative)
1080192895Sjamie	insn_static_data->operand_alternative = op_alt;
1081192895Sjamie    }
1082192895Sjamie  if (GET_CODE (PATTERN (insn)) == CLOBBER || GET_CODE (PATTERN (insn)) == USE)
1083191673Sjamie    insn_static_data->hard_regs = NULL;
1084191673Sjamie  else
1085191673Sjamie    insn_static_data->hard_regs
1086191673Sjamie      = collect_non_operand_hard_regs (&PATTERN (insn), data,
1087191673Sjamie				       NULL, OP_IN, false);
1088191673Sjamie  data->arg_hard_regs = NULL;
1089191673Sjamie  if (CALL_P (insn))
1090191673Sjamie    {
1091191673Sjamie      bool use_p;
1092191673Sjamie      rtx link;
1093191673Sjamie      int n_hard_regs, regno, arg_hard_regs[FIRST_PSEUDO_REGISTER];
1094191673Sjamie
1095191673Sjamie      n_hard_regs = 0;
1096191673Sjamie      /* Finding implicit hard register usage.	We believe it will be
1097191673Sjamie	 not changed whatever transformations are used.	 Call insns
1098191673Sjamie	 are such example.  */
1099191673Sjamie      for (link = CALL_INSN_FUNCTION_USAGE (insn);
1100192895Sjamie	   link != NULL_RTX;
1101191673Sjamie	   link = XEXP (link, 1))
1102191673Sjamie	if (((use_p = GET_CODE (XEXP (link, 0)) == USE)
1103191673Sjamie	     || GET_CODE (XEXP (link, 0)) == CLOBBER)
1104191673Sjamie	    && REG_P (XEXP (XEXP (link, 0), 0)))
1105191673Sjamie	  {
1106191673Sjamie	    regno = REGNO (XEXP (XEXP (link, 0), 0));
1107191673Sjamie	    lra_assert (regno < FIRST_PSEUDO_REGISTER);
1108191673Sjamie	    /* It is an argument register.  */
1109191673Sjamie	    for (i = (hard_regno_nregs
1110191673Sjamie		      [regno][GET_MODE (XEXP (XEXP (link, 0), 0))]) - 1;
1111191673Sjamie		 i >= 0;
1112191673Sjamie		 i--)
1113191673Sjamie	      arg_hard_regs[n_hard_regs++]
1114191673Sjamie		= regno + i + (use_p ? 0 : FIRST_PSEUDO_REGISTER);
1115191673Sjamie	  }
1116191673Sjamie      if (n_hard_regs != 0)
1117191673Sjamie	{
1118191673Sjamie	  arg_hard_regs[n_hard_regs++] = -1;
1119191673Sjamie	  data->arg_hard_regs = XNEWVEC (int, n_hard_regs);
1120191673Sjamie	  memcpy (data->arg_hard_regs, arg_hard_regs,
1121196835Sjamie		  sizeof (int) * n_hard_regs);
1122196835Sjamie	}
1123196835Sjamie    }
1124196835Sjamie  /* Some output operand can be recognized only from the context not
1125192895Sjamie     from the constraints which are empty in this case.	 Call insn may
1126192895Sjamie     contain a hard register in set destination with empty constraint
1127192895Sjamie     and extract_insn treats them as an input.	*/
1128192895Sjamie  for (i = 0; i < insn_static_data->n_operands; i++)
1129192895Sjamie    {
1130196835Sjamie      int j;
1131192895Sjamie      rtx pat, set;
1132196835Sjamie      struct lra_operand_data *operand = &insn_static_data->operand[i];
1133196835Sjamie
1134192895Sjamie      /* ??? Should we treat 'X' the same way.	It looks to me that
1135192895Sjamie	 'X' means anything and empty constraint means we do not
1136192895Sjamie	 care.	*/
1137192895Sjamie      if (operand->type != OP_IN || *operand->constraint != '\0'
1138192895Sjamie	  || operand->is_operator)
1139192895Sjamie	continue;
1140192895Sjamie      pat = PATTERN (insn);
1141192895Sjamie      if (GET_CODE (pat) == SET)
1142192895Sjamie	{
1143192895Sjamie	  if (data->operand_loc[i] != &SET_DEST (pat))
1144192895Sjamie	    continue;
1145192895Sjamie	}
1146192895Sjamie      else if (GET_CODE (pat) == PARALLEL)
1147192895Sjamie	{
1148192895Sjamie	  for (j = XVECLEN (pat, 0) - 1; j >= 0; j--)
1149192895Sjamie	    {
1150196835Sjamie	      set = XVECEXP (PATTERN (insn), 0, j);
1151192895Sjamie	      if (GET_CODE (set) == SET
1152191673Sjamie		  && &SET_DEST (set) == data->operand_loc[i])
1153192895Sjamie		break;
1154192895Sjamie	    }
1155192895Sjamie	  if (j < 0)
1156191673Sjamie	    continue;
1157192895Sjamie	}
1158191673Sjamie      else
1159192895Sjamie	continue;
1160191673Sjamie      operand->type = OP_OUT;
1161191673Sjamie    }
1162191673Sjamie  return data;
1163191673Sjamie}
1164191673Sjamie
1165191673Sjamie/* Return info about insn give by UID.	The info should be already set
1166191673Sjamie   up.	*/
1167191673Sjamiestatic lra_insn_recog_data_t
1168191673Sjamieget_insn_recog_data_by_uid (int uid)
1169191673Sjamie{
1170191673Sjamie  lra_insn_recog_data_t data;
1171191673Sjamie
1172191673Sjamie  data = lra_insn_recog_data[uid];
1173191673Sjamie  lra_assert (data != NULL);
1174191673Sjamie  return data;
1175191673Sjamie}
1176191673Sjamie
1177191673Sjamie/* Invalidate all info about insn given by its UID.  */
1178191673Sjamiestatic void
1179192895Sjamieinvalidate_insn_recog_data (int uid)
1180191673Sjamie{
1181191673Sjamie  lra_insn_recog_data_t data;
1182191673Sjamie
1183191673Sjamie  data = lra_insn_recog_data[uid];
1184191673Sjamie  lra_assert (data != NULL);
1185191673Sjamie  free_insn_recog_data (data);
1186191673Sjamie  lra_insn_recog_data[uid] = NULL;
1187191673Sjamie}
1188191673Sjamie
1189191673Sjamie/* Update all the insn info about INSN.	 It is usually called when
1190191673Sjamie   something in the insn was changed.  Return the updated info.	 */
1191191673Sjamielra_insn_recog_data_t
1192191673Sjamielra_update_insn_recog_data (rtx_insn *insn)
1193191673Sjamie{
1194191673Sjamie  lra_insn_recog_data_t data;
1195191673Sjamie  int n;
1196191673Sjamie  unsigned int uid = INSN_UID (insn);
1197191673Sjamie  struct lra_static_insn_data *insn_static_data;
1198191673Sjamie  HOST_WIDE_INT sp_offset = 0;
1199191673Sjamie
1200191673Sjamie  check_and_expand_insn_recog_data (uid);
1201191673Sjamie  if ((data = lra_insn_recog_data[uid]) != NULL
1202191673Sjamie      && data->icode != INSN_CODE (insn))
1203191673Sjamie    {
1204191673Sjamie      sp_offset = data->sp_offset;
1205191673Sjamie      invalidate_insn_data_regno_info (data, insn, get_insn_freq (insn));
1206191673Sjamie      invalidate_insn_recog_data (uid);
1207191673Sjamie      data = NULL;
1208191673Sjamie    }
1209191673Sjamie  if (data == NULL)
1210191673Sjamie    {
1211191673Sjamie      data = lra_get_insn_recog_data (insn);
1212191673Sjamie      /* Initiate or restore SP offset.  */
1213191673Sjamie      data->sp_offset = sp_offset;
1214191673Sjamie      return data;
1215191673Sjamie    }
1216191673Sjamie  insn_static_data = data->insn_static_data;
1217191673Sjamie  data->used_insn_alternative = -1;
1218191673Sjamie  if (DEBUG_INSN_P (insn))
1219191673Sjamie    return data;
1220191673Sjamie  if (data->icode < 0)
1221191673Sjamie    {
1222185435Sbz      int nop;
1223191673Sjamie      machine_mode operand_mode[MAX_RECOG_OPERANDS];
1224191673Sjamie      const char *constraints[MAX_RECOG_OPERANDS];
1225194762Sjamie
1226194762Sjamie      nop = asm_noperands (PATTERN (insn));
1227194762Sjamie      if (nop >= 0)
1228194762Sjamie	{
1229194762Sjamie	  lra_assert (nop == data->insn_static_data->n_operands);
1230194762Sjamie	  /* Now get the operand values and constraints out of the
1231191673Sjamie	     insn.  */
1232192895Sjamie	  decode_asm_operands (PATTERN (insn), NULL,
1233192895Sjamie			       data->operand_loc,
1234192895Sjamie			       constraints, operand_mode, NULL);
1235192895Sjamie#ifdef ENABLE_CHECKING
1236192895Sjamie	  {
1237192895Sjamie	    int i;
1238192895Sjamie
1239192895Sjamie	    for (i = 0; i < nop; i++)
1240192895Sjamie	      lra_assert
1241192895Sjamie		(insn_static_data->operand[i].mode == operand_mode[i]
1242191673Sjamie		 && insn_static_data->operand[i].constraint == constraints[i]
1243191673Sjamie		 && ! insn_static_data->operand[i].is_operator);
1244191673Sjamie	  }
1245191673Sjamie#endif
1246191673Sjamie	}
1247191673Sjamie#ifdef ENABLE_CHECKING
1248191673Sjamie      {
1249191673Sjamie	int i;
1250191673Sjamie
1251191673Sjamie	for (i = 0; i < insn_static_data->n_operands; i++)
1252191673Sjamie	  lra_assert
1253191673Sjamie	    (insn_static_data->operand[i].type
1254191673Sjamie	     == (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT
1255191673Sjamie		 : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
1256191673Sjamie		 : OP_IN));
1257191673Sjamie      }
1258191673Sjamie#endif
1259191673Sjamie    }
1260191673Sjamie  else
1261192895Sjamie    {
1262192895Sjamie      insn_extract (insn);
1263192895Sjamie      n = insn_static_data->n_operands;
1264191673Sjamie      if (n != 0)
1265191673Sjamie	memcpy (data->operand_loc, recog_data.operand_loc, n * sizeof (rtx *));
1266191673Sjamie      n = insn_static_data->n_dups;
1267191673Sjamie      if (n != 0)
1268191673Sjamie	memcpy (data->dup_loc, recog_data.dup_loc, n * sizeof (rtx *));
1269191673Sjamie      lra_assert (check_bool_attrs (insn));
1270191673Sjamie    }
1271191673Sjamie  return data;
1272191673Sjamie}
1273191673Sjamie
1274191673Sjamie/* Set up that INSN is using alternative ALT now.  */
1275191673Sjamievoid
1276191673Sjamielra_set_used_insn_alternative (rtx_insn *insn, int alt)
1277191673Sjamie{
1278191673Sjamie  lra_insn_recog_data_t data;
1279191673Sjamie
1280191673Sjamie  data = lra_get_insn_recog_data (insn);
1281191673Sjamie  data->used_insn_alternative = alt;
1282192895Sjamie}
1283192895Sjamie
1284194762Sjamie/* Set up that insn with UID is using alternative ALT now.  The insn
1285185435Sbz   info should be already set up.  */
1286192895Sjamievoid
1287191673Sjamielra_set_used_insn_alternative_by_uid (int uid, int alt)
1288192895Sjamie{
1289192895Sjamie  lra_insn_recog_data_t data;
1290191673Sjamie
1291191673Sjamie  check_and_expand_insn_recog_data (uid);
1292191673Sjamie  data = lra_insn_recog_data[uid];
1293191673Sjamie  lra_assert (data != NULL);
1294192895Sjamie  data->used_insn_alternative = alt;
1295191673Sjamie}
1296191673Sjamie
1297195944Sjamie
1298195944Sjamie
1299195945Sjamie/* This page contains code dealing with common register info and
1300195945Sjamie   pseudo copies.  */
1301195945Sjamie
1302195945Sjamie/* The size of the following array.  */
1303195945Sjamiestatic int reg_info_size;
1304192895Sjamie/* Common info about each register.  */
1305195974Sjamiestruct lra_reg *lra_reg_info;
1306195974Sjamie
1307195974Sjamie/* Last register value.	 */
1308195974Sjamiestatic int last_reg_value;
1309195974Sjamie
1310195974Sjamie/* Return new register value.  */
1311195974Sjamiestatic int
1312195974Sjamieget_new_reg_value (void)
1313195974Sjamie{
1314195974Sjamie  return ++last_reg_value;
1315195974Sjamie}
1316195974Sjamie
1317195974Sjamie/* Pools for copies.  */
1318195974Sjamiestatic alloc_pool copy_pool;
1319192895Sjamie
1320192895Sjamie/* Vec referring to pseudo copies.  */
1321195974Sjamiestatic vec<lra_copy_t> copy_vec;
1322195974Sjamie
1323195974Sjamie/* Initialize I-th element of lra_reg_info.  */
1324195974Sjamiestatic inline void
1325195974Sjamieinitialize_lra_reg_info_element (int i)
1326195974Sjamie{
1327195974Sjamie  bitmap_initialize (&lra_reg_info[i].insn_bitmap, &reg_obstack);
1328195974Sjamie#ifdef STACK_REGS
1329195974Sjamie  lra_reg_info[i].no_stack_p = false;
1330195974Sjamie#endif
1331195974Sjamie  CLEAR_HARD_REG_SET (lra_reg_info[i].conflict_hard_regs);
1332195974Sjamie  CLEAR_HARD_REG_SET (lra_reg_info[i].actual_call_used_reg_set);
1333195974Sjamie  lra_reg_info[i].preferred_hard_regno1 = -1;
1334195974Sjamie  lra_reg_info[i].preferred_hard_regno2 = -1;
1335192895Sjamie  lra_reg_info[i].preferred_hard_regno_profit1 = 0;
1336195945Sjamie  lra_reg_info[i].preferred_hard_regno_profit2 = 0;
1337195945Sjamie  lra_reg_info[i].biggest_mode = VOIDmode;
1338202468Sbz  lra_reg_info[i].live_ranges = NULL;
1339202468Sbz  lra_reg_info[i].nrefs = lra_reg_info[i].freq = 0;
1340202468Sbz  lra_reg_info[i].last_reload = 0;
1341192895Sjamie  lra_reg_info[i].restore_regno = -1;
1342192895Sjamie  lra_reg_info[i].val = get_new_reg_value ();
1343196002Sjamie  lra_reg_info[i].offset = 0;
1344232059Smm  lra_reg_info[i].copies = NULL;
1345191673Sjamie}
1346280632Sian
1347280632Sian/* Initialize common reg info and copies.  */
1348280632Sianstatic void
1349280632Sianinit_reg_info (void)
1350280632Sian{
1351280632Sian  int i;
1352192895Sjamie
1353192895Sjamie  last_reg_value = 0;
1354191673Sjamie  reg_info_size = max_reg_num () * 3 / 2 + 1;
1355194251Sjamie  lra_reg_info = XNEWVEC (struct lra_reg, reg_info_size);
1356194251Sjamie  for (i = 0; i < reg_info_size; i++)
1357194251Sjamie    initialize_lra_reg_info_element (i);
1358194251Sjamie  copy_pool
1359194251Sjamie    = create_alloc_pool ("lra copies", sizeof (struct lra_copy), 100);
1360185435Sbz  copy_vec.create (100);
1361191673Sjamie}
1362191673Sjamie
1363185435Sbz
1364192895Sjamie/* Finish common reg info and copies.  */
1365191673Sjamiestatic void
1366191673Sjamiefinish_reg_info (void)
1367191673Sjamie{
1368191673Sjamie  int i;
1369185435Sbz
1370191673Sjamie  for (i = 0; i < reg_info_size; i++)
1371185435Sbz    bitmap_clear (&lra_reg_info[i].insn_bitmap);
1372191673Sjamie  free (lra_reg_info);
1373191673Sjamie  reg_info_size = 0;
1374191673Sjamie  free_alloc_pool (copy_pool);
1375185435Sbz  copy_vec.release ();
1376191673Sjamie}
1377191673Sjamie
1378195974Sjamie/* Expand common reg info if it is necessary.  */
1379195974Sjamiestatic void
1380195974Sjamieexpand_reg_info (void)
1381195974Sjamie{
1382195974Sjamie  int i, old = reg_info_size;
1383195945Sjamie
1384195945Sjamie  if (reg_info_size > max_reg_num ())
1385195945Sjamie    return;
1386195945Sjamie  reg_info_size = max_reg_num () * 3 / 2 + 1;
1387195945Sjamie  lra_reg_info = XRESIZEVEC (struct lra_reg, lra_reg_info, reg_info_size);
1388195945Sjamie  for (i = old; i < reg_info_size; i++)
1389195945Sjamie    initialize_lra_reg_info_element (i);
1390195945Sjamie}
1391195945Sjamie
1392195974Sjamie/* Free all copies.  */
1393195974Sjamievoid
1394195974Sjamielra_free_copies (void)
1395195974Sjamie{
1396195974Sjamie  lra_copy_t cp;
1397195974Sjamie
1398195974Sjamie  while (copy_vec.length () != 0)
1399195974Sjamie    {
1400195974Sjamie      cp = copy_vec.pop ();
1401195974Sjamie      lra_reg_info[cp->regno1].copies = lra_reg_info[cp->regno2].copies = NULL;
1402195974Sjamie      pool_free (copy_pool, cp);
1403195974Sjamie    }
1404195974Sjamie}
1405195974Sjamie
1406195974Sjamie/* Create copy of two pseudos REGNO1 and REGNO2.  The copy execution
1407195974Sjamie   frequency is FREQ.  */
1408191673Sjamievoid
1409185435Sbzlra_create_copy (int regno1, int regno2, int freq)
1410191673Sjamie{
1411192895Sjamie  bool regno1_dest_p;
1412192895Sjamie  lra_copy_t cp;
1413192895Sjamie
1414192895Sjamie  lra_assert (regno1 != regno2);
1415192895Sjamie  regno1_dest_p = true;
1416192895Sjamie  if (regno1 > regno2)
1417194762Sjamie    {
1418194762Sjamie      int temp = regno2;
1419194762Sjamie
1420194762Sjamie      regno1_dest_p = false;
1421194762Sjamie      regno2 = regno1;
1422194762Sjamie      regno1 = temp;
1423192895Sjamie    }
1424192895Sjamie  cp = (lra_copy_t) pool_alloc (copy_pool);
1425192895Sjamie  copy_vec.safe_push (cp);
1426192895Sjamie  cp->regno1_dest_p = regno1_dest_p;
1427192895Sjamie  cp->freq = freq;
1428192895Sjamie  cp->regno1 = regno1;
1429231267Smm  cp->regno2 = regno2;
1430231267Smm  cp->regno1_next = lra_reg_info[regno1].copies;
1431231267Smm  lra_reg_info[regno1].copies = cp;
1432231267Smm  cp->regno2_next = lra_reg_info[regno2].copies;
1433232059Smm  lra_reg_info[regno2].copies = cp;
1434231267Smm  if (lra_dump_file != NULL)
1435231267Smm    fprintf (lra_dump_file, "	   Creating copy r%d%sr%d@%d\n",
1436231267Smm	     regno1, regno1_dest_p ? "<-" : "->", regno2, freq);
1437231267Smm}
1438232059Smm
1439231267Smm/* Return N-th (0, 1, ...) copy.  If there is no copy, return
1440231267Smm   NULL.  */
1441231267Smmlra_copy_t
1442231267Smmlra_get_copy (int n)
1443231267Smm{
1444232059Smm  if (n >= (int) copy_vec.length ())
1445231267Smm    return NULL;
1446231267Smm  return copy_vec[n];
1447231267Smm}
1448185435Sbz
1449195974Sjamie
1450192895Sjamie
1451195974Sjamie/* This page contains code dealing with info about registers in
1452195974Sjamie   insns.  */
1453195974Sjamie
1454195974Sjamie/* Process X of insn UID recursively and add info (operand type is
1455195974Sjamie   given by TYPE, flag of that it is early clobber is EARLY_CLOBBER)
1456195974Sjamie   about registers in X to the insn DATA.  */
1457195974Sjamiestatic void
1458195974Sjamieadd_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
1459195974Sjamie			     enum op_type type, bool early_clobber)
1460195974Sjamie{
1461195974Sjamie  int i, j, regno;
1462195974Sjamie  bool subreg_p;
1463195974Sjamie  machine_mode mode;
1464195974Sjamie  const char *fmt;
1465195974Sjamie  enum rtx_code code;
1466195974Sjamie  struct lra_insn_reg *curr;
1467195974Sjamie
1468195974Sjamie  code = GET_CODE (x);
1469195974Sjamie  mode = GET_MODE (x);
1470195974Sjamie  subreg_p = false;
1471195974Sjamie  if (GET_CODE (x) == SUBREG)
1472195974Sjamie    {
1473195974Sjamie      x = SUBREG_REG (x);
1474195974Sjamie      code = GET_CODE (x);
1475192895Sjamie      if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x)))
1476192895Sjamie	{
1477192895Sjamie	  mode = GET_MODE (x);
1478192895Sjamie	  if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode))
1479192895Sjamie	    subreg_p = true;
1480192895Sjamie	}
1481192895Sjamie    }
1482195974Sjamie  if (REG_P (x))
1483195974Sjamie    {
1484195974Sjamie      regno = REGNO (x);
1485195974Sjamie      /* Process all regs even unallocatable ones as we need info about
1486195974Sjamie	 all regs for rematerialization pass.  */
1487195974Sjamie      expand_reg_info ();
1488195974Sjamie      if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid))
1489195945Sjamie	{
1490195974Sjamie	  data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
1491195974Sjamie				     early_clobber, data->regs);
1492195974Sjamie	  return;
1493195945Sjamie	}
1494195974Sjamie      else
1495195974Sjamie	{
1496195945Sjamie	  for (curr = data->regs; curr != NULL; curr = curr->next)
1497195974Sjamie	    if (curr->regno == regno)
1498195945Sjamie	      {
1499195974Sjamie		if (curr->subreg_p != subreg_p || curr->biggest_mode != mode)
1500192895Sjamie		  /* The info can not be integrated into the found
1501195974Sjamie		     structure.  */
1502195974Sjamie		  data->regs = new_insn_reg (data->insn, regno, type, mode,
1503195974Sjamie					     subreg_p, early_clobber,
1504195974Sjamie					     data->regs);
1505195974Sjamie		else
1506195974Sjamie		  {
1507195974Sjamie		    if (curr->type != type)
1508195974Sjamie		      curr->type = OP_INOUT;
1509195974Sjamie		    if (curr->early_clobber != early_clobber)
1510195974Sjamie		      curr->early_clobber = true;
1511195974Sjamie		  }
1512195974Sjamie		return;
1513195974Sjamie	      }
1514195974Sjamie	  gcc_unreachable ();
1515192895Sjamie	}
1516192895Sjamie    }
1517192895Sjamie
1518192895Sjamie  switch (code)
1519185435Sbz    {
1520191673Sjamie    case SET:
1521195974Sjamie      add_regs_to_insn_regno_info (data, SET_DEST (x), uid, OP_OUT, false);
1522192895Sjamie      add_regs_to_insn_regno_info (data, SET_SRC (x), uid, OP_IN, false);
1523195974Sjamie      break;
1524195974Sjamie    case CLOBBER:
1525195974Sjamie      /* We treat clobber of non-operand hard registers as early
1526195974Sjamie	 clobber (the behavior is expected from asm).  */
1527195974Sjamie      add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_OUT, true);
1528195974Sjamie      break;
1529195974Sjamie    case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
1530195974Sjamie      add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_INOUT, false);
1531195974Sjamie      break;
1532195974Sjamie    case PRE_MODIFY: case POST_MODIFY:
1533195974Sjamie      add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_INOUT, false);
1534195974Sjamie      add_regs_to_insn_regno_info (data, XEXP (x, 1), uid, OP_IN, false);
1535195974Sjamie      break;
1536195974Sjamie    default:
1537195974Sjamie      if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
1538195974Sjamie	/* Some targets place small structures in registers for return
1539195974Sjamie	   values of functions, and those registers are wrapped in
1540195974Sjamie	   PARALLEL that we may see as the destination of a SET.  Here
1541195974Sjamie	   is an example:
1542195974Sjamie
1543195974Sjamie	   (call_insn 13 12 14 2 (set (parallel:BLK [
1544195974Sjamie		(expr_list:REG_DEP_TRUE (reg:DI 0 ax)
1545195974Sjamie		    (const_int 0 [0]))
1546192895Sjamie		(expr_list:REG_DEP_TRUE (reg:DI 1 dx)
1547192895Sjamie		    (const_int 8 [0x8]))
1548192895Sjamie	       ])
1549192895Sjamie	     (call (mem:QI (symbol_ref:DI (...	*/
1550192895Sjamie	type = OP_IN;
1551192895Sjamie      fmt = GET_RTX_FORMAT (code);
1552192895Sjamie      for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1553195974Sjamie	{
1554195974Sjamie	  if (fmt[i] == 'e')
1555195945Sjamie	    add_regs_to_insn_regno_info (data, XEXP (x, i), uid, type, false);
1556195974Sjamie	  else if (fmt[i] == 'E')
1557195974Sjamie	    {
1558195974Sjamie	      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1559195945Sjamie		add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), uid,
1560195974Sjamie					     type, false);
1561195974Sjamie	    }
1562195945Sjamie	}
1563195974Sjamie    }
1564195945Sjamie}
1565195974Sjamie
1566192895Sjamie/* Return execution frequency of INSN.	*/
1567195974Sjamiestatic int
1568195974Sjamieget_insn_freq (rtx_insn *insn)
1569195974Sjamie{
1570195974Sjamie  basic_block bb = BLOCK_FOR_INSN (insn);
1571195974Sjamie
1572195974Sjamie  gcc_checking_assert (bb != NULL);
1573195974Sjamie  return REG_FREQ_FROM_BB (bb);
1574195974Sjamie}
1575195974Sjamie
1576195974Sjamie/* Invalidate all reg info of INSN with DATA and execution frequency
1577195974Sjamie   FREQ.  Update common info about the invalidated registers.  */
1578195974Sjamiestatic void
1579195974Sjamieinvalidate_insn_data_regno_info (lra_insn_recog_data_t data, rtx_insn *insn,
1580195974Sjamie				 int freq)
1581192895Sjamie{
1582192895Sjamie  int uid;
1583191673Sjamie  bool debug_p;
1584192895Sjamie  unsigned int i;
1585191673Sjamie  struct lra_insn_reg *ir, *next_ir;
1586192895Sjamie
1587192895Sjamie  uid = INSN_UID (insn);
1588191673Sjamie  debug_p = DEBUG_INSN_P (insn);
1589191673Sjamie  for (ir = data->regs; ir != NULL; ir = next_ir)
1590191673Sjamie    {
1591196835Sjamie      i = ir->regno;
1592196835Sjamie      next_ir = ir->next;
1593191673Sjamie      free_insn_reg (ir);
1594196835Sjamie      bitmap_clear_bit (&lra_reg_info[i].insn_bitmap, uid);
1595196835Sjamie      if (i >= FIRST_PSEUDO_REGISTER && ! debug_p)
1596192895Sjamie	{
1597191673Sjamie	  lra_reg_info[i].nrefs--;
1598191673Sjamie	  lra_reg_info[i].freq -= freq;
1599192895Sjamie	  lra_assert (lra_reg_info[i].nrefs >= 0 && lra_reg_info[i].freq >= 0);
1600192895Sjamie	}
1601191673Sjamie    }
1602192895Sjamie  data->regs = NULL;
1603192895Sjamie}
1604192895Sjamie
1605192895Sjamie/* Invalidate all reg info of INSN.  Update common info about the
1606192895Sjamie   invalidated registers.  */
1607192895Sjamievoid
1608192895Sjamielra_invalidate_insn_regno_info (rtx_insn *insn)
1609192895Sjamie{
1610192895Sjamie  invalidate_insn_data_regno_info (lra_get_insn_recog_data (insn), insn,
1611192895Sjamie				   get_insn_freq (insn));
1612192895Sjamie}
1613192895Sjamie
1614192895Sjamie/* Update common reg info from reg info of insn given by its DATA and
1615191673Sjamie   execution frequency FREQ.  */
1616192895Sjamiestatic void
1617192895Sjamiesetup_insn_reg_info (lra_insn_recog_data_t data, int freq)
1618192895Sjamie{
1619192895Sjamie  unsigned int i;
1620185435Sbz  struct lra_insn_reg *ir;
1621191673Sjamie
1622191673Sjamie  for (ir = data->regs; ir != NULL; ir = ir->next)
1623192895Sjamie    if ((i = ir->regno) >= FIRST_PSEUDO_REGISTER)
1624195974Sjamie      {
1625195974Sjamie	lra_reg_info[i].nrefs++;
1626195974Sjamie	lra_reg_info[i].freq += freq;
1627195974Sjamie      }
1628195974Sjamie}
1629195974Sjamie
1630192895Sjamie/* Set up insn reg info of INSN.  Update common reg info from reg info
1631195945Sjamie   of INSN.  */
1632195945Sjamievoid
1633195945Sjamielra_update_insn_regno_info (rtx_insn *insn)
1634195945Sjamie{
1635195945Sjamie  int i, uid, freq;
1636195945Sjamie  lra_insn_recog_data_t data;
1637192895Sjamie  struct lra_static_insn_data *static_data;
1638192895Sjamie  enum rtx_code code;
1639192895Sjamie  rtx link;
1640192895Sjamie
1641192895Sjamie  if (! INSN_P (insn))
1642185435Sbz    return;
1643191673Sjamie  data = lra_get_insn_recog_data (insn);
1644191673Sjamie  static_data = data->insn_static_data;
1645192895Sjamie  freq = get_insn_freq (insn);
1646195974Sjamie  invalidate_insn_data_regno_info (data, insn, freq);
1647195974Sjamie  uid = INSN_UID (insn);
1648195974Sjamie  for (i = static_data->n_operands - 1; i >= 0; i--)
1649195974Sjamie    add_regs_to_insn_regno_info (data, *data->operand_loc[i], uid,
1650195974Sjamie				 static_data->operand[i].type,
1651195974Sjamie				 static_data->operand[i].early_clobber);
1652192895Sjamie  if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE)
1653195945Sjamie    add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), uid,
1654195945Sjamie				 code == USE ? OP_IN : OP_OUT, false);
1655195945Sjamie  if (CALL_P (insn))
1656195945Sjamie    /* On some targets call insns can refer to pseudos in memory in
1657195945Sjamie       CALL_INSN_FUNCTION_USAGE list.  Process them in order to
1658195945Sjamie       consider their occurrences in calls for different
1659192895Sjamie       transformations (e.g. inheritance) with given pseudos.  */
1660192895Sjamie    for (link = CALL_INSN_FUNCTION_USAGE (insn);
1661192895Sjamie	 link != NULL_RTX;
1662192895Sjamie	 link = XEXP (link, 1))
1663192895Sjamie      if (((code = GET_CODE (XEXP (link, 0))) == USE || code == CLOBBER)
1664191673Sjamie	  && MEM_P (XEXP (XEXP (link, 0), 0)))
1665191673Sjamie	add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), uid,
1666192895Sjamie				     code == USE ? OP_IN : OP_OUT, false);
1667191673Sjamie  if (NONDEBUG_INSN_P (insn))
1668192895Sjamie    setup_insn_reg_info (data, freq);
1669192895Sjamie}
1670192895Sjamie
1671192895Sjamie/* Return reg info of insn given by it UID.  */
1672192895Sjamiestruct lra_insn_reg *
1673194762Sjamielra_get_insn_regs (int uid)
1674194762Sjamie{
1675194762Sjamie  lra_insn_recog_data_t data;
1676194762Sjamie
1677194762Sjamie  data = get_insn_recog_data_by_uid (uid);
1678194762Sjamie  return data->regs;
1679194762Sjamie}
1680194762Sjamie
1681192895Sjamie
1682192895Sjamie
1683192895Sjamie/* This page contains code dealing with stack of the insns which
1684192895Sjamie   should be processed by the next constraint pass.  */
1685192895Sjamie
1686192895Sjamie/* Bitmap used to put an insn on the stack only in one exemplar.  */
1687192895Sjamiestatic sbitmap lra_constraint_insn_stack_bitmap;
1688231267Smm
1689231267Smm/* The stack itself.  */
1690231267Smmvec<rtx_insn *> lra_constraint_insn_stack;
1691231267Smm
1692232059Smm/* Put INSN on the stack.  If ALWAYS_UPDATE is true, always update the reg
1693231267Smm   info for INSN, otherwise only update it if INSN is not already on the
1694192895Sjamie   stack.  */
1695192895Sjamiestatic inline void
1696192895Sjamielra_push_insn_1 (rtx_insn *insn, bool always_update)
1697192895Sjamie{
1698192895Sjamie  unsigned int uid = INSN_UID (insn);
1699192895Sjamie  if (always_update)
1700192895Sjamie    lra_update_insn_regno_info (insn);
1701192895Sjamie  if (uid >= SBITMAP_SIZE (lra_constraint_insn_stack_bitmap))
1702192895Sjamie    lra_constraint_insn_stack_bitmap =
1703192895Sjamie      sbitmap_resize (lra_constraint_insn_stack_bitmap, 3 * uid / 2, 0);
1704192895Sjamie  if (bitmap_bit_p (lra_constraint_insn_stack_bitmap, uid))
1705192895Sjamie    return;
1706192895Sjamie  bitmap_set_bit (lra_constraint_insn_stack_bitmap, uid);
1707191673Sjamie  if (! always_update)
1708192895Sjamie    lra_update_insn_regno_info (insn);
1709230129Smm  lra_constraint_insn_stack.safe_push (insn);
1710230129Smm}
1711192895Sjamie
1712192895Sjamie/* Put INSN on the stack.  */
1713192895Sjamievoid
1714192895Sjamielra_push_insn (rtx_insn *insn)
1715191673Sjamie{
1716191673Sjamie  lra_push_insn_1 (insn, false);
1717193066Sjamie}
1718193066Sjamie
1719193066Sjamie/* Put INSN on the stack and update its reg info.  */
1720193066Sjamievoid
1721193066Sjamielra_push_insn_and_update_insn_regno_info (rtx_insn *insn)
1722193066Sjamie{
1723193066Sjamie  lra_push_insn_1 (insn, true);
1724193066Sjamie}
1725194118Sjamie
1726194118Sjamie/* Put insn with UID on the stack.  */
1727194118Sjamievoid
1728194118Sjamielra_push_insn_by_uid (unsigned int uid)
1729194118Sjamie{
1730194118Sjamie  lra_push_insn (lra_insn_recog_data[uid]->insn);
1731193066Sjamie}
1732193066Sjamie
1733193066Sjamie/* Take the last-inserted insns off the stack and return it.  */
1734193066Sjamiertx_insn *
1735193066Sjamielra_pop_insn (void)
1736194118Sjamie{
1737193066Sjamie  rtx_insn *insn = lra_constraint_insn_stack.pop ();
1738194118Sjamie  bitmap_clear_bit (lra_constraint_insn_stack_bitmap, INSN_UID (insn));
1739194118Sjamie  return insn;
1740193066Sjamie}
1741194118Sjamie
1742193066Sjamie/* Return the current size of the insn stack.  */
1743193066Sjamieunsigned int
1744193066Sjamielra_insn_stack_length (void)
1745193066Sjamie{
1746193066Sjamie  return lra_constraint_insn_stack.length ();
1747193066Sjamie}
1748193066Sjamie
1749194118Sjamie/* Push insns FROM to TO (excluding it) going in reverse order.	 */
1750194118Sjamiestatic void
1751194118Sjamiepush_insns (rtx_insn *from, rtx_insn *to)
1752193066Sjamie{
1753194118Sjamie  rtx_insn *insn;
1754194118Sjamie
1755194118Sjamie  if (from == NULL_RTX)
1756193066Sjamie    return;
1757194118Sjamie  for (insn = from; insn != to; insn = PREV_INSN (insn))
1758194118Sjamie    if (INSN_P (insn))
1759194118Sjamie      lra_push_insn (insn);
1760193066Sjamie}
1761193066Sjamie
1762193066Sjamie/* Set up sp offset for insn in range [FROM, LAST].  The offset is
1763193066Sjamie   taken from the next BB insn after LAST or zero if there in such
1764193066Sjamie   insn.  */
1765192895Sjamiestatic void
1766192895Sjamiesetup_sp_offset (rtx_insn *from, rtx_insn *last)
1767192895Sjamie{
1768192895Sjamie  rtx_insn *before = next_nonnote_insn_bb (last);
1769192895Sjamie  HOST_WIDE_INT offset = (before == NULL_RTX || ! INSN_P (before)
1770192895Sjamie			  ? 0 : lra_get_insn_recog_data (before)->sp_offset);
1771191673Sjamie
1772191673Sjamie  for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
1773191673Sjamie    lra_get_insn_recog_data (insn)->sp_offset = offset;
1774191673Sjamie}
1775191673Sjamie
1776191673Sjamie/* Emit insns BEFORE before INSN and insns AFTER after INSN.  Put the
1777191673Sjamie   insns onto the stack.  Print about emitting the insns with
1778191673Sjamie   TITLE.  */
1779191673Sjamievoid
1780191673Sjamielra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after,
1781191673Sjamie		       const char *title)
1782191673Sjamie{
1783191673Sjamie  rtx_insn *last;
1784191673Sjamie
1785191673Sjamie  if (before == NULL_RTX && after == NULL_RTX)
1786191673Sjamie    return;
1787191673Sjamie  if (lra_dump_file != NULL)
1788185435Sbz    {
1789221362Strasz      dump_insn_slim (lra_dump_file, insn);
1790284665Strasz      if (before != NULL_RTX)
1791221362Strasz	{
1792221362Strasz	  fprintf (lra_dump_file,"    %s before:\n", title);
1793221362Strasz	  dump_rtl_slim (lra_dump_file, before, NULL, -1, 0);
1794192895Sjamie	}
1795192895Sjamie      if (after != NULL_RTX)
1796192895Sjamie	{
1797192895Sjamie	  fprintf (lra_dump_file, "    %s after:\n", title);
1798192895Sjamie	  dump_rtl_slim (lra_dump_file, after, NULL, -1, 0);
1799192895Sjamie	}
1800192895Sjamie      fprintf (lra_dump_file, "\n");
1801192895Sjamie    }
1802192895Sjamie  if (before != NULL_RTX)
1803192895Sjamie    {
1804195945Sjamie      if (cfun->can_throw_non_call_exceptions)
1805195945Sjamie	copy_reg_eh_region_note_forward (insn, before, NULL);
1806195945Sjamie      emit_insn_before (before, insn);
1807195945Sjamie      push_insns (PREV_INSN (insn), PREV_INSN (before));
1808195945Sjamie      setup_sp_offset (before, PREV_INSN (insn));
1809195945Sjamie    }
1810192895Sjamie  if (after != NULL_RTX)
1811192895Sjamie    {
1812192895Sjamie      if (cfun->can_throw_non_call_exceptions)
1813192895Sjamie	copy_reg_eh_region_note_forward (insn, after, NULL);
1814192895Sjamie      for (last = after; NEXT_INSN (last) != NULL_RTX; last = NEXT_INSN (last))
1815192895Sjamie	;
1816192895Sjamie      emit_insn_after (after, insn);
1817192895Sjamie      push_insns (last, insn);
1818192895Sjamie      setup_sp_offset (after, last);
1819192895Sjamie    }
1820192895Sjamie  if (cfun->can_throw_non_call_exceptions)
1821192895Sjamie    {
1822192895Sjamie      rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1823192895Sjamie      if (note && !insn_could_throw_p (insn))
1824192895Sjamie	remove_note (insn, note);
1825192895Sjamie    }
1826192895Sjamie}
1827195945Sjamie
1828195945Sjamie
1829195945Sjamie/* Replace all references to register OLD_REGNO in *LOC with pseudo
1830195945Sjamie   register NEW_REG.  Try to simplify subreg of constant if SUBREG_P.
1831195945Sjamie   Return true if any change was made.  */
1832195945Sjamiebool
1833192895Sjamielra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p)
1834192895Sjamie{
1835192895Sjamie  rtx x = *loc;
1836192895Sjamie  bool result = false;
1837192895Sjamie  enum rtx_code code;
1838192895Sjamie  const char *fmt;
1839192895Sjamie  int i, j;
1840192895Sjamie
1841192895Sjamie  if (x == NULL_RTX)
1842192895Sjamie    return false;
1843192895Sjamie
1844191673Sjamie  code = GET_CODE (x);
1845191673Sjamie  if (code == SUBREG && subreg_p)
1846191673Sjamie    {
1847191673Sjamie      rtx subst, inner = SUBREG_REG (x);
1848191673Sjamie      /* Transform subreg of constant while we still have inner mode
1849191673Sjamie	 of the subreg.  The subreg internal should not be an insn
1850191673Sjamie	 operand.  */
1851191673Sjamie      if (REG_P (inner) && (int) REGNO (inner) == old_regno
1852191673Sjamie	  && CONSTANT_P (new_reg)
1853191673Sjamie	  && (subst = simplify_subreg (GET_MODE (x), new_reg, GET_MODE (inner),
1854191673Sjamie				       SUBREG_BYTE (x))) != NULL_RTX)
1855191673Sjamie	{
1856191673Sjamie	  *loc = subst;
1857191673Sjamie	  return true;
1858191673Sjamie	}
1859191673Sjamie
1860191673Sjamie    }
1861191673Sjamie  else if (code == REG && (int) REGNO (x) == old_regno)
1862191673Sjamie    {
1863191673Sjamie      machine_mode mode = GET_MODE (x);
1864191673Sjamie      machine_mode inner_mode = GET_MODE (new_reg);
1865191673Sjamie
1866191673Sjamie      if (mode != inner_mode
1867191673Sjamie	  && ! (CONST_INT_P (new_reg) && SCALAR_INT_MODE_P (mode)))
1868191673Sjamie	{
1869191673Sjamie	  if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (inner_mode)
1870191673Sjamie	      || ! SCALAR_INT_MODE_P (inner_mode))
1871191673Sjamie	    new_reg = gen_rtx_SUBREG (mode, new_reg, 0);
1872191673Sjamie	  else
1873235803Strasz	    new_reg = gen_lowpart_SUBREG (mode, new_reg);
1874284665Strasz	}
1875271622Strasz      *loc = new_reg;
1876271622Strasz      return true;
1877235803Strasz    }
1878271622Strasz
1879271622Strasz  /* Scan all the operand sub-expressions.  */
1880235803Strasz  fmt = GET_RTX_FORMAT (code);
1881235803Strasz  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1882235803Strasz    {
1883235803Strasz      if (fmt[i] == 'e')
1884235803Strasz	{
1885191673Sjamie	  if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
1886191673Sjamie				     new_reg, subreg_p))
1887191673Sjamie	    result = true;
1888191673Sjamie	}
1889191673Sjamie      else if (fmt[i] == 'E')
1890191673Sjamie	{
1891191673Sjamie	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1892191673Sjamie	    if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno,
1893191673Sjamie				       new_reg, subreg_p))
1894191673Sjamie	      result = true;
1895191673Sjamie	}
1896191673Sjamie    }
1897191673Sjamie  return result;
1898191673Sjamie}
1899191673Sjamie
1900191673Sjamie/* Call lra_substitute_pseudo within an insn.  Try to simplify subreg
1901191673Sjamie   of constant if SUBREG_P.  This won't update the insn ptr, just the
1902191673Sjamie   contents of the insn.  */
1903191673Sjamiebool
1904191673Sjamielra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno,
1905232598Strasz				   rtx new_reg, bool subreg_p)
1906191673Sjamie{
1907191673Sjamie  rtx loc = insn;
1908192895Sjamie  return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p);
1909192895Sjamie}
1910192895Sjamie
1911192895Sjamie
1912192895Sjamie
1913191673Sjamie/* This page contains code dealing with scratches (changing them onto
1914191673Sjamie   pseudos and restoring them from the pseudos).
1915191673Sjamie
1916241896Skib   We change scratches into pseudos at the beginning of LRA to
1917191673Sjamie   simplify dealing with them (conflicts, hard register assignments).
1918191673Sjamie
1919191673Sjamie   If the pseudo denoting scratch was spilled it means that we do need
1920191673Sjamie   a hard register for it.  Such pseudos are transformed back to
1921191673Sjamie   scratches at the end of LRA.	 */
1922191673Sjamie
1923191673Sjamie/* Description of location of a former scratch operand.	 */
1924191673Sjamiestruct sloc
1925191673Sjamie{
1926191673Sjamie  rtx_insn *insn; /* Insn where the scratch was.  */
1927191673Sjamie  int nop;  /* Number of the operand which was a scratch.  */
1928191673Sjamie};
1929191673Sjamie
1930191673Sjamietypedef struct sloc *sloc_t;
1931191673Sjamie
1932191673Sjamie/* Locations of the former scratches.  */
1933191673Sjamiestatic vec<sloc_t> scratches;
1934191673Sjamie
1935191673Sjamie/* Bitmap of scratch regnos.  */
1936191673Sjamiestatic bitmap_head scratch_bitmap;
1937191673Sjamie
1938191673Sjamie/* Bitmap of scratch operands.	*/
1939191673Sjamiestatic bitmap_head scratch_operand_bitmap;
1940191673Sjamie
1941191673Sjamie/* Return true if pseudo REGNO is made of SCRATCH.  */
1942230407Smmbool
1943230407Smmlra_former_scratch_p (int regno)
1944191673Sjamie{
1945191673Sjamie  return bitmap_bit_p (&scratch_bitmap, regno);
1946191673Sjamie}
1947191673Sjamie
1948191673Sjamie/* Return true if the operand NOP of INSN is a former scratch.	*/
194982710Sdillonbool
1950191673Sjamielra_former_scratch_operand_p (rtx_insn *insn, int nop)
1951191673Sjamie{
1952191673Sjamie  return bitmap_bit_p (&scratch_operand_bitmap,
1953191673Sjamie		       INSN_UID (insn) * MAX_RECOG_OPERANDS + nop) != 0;
1954114168Smike}
195582710Sdillon
195646155Sphk/* Register operand NOP in INSN as a former scratch.  It will be
1957225617Skmacy   changed to scratch back, if it is necessary, at the LRA end.  */
195846155Sphkvoid
1959191673Sjamielra_register_new_scratch_op (rtx_insn *insn, int nop)
1960185435Sbz{
1961185435Sbz  lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
1962191673Sjamie  rtx op = *id->operand_loc[nop];
1963191673Sjamie  sloc_t loc = XNEW (struct sloc);
1964191673Sjamie  lra_assert (REG_P (op));
1965191673Sjamie  loc->insn = insn;
1966191673Sjamie  loc->nop = nop;
1967185435Sbz  scratches.safe_push (loc);
1968185435Sbz  bitmap_set_bit (&scratch_bitmap, REGNO (op));
1969191673Sjamie  bitmap_set_bit (&scratch_operand_bitmap,
1970191673Sjamie		  INSN_UID (insn) * MAX_RECOG_OPERANDS + nop);
1971191673Sjamie  add_reg_note (insn, REG_UNUSED, op);
1972191673Sjamie}
1973191673Sjamie
1974191673Sjamie/* Change scratches onto pseudos and save their location.  */
1975191673Sjamiestatic void
1976185435Sbzremove_scratches (void)
1977191673Sjamie{
1978191673Sjamie  int i;
1979191673Sjamie  bool insn_changed_p;
1980192895Sjamie  basic_block bb;
1981191673Sjamie  rtx_insn *insn;
1982191673Sjamie  rtx reg;
1983191673Sjamie  lra_insn_recog_data_t id;
1984192895Sjamie  struct lra_static_insn_data *static_id;
1985185435Sbz
1986191673Sjamie  scratches.create (get_max_uid ());
1987191673Sjamie  bitmap_initialize (&scratch_bitmap, &reg_obstack);
1988185435Sbz  bitmap_initialize (&scratch_operand_bitmap, &reg_obstack);
1989191673Sjamie  FOR_EACH_BB_FN (bb, cfun)
1990191673Sjamie    FOR_BB_INSNS (bb, insn)
1991191673Sjamie    if (INSN_P (insn))
1992191673Sjamie      {
1993191673Sjamie	id = lra_get_insn_recog_data (insn);
1994192895Sjamie	static_id = id->insn_static_data;
1995185435Sbz	insn_changed_p = false;
1996191673Sjamie	for (i = 0; i < static_id->n_operands; i++)
1997191673Sjamie	  if (GET_CODE (*id->operand_loc[i]) == SCRATCH
1998191673Sjamie	      && GET_MODE (*id->operand_loc[i]) != VOIDmode)
1999191673Sjamie	    {
2000191673Sjamie	      insn_changed_p = true;
2001191673Sjamie	      *id->operand_loc[i] = reg
2002191673Sjamie		= lra_create_new_reg (static_id->operand[i].mode,
2003192895Sjamie				      *id->operand_loc[i], ALL_REGS, NULL);
2004191673Sjamie	      lra_register_new_scratch_op (insn, i);
2005191673Sjamie	      if (lra_dump_file != NULL)
2006191673Sjamie		fprintf (lra_dump_file,
2007191673Sjamie			 "Removing SCRATCH in insn #%u (nop %d)\n",
2008191673Sjamie			 INSN_UID (insn), i);
2009191673Sjamie	    }
2010191673Sjamie	if (insn_changed_p)
2011191673Sjamie	  /* Because we might use DF right after caller-saves sub-pass
2012191673Sjamie	     we need to keep DF info up to date.  */
2013191673Sjamie	  df_insn_rescan (insn);
2014191673Sjamie      }
2015191673Sjamie}
2016191673Sjamie
2017191673Sjamie/* Changes pseudos created by function remove_scratches onto scratches.	 */
2018185435Sbzstatic void
2019191673Sjamierestore_scratches (void)
2020191673Sjamie{
2021191673Sjamie  int regno;
2022192895Sjamie  unsigned i;
2023191673Sjamie  sloc_t loc;
2024191673Sjamie  rtx_insn *last = NULL;
2025191673Sjamie  lra_insn_recog_data_t id = NULL;
2026191673Sjamie
2027191673Sjamie  for (i = 0; scratches.iterate (i, &loc); i++)
2028191673Sjamie    {
2029191673Sjamie      if (last != loc->insn)
2030191673Sjamie	{
2031191673Sjamie	  last = loc->insn;
2032191673Sjamie	  id = lra_get_insn_recog_data (last);
2033191673Sjamie	}
2034191673Sjamie      if (REG_P (*id->operand_loc[loc->nop])
2035191673Sjamie	  && ((regno = REGNO (*id->operand_loc[loc->nop]))
2036191673Sjamie	      >= FIRST_PSEUDO_REGISTER)
2037191673Sjamie	  && lra_get_regno_hard_regno (regno) < 0)
2038191673Sjamie	{
203946155Sphk	  /* It should be only case when scratch register with chosen
2040191673Sjamie	     constraint 'X' did not get memory or hard register.  */
2041191673Sjamie	  lra_assert (lra_former_scratch_p (regno));
2042191673Sjamie	  *id->operand_loc[loc->nop]
2043191673Sjamie	    = gen_rtx_SCRATCH (GET_MODE (*id->operand_loc[loc->nop]));
2044191673Sjamie	  lra_update_dup (id, loc->nop);
2045191673Sjamie	  if (lra_dump_file != NULL)
2046192895Sjamie	    fprintf (lra_dump_file, "Restoring SCRATCH in insn #%u(nop %d)\n",
2047191673Sjamie		     INSN_UID (loc->insn), loc->nop);
2048191673Sjamie	}
2049191673Sjamie    }
2050191673Sjamie  for (i = 0; scratches.iterate (i, &loc); i++)
2051191673Sjamie    free (loc);
2052191673Sjamie  scratches.release ();
2053191673Sjamie  bitmap_clear (&scratch_bitmap);
2054191673Sjamie  bitmap_clear (&scratch_operand_bitmap);
2055191673Sjamie}
2056191673Sjamie
2057191673Sjamie
2058191673Sjamie
2059191673Sjamie#ifdef ENABLE_CHECKING
2060191673Sjamie
2061191673Sjamie/* Function checks RTL for correctness.	 If FINAL_P is true, it is
2062185435Sbz   done at the end of LRA and the check is more rigorous.  */
2063191673Sjamiestatic void
2064191673Sjamiecheck_rtl (bool final_p)
2065191673Sjamie{
2066191673Sjamie  basic_block bb;
2067191673Sjamie  rtx_insn *insn;
2068191673Sjamie
2069191673Sjamie  lra_assert (! final_p || reload_completed);
2070191673Sjamie  FOR_EACH_BB_FN (bb, cfun)
2071191673Sjamie    FOR_BB_INSNS (bb, insn)
2072191673Sjamie    if (NONDEBUG_INSN_P (insn)
2073191673Sjamie	&& GET_CODE (PATTERN (insn)) != USE
2074191673Sjamie	&& GET_CODE (PATTERN (insn)) != CLOBBER
2075192895Sjamie	&& GET_CODE (PATTERN (insn)) != ASM_INPUT)
2076192895Sjamie      {
2077191673Sjamie	if (final_p)
2078191673Sjamie	  {
2079192895Sjamie#ifdef ENABLED_CHECKING
2080192895Sjamie	    extract_constrain_insn (insn);
2081192895Sjamie#endif
2082192895Sjamie	    continue;
2083191673Sjamie	  }
2084191673Sjamie	/* LRA code is based on assumption that all addresses can be
2085191673Sjamie	   correctly decomposed.  LRA can generate reloads for
2086192895Sjamie	   decomposable addresses.  The decomposition code checks the
2087191673Sjamie	   correctness of the addresses.  So we don't need to check
2088191673Sjamie	   the addresses here.  Don't call insn_invalid_p here, it can
2089191673Sjamie	   change the code at this stage.  */
2090191673Sjamie	if (recog_memoized (insn) < 0 && asm_noperands (PATTERN (insn)) < 0)
2091191673Sjamie	  fatal_insn_not_found (insn);
2092191673Sjamie      }
2093191673Sjamie}
2094191673Sjamie#endif /* #ifdef ENABLE_CHECKING */
2095191673Sjamie
2096191673Sjamie/* Determine if the current function has an exception receiver block
2097191673Sjamie   that reaches the exit block via non-exceptional edges  */
2098191673Sjamiestatic bool
2099191673Sjamiehas_nonexceptional_receiver (void)
2100191673Sjamie{
2101191673Sjamie  edge e;
2102191673Sjamie  edge_iterator ei;
2103191673Sjamie  basic_block *tos, *worklist, bb;
2104191673Sjamie
2105194762Sjamie  /* If we're not optimizing, then just err on the safe side.  */
2106194762Sjamie  if (!optimize)
2107194762Sjamie    return true;
2108194762Sjamie
2109194762Sjamie  /* First determine which blocks can reach exit via normal paths.  */
2110194762Sjamie  tos = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) + 1);
2111194762Sjamie
2112194762Sjamie  FOR_EACH_BB_FN (bb, cfun)
2113194118Sjamie    bb->flags &= ~BB_REACHABLE;
2114191673Sjamie
2115191673Sjamie  /* Place the exit block on our worklist.  */
2116194118Sjamie  EXIT_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_REACHABLE;
2117193066Sjamie  *tos++ = EXIT_BLOCK_PTR_FOR_FN (cfun);
2118193066Sjamie
2119194118Sjamie  /* Iterate: find everything reachable from what we've already seen.  */
2120193066Sjamie  while (tos != worklist)
2121193066Sjamie    {
2122205014Snwhitehorn      bb = *--tos;
2123217896Sdchagin
2124193066Sjamie      FOR_EACH_EDGE (e, ei, bb->preds)
2125193066Sjamie	if (e->flags & EDGE_ABNORMAL)
2126193066Sjamie	  {
2127193066Sjamie	    free (worklist);
2128193066Sjamie	    return true;
2129193066Sjamie	  }
2130193066Sjamie	else
2131193066Sjamie	  {
2132193066Sjamie	    basic_block src = e->src;
2133192895Sjamie
2134192895Sjamie	    if (!(src->flags & BB_REACHABLE))
2135191673Sjamie	      {
2136191673Sjamie		src->flags |= BB_REACHABLE;
2137231267Smm		*tos++ = src;
2138231267Smm	      }
2139231267Smm	  }
2140231267Smm    }
2141192895Sjamie  free (worklist);
2142192895Sjamie  /* No exceptional block reached exit unexceptionally.	 */
2143192895Sjamie  return false;
2144192895Sjamie}
2145192895Sjamie
2146192895Sjamie#ifdef AUTO_INC_DEC
2147192895Sjamie
2148192895Sjamie/* Process recursively X of INSN and add REG_INC notes if necessary.  */
2149192895Sjamiestatic void
2150192895Sjamieadd_auto_inc_notes (rtx_insn *insn, rtx x)
2151192895Sjamie{
2152192895Sjamie  enum rtx_code code = GET_CODE (x);
2153192895Sjamie  const char *fmt;
2154195870Sjamie  int i, j;
2155195870Sjamie
2156195870Sjamie  if (code == MEM && auto_inc_p (XEXP (x, 0)))
2157195870Sjamie    {
2158195870Sjamie      add_reg_note (insn, REG_INC, XEXP (XEXP (x, 0), 0));
2159195870Sjamie      return;
2160195870Sjamie    }
2161195870Sjamie
2162195870Sjamie  /* Scan all X sub-expressions.  */
2163195870Sjamie  fmt = GET_RTX_FORMAT (code);
2164195870Sjamie  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2165195870Sjamie    {
2166195870Sjamie      if (fmt[i] == 'e')
2167192895Sjamie	add_auto_inc_notes (insn, XEXP (x, i));
2168192895Sjamie      else if (fmt[i] == 'E')
2169192895Sjamie	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2170192895Sjamie	  add_auto_inc_notes (insn, XVECEXP (x, i, j));
2171192895Sjamie    }
2172192895Sjamie}
2173192895Sjamie
2174192895Sjamie#endif
2175192895Sjamie
2176192895Sjamie/* Remove all REG_DEAD and REG_UNUSED notes and regenerate REG_INC.
2177192895Sjamie   We change pseudos by hard registers without notification of DF and
2178192895Sjamie   that can make the notes obsolete.  DF-infrastructure does not deal
2179192895Sjamie   with REG_INC notes -- so we should regenerate them here.  */
2180191673Sjamiestatic void
2181191673Sjamieupdate_inc_notes (void)
2182191673Sjamie{
2183191673Sjamie  rtx *pnote;
2184191673Sjamie  basic_block bb;
2185191673Sjamie  rtx_insn *insn;
2186191673Sjamie
2187191673Sjamie  FOR_EACH_BB_FN (bb, cfun)
2188280632Sian    FOR_BB_INSNS (bb, insn)
2189280632Sian    if (NONDEBUG_INSN_P (insn))
2190280632Sian      {
2191280632Sian	pnote = &REG_NOTES (insn);
2192280632Sian	while (*pnote != 0)
2193280632Sian	  {
2194280632Sian	    if (REG_NOTE_KIND (*pnote) == REG_DEAD
2195191673Sjamie                || REG_NOTE_KIND (*pnote) == REG_UNUSED
2196191673Sjamie                || REG_NOTE_KIND (*pnote) == REG_INC)
2197191673Sjamie	      *pnote = XEXP (*pnote, 1);
2198191673Sjamie	    else
2199191673Sjamie	      pnote = &XEXP (*pnote, 1);
220046155Sphk	  }
2201191673Sjamie#ifdef AUTO_INC_DEC
2202191673Sjamie	add_auto_inc_notes (insn, PATTERN (insn));
220384828Sjhb#endif
2204191673Sjamie      }
2205191673Sjamie}
2206191673Sjamie
2207191673Sjamie/* Set to 1 while in lra.  */
2208191673Sjamieint lra_in_progress;
2209191673Sjamie
2210191673Sjamie/* Start of pseudo regnos before the LRA.  */
2211185435Sbzint lra_new_regno_start;
2212191673Sjamie
2213191673Sjamie/* Start of reload pseudo regnos before the new spill pass.  */
2214191673Sjamieint lra_constraint_new_regno_start;
2215191673Sjamie
2216191673Sjamie/* Avoid spilling pseudos with regno more than the following value if
2217191673Sjamie   it is possible.  */
2218191673Sjamieint lra_bad_spill_regno_start;
2219191673Sjamie
2220191673Sjamie/* Inheritance pseudo regnos before the new spill pass.	 */
2221191673Sjamiebitmap_head lra_inheritance_pseudos;
2222191673Sjamie
2223191673Sjamie/* Split regnos before the new spill pass.  */
2224191673Sjamiebitmap_head lra_split_regs;
2225191673Sjamie
2226191673Sjamie/* Reload pseudo regnos before the new assignmnet pass which still can
2227191673Sjamie   be spilled after the assinment pass as memory is also accepted in
2228191673Sjamie   insns for the reload pseudos.  */
2229191673Sjamiebitmap_head lra_optional_reload_pseudos;
2230191673Sjamie
2231191673Sjamie/* Pseudo regnos used for subreg reloads before the new assignment
2232191673Sjamie   pass.  Such pseudos still can be spilled after the assinment
2233185435Sbz   pass.  */
2234191673Sjamiebitmap_head lra_subreg_reload_pseudos;
2235191673Sjamie
2236191673Sjamie/* File used for output of LRA debug information.  */
2237191673SjamieFILE *lra_dump_file;
2238191673Sjamie
2239191673Sjamie/* True if we should try spill into registers of different classes
2240191673Sjamie   instead of memory.  */
2241191673Sjamiebool lra_reg_spill_p;
2242191673Sjamie
2243191673Sjamie/* Set up value LRA_REG_SPILL_P.  */
2244191673Sjamiestatic void
2245191673Sjamiesetup_reg_spill_flag (void)
2246191673Sjamie{
2247191673Sjamie  int cl, mode;
2248191673Sjamie
2249191673Sjamie  if (targetm.spill_class != NULL)
2250191673Sjamie    for (cl = 0; cl < (int) LIM_REG_CLASSES; cl++)
2251191673Sjamie      for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
2252191673Sjamie	if (targetm.spill_class ((enum reg_class) cl,
2253191673Sjamie				 (machine_mode) mode) != NO_REGS)
2254191673Sjamie	  {
2255191673Sjamie	    lra_reg_spill_p = true;
2256185435Sbz	    return;
2257191673Sjamie	  }
2258191673Sjamie  lra_reg_spill_p = false;
2259191673Sjamie}
2260113275Smike
2261192895Sjamie/* True if the current function is too big to use regular algorithms
2262191673Sjamie   in LRA. In other words, we should use simpler and faster algorithms
2263191673Sjamie   in LRA.  It also means we should not worry about generation code
2264191673Sjamie   for caller saves.  The value is set up in IRA.  */
2265191673Sjamiebool lra_simple_p;
2266191673Sjamie
2267191673Sjamie/* Major LRA entry function.  F is a file should be used to dump LRA
2268225617Skmacy   debug info.  */
2269191673Sjamievoid
2270192895Sjamielra (FILE *f)
2271192895Sjamie{
2272185435Sbz  int i;
2273191673Sjamie  bool live_p, scratch_p, inserted_p;
2274185435Sbz
2275191673Sjamie  lra_dump_file = f;
2276185435Sbz
2277185435Sbz  timevar_push (TV_LRA);
2278192895Sjamie
2279191673Sjamie  /* Make sure that the last insn is a note.  Some subsequent passes
2280185435Sbz     need it.  */
2281191673Sjamie  emit_note (NOTE_INSN_DELETED);
2282185435Sbz
2283185435Sbz  COPY_HARD_REG_SET (lra_no_alloc_regs, ira_no_alloc_regs);
2284192895Sjamie
2285192895Sjamie  init_reg_info ();
2286192895Sjamie  expand_reg_info ();
2287192895Sjamie
2288192895Sjamie  init_insn_recog_data ();
2289192895Sjamie
2290192895Sjamie#ifdef ENABLE_CHECKING
2291192895Sjamie  /* Some quick check on RTL generated by previous passes.  */
2292192895Sjamie  check_rtl (false);
2293192895Sjamie#endif
2294192895Sjamie
2295192895Sjamie  lra_in_progress = 1;
2296192895Sjamie
2297192895Sjamie  lra_live_range_iter = lra_coalesce_iter = lra_constraint_iter = 0;
2298192895Sjamie  lra_assignment_iter = lra_assignment_iter_after_spill = 0;
2299192895Sjamie  lra_inheritance_iter = lra_undo_inheritance_iter = 0;
2300192895Sjamie  lra_rematerialization_iter = 0;
2301192895Sjamie
2302192895Sjamie  setup_reg_spill_flag ();
2303192895Sjamie
2304192895Sjamie  /* Function remove_scratches can creates new pseudos for clobbers --
2305192895Sjamie     so set up lra_constraint_new_regno_start before its call to
2306192895Sjamie     permit changing reg classes for pseudos created by this
2307192895Sjamie     simplification.  */
2308192895Sjamie  lra_constraint_new_regno_start = lra_new_regno_start = max_reg_num ();
2309192895Sjamie  lra_bad_spill_regno_start = INT_MAX;
2310192895Sjamie  remove_scratches ();
2311192895Sjamie  scratch_p = lra_constraint_new_regno_start != max_reg_num ();
2312192895Sjamie
2313192895Sjamie  /* A function that has a non-local label that can reach the exit
2314192895Sjamie     block via non-exceptional paths must save all call-saved
2315192895Sjamie     registers.	 */
2316192895Sjamie  if (cfun->has_nonlocal_label && has_nonexceptional_receiver ())
2317192895Sjamie    crtl->saves_all_registers = 1;
2318192895Sjamie
2319192895Sjamie  if (crtl->saves_all_registers)
2320192895Sjamie    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2321192895Sjamie      if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
2322192895Sjamie	df_set_regs_ever_live (i, true);
2323192895Sjamie
2324192895Sjamie  /* We don't DF from now and avoid its using because it is to
2325191673Sjamie     expensive when a lot of RTL changes are made.  */
2326191673Sjamie  df_set_flags (DF_NO_INSN_RESCAN);
2327191673Sjamie  lra_constraint_insn_stack.create (get_max_uid ());
2328191673Sjamie  lra_constraint_insn_stack_bitmap = sbitmap_alloc (get_max_uid ());
2329191673Sjamie  bitmap_clear (lra_constraint_insn_stack_bitmap);
2330191673Sjamie  lra_live_ranges_init ();
2331179881Sdelphij  lra_constraints_init ();
2332113275Smike  lra_curr_reload_num = 0;
2333192895Sjamie  push_insns (get_last_insn (), NULL);
2334192895Sjamie  /* It is needed for the 1st coalescing.  */
2335192895Sjamie  bitmap_initialize (&lra_inheritance_pseudos, &reg_obstack);
2336192895Sjamie  bitmap_initialize (&lra_split_regs, &reg_obstack);
2337192895Sjamie  bitmap_initialize (&lra_optional_reload_pseudos, &reg_obstack);
2338192895Sjamie  bitmap_initialize (&lra_subreg_reload_pseudos, &reg_obstack);
2339192895Sjamie  live_p = false;
2340191673Sjamie  if (get_frame_size () != 0 && crtl->stack_alignment_needed)
2341191673Sjamie    /* If we have a stack frame, we must align it now.  The stack size
2342192895Sjamie       may be a part of the offset computation for register
2343191673Sjamie       elimination.  */
2344191673Sjamie    assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed);
2345113275Smike  lra_init_equiv ();
2346191673Sjamie  for (;;)
2347191673Sjamie    {
2348191673Sjamie      for (;;)
2349191673Sjamie	{
2350191673Sjamie	  /* We should try to assign hard registers to scratches even
2351191673Sjamie	     if there were no RTL transformations in
2352191673Sjamie	     lra_constraints.  */
2353191673Sjamie	  if (! lra_constraints (lra_constraint_iter == 0)
2354191673Sjamie	      && (lra_constraint_iter > 1
2355225617Skmacy		  || (! scratch_p && ! caller_save_needed)))
2356191673Sjamie	    break;
2357191673Sjamie	  /* Constraint transformations may result in that eliminable
2358191673Sjamie	     hard regs become uneliminable and pseudos which use them
2359192895Sjamie	     should be spilled.	 It is better to do it before pseudo
2360191673Sjamie	     assignments.
2361113275Smike
2362113275Smike	     For example, rs6000 can make
2363190466Sjamie	     RS6000_PIC_OFFSET_TABLE_REGNUM uneliminable if we started
2364113275Smike	     to use a constant pool.  */
2365114168Smike	  lra_eliminate (false, false);
2366114168Smike	  /* Do inheritance only for regular algorithms.  */
2367114168Smike	  if (! lra_simple_p)
2368113275Smike	    {
2369113275Smike	      if (flag_ipa_ra)
2370225617Skmacy		{
2371113275Smike		  if (live_p)
2372113275Smike		    lra_clear_live_ranges ();
2373191673Sjamie		  /* As a side-effect of lra_create_live_ranges, we calculate
2374167309Spjd		     actual_call_used_reg_set,  which is needed during
2375164032Srwatson		     lra_inheritance.  */
2376126023Snectar		  lra_create_live_ranges (true, true);
2377126023Snectar		  live_p = true;
2378126023Snectar		}
2379168401Spjd	      lra_inheritance ();
2380192895Sjamie	    }
2381113275Smike	  if (live_p)
2382168401Spjd	    lra_clear_live_ranges ();
2383113275Smike	  /* We need live ranges for lra_assign -- so build them.  But
2384113275Smike	     don't remove dead insns or change global live info as we
2385185435Sbz	     can undo inheritance transformations after inheritance
2386185435Sbz	     pseudo assigning.  */
2387185435Sbz	  lra_create_live_ranges (true, false);
2388191673Sjamie	  live_p = true;
2389185435Sbz	  /* If we don't spill non-reload and non-inheritance pseudos,
2390191673Sjamie	     there is no sense to run memory-memory move coalescing.
2391185435Sbz	     If inheritance pseudos were spilled, the memory-memory
2392185435Sbz	     moves involving them will be removed by pass undoing
2393185435Sbz	     inheritance.  */
2394185435Sbz	  if (lra_simple_p)
2395191673Sjamie	    lra_assign ();
2396191673Sjamie	  else
2397191673Sjamie	    {
2398191673Sjamie	      bool spill_p = !lra_assign ();
2399191673Sjamie
2400191673Sjamie	      if (lra_undo_inheritance ())
2401191673Sjamie		live_p = false;
2402192895Sjamie	      if (spill_p)
2403191673Sjamie		{
2404191673Sjamie		  if (! live_p)
2405241896Skib		    {
2406191673Sjamie		      lra_create_live_ranges (true, true);
2407191673Sjamie		      live_p = true;
2408191673Sjamie		    }
2409191673Sjamie		  if (lra_coalesce ())
2410191673Sjamie		    live_p = false;
2411191673Sjamie		}
2412191673Sjamie	      if (! live_p)
2413191673Sjamie		lra_clear_live_ranges ();
2414191673Sjamie	    }
2415113275Smike	}
2416191673Sjamie      /* Don't clear optional reloads bitmap until all constraints are
2417113275Smike	 satisfied as we need to differ them from regular reloads.  */
2418191673Sjamie      bitmap_clear (&lra_optional_reload_pseudos);
2419191673Sjamie      bitmap_clear (&lra_subreg_reload_pseudos);
2420191673Sjamie      bitmap_clear (&lra_inheritance_pseudos);
2421191673Sjamie      bitmap_clear (&lra_split_regs);
2422191673Sjamie      if (! live_p)
2423191673Sjamie	{
2424191673Sjamie	  /* We need full live info for spilling pseudos into
2425168401Spjd	     registers instead of memory.  */
2426113275Smike	  lra_create_live_ranges (lra_reg_spill_p, true);
2427185435Sbz	  live_p = true;
2428185435Sbz	}
2429185435Sbz      /* We should check necessity for spilling here as the above live
2430192895Sjamie	 range pass can remove spilled pseudos.  */
2431191673Sjamie      if (! lra_need_for_spills_p ())
2432185435Sbz	break;
2433185435Sbz      /* Now we know what pseudos should be spilled.  Try to
2434191673Sjamie	 rematerialize them first.  */
2435185435Sbz      if (lra_remat ())
2436175202Sattilio	{
2437113275Smike	  /* We need full live info -- see the comment above.  */
2438113275Smike	  lra_create_live_ranges (lra_reg_spill_p, true);
2439113275Smike	  live_p = true;
2440172930Srwatson	  if (! lra_need_for_spills_p ())
2441113275Smike	    break;
2442113275Smike	}
2443175294Sattilio      lra_spill ();
2444191673Sjamie      /* Assignment of stack slots changes elimination offsets for
2445241896Skib	 some eliminations.  So update the offsets here.  */
2446113275Smike      lra_eliminate (false, false);
244784828Sjhb      lra_constraint_new_regno_start = max_reg_num ();
244884828Sjhb      if (lra_bad_spill_regno_start == INT_MAX
244984828Sjhb	  && lra_inheritance_iter > LRA_MAX_INHERITANCE_PASSES
2450113275Smike	  && lra_rematerialization_iter > LRA_MAX_REMATERIALIZATION_PASSES)
245184828Sjhb	/* After switching off inheritance and rematerialization
2452113630Sjhb	   passes, avoid spilling reload pseudos will be created to
245384828Sjhb	   prevent LRA cycling in some complicated cases.  */
245484828Sjhb	lra_bad_spill_regno_start = lra_constraint_new_regno_start;
2455220137Strasz      lra_assignment_iter_after_spill = 0;
2456220137Strasz    }
2457220137Strasz  restore_scratches ();
245884828Sjhb  lra_eliminate (true, false);
2459192895Sjamie  lra_final_code_change ();
246046155Sphk  lra_in_progress = 0;
2461191673Sjamie  if (live_p)
2462175294Sattilio    lra_clear_live_ranges ();
2463191673Sjamie  lra_live_ranges_finish ();
2464191673Sjamie  lra_constraints_finish ();
2465192895Sjamie  finish_reg_info ();
2466191673Sjamie  sbitmap_free (lra_constraint_insn_stack_bitmap);
246746155Sphk  lra_constraint_insn_stack.release ();
246846155Sphk  finish_insn_recog_data ();
246946155Sphk  regstat_free_n_sets_and_refs ();
2470192895Sjamie  regstat_free_ri ();
2471113275Smike  reload_completed = 1;
2472113275Smike  update_inc_notes ();
2473113275Smike
2474168399Spjd  inserted_p = fixup_abnormal_edges ();
2475113275Smike
2476113275Smike  /* We've possibly turned single trapping insn into multiple ones.  */
2477113275Smike  if (cfun->can_throw_non_call_exceptions)
2478113275Smike    {
2479168401Spjd      sbitmap blocks;
2480191673Sjamie      blocks = sbitmap_alloc (last_basic_block_for_fn (cfun));
2481113275Smike      bitmap_ones (blocks);
2482113275Smike      find_many_sub_basic_blocks (blocks);
2483191673Sjamie      sbitmap_free (blocks);
2484191673Sjamie    }
2485191673Sjamie
2486113275Smike  if (inserted_p)
2487113275Smike    commit_edge_insertions ();
2488113275Smike
2489113275Smike  /* Replacing pseudos with their memory equivalents might have
2490113275Smike     created shared rtx.  Subsequent passes would get confused
2491191673Sjamie     by this, so unshare everything here.  */
2492192895Sjamie  unshare_all_rtl_again (get_insns ());
2493191673Sjamie
2494191673Sjamie#ifdef ENABLE_CHECKING
2495192895Sjamie  check_rtl (true);
2496191673Sjamie#endif
2497192895Sjamie
2498192895Sjamie  timevar_pop (TV_LRA);
2499192895Sjamie}
2500192895Sjamie
2501192895Sjamie/* Called once per compiler to initialize LRA data once.  */
2502192895Sjamievoid
2503192895Sjamielra_init_once (void)
2504192895Sjamie{
2505192895Sjamie  init_insn_code_data_once ();
2506192895Sjamie}
2507192895Sjamie
2508192895Sjamie/* Called once per compiler to finish LRA data which are initialize
2509192895Sjamie   once.  */
2510192895Sjamievoid
2511192895Sjamielra_finish_once (void)
2512192895Sjamie{
2513192895Sjamie  finish_insn_code_data_once ();
2514192895Sjamie}
2515192895Sjamie