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