xref: /dflybsd-src/contrib/gcc-4.7/gcc/reginfo.c (revision 0a8dc9fc45f4d0b236341a473fac4a486375f60c)
1e4b17023SJohn Marino /* Compute different info about registers.
2e4b17023SJohn Marino    Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996
3e4b17023SJohn Marino    1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4e4b17023SJohn Marino    2009, 2010, 2011  Free Software Foundation, Inc.
5e4b17023SJohn Marino 
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino 
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino 
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino 
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21e4b17023SJohn Marino 
22e4b17023SJohn Marino 
23e4b17023SJohn Marino /* This file contains regscan pass of the compiler and passes for
24e4b17023SJohn Marino    dealing with info about modes of pseudo-registers inside
25e4b17023SJohn Marino    subregisters.  It also defines some tables of information about the
26e4b17023SJohn Marino    hardware registers, function init_reg_sets to initialize the
27e4b17023SJohn Marino    tables, and other auxiliary functions to deal with info about
28e4b17023SJohn Marino    registers and their classes.  */
29e4b17023SJohn Marino 
30e4b17023SJohn Marino #include "config.h"
31e4b17023SJohn Marino #include "system.h"
32e4b17023SJohn Marino #include "coretypes.h"
33e4b17023SJohn Marino #include "tm.h"
34e4b17023SJohn Marino #include "hard-reg-set.h"
35e4b17023SJohn Marino #include "rtl.h"
36e4b17023SJohn Marino #include "expr.h"
37e4b17023SJohn Marino #include "tm_p.h"
38e4b17023SJohn Marino #include "flags.h"
39e4b17023SJohn Marino #include "basic-block.h"
40e4b17023SJohn Marino #include "regs.h"
41e4b17023SJohn Marino #include "addresses.h"
42e4b17023SJohn Marino #include "function.h"
43e4b17023SJohn Marino #include "insn-config.h"
44e4b17023SJohn Marino #include "recog.h"
45e4b17023SJohn Marino #include "reload.h"
46e4b17023SJohn Marino #include "diagnostic-core.h"
47e4b17023SJohn Marino #include "output.h"
48e4b17023SJohn Marino #include "timevar.h"
49e4b17023SJohn Marino #include "hashtab.h"
50e4b17023SJohn Marino #include "target.h"
51e4b17023SJohn Marino #include "tree-pass.h"
52e4b17023SJohn Marino #include "df.h"
53e4b17023SJohn Marino #include "ira.h"
54e4b17023SJohn Marino 
55e4b17023SJohn Marino /* Maximum register number used in this function, plus one.  */
56e4b17023SJohn Marino 
57e4b17023SJohn Marino int max_regno;
58e4b17023SJohn Marino 
59e4b17023SJohn Marino 
60e4b17023SJohn Marino struct target_hard_regs default_target_hard_regs;
61e4b17023SJohn Marino struct target_regs default_target_regs;
62e4b17023SJohn Marino #if SWITCHABLE_TARGET
63e4b17023SJohn Marino struct target_hard_regs *this_target_hard_regs = &default_target_hard_regs;
64e4b17023SJohn Marino struct target_regs *this_target_regs = &default_target_regs;
65e4b17023SJohn Marino #endif
66e4b17023SJohn Marino 
67e4b17023SJohn Marino /* Data for initializing fixed_regs.  */
68e4b17023SJohn Marino static const char initial_fixed_regs[] = FIXED_REGISTERS;
69e4b17023SJohn Marino 
70e4b17023SJohn Marino /* Data for initializing call_used_regs.  */
71e4b17023SJohn Marino static const char initial_call_used_regs[] = CALL_USED_REGISTERS;
72e4b17023SJohn Marino 
73e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
74e4b17023SJohn Marino /* Data for initializing call_really_used_regs.  */
75e4b17023SJohn Marino static const char initial_call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
76e4b17023SJohn Marino #endif
77e4b17023SJohn Marino 
78e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
79e4b17023SJohn Marino #define CALL_REALLY_USED_REGNO_P(X)  call_really_used_regs[X]
80e4b17023SJohn Marino #else
81e4b17023SJohn Marino #define CALL_REALLY_USED_REGNO_P(X)  call_used_regs[X]
82e4b17023SJohn Marino #endif
83e4b17023SJohn Marino 
84e4b17023SJohn Marino /* Indexed by hard register number, contains 1 for registers
85e4b17023SJohn Marino    that are being used for global register decls.
86e4b17023SJohn Marino    These must be exempt from ordinary flow analysis
87e4b17023SJohn Marino    and are also considered fixed.  */
88e4b17023SJohn Marino char global_regs[FIRST_PSEUDO_REGISTER];
89e4b17023SJohn Marino 
90e4b17023SJohn Marino /* Declaration for the global register. */
91*95d28233SJohn Marino tree global_regs_decl[FIRST_PSEUDO_REGISTER];
92e4b17023SJohn Marino 
93e4b17023SJohn Marino /* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used
94e4b17023SJohn Marino    in dataflow more conveniently.  */
95e4b17023SJohn Marino regset regs_invalidated_by_call_regset;
96e4b17023SJohn Marino 
97e4b17023SJohn Marino /* Same information as FIXED_REG_SET but in regset form.  */
98e4b17023SJohn Marino regset fixed_reg_set_regset;
99e4b17023SJohn Marino 
100e4b17023SJohn Marino /* The bitmap_obstack is used to hold some static variables that
101e4b17023SJohn Marino    should not be reset after each function is compiled.  */
102e4b17023SJohn Marino static bitmap_obstack persistent_obstack;
103e4b17023SJohn Marino 
104e4b17023SJohn Marino /* Used to initialize reg_alloc_order.  */
105e4b17023SJohn Marino #ifdef REG_ALLOC_ORDER
106e4b17023SJohn Marino static int initial_reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
107e4b17023SJohn Marino #endif
108e4b17023SJohn Marino 
109e4b17023SJohn Marino /* The same information, but as an array of unsigned ints.  We copy from
110e4b17023SJohn Marino    these unsigned ints to the table above.  We do this so the tm.h files
111e4b17023SJohn Marino    do not have to be aware of the wordsize for machines with <= 64 regs.
112e4b17023SJohn Marino    Note that we hard-code 32 here, not HOST_BITS_PER_INT.  */
113e4b17023SJohn Marino #define N_REG_INTS  \
114e4b17023SJohn Marino   ((FIRST_PSEUDO_REGISTER + (32 - 1)) / 32)
115e4b17023SJohn Marino 
116e4b17023SJohn Marino static const unsigned int_reg_class_contents[N_REG_CLASSES][N_REG_INTS]
117e4b17023SJohn Marino   = REG_CLASS_CONTENTS;
118e4b17023SJohn Marino 
119e4b17023SJohn Marino /* Array containing all of the register names.  */
120e4b17023SJohn Marino static const char *const initial_reg_names[] = REGISTER_NAMES;
121e4b17023SJohn Marino 
122e4b17023SJohn Marino /* Array containing all of the register class names.  */
123e4b17023SJohn Marino const char * reg_class_names[] = REG_CLASS_NAMES;
124e4b17023SJohn Marino 
125e4b17023SJohn Marino #define last_mode_for_init_move_cost \
126e4b17023SJohn Marino   (this_target_regs->x_last_mode_for_init_move_cost)
127e4b17023SJohn Marino 
128e4b17023SJohn Marino /* No more global register variables may be declared; true once
129e4b17023SJohn Marino    reginfo has been initialized.  */
130e4b17023SJohn Marino static int no_global_reg_vars = 0;
131e4b17023SJohn Marino 
132e4b17023SJohn Marino /* Given a register bitmap, turn on the bits in a HARD_REG_SET that
133e4b17023SJohn Marino    correspond to the hard registers, if any, set in that map.  This
134e4b17023SJohn Marino    could be done far more efficiently by having all sorts of special-cases
135e4b17023SJohn Marino    with moving single words, but probably isn't worth the trouble.  */
136e4b17023SJohn Marino void
reg_set_to_hard_reg_set(HARD_REG_SET * to,const_bitmap from)137e4b17023SJohn Marino reg_set_to_hard_reg_set (HARD_REG_SET *to, const_bitmap from)
138e4b17023SJohn Marino {
139e4b17023SJohn Marino   unsigned i;
140e4b17023SJohn Marino   bitmap_iterator bi;
141e4b17023SJohn Marino 
142e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
143e4b17023SJohn Marino     {
144e4b17023SJohn Marino       if (i >= FIRST_PSEUDO_REGISTER)
145e4b17023SJohn Marino 	return;
146e4b17023SJohn Marino       SET_HARD_REG_BIT (*to, i);
147e4b17023SJohn Marino     }
148e4b17023SJohn Marino }
149e4b17023SJohn Marino 
150e4b17023SJohn Marino /* Function called only once per target_globals to initialize the
151e4b17023SJohn Marino    target_hard_regs structure.  Once this is done, various switches
152e4b17023SJohn Marino    may override.  */
153e4b17023SJohn Marino void
init_reg_sets(void)154e4b17023SJohn Marino init_reg_sets (void)
155e4b17023SJohn Marino {
156e4b17023SJohn Marino   int i, j;
157e4b17023SJohn Marino 
158e4b17023SJohn Marino   /* First copy the register information from the initial int form into
159e4b17023SJohn Marino      the regsets.  */
160e4b17023SJohn Marino 
161e4b17023SJohn Marino   for (i = 0; i < N_REG_CLASSES; i++)
162e4b17023SJohn Marino     {
163e4b17023SJohn Marino       CLEAR_HARD_REG_SET (reg_class_contents[i]);
164e4b17023SJohn Marino 
165e4b17023SJohn Marino       /* Note that we hard-code 32 here, not HOST_BITS_PER_INT.  */
166e4b17023SJohn Marino       for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
167e4b17023SJohn Marino 	if (int_reg_class_contents[i][j / 32]
168e4b17023SJohn Marino 	    & ((unsigned) 1 << (j % 32)))
169e4b17023SJohn Marino 	  SET_HARD_REG_BIT (reg_class_contents[i], j);
170e4b17023SJohn Marino     }
171e4b17023SJohn Marino 
172e4b17023SJohn Marino   /* Sanity check: make sure the target macros FIXED_REGISTERS and
173e4b17023SJohn Marino      CALL_USED_REGISTERS had the right number of initializers.  */
174e4b17023SJohn Marino   gcc_assert (sizeof fixed_regs == sizeof initial_fixed_regs);
175e4b17023SJohn Marino   gcc_assert (sizeof call_used_regs == sizeof initial_call_used_regs);
176e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
177e4b17023SJohn Marino   gcc_assert (sizeof call_really_used_regs
178e4b17023SJohn Marino 	      == sizeof initial_call_really_used_regs);
179e4b17023SJohn Marino #endif
180e4b17023SJohn Marino #ifdef REG_ALLOC_ORDER
181e4b17023SJohn Marino   gcc_assert (sizeof reg_alloc_order == sizeof initial_reg_alloc_order);
182e4b17023SJohn Marino #endif
183e4b17023SJohn Marino   gcc_assert (sizeof reg_names == sizeof initial_reg_names);
184e4b17023SJohn Marino 
185e4b17023SJohn Marino   memcpy (fixed_regs, initial_fixed_regs, sizeof fixed_regs);
186e4b17023SJohn Marino   memcpy (call_used_regs, initial_call_used_regs, sizeof call_used_regs);
187e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
188e4b17023SJohn Marino   memcpy (call_really_used_regs, initial_call_really_used_regs,
189e4b17023SJohn Marino 	  sizeof call_really_used_regs);
190e4b17023SJohn Marino #endif
191e4b17023SJohn Marino #ifdef REG_ALLOC_ORDER
192e4b17023SJohn Marino   memcpy (reg_alloc_order, initial_reg_alloc_order, sizeof reg_alloc_order);
193e4b17023SJohn Marino #endif
194e4b17023SJohn Marino   memcpy (reg_names, initial_reg_names, sizeof reg_names);
195e4b17023SJohn Marino 
196e4b17023SJohn Marino   SET_HARD_REG_SET (accessible_reg_set);
197e4b17023SJohn Marino   SET_HARD_REG_SET (operand_reg_set);
198e4b17023SJohn Marino }
199e4b17023SJohn Marino 
200e4b17023SJohn Marino /* Initialize may_move_cost and friends for mode M.  */
201e4b17023SJohn Marino void
init_move_cost(enum machine_mode m)202e4b17023SJohn Marino init_move_cost (enum machine_mode m)
203e4b17023SJohn Marino {
204e4b17023SJohn Marino   static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
205e4b17023SJohn Marino   bool all_match = true;
206e4b17023SJohn Marino   unsigned int i, j;
207e4b17023SJohn Marino 
208e4b17023SJohn Marino   gcc_assert (have_regs_of_mode[m]);
209e4b17023SJohn Marino   for (i = 0; i < N_REG_CLASSES; i++)
210e4b17023SJohn Marino     if (contains_reg_of_mode[i][m])
211e4b17023SJohn Marino       for (j = 0; j < N_REG_CLASSES; j++)
212e4b17023SJohn Marino 	{
213e4b17023SJohn Marino 	  int cost;
214e4b17023SJohn Marino 	  if (!contains_reg_of_mode[j][m])
215e4b17023SJohn Marino 	    cost = 65535;
216e4b17023SJohn Marino 	  else
217e4b17023SJohn Marino 	    {
218e4b17023SJohn Marino 	      cost = register_move_cost (m, (enum reg_class) i,
219e4b17023SJohn Marino 					 (enum reg_class) j);
220e4b17023SJohn Marino 	      gcc_assert (cost < 65535);
221e4b17023SJohn Marino 	    }
222e4b17023SJohn Marino 	  all_match &= (last_move_cost[i][j] == cost);
223e4b17023SJohn Marino 	  last_move_cost[i][j] = cost;
224e4b17023SJohn Marino 	}
225e4b17023SJohn Marino   if (all_match && last_mode_for_init_move_cost != -1)
226e4b17023SJohn Marino     {
227e4b17023SJohn Marino       move_cost[m] = move_cost[last_mode_for_init_move_cost];
228e4b17023SJohn Marino       may_move_in_cost[m] = may_move_in_cost[last_mode_for_init_move_cost];
229e4b17023SJohn Marino       may_move_out_cost[m] = may_move_out_cost[last_mode_for_init_move_cost];
230e4b17023SJohn Marino       return;
231e4b17023SJohn Marino     }
232e4b17023SJohn Marino   last_mode_for_init_move_cost = m;
233e4b17023SJohn Marino   move_cost[m] = (move_table *)xmalloc (sizeof (move_table)
234e4b17023SJohn Marino 					* N_REG_CLASSES);
235e4b17023SJohn Marino   may_move_in_cost[m] = (move_table *)xmalloc (sizeof (move_table)
236e4b17023SJohn Marino 					       * N_REG_CLASSES);
237e4b17023SJohn Marino   may_move_out_cost[m] = (move_table *)xmalloc (sizeof (move_table)
238e4b17023SJohn Marino 					        * N_REG_CLASSES);
239e4b17023SJohn Marino   for (i = 0; i < N_REG_CLASSES; i++)
240e4b17023SJohn Marino     if (contains_reg_of_mode[i][m])
241e4b17023SJohn Marino       for (j = 0; j < N_REG_CLASSES; j++)
242e4b17023SJohn Marino 	{
243e4b17023SJohn Marino 	  int cost;
244e4b17023SJohn Marino 	  enum reg_class *p1, *p2;
245e4b17023SJohn Marino 
246e4b17023SJohn Marino 	  if (last_move_cost[i][j] == 65535)
247e4b17023SJohn Marino 	    {
248e4b17023SJohn Marino 	      move_cost[m][i][j] = 65535;
249e4b17023SJohn Marino 	      may_move_in_cost[m][i][j] = 65535;
250e4b17023SJohn Marino 	      may_move_out_cost[m][i][j] = 65535;
251e4b17023SJohn Marino 	    }
252e4b17023SJohn Marino 	  else
253e4b17023SJohn Marino 	    {
254e4b17023SJohn Marino 	      cost = last_move_cost[i][j];
255e4b17023SJohn Marino 
256e4b17023SJohn Marino 	      for (p2 = &reg_class_subclasses[j][0];
257e4b17023SJohn Marino 		   *p2 != LIM_REG_CLASSES; p2++)
258e4b17023SJohn Marino 		if (*p2 != i && contains_reg_of_mode[*p2][m])
259e4b17023SJohn Marino 		  cost = MAX (cost, move_cost[m][i][*p2]);
260e4b17023SJohn Marino 
261e4b17023SJohn Marino 	      for (p1 = &reg_class_subclasses[i][0];
262e4b17023SJohn Marino 		   *p1 != LIM_REG_CLASSES; p1++)
263e4b17023SJohn Marino 		if (*p1 != j && contains_reg_of_mode[*p1][m])
264e4b17023SJohn Marino 		  cost = MAX (cost, move_cost[m][*p1][j]);
265e4b17023SJohn Marino 
266e4b17023SJohn Marino 	      gcc_assert (cost <= 65535);
267e4b17023SJohn Marino 	      move_cost[m][i][j] = cost;
268e4b17023SJohn Marino 
269e4b17023SJohn Marino 	      if (reg_class_subset_p ((enum reg_class) i, (enum reg_class) j))
270e4b17023SJohn Marino 		may_move_in_cost[m][i][j] = 0;
271e4b17023SJohn Marino 	      else
272e4b17023SJohn Marino 		may_move_in_cost[m][i][j] = cost;
273e4b17023SJohn Marino 
274e4b17023SJohn Marino 	      if (reg_class_subset_p ((enum reg_class) j, (enum reg_class) i))
275e4b17023SJohn Marino 		may_move_out_cost[m][i][j] = 0;
276e4b17023SJohn Marino 	      else
277e4b17023SJohn Marino 		may_move_out_cost[m][i][j] = cost;
278e4b17023SJohn Marino 	    }
279e4b17023SJohn Marino 	}
280e4b17023SJohn Marino     else
281e4b17023SJohn Marino       for (j = 0; j < N_REG_CLASSES; j++)
282e4b17023SJohn Marino 	{
283e4b17023SJohn Marino 	  move_cost[m][i][j] = 65535;
284e4b17023SJohn Marino 	  may_move_in_cost[m][i][j] = 65535;
285e4b17023SJohn Marino 	  may_move_out_cost[m][i][j] = 65535;
286e4b17023SJohn Marino 	}
287e4b17023SJohn Marino }
288e4b17023SJohn Marino 
289e4b17023SJohn Marino /* We need to save copies of some of the register information which
290e4b17023SJohn Marino    can be munged by command-line switches so we can restore it during
291e4b17023SJohn Marino    subsequent back-end reinitialization.  */
292e4b17023SJohn Marino static char saved_fixed_regs[FIRST_PSEUDO_REGISTER];
293e4b17023SJohn Marino static char saved_call_used_regs[FIRST_PSEUDO_REGISTER];
294e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
295e4b17023SJohn Marino static char saved_call_really_used_regs[FIRST_PSEUDO_REGISTER];
296e4b17023SJohn Marino #endif
297e4b17023SJohn Marino static const char *saved_reg_names[FIRST_PSEUDO_REGISTER];
298e4b17023SJohn Marino static HARD_REG_SET saved_accessible_reg_set;
299e4b17023SJohn Marino static HARD_REG_SET saved_operand_reg_set;
300e4b17023SJohn Marino 
301e4b17023SJohn Marino /* Save the register information.  */
302e4b17023SJohn Marino void
save_register_info(void)303e4b17023SJohn Marino save_register_info (void)
304e4b17023SJohn Marino {
305e4b17023SJohn Marino   /* Sanity check:  make sure the target macros FIXED_REGISTERS and
306e4b17023SJohn Marino      CALL_USED_REGISTERS had the right number of initializers.  */
307e4b17023SJohn Marino   gcc_assert (sizeof fixed_regs == sizeof saved_fixed_regs);
308e4b17023SJohn Marino   gcc_assert (sizeof call_used_regs == sizeof saved_call_used_regs);
309e4b17023SJohn Marino   memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs);
310e4b17023SJohn Marino   memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs);
311e4b17023SJohn Marino 
312e4b17023SJohn Marino   /* Likewise for call_really_used_regs.  */
313e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
314e4b17023SJohn Marino   gcc_assert (sizeof call_really_used_regs
315e4b17023SJohn Marino 	      == sizeof saved_call_really_used_regs);
316e4b17023SJohn Marino   memcpy (saved_call_really_used_regs, call_really_used_regs,
317e4b17023SJohn Marino 	  sizeof call_really_used_regs);
318e4b17023SJohn Marino #endif
319e4b17023SJohn Marino 
320e4b17023SJohn Marino   /* And similarly for reg_names.  */
321e4b17023SJohn Marino   gcc_assert (sizeof reg_names == sizeof saved_reg_names);
322e4b17023SJohn Marino   memcpy (saved_reg_names, reg_names, sizeof reg_names);
323e4b17023SJohn Marino   COPY_HARD_REG_SET (saved_accessible_reg_set, accessible_reg_set);
324e4b17023SJohn Marino   COPY_HARD_REG_SET (saved_operand_reg_set, operand_reg_set);
325e4b17023SJohn Marino }
326e4b17023SJohn Marino 
327e4b17023SJohn Marino /* Restore the register information.  */
328e4b17023SJohn Marino static void
restore_register_info(void)329e4b17023SJohn Marino restore_register_info (void)
330e4b17023SJohn Marino {
331e4b17023SJohn Marino   memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs);
332e4b17023SJohn Marino   memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs);
333e4b17023SJohn Marino 
334e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
335e4b17023SJohn Marino   memcpy (call_really_used_regs, saved_call_really_used_regs,
336e4b17023SJohn Marino 	  sizeof call_really_used_regs);
337e4b17023SJohn Marino #endif
338e4b17023SJohn Marino 
339e4b17023SJohn Marino   memcpy (reg_names, saved_reg_names, sizeof reg_names);
340e4b17023SJohn Marino   COPY_HARD_REG_SET (accessible_reg_set, saved_accessible_reg_set);
341e4b17023SJohn Marino   COPY_HARD_REG_SET (operand_reg_set, saved_operand_reg_set);
342e4b17023SJohn Marino }
343e4b17023SJohn Marino 
344e4b17023SJohn Marino /* After switches have been processed, which perhaps alter
345e4b17023SJohn Marino    `fixed_regs' and `call_used_regs', convert them to HARD_REG_SETs.  */
346e4b17023SJohn Marino static void
init_reg_sets_1(void)347e4b17023SJohn Marino init_reg_sets_1 (void)
348e4b17023SJohn Marino {
349e4b17023SJohn Marino   unsigned int i, j;
350e4b17023SJohn Marino   unsigned int /* enum machine_mode */ m;
351e4b17023SJohn Marino 
352e4b17023SJohn Marino   restore_register_info ();
353e4b17023SJohn Marino 
354e4b17023SJohn Marino #ifdef REG_ALLOC_ORDER
355e4b17023SJohn Marino   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
356e4b17023SJohn Marino     inv_reg_alloc_order[reg_alloc_order[i]] = i;
357e4b17023SJohn Marino #endif
358e4b17023SJohn Marino 
359e4b17023SJohn Marino   /* Let the target tweak things if necessary.  */
360e4b17023SJohn Marino 
361e4b17023SJohn Marino   targetm.conditional_register_usage ();
362e4b17023SJohn Marino 
363e4b17023SJohn Marino   /* Compute number of hard regs in each class.  */
364e4b17023SJohn Marino 
365e4b17023SJohn Marino   memset (reg_class_size, 0, sizeof reg_class_size);
366e4b17023SJohn Marino   for (i = 0; i < N_REG_CLASSES; i++)
367e4b17023SJohn Marino     {
368e4b17023SJohn Marino       bool any_nonfixed = false;
369e4b17023SJohn Marino       for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
370e4b17023SJohn Marino 	if (TEST_HARD_REG_BIT (reg_class_contents[i], j))
371e4b17023SJohn Marino 	  {
372e4b17023SJohn Marino 	    reg_class_size[i]++;
373e4b17023SJohn Marino 	    if (!fixed_regs[j])
374e4b17023SJohn Marino 	      any_nonfixed = true;
375e4b17023SJohn Marino 	  }
376e4b17023SJohn Marino       class_only_fixed_regs[i] = !any_nonfixed;
377e4b17023SJohn Marino     }
378e4b17023SJohn Marino 
379e4b17023SJohn Marino   /* Initialize the table of subunions.
380e4b17023SJohn Marino      reg_class_subunion[I][J] gets the largest-numbered reg-class
381e4b17023SJohn Marino      that is contained in the union of classes I and J.  */
382e4b17023SJohn Marino 
383e4b17023SJohn Marino   memset (reg_class_subunion, 0, sizeof reg_class_subunion);
384e4b17023SJohn Marino   for (i = 0; i < N_REG_CLASSES; i++)
385e4b17023SJohn Marino     {
386e4b17023SJohn Marino       for (j = 0; j < N_REG_CLASSES; j++)
387e4b17023SJohn Marino 	{
388e4b17023SJohn Marino 	  HARD_REG_SET c;
389e4b17023SJohn Marino 	  int k;
390e4b17023SJohn Marino 
391e4b17023SJohn Marino 	  COPY_HARD_REG_SET (c, reg_class_contents[i]);
392e4b17023SJohn Marino 	  IOR_HARD_REG_SET (c, reg_class_contents[j]);
393e4b17023SJohn Marino 	  for (k = 0; k < N_REG_CLASSES; k++)
394e4b17023SJohn Marino 	    if (hard_reg_set_subset_p (reg_class_contents[k], c)
395e4b17023SJohn Marino 		&& !hard_reg_set_subset_p (reg_class_contents[k],
396e4b17023SJohn Marino 					  reg_class_contents
397e4b17023SJohn Marino 					  [(int) reg_class_subunion[i][j]]))
398e4b17023SJohn Marino 	      reg_class_subunion[i][j] = (enum reg_class) k;
399e4b17023SJohn Marino 	}
400e4b17023SJohn Marino     }
401e4b17023SJohn Marino 
402e4b17023SJohn Marino   /* Initialize the table of superunions.
403e4b17023SJohn Marino      reg_class_superunion[I][J] gets the smallest-numbered reg-class
404e4b17023SJohn Marino      containing the union of classes I and J.  */
405e4b17023SJohn Marino 
406e4b17023SJohn Marino   memset (reg_class_superunion, 0, sizeof reg_class_superunion);
407e4b17023SJohn Marino   for (i = 0; i < N_REG_CLASSES; i++)
408e4b17023SJohn Marino     {
409e4b17023SJohn Marino       for (j = 0; j < N_REG_CLASSES; j++)
410e4b17023SJohn Marino 	{
411e4b17023SJohn Marino 	  HARD_REG_SET c;
412e4b17023SJohn Marino 	  int k;
413e4b17023SJohn Marino 
414e4b17023SJohn Marino 	  COPY_HARD_REG_SET (c, reg_class_contents[i]);
415e4b17023SJohn Marino 	  IOR_HARD_REG_SET (c, reg_class_contents[j]);
416e4b17023SJohn Marino 	  for (k = 0; k < N_REG_CLASSES; k++)
417e4b17023SJohn Marino 	    if (hard_reg_set_subset_p (c, reg_class_contents[k]))
418e4b17023SJohn Marino 	      break;
419e4b17023SJohn Marino 
420e4b17023SJohn Marino 	  reg_class_superunion[i][j] = (enum reg_class) k;
421e4b17023SJohn Marino 	}
422e4b17023SJohn Marino     }
423e4b17023SJohn Marino 
424e4b17023SJohn Marino   /* Initialize the tables of subclasses and superclasses of each reg class.
425e4b17023SJohn Marino      First clear the whole table, then add the elements as they are found.  */
426e4b17023SJohn Marino 
427e4b17023SJohn Marino   for (i = 0; i < N_REG_CLASSES; i++)
428e4b17023SJohn Marino     {
429e4b17023SJohn Marino       for (j = 0; j < N_REG_CLASSES; j++)
430e4b17023SJohn Marino 	reg_class_subclasses[i][j] = LIM_REG_CLASSES;
431e4b17023SJohn Marino     }
432e4b17023SJohn Marino 
433e4b17023SJohn Marino   for (i = 0; i < N_REG_CLASSES; i++)
434e4b17023SJohn Marino     {
435e4b17023SJohn Marino       if (i == (int) NO_REGS)
436e4b17023SJohn Marino 	continue;
437e4b17023SJohn Marino 
438e4b17023SJohn Marino       for (j = i + 1; j < N_REG_CLASSES; j++)
439e4b17023SJohn Marino 	if (hard_reg_set_subset_p (reg_class_contents[i],
440e4b17023SJohn Marino 				  reg_class_contents[j]))
441e4b17023SJohn Marino 	  {
442e4b17023SJohn Marino 	    /* Reg class I is a subclass of J.
443e4b17023SJohn Marino 	       Add J to the table of superclasses of I.  */
444e4b17023SJohn Marino 	    enum reg_class *p;
445e4b17023SJohn Marino 
446e4b17023SJohn Marino 	    /* Add I to the table of superclasses of J.  */
447e4b17023SJohn Marino 	    p = &reg_class_subclasses[j][0];
448e4b17023SJohn Marino 	    while (*p != LIM_REG_CLASSES) p++;
449e4b17023SJohn Marino 	    *p = (enum reg_class) i;
450e4b17023SJohn Marino 	  }
451e4b17023SJohn Marino     }
452e4b17023SJohn Marino 
453e4b17023SJohn Marino   /* Initialize "constant" tables.  */
454e4b17023SJohn Marino 
455e4b17023SJohn Marino   CLEAR_HARD_REG_SET (fixed_reg_set);
456e4b17023SJohn Marino   CLEAR_HARD_REG_SET (call_used_reg_set);
457e4b17023SJohn Marino   CLEAR_HARD_REG_SET (call_fixed_reg_set);
458e4b17023SJohn Marino   CLEAR_HARD_REG_SET (regs_invalidated_by_call);
459e4b17023SJohn Marino   if (!regs_invalidated_by_call_regset)
460e4b17023SJohn Marino     {
461e4b17023SJohn Marino       bitmap_obstack_initialize (&persistent_obstack);
462e4b17023SJohn Marino       regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack);
463e4b17023SJohn Marino     }
464e4b17023SJohn Marino   else
465e4b17023SJohn Marino     CLEAR_REG_SET (regs_invalidated_by_call_regset);
466e4b17023SJohn Marino   if (!fixed_reg_set_regset)
467e4b17023SJohn Marino     fixed_reg_set_regset = ALLOC_REG_SET (&persistent_obstack);
468e4b17023SJohn Marino   else
469e4b17023SJohn Marino     CLEAR_REG_SET (fixed_reg_set_regset);
470e4b17023SJohn Marino 
471e4b17023SJohn Marino   AND_HARD_REG_SET (operand_reg_set, accessible_reg_set);
472e4b17023SJohn Marino   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
473e4b17023SJohn Marino     {
474e4b17023SJohn Marino       /* As a special exception, registers whose class is NO_REGS are
475e4b17023SJohn Marino 	 not accepted by `register_operand'.  The reason for this change
476e4b17023SJohn Marino 	 is to allow the representation of special architecture artifacts
477e4b17023SJohn Marino 	 (such as a condition code register) without extending the rtl
478e4b17023SJohn Marino 	 definitions.  Since registers of class NO_REGS cannot be used
479e4b17023SJohn Marino 	 as registers in any case where register classes are examined,
480e4b17023SJohn Marino 	 it is better to apply this exception in a target-independent way.  */
481e4b17023SJohn Marino       if (REGNO_REG_CLASS (i) == NO_REGS)
482e4b17023SJohn Marino 	CLEAR_HARD_REG_BIT (operand_reg_set, i);
483e4b17023SJohn Marino 
484e4b17023SJohn Marino       /* If a register is too limited to be treated as a register operand,
485e4b17023SJohn Marino 	 then it should never be allocated to a pseudo.  */
486e4b17023SJohn Marino       if (!TEST_HARD_REG_BIT (operand_reg_set, i))
487e4b17023SJohn Marino 	{
488e4b17023SJohn Marino 	  fixed_regs[i] = 1;
489e4b17023SJohn Marino 	  call_used_regs[i] = 1;
490e4b17023SJohn Marino 	}
491e4b17023SJohn Marino 
492e4b17023SJohn Marino       /* call_used_regs must include fixed_regs.  */
493e4b17023SJohn Marino       gcc_assert (!fixed_regs[i] || call_used_regs[i]);
494e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
495e4b17023SJohn Marino       /* call_used_regs must include call_really_used_regs.  */
496e4b17023SJohn Marino       gcc_assert (!call_really_used_regs[i] || call_used_regs[i]);
497e4b17023SJohn Marino #endif
498e4b17023SJohn Marino 
499e4b17023SJohn Marino       if (fixed_regs[i])
500e4b17023SJohn Marino 	{
501e4b17023SJohn Marino 	  SET_HARD_REG_BIT (fixed_reg_set, i);
502e4b17023SJohn Marino 	  SET_REGNO_REG_SET (fixed_reg_set_regset, i);
503e4b17023SJohn Marino 	}
504e4b17023SJohn Marino 
505e4b17023SJohn Marino       if (call_used_regs[i])
506e4b17023SJohn Marino 	SET_HARD_REG_BIT (call_used_reg_set, i);
507e4b17023SJohn Marino 
508e4b17023SJohn Marino       /* There are a couple of fixed registers that we know are safe to
509e4b17023SJohn Marino 	 exclude from being clobbered by calls:
510e4b17023SJohn Marino 
511e4b17023SJohn Marino 	 The frame pointer is always preserved across calls.  The arg
512e4b17023SJohn Marino 	 pointer is if it is fixed.  The stack pointer usually is,
513e4b17023SJohn Marino 	 unless TARGET_RETURN_POPS_ARGS, in which case an explicit
514e4b17023SJohn Marino 	 CLOBBER will be present.  If we are generating PIC code, the
515e4b17023SJohn Marino 	 PIC offset table register is preserved across calls, though the
516e4b17023SJohn Marino 	 target can override that.  */
517e4b17023SJohn Marino 
518e4b17023SJohn Marino       if (i == STACK_POINTER_REGNUM)
519e4b17023SJohn Marino 	;
520e4b17023SJohn Marino       else if (global_regs[i])
521e4b17023SJohn Marino         {
522e4b17023SJohn Marino 	  SET_HARD_REG_BIT (regs_invalidated_by_call, i);
523e4b17023SJohn Marino 	  SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);
524e4b17023SJohn Marino 	}
525e4b17023SJohn Marino       else if (i == FRAME_POINTER_REGNUM)
526e4b17023SJohn Marino 	;
527e4b17023SJohn Marino #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
528e4b17023SJohn Marino       else if (i == HARD_FRAME_POINTER_REGNUM)
529e4b17023SJohn Marino 	;
530e4b17023SJohn Marino #endif
531e4b17023SJohn Marino #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
532e4b17023SJohn Marino       else if (i == ARG_POINTER_REGNUM && fixed_regs[i])
533e4b17023SJohn Marino 	;
534e4b17023SJohn Marino #endif
535e4b17023SJohn Marino       else if (!PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
536e4b17023SJohn Marino 	       && i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
537e4b17023SJohn Marino 	;
538e4b17023SJohn Marino       else if (CALL_REALLY_USED_REGNO_P (i))
539e4b17023SJohn Marino         {
540e4b17023SJohn Marino 	  SET_HARD_REG_BIT (regs_invalidated_by_call, i);
541e4b17023SJohn Marino 	  SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);
542e4b17023SJohn Marino         }
543e4b17023SJohn Marino     }
544e4b17023SJohn Marino 
545e4b17023SJohn Marino   COPY_HARD_REG_SET(call_fixed_reg_set, fixed_reg_set);
546e4b17023SJohn Marino 
547e4b17023SJohn Marino   /* Preserve global registers if called more than once.  */
548e4b17023SJohn Marino   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
549e4b17023SJohn Marino     {
550e4b17023SJohn Marino       if (global_regs[i])
551e4b17023SJohn Marino 	{
552e4b17023SJohn Marino 	  fixed_regs[i] = call_used_regs[i] = 1;
553e4b17023SJohn Marino 	  SET_HARD_REG_BIT (fixed_reg_set, i);
554e4b17023SJohn Marino 	  SET_HARD_REG_BIT (call_used_reg_set, i);
555e4b17023SJohn Marino 	  SET_HARD_REG_BIT (call_fixed_reg_set, i);
556e4b17023SJohn Marino 	}
557e4b17023SJohn Marino     }
558e4b17023SJohn Marino 
559e4b17023SJohn Marino   memset (have_regs_of_mode, 0, sizeof (have_regs_of_mode));
560e4b17023SJohn Marino   memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode));
561e4b17023SJohn Marino   for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++)
562e4b17023SJohn Marino     {
563e4b17023SJohn Marino       HARD_REG_SET ok_regs;
564e4b17023SJohn Marino       CLEAR_HARD_REG_SET (ok_regs);
565e4b17023SJohn Marino       for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
566e4b17023SJohn Marino 	if (!fixed_regs [j] && HARD_REGNO_MODE_OK (j, (enum machine_mode) m))
567e4b17023SJohn Marino 	  SET_HARD_REG_BIT (ok_regs, j);
568e4b17023SJohn Marino 
569e4b17023SJohn Marino       for (i = 0; i < N_REG_CLASSES; i++)
570e4b17023SJohn Marino 	if ((targetm.class_max_nregs ((reg_class_t) i, (enum machine_mode) m)
571e4b17023SJohn Marino 	     <= reg_class_size[i])
572e4b17023SJohn Marino 	    && hard_reg_set_intersect_p (ok_regs, reg_class_contents[i]))
573e4b17023SJohn Marino 	  {
574e4b17023SJohn Marino 	     contains_reg_of_mode [i][m] = 1;
575e4b17023SJohn Marino 	     have_regs_of_mode [m] = 1;
576e4b17023SJohn Marino 	  }
577e4b17023SJohn Marino      }
578e4b17023SJohn Marino 
579e4b17023SJohn Marino   /* Reset move_cost and friends, making sure we only free shared
580e4b17023SJohn Marino      table entries once.  */
581e4b17023SJohn Marino   for (i = 0; i < MAX_MACHINE_MODE; i++)
582e4b17023SJohn Marino     if (move_cost[i])
583e4b17023SJohn Marino       {
584e4b17023SJohn Marino 	for (j = 0; j < i && move_cost[i] != move_cost[j]; j++)
585e4b17023SJohn Marino 	  ;
586e4b17023SJohn Marino 	if (i == j)
587e4b17023SJohn Marino 	  {
588e4b17023SJohn Marino 	    free (move_cost[i]);
589e4b17023SJohn Marino 	    free (may_move_in_cost[i]);
590e4b17023SJohn Marino 	    free (may_move_out_cost[i]);
591e4b17023SJohn Marino 	  }
592e4b17023SJohn Marino       }
593e4b17023SJohn Marino   memset (move_cost, 0, sizeof move_cost);
594e4b17023SJohn Marino   memset (may_move_in_cost, 0, sizeof may_move_in_cost);
595e4b17023SJohn Marino   memset (may_move_out_cost, 0, sizeof may_move_out_cost);
596e4b17023SJohn Marino   last_mode_for_init_move_cost = -1;
597e4b17023SJohn Marino }
598e4b17023SJohn Marino 
599e4b17023SJohn Marino /* Compute the table of register modes.
600e4b17023SJohn Marino    These values are used to record death information for individual registers
601e4b17023SJohn Marino    (as opposed to a multi-register mode).
602e4b17023SJohn Marino    This function might be invoked more than once, if the target has support
603e4b17023SJohn Marino    for changing register usage conventions on a per-function basis.
604e4b17023SJohn Marino */
605e4b17023SJohn Marino void
init_reg_modes_target(void)606e4b17023SJohn Marino init_reg_modes_target (void)
607e4b17023SJohn Marino {
608e4b17023SJohn Marino   int i, j;
609e4b17023SJohn Marino 
610e4b17023SJohn Marino   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
611e4b17023SJohn Marino     for (j = 0; j < MAX_MACHINE_MODE; j++)
612e4b17023SJohn Marino       hard_regno_nregs[i][j] = HARD_REGNO_NREGS(i, (enum machine_mode)j);
613e4b17023SJohn Marino 
614e4b17023SJohn Marino   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
615e4b17023SJohn Marino     {
616e4b17023SJohn Marino       reg_raw_mode[i] = choose_hard_reg_mode (i, 1, false);
617e4b17023SJohn Marino 
618e4b17023SJohn Marino       /* If we couldn't find a valid mode, just use the previous mode
619e4b17023SJohn Marino 	 if it is suitable, otherwise fall back on word_mode.  */
620e4b17023SJohn Marino       if (reg_raw_mode[i] == VOIDmode)
621e4b17023SJohn Marino     	{
622e4b17023SJohn Marino 	  if (i > 0 && hard_regno_nregs[i][reg_raw_mode[i - 1]] == 1)
623e4b17023SJohn Marino 	    reg_raw_mode[i] = reg_raw_mode[i - 1];
624e4b17023SJohn Marino 	  else
625e4b17023SJohn Marino 	    reg_raw_mode[i] = word_mode;
626e4b17023SJohn Marino 	}
627e4b17023SJohn Marino     }
628e4b17023SJohn Marino }
629e4b17023SJohn Marino 
630e4b17023SJohn Marino /* Finish initializing the register sets and initialize the register modes.
631e4b17023SJohn Marino    This function might be invoked more than once, if the target has support
632e4b17023SJohn Marino    for changing register usage conventions on a per-function basis.
633e4b17023SJohn Marino */
634e4b17023SJohn Marino void
init_regs(void)635e4b17023SJohn Marino init_regs (void)
636e4b17023SJohn Marino {
637e4b17023SJohn Marino   /* This finishes what was started by init_reg_sets, but couldn't be done
638e4b17023SJohn Marino      until after register usage was specified.  */
639e4b17023SJohn Marino   init_reg_sets_1 ();
640e4b17023SJohn Marino }
641e4b17023SJohn Marino 
642e4b17023SJohn Marino /* The same as previous function plus initializing IRA.  */
643e4b17023SJohn Marino void
reinit_regs(void)644e4b17023SJohn Marino reinit_regs (void)
645e4b17023SJohn Marino {
646e4b17023SJohn Marino   init_regs ();
647e4b17023SJohn Marino   /* caller_save needs to be re-initialized.  */
648e4b17023SJohn Marino   caller_save_initialized_p = false;
649e4b17023SJohn Marino   ira_init ();
650e4b17023SJohn Marino }
651e4b17023SJohn Marino 
652e4b17023SJohn Marino /* Initialize some fake stack-frame MEM references for use in
653e4b17023SJohn Marino    memory_move_secondary_cost.  */
654e4b17023SJohn Marino void
init_fake_stack_mems(void)655e4b17023SJohn Marino init_fake_stack_mems (void)
656e4b17023SJohn Marino {
657e4b17023SJohn Marino   int i;
658e4b17023SJohn Marino 
659e4b17023SJohn Marino   for (i = 0; i < MAX_MACHINE_MODE; i++)
660e4b17023SJohn Marino     top_of_stack[i] = gen_rtx_MEM ((enum machine_mode) i, stack_pointer_rtx);
661e4b17023SJohn Marino }
662e4b17023SJohn Marino 
663e4b17023SJohn Marino 
664e4b17023SJohn Marino /* Compute cost of moving data from a register of class FROM to one of
665e4b17023SJohn Marino    TO, using MODE.  */
666e4b17023SJohn Marino 
667e4b17023SJohn Marino int
register_move_cost(enum machine_mode mode,reg_class_t from,reg_class_t to)668e4b17023SJohn Marino register_move_cost (enum machine_mode mode, reg_class_t from, reg_class_t to)
669e4b17023SJohn Marino {
670e4b17023SJohn Marino   return targetm.register_move_cost (mode, from, to);
671e4b17023SJohn Marino }
672e4b17023SJohn Marino 
673e4b17023SJohn Marino /* Compute cost of moving registers to/from memory.  */
674e4b17023SJohn Marino 
675e4b17023SJohn Marino int
memory_move_cost(enum machine_mode mode,reg_class_t rclass,bool in)676e4b17023SJohn Marino memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in)
677e4b17023SJohn Marino {
678e4b17023SJohn Marino   return targetm.memory_move_cost (mode, rclass, in);
679e4b17023SJohn Marino }
680e4b17023SJohn Marino 
681e4b17023SJohn Marino /* Compute extra cost of moving registers to/from memory due to reloads.
682e4b17023SJohn Marino    Only needed if secondary reloads are required for memory moves.  */
683e4b17023SJohn Marino int
memory_move_secondary_cost(enum machine_mode mode,reg_class_t rclass,bool in)684e4b17023SJohn Marino memory_move_secondary_cost (enum machine_mode mode, reg_class_t rclass,
685e4b17023SJohn Marino 			    bool in)
686e4b17023SJohn Marino {
687e4b17023SJohn Marino   reg_class_t altclass;
688e4b17023SJohn Marino   int partial_cost = 0;
689e4b17023SJohn Marino   /* We need a memory reference to feed to SECONDARY... macros.  */
690e4b17023SJohn Marino   /* mem may be unused even if the SECONDARY_ macros are defined.  */
691e4b17023SJohn Marino   rtx mem ATTRIBUTE_UNUSED = top_of_stack[(int) mode];
692e4b17023SJohn Marino 
693e4b17023SJohn Marino   altclass = secondary_reload_class (in ? 1 : 0, rclass, mode, mem);
694e4b17023SJohn Marino 
695e4b17023SJohn Marino   if (altclass == NO_REGS)
696e4b17023SJohn Marino     return 0;
697e4b17023SJohn Marino 
698e4b17023SJohn Marino   if (in)
699e4b17023SJohn Marino     partial_cost = register_move_cost (mode, altclass, rclass);
700e4b17023SJohn Marino   else
701e4b17023SJohn Marino     partial_cost = register_move_cost (mode, rclass, altclass);
702e4b17023SJohn Marino 
703e4b17023SJohn Marino   if (rclass == altclass)
704e4b17023SJohn Marino     /* This isn't simply a copy-to-temporary situation.  Can't guess
705e4b17023SJohn Marino        what it is, so TARGET_MEMORY_MOVE_COST really ought not to be
706e4b17023SJohn Marino        calling here in that case.
707e4b17023SJohn Marino 
708e4b17023SJohn Marino        I'm tempted to put in an assert here, but returning this will
709e4b17023SJohn Marino        probably only give poor estimates, which is what we would've
710e4b17023SJohn Marino        had before this code anyways.  */
711e4b17023SJohn Marino     return partial_cost;
712e4b17023SJohn Marino 
713e4b17023SJohn Marino   /* Check if the secondary reload register will also need a
714e4b17023SJohn Marino      secondary reload.  */
715e4b17023SJohn Marino   return memory_move_secondary_cost (mode, altclass, in) + partial_cost;
716e4b17023SJohn Marino }
717e4b17023SJohn Marino 
718e4b17023SJohn Marino /* Return a machine mode that is legitimate for hard reg REGNO and large
719e4b17023SJohn Marino    enough to save nregs.  If we can't find one, return VOIDmode.
720e4b17023SJohn Marino    If CALL_SAVED is true, only consider modes that are call saved.  */
721e4b17023SJohn Marino enum machine_mode
choose_hard_reg_mode(unsigned int regno ATTRIBUTE_UNUSED,unsigned int nregs,bool call_saved)722e4b17023SJohn Marino choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
723e4b17023SJohn Marino 		      unsigned int nregs, bool call_saved)
724e4b17023SJohn Marino {
725e4b17023SJohn Marino   unsigned int /* enum machine_mode */ m;
726e4b17023SJohn Marino   enum machine_mode found_mode = VOIDmode, mode;
727e4b17023SJohn Marino 
728e4b17023SJohn Marino   /* We first look for the largest integer mode that can be validly
729e4b17023SJohn Marino      held in REGNO.  If none, we look for the largest floating-point mode.
730e4b17023SJohn Marino      If we still didn't find a valid mode, try CCmode.  */
731e4b17023SJohn Marino 
732e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
733e4b17023SJohn Marino        mode != VOIDmode;
734e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
735e4b17023SJohn Marino     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
736e4b17023SJohn Marino 	&& HARD_REGNO_MODE_OK (regno, mode)
737e4b17023SJohn Marino 	&& (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
738e4b17023SJohn Marino       found_mode = mode;
739e4b17023SJohn Marino 
740e4b17023SJohn Marino   if (found_mode != VOIDmode)
741e4b17023SJohn Marino     return found_mode;
742e4b17023SJohn Marino 
743e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
744e4b17023SJohn Marino        mode != VOIDmode;
745e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
746e4b17023SJohn Marino     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
747e4b17023SJohn Marino 	&& HARD_REGNO_MODE_OK (regno, mode)
748e4b17023SJohn Marino 	&& (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
749e4b17023SJohn Marino       found_mode = mode;
750e4b17023SJohn Marino 
751e4b17023SJohn Marino   if (found_mode != VOIDmode)
752e4b17023SJohn Marino     return found_mode;
753e4b17023SJohn Marino 
754e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
755e4b17023SJohn Marino        mode != VOIDmode;
756e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
757e4b17023SJohn Marino     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
758e4b17023SJohn Marino 	&& HARD_REGNO_MODE_OK (regno, mode)
759e4b17023SJohn Marino 	&& (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
760e4b17023SJohn Marino       found_mode = mode;
761e4b17023SJohn Marino 
762e4b17023SJohn Marino   if (found_mode != VOIDmode)
763e4b17023SJohn Marino     return found_mode;
764e4b17023SJohn Marino 
765e4b17023SJohn Marino   for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
766e4b17023SJohn Marino        mode != VOIDmode;
767e4b17023SJohn Marino        mode = GET_MODE_WIDER_MODE (mode))
768e4b17023SJohn Marino     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
769e4b17023SJohn Marino 	&& HARD_REGNO_MODE_OK (regno, mode)
770e4b17023SJohn Marino 	&& (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
771e4b17023SJohn Marino       found_mode = mode;
772e4b17023SJohn Marino 
773e4b17023SJohn Marino   if (found_mode != VOIDmode)
774e4b17023SJohn Marino     return found_mode;
775e4b17023SJohn Marino 
776e4b17023SJohn Marino   /* Iterate over all of the CCmodes.  */
777e4b17023SJohn Marino   for (m = (unsigned int) CCmode; m < (unsigned int) NUM_MACHINE_MODES; ++m)
778e4b17023SJohn Marino     {
779e4b17023SJohn Marino       mode = (enum machine_mode) m;
780e4b17023SJohn Marino       if ((unsigned) hard_regno_nregs[regno][mode] == nregs
781e4b17023SJohn Marino 	  && HARD_REGNO_MODE_OK (regno, mode)
782e4b17023SJohn Marino 	  && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
783e4b17023SJohn Marino 	return mode;
784e4b17023SJohn Marino     }
785e4b17023SJohn Marino 
786e4b17023SJohn Marino   /* We can't find a mode valid for this register.  */
787e4b17023SJohn Marino   return VOIDmode;
788e4b17023SJohn Marino }
789e4b17023SJohn Marino 
790e4b17023SJohn Marino /* Specify the usage characteristics of the register named NAME.
791e4b17023SJohn Marino    It should be a fixed register if FIXED and a
792e4b17023SJohn Marino    call-used register if CALL_USED.  */
793e4b17023SJohn Marino void
fix_register(const char * name,int fixed,int call_used)794e4b17023SJohn Marino fix_register (const char *name, int fixed, int call_used)
795e4b17023SJohn Marino {
796e4b17023SJohn Marino   int i;
797e4b17023SJohn Marino   int reg, nregs;
798e4b17023SJohn Marino 
799e4b17023SJohn Marino   /* Decode the name and update the primary form of
800e4b17023SJohn Marino      the register info.  */
801e4b17023SJohn Marino 
802e4b17023SJohn Marino   if ((reg = decode_reg_name_and_count (name, &nregs)) >= 0)
803e4b17023SJohn Marino     {
804e4b17023SJohn Marino       gcc_assert (nregs >= 1);
805e4b17023SJohn Marino       for (i = reg; i < reg + nregs; i++)
806e4b17023SJohn Marino 	{
807e4b17023SJohn Marino 	  if ((i == STACK_POINTER_REGNUM
808e4b17023SJohn Marino #ifdef HARD_FRAME_POINTER_REGNUM
809e4b17023SJohn Marino 	       || i == HARD_FRAME_POINTER_REGNUM
810e4b17023SJohn Marino #else
811e4b17023SJohn Marino 	       || i == FRAME_POINTER_REGNUM
812e4b17023SJohn Marino #endif
813e4b17023SJohn Marino 	       )
814e4b17023SJohn Marino 	      && (fixed == 0 || call_used == 0))
815e4b17023SJohn Marino 	    {
816e4b17023SJohn Marino 	      switch (fixed)
817e4b17023SJohn Marino 		{
818e4b17023SJohn Marino 		case 0:
819e4b17023SJohn Marino 		  switch (call_used)
820e4b17023SJohn Marino 		    {
821e4b17023SJohn Marino 		    case 0:
822e4b17023SJohn Marino 		      error ("can%'t use %qs as a call-saved register", name);
823e4b17023SJohn Marino 		      break;
824e4b17023SJohn Marino 
825e4b17023SJohn Marino 		    case 1:
826e4b17023SJohn Marino 		      error ("can%'t use %qs as a call-used register", name);
827e4b17023SJohn Marino 		      break;
828e4b17023SJohn Marino 
829e4b17023SJohn Marino 		    default:
830e4b17023SJohn Marino 		      gcc_unreachable ();
831e4b17023SJohn Marino 		    }
832e4b17023SJohn Marino 		  break;
833e4b17023SJohn Marino 
834e4b17023SJohn Marino 		case 1:
835e4b17023SJohn Marino 		  switch (call_used)
836e4b17023SJohn Marino 		    {
837e4b17023SJohn Marino 		    case 1:
838e4b17023SJohn Marino 		      error ("can%'t use %qs as a fixed register", name);
839e4b17023SJohn Marino 		      break;
840e4b17023SJohn Marino 
841e4b17023SJohn Marino 		    case 0:
842e4b17023SJohn Marino 		    default:
843e4b17023SJohn Marino 		      gcc_unreachable ();
844e4b17023SJohn Marino 		    }
845e4b17023SJohn Marino 		  break;
846e4b17023SJohn Marino 
847e4b17023SJohn Marino 		default:
848e4b17023SJohn Marino 		  gcc_unreachable ();
849e4b17023SJohn Marino 		}
850e4b17023SJohn Marino 	    }
851e4b17023SJohn Marino 	  else
852e4b17023SJohn Marino 	    {
853e4b17023SJohn Marino 	      fixed_regs[i] = fixed;
854e4b17023SJohn Marino 	      call_used_regs[i] = call_used;
855e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
856e4b17023SJohn Marino 	      if (fixed == 0)
857e4b17023SJohn Marino 		call_really_used_regs[i] = call_used;
858e4b17023SJohn Marino #endif
859e4b17023SJohn Marino 	    }
860e4b17023SJohn Marino 	}
861e4b17023SJohn Marino     }
862e4b17023SJohn Marino   else
863e4b17023SJohn Marino     {
864e4b17023SJohn Marino       warning (0, "unknown register name: %s", name);
865e4b17023SJohn Marino     }
866e4b17023SJohn Marino }
867e4b17023SJohn Marino 
868e4b17023SJohn Marino /* Mark register number I as global.  */
869e4b17023SJohn Marino void
globalize_reg(tree decl,int i)870e4b17023SJohn Marino globalize_reg (tree decl, int i)
871e4b17023SJohn Marino {
872e4b17023SJohn Marino   location_t loc = DECL_SOURCE_LOCATION (decl);
873e4b17023SJohn Marino 
874e4b17023SJohn Marino #ifdef STACK_REGS
875e4b17023SJohn Marino   if (IN_RANGE (i, FIRST_STACK_REG, LAST_STACK_REG))
876e4b17023SJohn Marino     {
877e4b17023SJohn Marino       error ("stack register used for global register variable");
878e4b17023SJohn Marino       return;
879e4b17023SJohn Marino     }
880e4b17023SJohn Marino #endif
881e4b17023SJohn Marino 
882e4b17023SJohn Marino   if (fixed_regs[i] == 0 && no_global_reg_vars)
883e4b17023SJohn Marino     error_at (loc, "global register variable follows a function definition");
884e4b17023SJohn Marino 
885e4b17023SJohn Marino   if (global_regs[i])
886e4b17023SJohn Marino     {
887e4b17023SJohn Marino       warning_at (loc, 0,
888e4b17023SJohn Marino 		  "register of %qD used for multiple global register variables",
889e4b17023SJohn Marino 		  decl);
890e4b17023SJohn Marino       inform (DECL_SOURCE_LOCATION (global_regs_decl[i]),
891e4b17023SJohn Marino 	      "conflicts with %qD", global_regs_decl[i]);
892e4b17023SJohn Marino       return;
893e4b17023SJohn Marino     }
894e4b17023SJohn Marino 
895e4b17023SJohn Marino   if (call_used_regs[i] && ! fixed_regs[i])
896e4b17023SJohn Marino     warning_at (loc, 0, "call-clobbered register used for global register variable");
897e4b17023SJohn Marino 
898e4b17023SJohn Marino   global_regs[i] = 1;
899e4b17023SJohn Marino   global_regs_decl[i] = decl;
900e4b17023SJohn Marino 
901e4b17023SJohn Marino   /* If we're globalizing the frame pointer, we need to set the
902e4b17023SJohn Marino      appropriate regs_invalidated_by_call bit, even if it's already
903e4b17023SJohn Marino      set in fixed_regs.  */
904e4b17023SJohn Marino   if (i != STACK_POINTER_REGNUM)
905e4b17023SJohn Marino     {
906e4b17023SJohn Marino       SET_HARD_REG_BIT (regs_invalidated_by_call, i);
907e4b17023SJohn Marino       SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);
908e4b17023SJohn Marino     }
909e4b17023SJohn Marino 
910e4b17023SJohn Marino   /* If already fixed, nothing else to do.  */
911e4b17023SJohn Marino   if (fixed_regs[i])
912e4b17023SJohn Marino     return;
913e4b17023SJohn Marino 
914e4b17023SJohn Marino   fixed_regs[i] = call_used_regs[i] = 1;
915e4b17023SJohn Marino #ifdef CALL_REALLY_USED_REGISTERS
916e4b17023SJohn Marino   call_really_used_regs[i] = 1;
917e4b17023SJohn Marino #endif
918e4b17023SJohn Marino 
919e4b17023SJohn Marino   SET_HARD_REG_BIT (fixed_reg_set, i);
920e4b17023SJohn Marino   SET_HARD_REG_BIT (call_used_reg_set, i);
921e4b17023SJohn Marino   SET_HARD_REG_BIT (call_fixed_reg_set, i);
922e4b17023SJohn Marino 
923e4b17023SJohn Marino   reinit_regs ();
924e4b17023SJohn Marino }
925e4b17023SJohn Marino 
926e4b17023SJohn Marino 
927e4b17023SJohn Marino /* Structure used to record preferences of given pseudo.  */
928e4b17023SJohn Marino struct reg_pref
929e4b17023SJohn Marino {
930e4b17023SJohn Marino   /* (enum reg_class) prefclass is the preferred class.  May be
931e4b17023SJohn Marino      NO_REGS if no class is better than memory.  */
932e4b17023SJohn Marino   char prefclass;
933e4b17023SJohn Marino 
934e4b17023SJohn Marino   /* altclass is a register class that we should use for allocating
935e4b17023SJohn Marino      pseudo if no register in the preferred class is available.
936e4b17023SJohn Marino      If no register in this class is available, memory is preferred.
937e4b17023SJohn Marino 
938e4b17023SJohn Marino      It might appear to be more general to have a bitmask of classes here,
939e4b17023SJohn Marino      but since it is recommended that there be a class corresponding to the
940e4b17023SJohn Marino      union of most major pair of classes, that generality is not required.  */
941e4b17023SJohn Marino   char altclass;
942e4b17023SJohn Marino 
943e4b17023SJohn Marino   /* allocnoclass is a register class that IRA uses for allocating
944e4b17023SJohn Marino      the pseudo.  */
945e4b17023SJohn Marino   char allocnoclass;
946e4b17023SJohn Marino };
947e4b17023SJohn Marino 
948e4b17023SJohn Marino /* Record preferences of each pseudo.  This is available after RA is
949e4b17023SJohn Marino    run.  */
950e4b17023SJohn Marino static struct reg_pref *reg_pref;
951e4b17023SJohn Marino 
952e4b17023SJohn Marino /* Current size of reg_info.  */
953e4b17023SJohn Marino static int reg_info_size;
954e4b17023SJohn Marino 
955e4b17023SJohn Marino /* Return the reg_class in which pseudo reg number REGNO is best allocated.
956e4b17023SJohn Marino    This function is sometimes called before the info has been computed.
957e4b17023SJohn Marino    When that happens, just return GENERAL_REGS, which is innocuous.  */
958e4b17023SJohn Marino enum reg_class
reg_preferred_class(int regno)959e4b17023SJohn Marino reg_preferred_class (int regno)
960e4b17023SJohn Marino {
961e4b17023SJohn Marino   if (reg_pref == 0)
962e4b17023SJohn Marino     return GENERAL_REGS;
963e4b17023SJohn Marino 
964e4b17023SJohn Marino   return (enum reg_class) reg_pref[regno].prefclass;
965e4b17023SJohn Marino }
966e4b17023SJohn Marino 
967e4b17023SJohn Marino enum reg_class
reg_alternate_class(int regno)968e4b17023SJohn Marino reg_alternate_class (int regno)
969e4b17023SJohn Marino {
970e4b17023SJohn Marino   if (reg_pref == 0)
971e4b17023SJohn Marino     return ALL_REGS;
972e4b17023SJohn Marino 
973e4b17023SJohn Marino   return (enum reg_class) reg_pref[regno].altclass;
974e4b17023SJohn Marino }
975e4b17023SJohn Marino 
976e4b17023SJohn Marino /* Return the reg_class which is used by IRA for its allocation.  */
977e4b17023SJohn Marino enum reg_class
reg_allocno_class(int regno)978e4b17023SJohn Marino reg_allocno_class (int regno)
979e4b17023SJohn Marino {
980e4b17023SJohn Marino   if (reg_pref == 0)
981e4b17023SJohn Marino     return NO_REGS;
982e4b17023SJohn Marino 
983e4b17023SJohn Marino   return (enum reg_class) reg_pref[regno].allocnoclass;
984e4b17023SJohn Marino }
985e4b17023SJohn Marino 
986e4b17023SJohn Marino 
987e4b17023SJohn Marino 
988e4b17023SJohn Marino /* Allocate space for reg info.  */
989e4b17023SJohn Marino static void
allocate_reg_info(void)990e4b17023SJohn Marino allocate_reg_info (void)
991e4b17023SJohn Marino {
992e4b17023SJohn Marino   reg_info_size = max_reg_num ();
993e4b17023SJohn Marino   gcc_assert (! reg_pref && ! reg_renumber);
994e4b17023SJohn Marino   reg_renumber = XNEWVEC (short, reg_info_size);
995e4b17023SJohn Marino   reg_pref = XCNEWVEC (struct reg_pref, reg_info_size);
996e4b17023SJohn Marino   memset (reg_renumber, -1, reg_info_size * sizeof (short));
997e4b17023SJohn Marino }
998e4b17023SJohn Marino 
999e4b17023SJohn Marino 
1000e4b17023SJohn Marino /* Resize reg info. The new elements will be uninitialized.  Return
1001e4b17023SJohn Marino    TRUE if new elements (for new pseudos) were added.  */
1002e4b17023SJohn Marino bool
resize_reg_info(void)1003e4b17023SJohn Marino resize_reg_info (void)
1004e4b17023SJohn Marino {
1005e4b17023SJohn Marino   int old;
1006e4b17023SJohn Marino 
1007e4b17023SJohn Marino   if (reg_pref == NULL)
1008e4b17023SJohn Marino     {
1009e4b17023SJohn Marino       allocate_reg_info ();
1010e4b17023SJohn Marino       return true;
1011e4b17023SJohn Marino     }
1012e4b17023SJohn Marino   if (reg_info_size == max_reg_num ())
1013e4b17023SJohn Marino     return false;
1014e4b17023SJohn Marino   old = reg_info_size;
1015e4b17023SJohn Marino   reg_info_size = max_reg_num ();
1016e4b17023SJohn Marino   gcc_assert (reg_pref && reg_renumber);
1017e4b17023SJohn Marino   reg_renumber = XRESIZEVEC (short, reg_renumber, reg_info_size);
1018e4b17023SJohn Marino   reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, reg_info_size);
1019e4b17023SJohn Marino   memset (reg_pref + old, -1,
1020e4b17023SJohn Marino 	  (reg_info_size - old) * sizeof (struct reg_pref));
1021e4b17023SJohn Marino   memset (reg_renumber + old, -1, (reg_info_size - old) * sizeof (short));
1022e4b17023SJohn Marino   return true;
1023e4b17023SJohn Marino }
1024e4b17023SJohn Marino 
1025e4b17023SJohn Marino 
1026e4b17023SJohn Marino /* Free up the space allocated by allocate_reg_info.  */
1027e4b17023SJohn Marino void
free_reg_info(void)1028e4b17023SJohn Marino free_reg_info (void)
1029e4b17023SJohn Marino {
1030e4b17023SJohn Marino   if (reg_pref)
1031e4b17023SJohn Marino     {
1032e4b17023SJohn Marino       free (reg_pref);
1033e4b17023SJohn Marino       reg_pref = NULL;
1034e4b17023SJohn Marino     }
1035e4b17023SJohn Marino 
1036e4b17023SJohn Marino   if (reg_renumber)
1037e4b17023SJohn Marino     {
1038e4b17023SJohn Marino       free (reg_renumber);
1039e4b17023SJohn Marino       reg_renumber = NULL;
1040e4b17023SJohn Marino     }
1041e4b17023SJohn Marino }
1042e4b17023SJohn Marino 
1043e4b17023SJohn Marino /* Initialize some global data for this pass.  */
1044e4b17023SJohn Marino static unsigned int
reginfo_init(void)1045e4b17023SJohn Marino reginfo_init (void)
1046e4b17023SJohn Marino {
1047e4b17023SJohn Marino   if (df)
1048e4b17023SJohn Marino     df_compute_regs_ever_live (true);
1049e4b17023SJohn Marino 
1050e4b17023SJohn Marino   /* This prevents dump_flow_info from losing if called
1051e4b17023SJohn Marino      before reginfo is run.  */
1052e4b17023SJohn Marino   reg_pref = NULL;
1053e4b17023SJohn Marino   /* No more global register variables may be declared.  */
1054e4b17023SJohn Marino   no_global_reg_vars = 1;
1055e4b17023SJohn Marino   return 1;
1056e4b17023SJohn Marino }
1057e4b17023SJohn Marino 
1058e4b17023SJohn Marino struct rtl_opt_pass pass_reginfo_init =
1059e4b17023SJohn Marino {
1060e4b17023SJohn Marino  {
1061e4b17023SJohn Marino   RTL_PASS,
1062e4b17023SJohn Marino   "reginfo",                            /* name */
1063e4b17023SJohn Marino   NULL,                                 /* gate */
1064e4b17023SJohn Marino   reginfo_init,                         /* execute */
1065e4b17023SJohn Marino   NULL,                                 /* sub */
1066e4b17023SJohn Marino   NULL,                                 /* next */
1067e4b17023SJohn Marino   0,                                    /* static_pass_number */
1068e4b17023SJohn Marino   TV_NONE,                              /* tv_id */
1069e4b17023SJohn Marino   0,                                    /* properties_required */
1070e4b17023SJohn Marino   0,                                    /* properties_provided */
1071e4b17023SJohn Marino   0,                                    /* properties_destroyed */
1072e4b17023SJohn Marino   0,                                    /* todo_flags_start */
1073e4b17023SJohn Marino   0                                     /* todo_flags_finish */
1074e4b17023SJohn Marino  }
1075e4b17023SJohn Marino };
1076e4b17023SJohn Marino 
1077e4b17023SJohn Marino 
1078e4b17023SJohn Marino 
1079e4b17023SJohn Marino /* Set up preferred, alternate, and cover classes for REGNO as
1080e4b17023SJohn Marino    PREFCLASS, ALTCLASS, and ALLOCNOCLASS.  */
1081e4b17023SJohn Marino void
setup_reg_classes(int regno,enum reg_class prefclass,enum reg_class altclass,enum reg_class allocnoclass)1082e4b17023SJohn Marino setup_reg_classes (int regno,
1083e4b17023SJohn Marino 		   enum reg_class prefclass, enum reg_class altclass,
1084e4b17023SJohn Marino 		   enum reg_class allocnoclass)
1085e4b17023SJohn Marino {
1086e4b17023SJohn Marino   if (reg_pref == NULL)
1087e4b17023SJohn Marino     return;
1088e4b17023SJohn Marino   gcc_assert (reg_info_size == max_reg_num ());
1089e4b17023SJohn Marino   reg_pref[regno].prefclass = prefclass;
1090e4b17023SJohn Marino   reg_pref[regno].altclass = altclass;
1091e4b17023SJohn Marino   reg_pref[regno].allocnoclass = allocnoclass;
1092e4b17023SJohn Marino }
1093e4b17023SJohn Marino 
1094e4b17023SJohn Marino 
1095e4b17023SJohn Marino /* This is the `regscan' pass of the compiler, run just before cse and
1096e4b17023SJohn Marino    again just before loop.  It finds the first and last use of each
1097e4b17023SJohn Marino    pseudo-register.  */
1098e4b17023SJohn Marino 
1099e4b17023SJohn Marino static void reg_scan_mark_refs (rtx, rtx);
1100e4b17023SJohn Marino 
1101e4b17023SJohn Marino void
reg_scan(rtx f,unsigned int nregs ATTRIBUTE_UNUSED)1102e4b17023SJohn Marino reg_scan (rtx f, unsigned int nregs ATTRIBUTE_UNUSED)
1103e4b17023SJohn Marino {
1104e4b17023SJohn Marino   rtx insn;
1105e4b17023SJohn Marino 
1106e4b17023SJohn Marino   timevar_push (TV_REG_SCAN);
1107e4b17023SJohn Marino 
1108e4b17023SJohn Marino   for (insn = f; insn; insn = NEXT_INSN (insn))
1109e4b17023SJohn Marino     if (INSN_P (insn))
1110e4b17023SJohn Marino       {
1111e4b17023SJohn Marino 	reg_scan_mark_refs (PATTERN (insn), insn);
1112e4b17023SJohn Marino 	if (REG_NOTES (insn))
1113e4b17023SJohn Marino 	  reg_scan_mark_refs (REG_NOTES (insn), insn);
1114e4b17023SJohn Marino       }
1115e4b17023SJohn Marino 
1116e4b17023SJohn Marino   timevar_pop (TV_REG_SCAN);
1117e4b17023SJohn Marino }
1118e4b17023SJohn Marino 
1119e4b17023SJohn Marino 
1120e4b17023SJohn Marino /* X is the expression to scan.  INSN is the insn it appears in.
1121e4b17023SJohn Marino    NOTE_FLAG is nonzero if X is from INSN's notes rather than its body.
1122e4b17023SJohn Marino    We should only record information for REGs with numbers
1123e4b17023SJohn Marino    greater than or equal to MIN_REGNO.  */
1124e4b17023SJohn Marino static void
reg_scan_mark_refs(rtx x,rtx insn)1125e4b17023SJohn Marino reg_scan_mark_refs (rtx x, rtx insn)
1126e4b17023SJohn Marino {
1127e4b17023SJohn Marino   enum rtx_code code;
1128e4b17023SJohn Marino   rtx dest;
1129e4b17023SJohn Marino   rtx note;
1130e4b17023SJohn Marino 
1131e4b17023SJohn Marino   if (!x)
1132e4b17023SJohn Marino     return;
1133e4b17023SJohn Marino   code = GET_CODE (x);
1134e4b17023SJohn Marino   switch (code)
1135e4b17023SJohn Marino     {
1136e4b17023SJohn Marino     case CONST:
1137e4b17023SJohn Marino     case CONST_INT:
1138e4b17023SJohn Marino     case CONST_DOUBLE:
1139e4b17023SJohn Marino     case CONST_FIXED:
1140e4b17023SJohn Marino     case CONST_VECTOR:
1141e4b17023SJohn Marino     case CC0:
1142e4b17023SJohn Marino     case PC:
1143e4b17023SJohn Marino     case SYMBOL_REF:
1144e4b17023SJohn Marino     case LABEL_REF:
1145e4b17023SJohn Marino     case ADDR_VEC:
1146e4b17023SJohn Marino     case ADDR_DIFF_VEC:
1147e4b17023SJohn Marino     case REG:
1148e4b17023SJohn Marino       return;
1149e4b17023SJohn Marino 
1150e4b17023SJohn Marino     case EXPR_LIST:
1151e4b17023SJohn Marino       if (XEXP (x, 0))
1152e4b17023SJohn Marino 	reg_scan_mark_refs (XEXP (x, 0), insn);
1153e4b17023SJohn Marino       if (XEXP (x, 1))
1154e4b17023SJohn Marino 	reg_scan_mark_refs (XEXP (x, 1), insn);
1155e4b17023SJohn Marino       break;
1156e4b17023SJohn Marino 
1157e4b17023SJohn Marino     case INSN_LIST:
1158e4b17023SJohn Marino       if (XEXP (x, 1))
1159e4b17023SJohn Marino 	reg_scan_mark_refs (XEXP (x, 1), insn);
1160e4b17023SJohn Marino       break;
1161e4b17023SJohn Marino 
1162e4b17023SJohn Marino     case CLOBBER:
1163e4b17023SJohn Marino       if (MEM_P (XEXP (x, 0)))
1164e4b17023SJohn Marino 	reg_scan_mark_refs (XEXP (XEXP (x, 0), 0), insn);
1165e4b17023SJohn Marino       break;
1166e4b17023SJohn Marino 
1167e4b17023SJohn Marino     case SET:
1168e4b17023SJohn Marino       /* Count a set of the destination if it is a register.  */
1169e4b17023SJohn Marino       for (dest = SET_DEST (x);
1170e4b17023SJohn Marino 	   GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
1171e4b17023SJohn Marino 	   || GET_CODE (dest) == ZERO_EXTEND;
1172e4b17023SJohn Marino 	   dest = XEXP (dest, 0))
1173e4b17023SJohn Marino 	;
1174e4b17023SJohn Marino 
1175e4b17023SJohn Marino       /* If this is setting a pseudo from another pseudo or the sum of a
1176e4b17023SJohn Marino 	 pseudo and a constant integer and the other pseudo is known to be
1177e4b17023SJohn Marino 	 a pointer, set the destination to be a pointer as well.
1178e4b17023SJohn Marino 
1179e4b17023SJohn Marino 	 Likewise if it is setting the destination from an address or from a
1180e4b17023SJohn Marino 	 value equivalent to an address or to the sum of an address and
1181e4b17023SJohn Marino 	 something else.
1182e4b17023SJohn Marino 
1183e4b17023SJohn Marino 	 But don't do any of this if the pseudo corresponds to a user
1184e4b17023SJohn Marino 	 variable since it should have already been set as a pointer based
1185e4b17023SJohn Marino 	 on the type.  */
1186e4b17023SJohn Marino 
1187e4b17023SJohn Marino       if (REG_P (SET_DEST (x))
1188e4b17023SJohn Marino 	  && REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER
1189e4b17023SJohn Marino 	  /* If the destination pseudo is set more than once, then other
1190e4b17023SJohn Marino 	     sets might not be to a pointer value (consider access to a
1191e4b17023SJohn Marino 	     union in two threads of control in the presence of global
1192e4b17023SJohn Marino 	     optimizations).  So only set REG_POINTER on the destination
1193e4b17023SJohn Marino 	     pseudo if this is the only set of that pseudo.  */
1194e4b17023SJohn Marino 	  && DF_REG_DEF_COUNT (REGNO (SET_DEST (x))) == 1
1195e4b17023SJohn Marino 	  && ! REG_USERVAR_P (SET_DEST (x))
1196e4b17023SJohn Marino 	  && ! REG_POINTER (SET_DEST (x))
1197e4b17023SJohn Marino 	  && ((REG_P (SET_SRC (x))
1198e4b17023SJohn Marino 	       && REG_POINTER (SET_SRC (x)))
1199e4b17023SJohn Marino 	      || ((GET_CODE (SET_SRC (x)) == PLUS
1200e4b17023SJohn Marino 		   || GET_CODE (SET_SRC (x)) == LO_SUM)
1201e4b17023SJohn Marino 		  && CONST_INT_P (XEXP (SET_SRC (x), 1))
1202e4b17023SJohn Marino 		  && REG_P (XEXP (SET_SRC (x), 0))
1203e4b17023SJohn Marino 		  && REG_POINTER (XEXP (SET_SRC (x), 0)))
1204e4b17023SJohn Marino 	      || GET_CODE (SET_SRC (x)) == CONST
1205e4b17023SJohn Marino 	      || GET_CODE (SET_SRC (x)) == SYMBOL_REF
1206e4b17023SJohn Marino 	      || GET_CODE (SET_SRC (x)) == LABEL_REF
1207e4b17023SJohn Marino 	      || (GET_CODE (SET_SRC (x)) == HIGH
1208e4b17023SJohn Marino 		  && (GET_CODE (XEXP (SET_SRC (x), 0)) == CONST
1209e4b17023SJohn Marino 		      || GET_CODE (XEXP (SET_SRC (x), 0)) == SYMBOL_REF
1210e4b17023SJohn Marino 		      || GET_CODE (XEXP (SET_SRC (x), 0)) == LABEL_REF))
1211e4b17023SJohn Marino 	      || ((GET_CODE (SET_SRC (x)) == PLUS
1212e4b17023SJohn Marino 		   || GET_CODE (SET_SRC (x)) == LO_SUM)
1213e4b17023SJohn Marino 		  && (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST
1214e4b17023SJohn Marino 		      || GET_CODE (XEXP (SET_SRC (x), 1)) == SYMBOL_REF
1215e4b17023SJohn Marino 		      || GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF))
1216e4b17023SJohn Marino 	      || ((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
1217e4b17023SJohn Marino 		  && (GET_CODE (XEXP (note, 0)) == CONST
1218e4b17023SJohn Marino 		      || GET_CODE (XEXP (note, 0)) == SYMBOL_REF
1219e4b17023SJohn Marino 		      || GET_CODE (XEXP (note, 0)) == LABEL_REF))))
1220e4b17023SJohn Marino 	REG_POINTER (SET_DEST (x)) = 1;
1221e4b17023SJohn Marino 
1222e4b17023SJohn Marino       /* If this is setting a register from a register or from a simple
1223e4b17023SJohn Marino 	 conversion of a register, propagate REG_EXPR.  */
1224e4b17023SJohn Marino       if (REG_P (dest) && !REG_ATTRS (dest))
1225e4b17023SJohn Marino 	{
1226e4b17023SJohn Marino 	  rtx src = SET_SRC (x);
1227e4b17023SJohn Marino 
1228e4b17023SJohn Marino 	  while (GET_CODE (src) == SIGN_EXTEND
1229e4b17023SJohn Marino 		 || GET_CODE (src) == ZERO_EXTEND
1230e4b17023SJohn Marino 		 || GET_CODE (src) == TRUNCATE
1231e4b17023SJohn Marino 		 || (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
1232e4b17023SJohn Marino 	    src = XEXP (src, 0);
1233e4b17023SJohn Marino 
1234e4b17023SJohn Marino 	  set_reg_attrs_from_value (dest, src);
1235e4b17023SJohn Marino 	}
1236e4b17023SJohn Marino 
1237e4b17023SJohn Marino       /* ... fall through ...  */
1238e4b17023SJohn Marino 
1239e4b17023SJohn Marino     default:
1240e4b17023SJohn Marino       {
1241e4b17023SJohn Marino 	const char *fmt = GET_RTX_FORMAT (code);
1242e4b17023SJohn Marino 	int i;
1243e4b17023SJohn Marino 	for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1244e4b17023SJohn Marino 	  {
1245e4b17023SJohn Marino 	    if (fmt[i] == 'e')
1246e4b17023SJohn Marino 	      reg_scan_mark_refs (XEXP (x, i), insn);
1247e4b17023SJohn Marino 	    else if (fmt[i] == 'E' && XVEC (x, i) != 0)
1248e4b17023SJohn Marino 	      {
1249e4b17023SJohn Marino 		int j;
1250e4b17023SJohn Marino 		for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1251e4b17023SJohn Marino 		  reg_scan_mark_refs (XVECEXP (x, i, j), insn);
1252e4b17023SJohn Marino 	      }
1253e4b17023SJohn Marino 	  }
1254e4b17023SJohn Marino       }
1255e4b17023SJohn Marino     }
1256e4b17023SJohn Marino }
1257e4b17023SJohn Marino 
1258e4b17023SJohn Marino 
1259e4b17023SJohn Marino /* Return nonzero if C1 is a subset of C2, i.e., if every register in C1
1260e4b17023SJohn Marino    is also in C2.  */
1261e4b17023SJohn Marino int
reg_class_subset_p(reg_class_t c1,reg_class_t c2)1262e4b17023SJohn Marino reg_class_subset_p (reg_class_t c1, reg_class_t c2)
1263e4b17023SJohn Marino {
1264e4b17023SJohn Marino   return (c1 == c2
1265e4b17023SJohn Marino 	  || c2 == ALL_REGS
1266e4b17023SJohn Marino 	  || hard_reg_set_subset_p (reg_class_contents[(int) c1],
1267e4b17023SJohn Marino 				   reg_class_contents[(int) c2]));
1268e4b17023SJohn Marino }
1269e4b17023SJohn Marino 
1270e4b17023SJohn Marino /* Return nonzero if there is a register that is in both C1 and C2.  */
1271e4b17023SJohn Marino int
reg_classes_intersect_p(reg_class_t c1,reg_class_t c2)1272e4b17023SJohn Marino reg_classes_intersect_p (reg_class_t c1, reg_class_t c2)
1273e4b17023SJohn Marino {
1274e4b17023SJohn Marino   return (c1 == c2
1275e4b17023SJohn Marino 	  || c1 == ALL_REGS
1276e4b17023SJohn Marino 	  || c2 == ALL_REGS
1277e4b17023SJohn Marino 	  || hard_reg_set_intersect_p (reg_class_contents[(int) c1],
1278e4b17023SJohn Marino 				      reg_class_contents[(int) c2]));
1279e4b17023SJohn Marino }
1280e4b17023SJohn Marino 
1281e4b17023SJohn Marino 
1282e4b17023SJohn Marino 
1283e4b17023SJohn Marino /* Passes for keeping and updating info about modes of registers
1284e4b17023SJohn Marino    inside subregisters.  */
1285e4b17023SJohn Marino 
1286e4b17023SJohn Marino #ifdef CANNOT_CHANGE_MODE_CLASS
1287e4b17023SJohn Marino 
1288e4b17023SJohn Marino static bitmap invalid_mode_changes;
1289e4b17023SJohn Marino 
1290e4b17023SJohn Marino static void
record_subregs_of_mode(rtx subreg,bitmap subregs_of_mode)1291e4b17023SJohn Marino record_subregs_of_mode (rtx subreg, bitmap subregs_of_mode)
1292e4b17023SJohn Marino {
1293e4b17023SJohn Marino   enum machine_mode mode;
1294e4b17023SJohn Marino   unsigned int regno;
1295e4b17023SJohn Marino 
1296e4b17023SJohn Marino   if (!REG_P (SUBREG_REG (subreg)))
1297e4b17023SJohn Marino     return;
1298e4b17023SJohn Marino 
1299e4b17023SJohn Marino   regno = REGNO (SUBREG_REG (subreg));
1300e4b17023SJohn Marino   mode = GET_MODE (subreg);
1301e4b17023SJohn Marino 
1302e4b17023SJohn Marino   if (regno < FIRST_PSEUDO_REGISTER)
1303e4b17023SJohn Marino     return;
1304e4b17023SJohn Marino 
1305e4b17023SJohn Marino   if (bitmap_set_bit (subregs_of_mode,
1306e4b17023SJohn Marino 		      regno * NUM_MACHINE_MODES + (unsigned int) mode))
1307e4b17023SJohn Marino     {
1308e4b17023SJohn Marino       unsigned int rclass;
1309e4b17023SJohn Marino       for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
1310e4b17023SJohn Marino 	if (!bitmap_bit_p (invalid_mode_changes,
1311e4b17023SJohn Marino 			   regno * N_REG_CLASSES + rclass)
1312e4b17023SJohn Marino 	    && CANNOT_CHANGE_MODE_CLASS (PSEUDO_REGNO_MODE (regno),
1313e4b17023SJohn Marino 					 mode, (enum reg_class) rclass))
1314e4b17023SJohn Marino 	  bitmap_set_bit (invalid_mode_changes,
1315e4b17023SJohn Marino 			  regno * N_REG_CLASSES + rclass);
1316e4b17023SJohn Marino     }
1317e4b17023SJohn Marino }
1318e4b17023SJohn Marino 
1319e4b17023SJohn Marino /* Call record_subregs_of_mode for all the subregs in X.  */
1320e4b17023SJohn Marino static void
find_subregs_of_mode(rtx x,bitmap subregs_of_mode)1321e4b17023SJohn Marino find_subregs_of_mode (rtx x, bitmap subregs_of_mode)
1322e4b17023SJohn Marino {
1323e4b17023SJohn Marino   enum rtx_code code = GET_CODE (x);
1324e4b17023SJohn Marino   const char * const fmt = GET_RTX_FORMAT (code);
1325e4b17023SJohn Marino   int i;
1326e4b17023SJohn Marino 
1327e4b17023SJohn Marino   if (code == SUBREG)
1328e4b17023SJohn Marino     record_subregs_of_mode (x, subregs_of_mode);
1329e4b17023SJohn Marino 
1330e4b17023SJohn Marino   /* Time for some deep diving.  */
1331e4b17023SJohn Marino   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1332e4b17023SJohn Marino     {
1333e4b17023SJohn Marino       if (fmt[i] == 'e')
1334e4b17023SJohn Marino 	find_subregs_of_mode (XEXP (x, i), subregs_of_mode);
1335e4b17023SJohn Marino       else if (fmt[i] == 'E')
1336e4b17023SJohn Marino 	{
1337e4b17023SJohn Marino 	  int j;
1338e4b17023SJohn Marino 	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1339e4b17023SJohn Marino 	    find_subregs_of_mode (XVECEXP (x, i, j), subregs_of_mode);
1340e4b17023SJohn Marino 	}
1341e4b17023SJohn Marino     }
1342e4b17023SJohn Marino }
1343e4b17023SJohn Marino 
1344e4b17023SJohn Marino void
init_subregs_of_mode(void)1345e4b17023SJohn Marino init_subregs_of_mode (void)
1346e4b17023SJohn Marino {
1347e4b17023SJohn Marino   basic_block bb;
1348e4b17023SJohn Marino   rtx insn;
1349e4b17023SJohn Marino   bitmap_obstack srom_obstack;
1350e4b17023SJohn Marino   bitmap subregs_of_mode;
1351e4b17023SJohn Marino 
1352e4b17023SJohn Marino   gcc_assert (invalid_mode_changes == NULL);
1353e4b17023SJohn Marino   invalid_mode_changes = BITMAP_ALLOC (NULL);
1354e4b17023SJohn Marino   bitmap_obstack_initialize (&srom_obstack);
1355e4b17023SJohn Marino   subregs_of_mode = BITMAP_ALLOC (&srom_obstack);
1356e4b17023SJohn Marino 
1357e4b17023SJohn Marino   FOR_EACH_BB (bb)
1358e4b17023SJohn Marino     FOR_BB_INSNS (bb, insn)
1359e4b17023SJohn Marino       if (NONDEBUG_INSN_P (insn))
1360e4b17023SJohn Marino         find_subregs_of_mode (PATTERN (insn), subregs_of_mode);
1361e4b17023SJohn Marino 
1362e4b17023SJohn Marino   BITMAP_FREE (subregs_of_mode);
1363e4b17023SJohn Marino   bitmap_obstack_release (&srom_obstack);
1364e4b17023SJohn Marino }
1365e4b17023SJohn Marino 
1366e4b17023SJohn Marino /* Return 1 if REGNO has had an invalid mode change in CLASS from FROM
1367e4b17023SJohn Marino    mode.  */
1368e4b17023SJohn Marino bool
invalid_mode_change_p(unsigned int regno,enum reg_class rclass)1369e4b17023SJohn Marino invalid_mode_change_p (unsigned int regno,
1370e4b17023SJohn Marino 		       enum reg_class rclass)
1371e4b17023SJohn Marino {
1372e4b17023SJohn Marino   return bitmap_bit_p (invalid_mode_changes,
1373e4b17023SJohn Marino 		       regno * N_REG_CLASSES + (unsigned) rclass);
1374e4b17023SJohn Marino }
1375e4b17023SJohn Marino 
1376e4b17023SJohn Marino void
finish_subregs_of_mode(void)1377e4b17023SJohn Marino finish_subregs_of_mode (void)
1378e4b17023SJohn Marino {
1379e4b17023SJohn Marino   BITMAP_FREE (invalid_mode_changes);
1380e4b17023SJohn Marino }
1381e4b17023SJohn Marino #else
1382e4b17023SJohn Marino void
init_subregs_of_mode(void)1383e4b17023SJohn Marino init_subregs_of_mode (void)
1384e4b17023SJohn Marino {
1385e4b17023SJohn Marino }
1386e4b17023SJohn Marino void
finish_subregs_of_mode(void)1387e4b17023SJohn Marino finish_subregs_of_mode (void)
1388e4b17023SJohn Marino {
1389e4b17023SJohn Marino }
1390e4b17023SJohn Marino 
1391e4b17023SJohn Marino #endif /* CANNOT_CHANGE_MODE_CLASS */
1392