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