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