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