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