Mercurial > hg > CbC > CbC_gcc
annotate gcc/lower-subreg.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 /* Decompose multiword subregs. |
145 | 2 Copyright (C) 2007-2020 Free Software Foundation, Inc. |
0 | 3 Contributed by Richard Henderson <rth@redhat.com> |
4 Ian Lance Taylor <iant@google.com> | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 #include "config.h" | |
23 #include "system.h" | |
24 #include "coretypes.h" | |
111 | 25 #include "backend.h" |
0 | 26 #include "rtl.h" |
111 | 27 #include "tree.h" |
28 #include "cfghooks.h" | |
29 #include "df.h" | |
30 #include "memmodel.h" | |
0 | 31 #include "tm_p.h" |
111 | 32 #include "expmed.h" |
0 | 33 #include "insn-config.h" |
111 | 34 #include "emit-rtl.h" |
0 | 35 #include "recog.h" |
111 | 36 #include "cfgrtl.h" |
37 #include "cfgbuild.h" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
38 #include "dce.h" |
0 | 39 #include "expr.h" |
40 #include "tree-pass.h" | |
111 | 41 #include "lower-subreg.h" |
42 #include "rtl-iter.h" | |
43 #include "target.h" | |
0 | 44 |
45 | |
46 /* Decompose multi-word pseudo-registers into individual | |
111 | 47 pseudo-registers when possible and profitable. This is possible |
48 when all the uses of a multi-word register are via SUBREG, or are | |
49 copies of the register to another location. Breaking apart the | |
50 register permits more CSE and permits better register allocation. | |
51 This is profitable if the machine does not have move instructions | |
52 to do this. | |
53 | |
54 This pass only splits moves with modes that are wider than | |
55 word_mode and ASHIFTs, LSHIFTRTs, ASHIFTRTs and ZERO_EXTENDs with | |
56 integer modes that are twice the width of word_mode. The latter | |
57 could be generalized if there was a need to do this, but the trend in | |
58 architectures is to not need this. | |
59 | |
60 There are two useful preprocessor defines for use by maintainers: | |
61 | |
62 #define LOG_COSTS 1 | |
63 | |
64 if you wish to see the actual cost estimates that are being used | |
65 for each mode wider than word mode and the cost estimates for zero | |
66 extension and the shifts. This can be useful when port maintainers | |
67 are tuning insn rtx costs. | |
68 | |
69 #define FORCE_LOWERING 1 | |
70 | |
71 if you wish to test the pass with all the transformation forced on. | |
72 This can be useful for finding bugs in the transformations. */ | |
73 | |
74 #define LOG_COSTS 0 | |
75 #define FORCE_LOWERING 0 | |
0 | 76 |
77 /* Bit N in this bitmap is set if regno N is used in a context in | |
78 which we can decompose it. */ | |
79 static bitmap decomposable_context; | |
80 | |
81 /* Bit N in this bitmap is set if regno N is used in a context in | |
145 | 82 which it cannot be decomposed. */ |
0 | 83 static bitmap non_decomposable_context; |
84 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
85 /* Bit N in this bitmap is set if regno N is used in a subreg |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
86 which changes the mode but not the size. This typically happens |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
87 when the register accessed as a floating-point value; we want to |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
88 avoid generating accesses to its subwords in integer modes. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
89 static bitmap subreg_context; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
90 |
0 | 91 /* Bit N in the bitmap in element M of this array is set if there is a |
92 copy from reg M to reg N. */ | |
111 | 93 static vec<bitmap> reg_copy_graph; |
94 | |
95 struct target_lower_subreg default_target_lower_subreg; | |
96 #if SWITCHABLE_TARGET | |
97 struct target_lower_subreg *this_target_lower_subreg | |
98 = &default_target_lower_subreg; | |
99 #endif | |
100 | |
101 #define twice_word_mode \ | |
102 this_target_lower_subreg->x_twice_word_mode | |
103 #define choices \ | |
104 this_target_lower_subreg->x_choices | |
105 | |
131 | 106 /* Return true if MODE is a mode we know how to lower. When returning true, |
107 store its byte size in *BYTES and its word size in *WORDS. */ | |
108 | |
109 static inline bool | |
110 interesting_mode_p (machine_mode mode, unsigned int *bytes, | |
111 unsigned int *words) | |
112 { | |
113 if (!GET_MODE_SIZE (mode).is_constant (bytes)) | |
114 return false; | |
115 *words = CEIL (*bytes, UNITS_PER_WORD); | |
116 return true; | |
117 } | |
118 | |
111 | 119 /* RTXes used while computing costs. */ |
120 struct cost_rtxes { | |
121 /* Source and target registers. */ | |
122 rtx source; | |
123 rtx target; | |
124 | |
125 /* A twice_word_mode ZERO_EXTEND of SOURCE. */ | |
126 rtx zext; | |
127 | |
128 /* A shift of SOURCE. */ | |
129 rtx shift; | |
130 | |
131 /* A SET of TARGET. */ | |
132 rtx set; | |
133 }; | |
134 | |
135 /* Return the cost of a CODE shift in mode MODE by OP1 bits, using the | |
136 rtxes in RTXES. SPEED_P selects between the speed and size cost. */ | |
137 | |
138 static int | |
139 shift_cost (bool speed_p, struct cost_rtxes *rtxes, enum rtx_code code, | |
140 machine_mode mode, int op1) | |
141 { | |
142 PUT_CODE (rtxes->shift, code); | |
143 PUT_MODE (rtxes->shift, mode); | |
144 PUT_MODE (rtxes->source, mode); | |
131 | 145 XEXP (rtxes->shift, 1) = gen_int_shift_amount (mode, op1); |
111 | 146 return set_src_cost (rtxes->shift, mode, speed_p); |
147 } | |
148 | |
149 /* For each X in the range [0, BITS_PER_WORD), set SPLITTING[X] | |
150 to true if it is profitable to split a double-word CODE shift | |
151 of X + BITS_PER_WORD bits. SPEED_P says whether we are testing | |
152 for speed or size profitability. | |
153 | |
154 Use the rtxes in RTXES to calculate costs. WORD_MOVE_ZERO_COST is | |
155 the cost of moving zero into a word-mode register. WORD_MOVE_COST | |
156 is the cost of moving between word registers. */ | |
157 | |
158 static void | |
159 compute_splitting_shift (bool speed_p, struct cost_rtxes *rtxes, | |
160 bool *splitting, enum rtx_code code, | |
161 int word_move_zero_cost, int word_move_cost) | |
162 { | |
163 int wide_cost, narrow_cost, upper_cost, i; | |
164 | |
165 for (i = 0; i < BITS_PER_WORD; i++) | |
166 { | |
167 wide_cost = shift_cost (speed_p, rtxes, code, twice_word_mode, | |
168 i + BITS_PER_WORD); | |
169 if (i == 0) | |
170 narrow_cost = word_move_cost; | |
171 else | |
172 narrow_cost = shift_cost (speed_p, rtxes, code, word_mode, i); | |
173 | |
174 if (code != ASHIFTRT) | |
175 upper_cost = word_move_zero_cost; | |
176 else if (i == BITS_PER_WORD - 1) | |
177 upper_cost = word_move_cost; | |
178 else | |
179 upper_cost = shift_cost (speed_p, rtxes, code, word_mode, | |
180 BITS_PER_WORD - 1); | |
181 | |
182 if (LOG_COSTS) | |
183 fprintf (stderr, "%s %s by %d: original cost %d, split cost %d + %d\n", | |
184 GET_MODE_NAME (twice_word_mode), GET_RTX_NAME (code), | |
185 i + BITS_PER_WORD, wide_cost, narrow_cost, upper_cost); | |
186 | |
187 if (FORCE_LOWERING || wide_cost >= narrow_cost + upper_cost) | |
188 splitting[i] = true; | |
189 } | |
190 } | |
191 | |
192 /* Compute what we should do when optimizing for speed or size; SPEED_P | |
193 selects which. Use RTXES for computing costs. */ | |
194 | |
195 static void | |
196 compute_costs (bool speed_p, struct cost_rtxes *rtxes) | |
197 { | |
198 unsigned int i; | |
199 int word_move_zero_cost, word_move_cost; | |
0 | 200 |
111 | 201 PUT_MODE (rtxes->target, word_mode); |
202 SET_SRC (rtxes->set) = CONST0_RTX (word_mode); | |
203 word_move_zero_cost = set_rtx_cost (rtxes->set, speed_p); | |
204 | |
205 SET_SRC (rtxes->set) = rtxes->source; | |
206 word_move_cost = set_rtx_cost (rtxes->set, speed_p); | |
207 | |
208 if (LOG_COSTS) | |
209 fprintf (stderr, "%s move: from zero cost %d, from reg cost %d\n", | |
210 GET_MODE_NAME (word_mode), word_move_zero_cost, word_move_cost); | |
211 | |
212 for (i = 0; i < MAX_MACHINE_MODE; i++) | |
213 { | |
214 machine_mode mode = (machine_mode) i; | |
131 | 215 unsigned int size, factor; |
216 if (interesting_mode_p (mode, &size, &factor) && factor > 1) | |
111 | 217 { |
131 | 218 unsigned int mode_move_cost; |
111 | 219 |
220 PUT_MODE (rtxes->target, mode); | |
221 PUT_MODE (rtxes->source, mode); | |
222 mode_move_cost = set_rtx_cost (rtxes->set, speed_p); | |
223 | |
224 if (LOG_COSTS) | |
225 fprintf (stderr, "%s move: original cost %d, split cost %d * %d\n", | |
226 GET_MODE_NAME (mode), mode_move_cost, | |
227 word_move_cost, factor); | |
228 | |
229 if (FORCE_LOWERING || mode_move_cost >= word_move_cost * factor) | |
230 { | |
231 choices[speed_p].move_modes_to_split[i] = true; | |
232 choices[speed_p].something_to_do = true; | |
233 } | |
234 } | |
235 } | |
236 | |
237 /* For the moves and shifts, the only case that is checked is one | |
238 where the mode of the target is an integer mode twice the width | |
239 of the word_mode. | |
240 | |
241 If it is not profitable to split a double word move then do not | |
242 even consider the shifts or the zero extension. */ | |
243 if (choices[speed_p].move_modes_to_split[(int) twice_word_mode]) | |
244 { | |
245 int zext_cost; | |
246 | |
247 /* The only case here to check to see if moving the upper part with a | |
248 zero is cheaper than doing the zext itself. */ | |
249 PUT_MODE (rtxes->source, word_mode); | |
250 zext_cost = set_src_cost (rtxes->zext, twice_word_mode, speed_p); | |
251 | |
252 if (LOG_COSTS) | |
253 fprintf (stderr, "%s %s: original cost %d, split cost %d + %d\n", | |
254 GET_MODE_NAME (twice_word_mode), GET_RTX_NAME (ZERO_EXTEND), | |
255 zext_cost, word_move_cost, word_move_zero_cost); | |
256 | |
257 if (FORCE_LOWERING || zext_cost >= word_move_cost + word_move_zero_cost) | |
258 choices[speed_p].splitting_zext = true; | |
259 | |
260 compute_splitting_shift (speed_p, rtxes, | |
261 choices[speed_p].splitting_ashift, ASHIFT, | |
262 word_move_zero_cost, word_move_cost); | |
263 compute_splitting_shift (speed_p, rtxes, | |
264 choices[speed_p].splitting_lshiftrt, LSHIFTRT, | |
265 word_move_zero_cost, word_move_cost); | |
266 compute_splitting_shift (speed_p, rtxes, | |
267 choices[speed_p].splitting_ashiftrt, ASHIFTRT, | |
268 word_move_zero_cost, word_move_cost); | |
269 } | |
270 } | |
271 | |
272 /* Do one-per-target initialisation. This involves determining | |
273 which operations on the machine are profitable. If none are found, | |
274 then the pass just returns when called. */ | |
275 | |
276 void | |
277 init_lower_subreg (void) | |
278 { | |
279 struct cost_rtxes rtxes; | |
280 | |
281 memset (this_target_lower_subreg, 0, sizeof (*this_target_lower_subreg)); | |
282 | |
283 twice_word_mode = GET_MODE_2XWIDER_MODE (word_mode).require (); | |
284 | |
285 rtxes.target = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1); | |
286 rtxes.source = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 2); | |
287 rtxes.set = gen_rtx_SET (rtxes.target, rtxes.source); | |
288 rtxes.zext = gen_rtx_ZERO_EXTEND (twice_word_mode, rtxes.source); | |
289 rtxes.shift = gen_rtx_ASHIFT (twice_word_mode, rtxes.source, const0_rtx); | |
290 | |
291 if (LOG_COSTS) | |
292 fprintf (stderr, "\nSize costs\n==========\n\n"); | |
293 compute_costs (false, &rtxes); | |
294 | |
295 if (LOG_COSTS) | |
296 fprintf (stderr, "\nSpeed costs\n===========\n\n"); | |
297 compute_costs (true, &rtxes); | |
298 } | |
0 | 299 |
300 static bool | |
301 simple_move_operand (rtx x) | |
302 { | |
303 if (GET_CODE (x) == SUBREG) | |
304 x = SUBREG_REG (x); | |
305 | |
306 if (!OBJECT_P (x)) | |
307 return false; | |
308 | |
309 if (GET_CODE (x) == LABEL_REF | |
310 || GET_CODE (x) == SYMBOL_REF | |
311 || GET_CODE (x) == HIGH | |
312 || GET_CODE (x) == CONST) | |
313 return false; | |
314 | |
315 if (MEM_P (x) | |
316 && (MEM_VOLATILE_P (x) | |
111 | 317 || mode_dependent_address_p (XEXP (x, 0), MEM_ADDR_SPACE (x)))) |
0 | 318 return false; |
319 | |
320 return true; | |
321 } | |
322 | |
145 | 323 /* If X is an operator that can be treated as a simple move that we |
324 can split, then return the operand that is operated on. */ | |
325 | |
326 static rtx | |
327 operand_for_swap_move_operator (rtx x) | |
328 { | |
329 /* A word sized rotate of a register pair is equivalent to swapping | |
330 the registers in the register pair. */ | |
331 if (GET_CODE (x) == ROTATE | |
332 && GET_MODE (x) == twice_word_mode | |
333 && simple_move_operand (XEXP (x, 0)) | |
334 && CONST_INT_P (XEXP (x, 1)) | |
335 && INTVAL (XEXP (x, 1)) == BITS_PER_WORD) | |
336 return XEXP (x, 0); | |
337 | |
338 return NULL_RTX; | |
339 } | |
340 | |
111 | 341 /* If INSN is a single set between two objects that we want to split, |
342 return the single set. SPEED_P says whether we are optimizing | |
343 INSN for speed or size. | |
344 | |
345 INSN should have been passed to recog and extract_insn before this | |
346 is called. */ | |
0 | 347 |
348 static rtx | |
111 | 349 simple_move (rtx_insn *insn, bool speed_p) |
0 | 350 { |
145 | 351 rtx x, op; |
0 | 352 rtx set; |
111 | 353 machine_mode mode; |
0 | 354 |
355 if (recog_data.n_operands != 2) | |
356 return NULL_RTX; | |
357 | |
358 set = single_set (insn); | |
359 if (!set) | |
360 return NULL_RTX; | |
361 | |
362 x = SET_DEST (set); | |
363 if (x != recog_data.operand[0] && x != recog_data.operand[1]) | |
364 return NULL_RTX; | |
365 if (!simple_move_operand (x)) | |
366 return NULL_RTX; | |
367 | |
368 x = SET_SRC (set); | |
145 | 369 if ((op = operand_for_swap_move_operator (x)) != NULL_RTX) |
370 x = op; | |
371 | |
0 | 372 if (x != recog_data.operand[0] && x != recog_data.operand[1]) |
373 return NULL_RTX; | |
374 /* For the src we can handle ASM_OPERANDS, and it is beneficial for | |
375 things like x86 rdtsc which returns a DImode value. */ | |
376 if (GET_CODE (x) != ASM_OPERANDS | |
377 && !simple_move_operand (x)) | |
378 return NULL_RTX; | |
379 | |
380 /* We try to decompose in integer modes, to avoid generating | |
381 inefficient code copying between integer and floating point | |
382 registers. That means that we can't decompose if this is a | |
383 non-integer mode for which there is no integer mode of the same | |
384 size. */ | |
111 | 385 mode = GET_MODE (SET_DEST (set)); |
0 | 386 if (!SCALAR_INT_MODE_P (mode) |
111 | 387 && !int_mode_for_size (GET_MODE_BITSIZE (mode), 0).exists ()) |
0 | 388 return NULL_RTX; |
389 | |
390 /* Reject PARTIAL_INT modes. They are used for processor specific | |
391 purposes and it's probably best not to tamper with them. */ | |
392 if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT) | |
393 return NULL_RTX; | |
394 | |
111 | 395 if (!choices[speed_p].move_modes_to_split[(int) mode]) |
396 return NULL_RTX; | |
397 | |
0 | 398 return set; |
399 } | |
400 | |
401 /* If SET is a copy from one multi-word pseudo-register to another, | |
402 record that in reg_copy_graph. Return whether it is such a | |
403 copy. */ | |
404 | |
405 static bool | |
406 find_pseudo_copy (rtx set) | |
407 { | |
408 rtx dest = SET_DEST (set); | |
409 rtx src = SET_SRC (set); | |
145 | 410 rtx op; |
0 | 411 unsigned int rd, rs; |
412 bitmap b; | |
413 | |
145 | 414 if ((op = operand_for_swap_move_operator (src)) != NULL_RTX) |
415 src = op; | |
416 | |
0 | 417 if (!REG_P (dest) || !REG_P (src)) |
418 return false; | |
419 | |
420 rd = REGNO (dest); | |
421 rs = REGNO (src); | |
422 if (HARD_REGISTER_NUM_P (rd) || HARD_REGISTER_NUM_P (rs)) | |
423 return false; | |
424 | |
111 | 425 b = reg_copy_graph[rs]; |
0 | 426 if (b == NULL) |
427 { | |
428 b = BITMAP_ALLOC (NULL); | |
111 | 429 reg_copy_graph[rs] = b; |
0 | 430 } |
431 | |
432 bitmap_set_bit (b, rd); | |
433 | |
434 return true; | |
435 } | |
436 | |
437 /* Look through the registers in DECOMPOSABLE_CONTEXT. For each case | |
438 where they are copied to another register, add the register to | |
439 which they are copied to DECOMPOSABLE_CONTEXT. Use | |
440 NON_DECOMPOSABLE_CONTEXT to limit this--we don't bother to track | |
441 copies of registers which are in NON_DECOMPOSABLE_CONTEXT. */ | |
442 | |
443 static void | |
444 propagate_pseudo_copies (void) | |
445 { | |
111 | 446 auto_bitmap queue, propagate; |
0 | 447 |
448 bitmap_copy (queue, decomposable_context); | |
449 do | |
450 { | |
451 bitmap_iterator iter; | |
452 unsigned int i; | |
453 | |
454 bitmap_clear (propagate); | |
455 | |
456 EXECUTE_IF_SET_IN_BITMAP (queue, 0, i, iter) | |
457 { | |
111 | 458 bitmap b = reg_copy_graph[i]; |
0 | 459 if (b) |
460 bitmap_ior_and_compl_into (propagate, b, non_decomposable_context); | |
461 } | |
462 | |
463 bitmap_and_compl (queue, propagate, decomposable_context); | |
464 bitmap_ior_into (decomposable_context, propagate); | |
465 } | |
466 while (!bitmap_empty_p (queue)); | |
467 } | |
468 | |
469 /* A pointer to one of these values is passed to | |
111 | 470 find_decomposable_subregs. */ |
0 | 471 |
472 enum classify_move_insn | |
473 { | |
474 /* Not a simple move from one location to another. */ | |
475 NOT_SIMPLE_MOVE, | |
111 | 476 /* A simple move we want to decompose. */ |
477 DECOMPOSABLE_SIMPLE_MOVE, | |
478 /* Any other simple move. */ | |
0 | 479 SIMPLE_MOVE |
480 }; | |
481 | |
111 | 482 /* If we find a SUBREG in *LOC which we could use to decompose a |
483 pseudo-register, set a bit in DECOMPOSABLE_CONTEXT. If we find an | |
484 unadorned register which is not a simple pseudo-register copy, | |
485 DATA will point at the type of move, and we set a bit in | |
486 DECOMPOSABLE_CONTEXT or NON_DECOMPOSABLE_CONTEXT as appropriate. */ | |
0 | 487 |
111 | 488 static void |
489 find_decomposable_subregs (rtx *loc, enum classify_move_insn *pcmi) | |
0 | 490 { |
111 | 491 subrtx_var_iterator::array_type array; |
492 FOR_EACH_SUBRTX_VAR (iter, array, *loc, NONCONST) | |
493 { | |
494 rtx x = *iter; | |
495 if (GET_CODE (x) == SUBREG) | |
496 { | |
497 rtx inner = SUBREG_REG (x); | |
498 unsigned int regno, outer_size, inner_size, outer_words, inner_words; | |
499 | |
500 if (!REG_P (inner)) | |
501 continue; | |
0 | 502 |
111 | 503 regno = REGNO (inner); |
504 if (HARD_REGISTER_NUM_P (regno)) | |
505 { | |
506 iter.skip_subrtxes (); | |
507 continue; | |
508 } | |
509 | |
131 | 510 if (!interesting_mode_p (GET_MODE (x), &outer_size, &outer_words) |
511 || !interesting_mode_p (GET_MODE (inner), &inner_size, | |
512 &inner_words)) | |
513 continue; | |
0 | 514 |
111 | 515 /* We only try to decompose single word subregs of multi-word |
516 registers. When we find one, we return -1 to avoid iterating | |
517 over the inner register. | |
0 | 518 |
111 | 519 ??? This doesn't allow, e.g., DImode subregs of TImode values |
520 on 32-bit targets. We would need to record the way the | |
521 pseudo-register was used, and only decompose if all the uses | |
522 were the same number and size of pieces. Hopefully this | |
523 doesn't happen much. */ | |
0 | 524 |
131 | 525 if (outer_words == 1 |
526 && inner_words > 1 | |
527 /* Don't allow to decompose floating point subregs of | |
528 multi-word pseudos if the floating point mode does | |
529 not have word size, because otherwise we'd generate | |
530 a subreg with that floating mode from a different | |
531 sized integral pseudo which is not allowed by | |
532 validate_subreg. */ | |
533 && (!FLOAT_MODE_P (GET_MODE (x)) | |
534 || outer_size == UNITS_PER_WORD)) | |
111 | 535 { |
536 bitmap_set_bit (decomposable_context, regno); | |
537 iter.skip_subrtxes (); | |
538 continue; | |
539 } | |
0 | 540 |
111 | 541 /* If this is a cast from one mode to another, where the modes |
542 have the same size, and they are not tieable, then mark this | |
543 register as non-decomposable. If we decompose it we are | |
544 likely to mess up whatever the backend is trying to do. */ | |
545 if (outer_words > 1 | |
546 && outer_size == inner_size | |
547 && !targetm.modes_tieable_p (GET_MODE (x), GET_MODE (inner))) | |
548 { | |
549 bitmap_set_bit (non_decomposable_context, regno); | |
550 bitmap_set_bit (subreg_context, regno); | |
551 iter.skip_subrtxes (); | |
552 continue; | |
553 } | |
554 } | |
555 else if (REG_P (x)) | |
556 { | |
131 | 557 unsigned int regno, size, words; |
0 | 558 |
111 | 559 /* We will see an outer SUBREG before we see the inner REG, so |
560 when we see a plain REG here it means a direct reference to | |
561 the register. | |
0 | 562 |
111 | 563 If this is not a simple copy from one location to another, |
145 | 564 then we cannot decompose this register. If this is a simple |
111 | 565 copy we want to decompose, and the mode is right, |
566 then we mark the register as decomposable. | |
567 Otherwise we don't say anything about this register -- | |
568 it could be decomposed, but whether that would be | |
569 profitable depends upon how it is used elsewhere. | |
0 | 570 |
111 | 571 We only set bits in the bitmap for multi-word |
572 pseudo-registers, since those are the only ones we care about | |
573 and it keeps the size of the bitmaps down. */ | |
0 | 574 |
111 | 575 regno = REGNO (x); |
576 if (!HARD_REGISTER_NUM_P (regno) | |
131 | 577 && interesting_mode_p (GET_MODE (x), &size, &words) |
578 && words > 1) | |
111 | 579 { |
580 switch (*pcmi) | |
581 { | |
582 case NOT_SIMPLE_MOVE: | |
583 bitmap_set_bit (non_decomposable_context, regno); | |
584 break; | |
585 case DECOMPOSABLE_SIMPLE_MOVE: | |
586 if (targetm.modes_tieable_p (GET_MODE (x), word_mode)) | |
587 bitmap_set_bit (decomposable_context, regno); | |
588 break; | |
589 case SIMPLE_MOVE: | |
590 break; | |
591 default: | |
592 gcc_unreachable (); | |
593 } | |
594 } | |
595 } | |
596 else if (MEM_P (x)) | |
0 | 597 { |
111 | 598 enum classify_move_insn cmi_mem = NOT_SIMPLE_MOVE; |
599 | |
600 /* Any registers used in a MEM do not participate in a | |
601 SIMPLE_MOVE or DECOMPOSABLE_SIMPLE_MOVE. Do our own recursion | |
602 here, and return -1 to block the parent's recursion. */ | |
603 find_decomposable_subregs (&XEXP (x, 0), &cmi_mem); | |
604 iter.skip_subrtxes (); | |
0 | 605 } |
606 } | |
607 } | |
608 | |
609 /* Decompose REGNO into word-sized components. We smash the REG node | |
610 in place. This ensures that (1) something goes wrong quickly if we | |
611 fail to make some replacement, and (2) the debug information inside | |
612 the symbol table is automatically kept up to date. */ | |
613 | |
614 static void | |
615 decompose_register (unsigned int regno) | |
616 { | |
617 rtx reg; | |
131 | 618 unsigned int size, words, i; |
0 | 619 rtvec v; |
620 | |
621 reg = regno_reg_rtx[regno]; | |
622 | |
623 regno_reg_rtx[regno] = NULL_RTX; | |
624 | |
131 | 625 if (!interesting_mode_p (GET_MODE (reg), &size, &words)) |
626 gcc_unreachable (); | |
0 | 627 |
628 v = rtvec_alloc (words); | |
629 for (i = 0; i < words; ++i) | |
630 RTVEC_ELT (v, i) = gen_reg_rtx_offset (reg, word_mode, i * UNITS_PER_WORD); | |
631 | |
632 PUT_CODE (reg, CONCATN); | |
633 XVEC (reg, 0) = v; | |
634 | |
635 if (dump_file) | |
636 { | |
637 fprintf (dump_file, "; Splitting reg %u ->", regno); | |
638 for (i = 0; i < words; ++i) | |
639 fprintf (dump_file, " %u", REGNO (XVECEXP (reg, 0, i))); | |
640 fputc ('\n', dump_file); | |
641 } | |
642 } | |
643 | |
644 /* Get a SUBREG of a CONCATN. */ | |
645 | |
646 static rtx | |
131 | 647 simplify_subreg_concatn (machine_mode outermode, rtx op, poly_uint64 orig_byte) |
0 | 648 { |
131 | 649 unsigned int outer_size, outer_words, inner_size, inner_words; |
111 | 650 machine_mode innermode, partmode; |
0 | 651 rtx part; |
652 unsigned int final_offset; | |
131 | 653 unsigned int byte; |
0 | 654 |
655 innermode = GET_MODE (op); | |
131 | 656 if (!interesting_mode_p (outermode, &outer_size, &outer_words) |
657 || !interesting_mode_p (innermode, &inner_size, &inner_words)) | |
658 gcc_unreachable (); | |
659 | |
660 /* Must be constant if interesting_mode_p passes. */ | |
661 byte = orig_byte.to_constant (); | |
662 gcc_assert (GET_CODE (op) == CONCATN); | |
663 gcc_assert (byte % outer_size == 0); | |
664 | |
665 gcc_assert (byte < inner_size); | |
666 if (outer_size > inner_size) | |
111 | 667 return NULL_RTX; |
0 | 668 |
131 | 669 inner_size /= XVECLEN (op, 0); |
0 | 670 part = XVECEXP (op, 0, byte / inner_size); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
671 partmode = GET_MODE (part); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
672 |
111 | 673 final_offset = byte % inner_size; |
131 | 674 if (final_offset + outer_size > inner_size) |
111 | 675 return NULL_RTX; |
676 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
677 /* VECTOR_CSTs in debug expressions are expanded into CONCATN instead of |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
678 regular CONST_VECTORs. They have vector or integer modes, depending |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
679 on the capabilities of the target. Cope with them. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
680 if (partmode == VOIDmode && VECTOR_MODE_P (innermode)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
681 partmode = GET_MODE_INNER (innermode); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
682 else if (partmode == VOIDmode) |
111 | 683 partmode = mode_for_size (inner_size * BITS_PER_UNIT, |
684 GET_MODE_CLASS (innermode), 0).require (); | |
0 | 685 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
686 return simplify_gen_subreg (outermode, part, partmode, final_offset); |
0 | 687 } |
688 | |
689 /* Wrapper around simplify_gen_subreg which handles CONCATN. */ | |
690 | |
691 static rtx | |
111 | 692 simplify_gen_subreg_concatn (machine_mode outermode, rtx op, |
693 machine_mode innermode, unsigned int byte) | |
0 | 694 { |
695 rtx ret; | |
696 | |
697 /* We have to handle generating a SUBREG of a SUBREG of a CONCATN. | |
698 If OP is a SUBREG of a CONCATN, then it must be a simple mode | |
699 change with the same size and offset 0, or it must extract a | |
700 part. We shouldn't see anything else here. */ | |
701 if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == CONCATN) | |
702 { | |
703 rtx op2; | |
704 | |
131 | 705 if (known_eq (GET_MODE_SIZE (GET_MODE (op)), |
706 GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))) | |
707 && known_eq (SUBREG_BYTE (op), 0)) | |
0 | 708 return simplify_gen_subreg_concatn (outermode, SUBREG_REG (op), |
709 GET_MODE (SUBREG_REG (op)), byte); | |
710 | |
711 op2 = simplify_subreg_concatn (GET_MODE (op), SUBREG_REG (op), | |
712 SUBREG_BYTE (op)); | |
713 if (op2 == NULL_RTX) | |
714 { | |
715 /* We don't handle paradoxical subregs here. */ | |
111 | 716 gcc_assert (!paradoxical_subreg_p (outermode, GET_MODE (op))); |
717 gcc_assert (!paradoxical_subreg_p (op)); | |
0 | 718 op2 = simplify_subreg_concatn (outermode, SUBREG_REG (op), |
719 byte + SUBREG_BYTE (op)); | |
720 gcc_assert (op2 != NULL_RTX); | |
721 return op2; | |
722 } | |
723 | |
724 op = op2; | |
725 gcc_assert (op != NULL_RTX); | |
726 gcc_assert (innermode == GET_MODE (op)); | |
727 } | |
728 | |
729 if (GET_CODE (op) == CONCATN) | |
730 return simplify_subreg_concatn (outermode, op, byte); | |
731 | |
732 ret = simplify_gen_subreg (outermode, op, innermode, byte); | |
733 | |
734 /* If we see an insn like (set (reg:DI) (subreg:DI (reg:SI) 0)) then | |
735 resolve_simple_move will ask for the high part of the paradoxical | |
736 subreg, which does not have a value. Just return a zero. */ | |
737 if (ret == NULL_RTX | |
111 | 738 && paradoxical_subreg_p (op)) |
0 | 739 return CONST0_RTX (outermode); |
740 | |
741 gcc_assert (ret != NULL_RTX); | |
742 return ret; | |
743 } | |
744 | |
745 /* Return whether we should resolve X into the registers into which it | |
746 was decomposed. */ | |
747 | |
748 static bool | |
749 resolve_reg_p (rtx x) | |
750 { | |
751 return GET_CODE (x) == CONCATN; | |
752 } | |
753 | |
754 /* Return whether X is a SUBREG of a register which we need to | |
755 resolve. */ | |
756 | |
757 static bool | |
758 resolve_subreg_p (rtx x) | |
759 { | |
760 if (GET_CODE (x) != SUBREG) | |
761 return false; | |
762 return resolve_reg_p (SUBREG_REG (x)); | |
763 } | |
764 | |
111 | 765 /* Look for SUBREGs in *LOC which need to be decomposed. */ |
0 | 766 |
111 | 767 static bool |
768 resolve_subreg_use (rtx *loc, rtx insn) | |
0 | 769 { |
111 | 770 subrtx_ptr_iterator::array_type array; |
771 FOR_EACH_SUBRTX_PTR (iter, array, loc, NONCONST) | |
0 | 772 { |
111 | 773 rtx *loc = *iter; |
774 rtx x = *loc; | |
775 if (resolve_subreg_p (x)) | |
776 { | |
777 x = simplify_subreg_concatn (GET_MODE (x), SUBREG_REG (x), | |
778 SUBREG_BYTE (x)); | |
0 | 779 |
111 | 780 /* It is possible for a note to contain a reference which we can |
781 decompose. In this case, return 1 to the caller to indicate | |
782 that the note must be removed. */ | |
783 if (!x) | |
784 { | |
785 gcc_assert (!insn); | |
786 return true; | |
787 } | |
788 | |
789 validate_change (insn, loc, x, 1); | |
790 iter.skip_subrtxes (); | |
0 | 791 } |
111 | 792 else if (resolve_reg_p (x)) |
793 /* Return 1 to the caller to indicate that we found a direct | |
794 reference to a register which is being decomposed. This can | |
795 happen inside notes, multiword shift or zero-extend | |
796 instructions. */ | |
797 return true; | |
0 | 798 } |
799 | |
111 | 800 return false; |
0 | 801 } |
802 | |
803 /* Resolve any decomposed registers which appear in register notes on | |
804 INSN. */ | |
805 | |
806 static void | |
111 | 807 resolve_reg_notes (rtx_insn *insn) |
0 | 808 { |
809 rtx *pnote, note; | |
810 | |
811 note = find_reg_equal_equiv_note (insn); | |
812 if (note) | |
813 { | |
814 int old_count = num_validated_changes (); | |
111 | 815 if (resolve_subreg_use (&XEXP (note, 0), NULL_RTX)) |
0 | 816 remove_note (insn, note); |
817 else | |
818 if (old_count != num_validated_changes ()) | |
819 df_notes_rescan (insn); | |
820 } | |
821 | |
822 pnote = ®_NOTES (insn); | |
823 while (*pnote != NULL_RTX) | |
824 { | |
825 bool del = false; | |
826 | |
827 note = *pnote; | |
828 switch (REG_NOTE_KIND (note)) | |
829 { | |
830 case REG_DEAD: | |
831 case REG_UNUSED: | |
832 if (resolve_reg_p (XEXP (note, 0))) | |
833 del = true; | |
834 break; | |
835 | |
836 default: | |
837 break; | |
838 } | |
839 | |
840 if (del) | |
841 *pnote = XEXP (note, 1); | |
842 else | |
843 pnote = &XEXP (note, 1); | |
844 } | |
845 } | |
846 | |
847 /* Return whether X can be decomposed into subwords. */ | |
848 | |
849 static bool | |
850 can_decompose_p (rtx x) | |
851 { | |
852 if (REG_P (x)) | |
853 { | |
854 unsigned int regno = REGNO (x); | |
855 | |
856 if (HARD_REGISTER_NUM_P (regno)) | |
111 | 857 { |
131 | 858 unsigned int byte, num_bytes, num_words; |
111 | 859 |
131 | 860 if (!interesting_mode_p (GET_MODE (x), &num_bytes, &num_words)) |
861 return false; | |
111 | 862 for (byte = 0; byte < num_bytes; byte += UNITS_PER_WORD) |
863 if (simplify_subreg_regno (regno, GET_MODE (x), byte, word_mode) < 0) | |
864 return false; | |
865 return true; | |
866 } | |
0 | 867 else |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
868 return !bitmap_bit_p (subreg_context, regno); |
0 | 869 } |
870 | |
871 return true; | |
872 } | |
873 | |
145 | 874 /* OPND is a concatn operand this is used with a simple move operator. |
875 Return a new rtx with the concatn's operands swapped. */ | |
876 | |
877 static rtx | |
878 resolve_operand_for_swap_move_operator (rtx opnd) | |
879 { | |
880 gcc_assert (GET_CODE (opnd) == CONCATN); | |
881 rtx concatn = copy_rtx (opnd); | |
882 rtx op0 = XVECEXP (concatn, 0, 0); | |
883 rtx op1 = XVECEXP (concatn, 0, 1); | |
884 XVECEXP (concatn, 0, 0) = op1; | |
885 XVECEXP (concatn, 0, 1) = op0; | |
886 return concatn; | |
887 } | |
888 | |
0 | 889 /* Decompose the registers used in a simple move SET within INSN. If |
890 we don't change anything, return INSN, otherwise return the start | |
891 of the sequence of moves. */ | |
892 | |
111 | 893 static rtx_insn * |
894 resolve_simple_move (rtx set, rtx_insn *insn) | |
0 | 895 { |
145 | 896 rtx src, dest, real_dest, src_op; |
111 | 897 rtx_insn *insns; |
898 machine_mode orig_mode, dest_mode; | |
131 | 899 unsigned int orig_size, words; |
0 | 900 bool pushing; |
901 | |
902 src = SET_SRC (set); | |
903 dest = SET_DEST (set); | |
904 orig_mode = GET_MODE (dest); | |
905 | |
131 | 906 if (!interesting_mode_p (orig_mode, &orig_size, &words)) |
907 gcc_unreachable (); | |
111 | 908 gcc_assert (words > 1); |
0 | 909 |
910 start_sequence (); | |
911 | |
912 /* We have to handle copying from a SUBREG of a decomposed reg where | |
913 the SUBREG is larger than word size. Rather than assume that we | |
914 can take a word_mode SUBREG of the destination, we copy to a new | |
915 register and then copy that to the destination. */ | |
916 | |
917 real_dest = NULL_RTX; | |
918 | |
145 | 919 if ((src_op = operand_for_swap_move_operator (src)) != NULL_RTX) |
920 { | |
921 if (resolve_reg_p (dest)) | |
922 { | |
923 /* DEST is a CONCATN, so swap its operands and strip | |
924 SRC's operator. */ | |
925 dest = resolve_operand_for_swap_move_operator (dest); | |
926 src = src_op; | |
927 } | |
928 else if (resolve_reg_p (src_op)) | |
929 { | |
930 /* SRC is an operation on a CONCATN, so strip the operator and | |
931 swap the CONCATN's operands. */ | |
932 src = resolve_operand_for_swap_move_operator (src_op); | |
933 } | |
934 } | |
935 | |
0 | 936 if (GET_CODE (src) == SUBREG |
937 && resolve_reg_p (SUBREG_REG (src)) | |
131 | 938 && (maybe_ne (SUBREG_BYTE (src), 0) |
939 || maybe_ne (orig_size, GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))) | |
0 | 940 { |
941 real_dest = dest; | |
942 dest = gen_reg_rtx (orig_mode); | |
943 if (REG_P (real_dest)) | |
944 REG_ATTRS (dest) = REG_ATTRS (real_dest); | |
945 } | |
946 | |
947 /* Similarly if we are copying to a SUBREG of a decomposed reg where | |
948 the SUBREG is larger than word size. */ | |
949 | |
950 if (GET_CODE (dest) == SUBREG | |
951 && resolve_reg_p (SUBREG_REG (dest)) | |
131 | 952 && (maybe_ne (SUBREG_BYTE (dest), 0) |
953 || maybe_ne (orig_size, | |
954 GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))))) | |
0 | 955 { |
111 | 956 rtx reg, smove; |
957 rtx_insn *minsn; | |
0 | 958 |
959 reg = gen_reg_rtx (orig_mode); | |
960 minsn = emit_move_insn (reg, src); | |
961 smove = single_set (minsn); | |
962 gcc_assert (smove != NULL_RTX); | |
963 resolve_simple_move (smove, minsn); | |
964 src = reg; | |
965 } | |
966 | |
967 /* If we didn't have any big SUBREGS of decomposed registers, and | |
968 neither side of the move is a register we are decomposing, then | |
969 we don't have to do anything here. */ | |
970 | |
971 if (src == SET_SRC (set) | |
972 && dest == SET_DEST (set) | |
973 && !resolve_reg_p (src) | |
974 && !resolve_subreg_p (src) | |
975 && !resolve_reg_p (dest) | |
976 && !resolve_subreg_p (dest)) | |
977 { | |
978 end_sequence (); | |
979 return insn; | |
980 } | |
981 | |
982 /* It's possible for the code to use a subreg of a decomposed | |
983 register while forming an address. We need to handle that before | |
984 passing the address to emit_move_insn. We pass NULL_RTX as the | |
145 | 985 insn parameter to resolve_subreg_use because we cannot validate |
0 | 986 the insn yet. */ |
987 if (MEM_P (src) || MEM_P (dest)) | |
988 { | |
989 int acg; | |
990 | |
991 if (MEM_P (src)) | |
111 | 992 resolve_subreg_use (&XEXP (src, 0), NULL_RTX); |
0 | 993 if (MEM_P (dest)) |
111 | 994 resolve_subreg_use (&XEXP (dest, 0), NULL_RTX); |
0 | 995 acg = apply_change_group (); |
996 gcc_assert (acg); | |
997 } | |
998 | |
999 /* If SRC is a register which we can't decompose, or has side | |
1000 effects, we need to move via a temporary register. */ | |
1001 | |
1002 if (!can_decompose_p (src) | |
1003 || side_effects_p (src) | |
1004 || GET_CODE (src) == ASM_OPERANDS) | |
1005 { | |
1006 rtx reg; | |
1007 | |
1008 reg = gen_reg_rtx (orig_mode); | |
111 | 1009 |
1010 if (AUTO_INC_DEC) | |
1011 { | |
1012 rtx_insn *move = emit_move_insn (reg, src); | |
1013 if (MEM_P (src)) | |
1014 { | |
1015 rtx note = find_reg_note (insn, REG_INC, NULL_RTX); | |
1016 if (note) | |
1017 add_reg_note (move, REG_INC, XEXP (note, 0)); | |
1018 } | |
1019 } | |
1020 else | |
1021 emit_move_insn (reg, src); | |
1022 | |
0 | 1023 src = reg; |
1024 } | |
1025 | |
1026 /* If DEST is a register which we can't decompose, or has side | |
1027 effects, we need to first move to a temporary register. We | |
1028 handle the common case of pushing an operand directly. We also | |
1029 go through a temporary register if it holds a floating point | |
1030 value. This gives us better code on systems which can't move | |
1031 data easily between integer and floating point registers. */ | |
1032 | |
1033 dest_mode = orig_mode; | |
1034 pushing = push_operand (dest, dest_mode); | |
1035 if (!can_decompose_p (dest) | |
1036 || (side_effects_p (dest) && !pushing) | |
1037 || (!SCALAR_INT_MODE_P (dest_mode) | |
1038 && !resolve_reg_p (dest) | |
1039 && !resolve_subreg_p (dest))) | |
1040 { | |
1041 if (real_dest == NULL_RTX) | |
1042 real_dest = dest; | |
1043 if (!SCALAR_INT_MODE_P (dest_mode)) | |
111 | 1044 dest_mode = int_mode_for_mode (dest_mode).require (); |
0 | 1045 dest = gen_reg_rtx (dest_mode); |
1046 if (REG_P (real_dest)) | |
1047 REG_ATTRS (dest) = REG_ATTRS (real_dest); | |
1048 } | |
1049 | |
1050 if (pushing) | |
1051 { | |
1052 unsigned int i, j, jinc; | |
1053 | |
131 | 1054 gcc_assert (orig_size % UNITS_PER_WORD == 0); |
0 | 1055 gcc_assert (GET_CODE (XEXP (dest, 0)) != PRE_MODIFY); |
1056 gcc_assert (GET_CODE (XEXP (dest, 0)) != POST_MODIFY); | |
1057 | |
1058 if (WORDS_BIG_ENDIAN == STACK_GROWS_DOWNWARD) | |
1059 { | |
1060 j = 0; | |
1061 jinc = 1; | |
1062 } | |
1063 else | |
1064 { | |
1065 j = words - 1; | |
1066 jinc = -1; | |
1067 } | |
1068 | |
1069 for (i = 0; i < words; ++i, j += jinc) | |
1070 { | |
1071 rtx temp; | |
1072 | |
1073 temp = copy_rtx (XEXP (dest, 0)); | |
1074 temp = adjust_automodify_address_nv (dest, word_mode, temp, | |
1075 j * UNITS_PER_WORD); | |
1076 emit_move_insn (temp, | |
1077 simplify_gen_subreg_concatn (word_mode, src, | |
1078 orig_mode, | |
1079 j * UNITS_PER_WORD)); | |
1080 } | |
1081 } | |
1082 else | |
1083 { | |
1084 unsigned int i; | |
1085 | |
1086 if (REG_P (dest) && !HARD_REGISTER_NUM_P (REGNO (dest))) | |
1087 emit_clobber (dest); | |
1088 | |
1089 for (i = 0; i < words; ++i) | |
1090 emit_move_insn (simplify_gen_subreg_concatn (word_mode, dest, | |
1091 dest_mode, | |
1092 i * UNITS_PER_WORD), | |
1093 simplify_gen_subreg_concatn (word_mode, src, | |
1094 orig_mode, | |
1095 i * UNITS_PER_WORD)); | |
1096 } | |
1097 | |
1098 if (real_dest != NULL_RTX) | |
1099 { | |
111 | 1100 rtx mdest, smove; |
1101 rtx_insn *minsn; | |
0 | 1102 |
1103 if (dest_mode == orig_mode) | |
1104 mdest = dest; | |
1105 else | |
1106 mdest = simplify_gen_subreg (orig_mode, dest, GET_MODE (dest), 0); | |
1107 minsn = emit_move_insn (real_dest, mdest); | |
1108 | |
111 | 1109 if (AUTO_INC_DEC && MEM_P (real_dest) |
1110 && !(resolve_reg_p (real_dest) || resolve_subreg_p (real_dest))) | |
1111 { | |
1112 rtx note = find_reg_note (insn, REG_INC, NULL_RTX); | |
1113 if (note) | |
1114 add_reg_note (minsn, REG_INC, XEXP (note, 0)); | |
1115 } | |
1116 | |
0 | 1117 smove = single_set (minsn); |
1118 gcc_assert (smove != NULL_RTX); | |
1119 | |
1120 resolve_simple_move (smove, minsn); | |
1121 } | |
1122 | |
1123 insns = get_insns (); | |
1124 end_sequence (); | |
1125 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1126 copy_reg_eh_region_note_forward (insn, insns, NULL_RTX); |
0 | 1127 |
1128 emit_insn_before (insns, insn); | |
1129 | |
111 | 1130 /* If we get here via self-recursion, then INSN is not yet in the insns |
1131 chain and delete_insn will fail. We only want to remove INSN from the | |
1132 current sequence. See PR56738. */ | |
1133 if (in_sequence_p ()) | |
1134 remove_insn (insn); | |
1135 else | |
1136 delete_insn (insn); | |
0 | 1137 |
1138 return insns; | |
1139 } | |
1140 | |
1141 /* Change a CLOBBER of a decomposed register into a CLOBBER of the | |
1142 component registers. Return whether we changed something. */ | |
1143 | |
1144 static bool | |
111 | 1145 resolve_clobber (rtx pat, rtx_insn *insn) |
0 | 1146 { |
1147 rtx reg; | |
111 | 1148 machine_mode orig_mode; |
131 | 1149 unsigned int orig_size, words, i; |
0 | 1150 int ret; |
1151 | |
1152 reg = XEXP (pat, 0); | |
1153 if (!resolve_reg_p (reg) && !resolve_subreg_p (reg)) | |
1154 return false; | |
1155 | |
1156 orig_mode = GET_MODE (reg); | |
131 | 1157 if (!interesting_mode_p (orig_mode, &orig_size, &words)) |
1158 gcc_unreachable (); | |
0 | 1159 |
1160 ret = validate_change (NULL_RTX, &XEXP (pat, 0), | |
1161 simplify_gen_subreg_concatn (word_mode, reg, | |
1162 orig_mode, 0), | |
1163 0); | |
1164 df_insn_rescan (insn); | |
1165 gcc_assert (ret != 0); | |
1166 | |
1167 for (i = words - 1; i > 0; --i) | |
1168 { | |
1169 rtx x; | |
1170 | |
1171 x = simplify_gen_subreg_concatn (word_mode, reg, orig_mode, | |
1172 i * UNITS_PER_WORD); | |
1173 x = gen_rtx_CLOBBER (VOIDmode, x); | |
1174 emit_insn_after (x, insn); | |
1175 } | |
1176 | |
1177 resolve_reg_notes (insn); | |
1178 | |
1179 return true; | |
1180 } | |
1181 | |
1182 /* A USE of a decomposed register is no longer meaningful. Return | |
1183 whether we changed something. */ | |
1184 | |
1185 static bool | |
111 | 1186 resolve_use (rtx pat, rtx_insn *insn) |
0 | 1187 { |
1188 if (resolve_reg_p (XEXP (pat, 0)) || resolve_subreg_p (XEXP (pat, 0))) | |
1189 { | |
1190 delete_insn (insn); | |
1191 return true; | |
1192 } | |
1193 | |
1194 resolve_reg_notes (insn); | |
1195 | |
1196 return false; | |
1197 } | |
1198 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1199 /* A VAR_LOCATION can be simplified. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1200 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1201 static void |
111 | 1202 resolve_debug (rtx_insn *insn) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1203 { |
111 | 1204 subrtx_ptr_iterator::array_type array; |
1205 FOR_EACH_SUBRTX_PTR (iter, array, &PATTERN (insn), NONCONST) | |
1206 { | |
1207 rtx *loc = *iter; | |
1208 rtx x = *loc; | |
1209 if (resolve_subreg_p (x)) | |
1210 { | |
1211 x = simplify_subreg_concatn (GET_MODE (x), SUBREG_REG (x), | |
1212 SUBREG_BYTE (x)); | |
1213 | |
1214 if (x) | |
1215 *loc = x; | |
1216 else | |
1217 x = copy_rtx (*loc); | |
1218 } | |
1219 if (resolve_reg_p (x)) | |
1220 *loc = copy_rtx (x); | |
1221 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1222 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1223 df_insn_rescan (insn); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1224 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1225 resolve_reg_notes (insn); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1226 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1227 |
111 | 1228 /* Check if INSN is a decomposable multiword-shift or zero-extend and |
1229 set the decomposable_context bitmap accordingly. SPEED_P is true | |
1230 if we are optimizing INSN for speed rather than size. Return true | |
1231 if INSN is decomposable. */ | |
0 | 1232 |
111 | 1233 static bool |
1234 find_decomposable_shift_zext (rtx_insn *insn, bool speed_p) | |
0 | 1235 { |
1236 rtx set; | |
1237 rtx op; | |
1238 rtx op_operand; | |
1239 | |
1240 set = single_set (insn); | |
1241 if (!set) | |
111 | 1242 return false; |
0 | 1243 |
1244 op = SET_SRC (set); | |
1245 if (GET_CODE (op) != ASHIFT | |
1246 && GET_CODE (op) != LSHIFTRT | |
111 | 1247 && GET_CODE (op) != ASHIFTRT |
0 | 1248 && GET_CODE (op) != ZERO_EXTEND) |
111 | 1249 return false; |
0 | 1250 |
1251 op_operand = XEXP (op, 0); | |
1252 if (!REG_P (SET_DEST (set)) || !REG_P (op_operand) | |
1253 || HARD_REGISTER_NUM_P (REGNO (SET_DEST (set))) | |
1254 || HARD_REGISTER_NUM_P (REGNO (op_operand)) | |
111 | 1255 || GET_MODE (op) != twice_word_mode) |
1256 return false; | |
0 | 1257 |
1258 if (GET_CODE (op) == ZERO_EXTEND) | |
1259 { | |
1260 if (GET_MODE (op_operand) != word_mode | |
111 | 1261 || !choices[speed_p].splitting_zext) |
1262 return false; | |
0 | 1263 } |
1264 else /* left or right shift */ | |
1265 { | |
111 | 1266 bool *splitting = (GET_CODE (op) == ASHIFT |
1267 ? choices[speed_p].splitting_ashift | |
1268 : GET_CODE (op) == ASHIFTRT | |
1269 ? choices[speed_p].splitting_ashiftrt | |
1270 : choices[speed_p].splitting_lshiftrt); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1271 if (!CONST_INT_P (XEXP (op, 1)) |
111 | 1272 || !IN_RANGE (INTVAL (XEXP (op, 1)), BITS_PER_WORD, |
1273 2 * BITS_PER_WORD - 1) | |
1274 || !splitting[INTVAL (XEXP (op, 1)) - BITS_PER_WORD]) | |
1275 return false; | |
1276 | |
1277 bitmap_set_bit (decomposable_context, REGNO (op_operand)); | |
0 | 1278 } |
1279 | |
1280 bitmap_set_bit (decomposable_context, REGNO (SET_DEST (set))); | |
1281 | |
111 | 1282 return true; |
0 | 1283 } |
1284 | |
1285 /* Decompose a more than word wide shift (in INSN) of a multiword | |
1286 pseudo or a multiword zero-extend of a wordmode pseudo into a move | |
1287 and 'set to zero' insn. Return a pointer to the new insn when a | |
1288 replacement was done. */ | |
1289 | |
111 | 1290 static rtx_insn * |
1291 resolve_shift_zext (rtx_insn *insn) | |
0 | 1292 { |
1293 rtx set; | |
1294 rtx op; | |
1295 rtx op_operand; | |
111 | 1296 rtx_insn *insns; |
1297 rtx src_reg, dest_reg, dest_upper, upper_src = NULL_RTX; | |
0 | 1298 int src_reg_num, dest_reg_num, offset1, offset2, src_offset; |
111 | 1299 scalar_int_mode inner_mode; |
0 | 1300 |
1301 set = single_set (insn); | |
1302 if (!set) | |
111 | 1303 return NULL; |
0 | 1304 |
1305 op = SET_SRC (set); | |
1306 if (GET_CODE (op) != ASHIFT | |
1307 && GET_CODE (op) != LSHIFTRT | |
111 | 1308 && GET_CODE (op) != ASHIFTRT |
0 | 1309 && GET_CODE (op) != ZERO_EXTEND) |
111 | 1310 return NULL; |
0 | 1311 |
1312 op_operand = XEXP (op, 0); | |
111 | 1313 if (!is_a <scalar_int_mode> (GET_MODE (op_operand), &inner_mode)) |
1314 return NULL; | |
0 | 1315 |
111 | 1316 /* We can tear this operation apart only if the regs were already |
1317 torn apart. */ | |
0 | 1318 if (!resolve_reg_p (SET_DEST (set)) && !resolve_reg_p (op_operand)) |
111 | 1319 return NULL; |
0 | 1320 |
1321 /* src_reg_num is the number of the word mode register which we | |
1322 are operating on. For a left shift and a zero_extend on little | |
1323 endian machines this is register 0. */ | |
111 | 1324 src_reg_num = (GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFTRT) |
1325 ? 1 : 0; | |
0 | 1326 |
111 | 1327 if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD) |
0 | 1328 src_reg_num = 1 - src_reg_num; |
1329 | |
1330 if (GET_CODE (op) == ZERO_EXTEND) | |
1331 dest_reg_num = WORDS_BIG_ENDIAN ? 1 : 0; | |
1332 else | |
1333 dest_reg_num = 1 - src_reg_num; | |
1334 | |
1335 offset1 = UNITS_PER_WORD * dest_reg_num; | |
1336 offset2 = UNITS_PER_WORD * (1 - dest_reg_num); | |
1337 src_offset = UNITS_PER_WORD * src_reg_num; | |
1338 | |
1339 start_sequence (); | |
1340 | |
1341 dest_reg = simplify_gen_subreg_concatn (word_mode, SET_DEST (set), | |
1342 GET_MODE (SET_DEST (set)), | |
1343 offset1); | |
111 | 1344 dest_upper = simplify_gen_subreg_concatn (word_mode, SET_DEST (set), |
1345 GET_MODE (SET_DEST (set)), | |
1346 offset2); | |
0 | 1347 src_reg = simplify_gen_subreg_concatn (word_mode, op_operand, |
1348 GET_MODE (op_operand), | |
1349 src_offset); | |
111 | 1350 if (GET_CODE (op) == ASHIFTRT |
1351 && INTVAL (XEXP (op, 1)) != 2 * BITS_PER_WORD - 1) | |
1352 upper_src = expand_shift (RSHIFT_EXPR, word_mode, copy_rtx (src_reg), | |
1353 BITS_PER_WORD - 1, NULL_RTX, 0); | |
1354 | |
0 | 1355 if (GET_CODE (op) != ZERO_EXTEND) |
1356 { | |
1357 int shift_count = INTVAL (XEXP (op, 1)); | |
1358 if (shift_count > BITS_PER_WORD) | |
1359 src_reg = expand_shift (GET_CODE (op) == ASHIFT ? | |
1360 LSHIFT_EXPR : RSHIFT_EXPR, | |
1361 word_mode, src_reg, | |
111 | 1362 shift_count - BITS_PER_WORD, |
1363 dest_reg, GET_CODE (op) != ASHIFTRT); | |
0 | 1364 } |
1365 | |
1366 if (dest_reg != src_reg) | |
1367 emit_move_insn (dest_reg, src_reg); | |
111 | 1368 if (GET_CODE (op) != ASHIFTRT) |
1369 emit_move_insn (dest_upper, CONST0_RTX (word_mode)); | |
1370 else if (INTVAL (XEXP (op, 1)) == 2 * BITS_PER_WORD - 1) | |
1371 emit_move_insn (dest_upper, copy_rtx (src_reg)); | |
1372 else | |
1373 emit_move_insn (dest_upper, upper_src); | |
0 | 1374 insns = get_insns (); |
1375 | |
1376 end_sequence (); | |
1377 | |
1378 emit_insn_before (insns, insn); | |
1379 | |
1380 if (dump_file) | |
1381 { | |
111 | 1382 rtx_insn *in; |
0 | 1383 fprintf (dump_file, "; Replacing insn: %d with insns: ", INSN_UID (insn)); |
1384 for (in = insns; in != insn; in = NEXT_INSN (in)) | |
1385 fprintf (dump_file, "%d ", INSN_UID (in)); | |
1386 fprintf (dump_file, "\n"); | |
1387 } | |
1388 | |
1389 delete_insn (insn); | |
1390 return insns; | |
1391 } | |
1392 | |
111 | 1393 /* Print to dump_file a description of what we're doing with shift code CODE. |
1394 SPLITTING[X] is true if we are splitting shifts by X + BITS_PER_WORD. */ | |
1395 | |
1396 static void | |
1397 dump_shift_choices (enum rtx_code code, bool *splitting) | |
1398 { | |
1399 int i; | |
1400 const char *sep; | |
1401 | |
1402 fprintf (dump_file, | |
1403 " Splitting mode %s for %s lowering with shift amounts = ", | |
1404 GET_MODE_NAME (twice_word_mode), GET_RTX_NAME (code)); | |
1405 sep = ""; | |
1406 for (i = 0; i < BITS_PER_WORD; i++) | |
1407 if (splitting[i]) | |
1408 { | |
1409 fprintf (dump_file, "%s%d", sep, i + BITS_PER_WORD); | |
1410 sep = ","; | |
1411 } | |
1412 fprintf (dump_file, "\n"); | |
1413 } | |
1414 | |
1415 /* Print to dump_file a description of what we're doing when optimizing | |
1416 for speed or size; SPEED_P says which. DESCRIPTION is a description | |
1417 of the SPEED_P choice. */ | |
0 | 1418 |
1419 static void | |
111 | 1420 dump_choices (bool speed_p, const char *description) |
1421 { | |
131 | 1422 unsigned int size, factor, i; |
111 | 1423 |
1424 fprintf (dump_file, "Choices when optimizing for %s:\n", description); | |
1425 | |
1426 for (i = 0; i < MAX_MACHINE_MODE; i++) | |
131 | 1427 if (interesting_mode_p ((machine_mode) i, &size, &factor) |
1428 && factor > 1) | |
111 | 1429 fprintf (dump_file, " %s mode %s for copy lowering.\n", |
1430 choices[speed_p].move_modes_to_split[i] | |
1431 ? "Splitting" | |
1432 : "Skipping", | |
1433 GET_MODE_NAME ((machine_mode) i)); | |
1434 | |
1435 fprintf (dump_file, " %s mode %s for zero_extend lowering.\n", | |
1436 choices[speed_p].splitting_zext ? "Splitting" : "Skipping", | |
1437 GET_MODE_NAME (twice_word_mode)); | |
1438 | |
1439 dump_shift_choices (ASHIFT, choices[speed_p].splitting_ashift); | |
1440 dump_shift_choices (LSHIFTRT, choices[speed_p].splitting_lshiftrt); | |
1441 dump_shift_choices (ASHIFTRT, choices[speed_p].splitting_ashiftrt); | |
1442 fprintf (dump_file, "\n"); | |
1443 } | |
1444 | |
1445 /* Look for registers which are always accessed via word-sized SUBREGs | |
1446 or -if DECOMPOSE_COPIES is true- via copies. Decompose these | |
1447 registers into several word-sized pseudo-registers. */ | |
1448 | |
1449 static void | |
1450 decompose_multiword_subregs (bool decompose_copies) | |
0 | 1451 { |
1452 unsigned int max; | |
1453 basic_block bb; | |
111 | 1454 bool speed_p; |
0 | 1455 |
111 | 1456 if (dump_file) |
1457 { | |
1458 dump_choices (false, "size"); | |
1459 dump_choices (true, "speed"); | |
1460 } | |
1461 | |
1462 /* Check if this target even has any modes to consider lowering. */ | |
1463 if (!choices[false].something_to_do && !choices[true].something_to_do) | |
1464 { | |
1465 if (dump_file) | |
1466 fprintf (dump_file, "Nothing to do!\n"); | |
1467 return; | |
1468 } | |
0 | 1469 |
1470 max = max_reg_num (); | |
1471 | |
1472 /* First see if there are any multi-word pseudo-registers. If there | |
1473 aren't, there is nothing we can do. This should speed up this | |
1474 pass in the normal case, since it should be faster than scanning | |
1475 all the insns. */ | |
1476 { | |
1477 unsigned int i; | |
111 | 1478 bool useful_modes_seen = false; |
0 | 1479 |
1480 for (i = FIRST_PSEUDO_REGISTER; i < max; ++i) | |
111 | 1481 if (regno_reg_rtx[i] != NULL) |
1482 { | |
1483 machine_mode mode = GET_MODE (regno_reg_rtx[i]); | |
1484 if (choices[false].move_modes_to_split[(int) mode] | |
1485 || choices[true].move_modes_to_split[(int) mode]) | |
1486 { | |
1487 useful_modes_seen = true; | |
1488 break; | |
1489 } | |
1490 } | |
1491 | |
1492 if (!useful_modes_seen) | |
0 | 1493 { |
111 | 1494 if (dump_file) |
1495 fprintf (dump_file, "Nothing to lower in this function.\n"); | |
1496 return; | |
0 | 1497 } |
1498 } | |
1499 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1500 if (df) |
111 | 1501 { |
1502 df_set_flags (DF_DEFER_INSN_RESCAN); | |
1503 run_word_dce (); | |
1504 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1505 |
111 | 1506 /* FIXME: It may be possible to change this code to look for each |
1507 multi-word pseudo-register and to find each insn which sets or | |
1508 uses that register. That should be faster than scanning all the | |
1509 insns. */ | |
0 | 1510 |
1511 decomposable_context = BITMAP_ALLOC (NULL); | |
1512 non_decomposable_context = BITMAP_ALLOC (NULL); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1513 subreg_context = BITMAP_ALLOC (NULL); |
0 | 1514 |
111 | 1515 reg_copy_graph.create (max); |
1516 reg_copy_graph.safe_grow_cleared (max); | |
1517 memset (reg_copy_graph.address (), 0, sizeof (bitmap) * max); | |
0 | 1518 |
111 | 1519 speed_p = optimize_function_for_speed_p (cfun); |
1520 FOR_EACH_BB_FN (bb, cfun) | |
0 | 1521 { |
111 | 1522 rtx_insn *insn; |
0 | 1523 |
1524 FOR_BB_INSNS (bb, insn) | |
1525 { | |
1526 rtx set; | |
1527 enum classify_move_insn cmi; | |
1528 int i, n; | |
1529 | |
1530 if (!INSN_P (insn) | |
1531 || GET_CODE (PATTERN (insn)) == CLOBBER | |
1532 || GET_CODE (PATTERN (insn)) == USE) | |
1533 continue; | |
1534 | |
111 | 1535 recog_memoized (insn); |
1536 | |
1537 if (find_decomposable_shift_zext (insn, speed_p)) | |
0 | 1538 continue; |
1539 | |
1540 extract_insn (insn); | |
1541 | |
111 | 1542 set = simple_move (insn, speed_p); |
0 | 1543 |
1544 if (!set) | |
1545 cmi = NOT_SIMPLE_MOVE; | |
1546 else | |
1547 { | |
111 | 1548 /* We mark pseudo-to-pseudo copies as decomposable during the |
1549 second pass only. The first pass is so early that there is | |
1550 good chance such moves will be optimized away completely by | |
1551 subsequent optimizations anyway. | |
1552 | |
1553 However, we call find_pseudo_copy even during the first pass | |
1554 so as to properly set up the reg_copy_graph. */ | |
0 | 1555 if (find_pseudo_copy (set)) |
111 | 1556 cmi = decompose_copies? DECOMPOSABLE_SIMPLE_MOVE : SIMPLE_MOVE; |
0 | 1557 else |
1558 cmi = SIMPLE_MOVE; | |
1559 } | |
1560 | |
1561 n = recog_data.n_operands; | |
1562 for (i = 0; i < n; ++i) | |
1563 { | |
111 | 1564 find_decomposable_subregs (&recog_data.operand[i], &cmi); |
0 | 1565 |
1566 /* We handle ASM_OPERANDS as a special case to support | |
1567 things like x86 rdtsc which returns a DImode value. | |
1568 We can decompose the output, which will certainly be | |
1569 operand 0, but not the inputs. */ | |
1570 | |
1571 if (cmi == SIMPLE_MOVE | |
1572 && GET_CODE (SET_SRC (set)) == ASM_OPERANDS) | |
1573 { | |
1574 gcc_assert (i == 0); | |
1575 cmi = NOT_SIMPLE_MOVE; | |
1576 } | |
1577 } | |
1578 } | |
1579 } | |
1580 | |
1581 bitmap_and_compl_into (decomposable_context, non_decomposable_context); | |
1582 if (!bitmap_empty_p (decomposable_context)) | |
1583 { | |
1584 unsigned int i; | |
1585 sbitmap_iterator sbi; | |
1586 bitmap_iterator iter; | |
1587 unsigned int regno; | |
1588 | |
1589 propagate_pseudo_copies (); | |
1590 | |
111 | 1591 auto_sbitmap sub_blocks (last_basic_block_for_fn (cfun)); |
1592 bitmap_clear (sub_blocks); | |
0 | 1593 |
1594 EXECUTE_IF_SET_IN_BITMAP (decomposable_context, 0, regno, iter) | |
1595 decompose_register (regno); | |
1596 | |
111 | 1597 FOR_EACH_BB_FN (bb, cfun) |
0 | 1598 { |
111 | 1599 rtx_insn *insn; |
0 | 1600 |
1601 FOR_BB_INSNS (bb, insn) | |
1602 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1603 rtx pat; |
0 | 1604 |
1605 if (!INSN_P (insn)) | |
1606 continue; | |
1607 | |
1608 pat = PATTERN (insn); | |
1609 if (GET_CODE (pat) == CLOBBER) | |
1610 resolve_clobber (pat, insn); | |
1611 else if (GET_CODE (pat) == USE) | |
1612 resolve_use (pat, insn); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1613 else if (DEBUG_INSN_P (insn)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1614 resolve_debug (insn); |
0 | 1615 else |
1616 { | |
1617 rtx set; | |
1618 int i; | |
1619 | |
1620 recog_memoized (insn); | |
1621 extract_insn (insn); | |
1622 | |
111 | 1623 set = simple_move (insn, speed_p); |
0 | 1624 if (set) |
1625 { | |
111 | 1626 rtx_insn *orig_insn = insn; |
0 | 1627 bool cfi = control_flow_insn_p (insn); |
1628 | |
1629 /* We can end up splitting loads to multi-word pseudos | |
1630 into separate loads to machine word size pseudos. | |
1631 When this happens, we first had one load that can | |
1632 throw, and after resolve_simple_move we'll have a | |
1633 bunch of loads (at least two). All those loads may | |
1634 trap if we can have non-call exceptions, so they | |
1635 all will end the current basic block. We split the | |
1636 block after the outer loop over all insns, but we | |
1637 make sure here that we will be able to split the | |
1638 basic block and still produce the correct control | |
1639 flow graph for it. */ | |
1640 gcc_assert (!cfi | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1641 || (cfun->can_throw_non_call_exceptions |
0 | 1642 && can_throw_internal (insn))); |
1643 | |
1644 insn = resolve_simple_move (set, insn); | |
1645 if (insn != orig_insn) | |
1646 { | |
1647 recog_memoized (insn); | |
1648 extract_insn (insn); | |
1649 | |
1650 if (cfi) | |
111 | 1651 bitmap_set_bit (sub_blocks, bb->index); |
0 | 1652 } |
1653 } | |
1654 else | |
1655 { | |
111 | 1656 rtx_insn *decomposed_shift; |
0 | 1657 |
1658 decomposed_shift = resolve_shift_zext (insn); | |
1659 if (decomposed_shift != NULL_RTX) | |
1660 { | |
1661 insn = decomposed_shift; | |
1662 recog_memoized (insn); | |
1663 extract_insn (insn); | |
1664 } | |
1665 } | |
1666 | |
1667 for (i = recog_data.n_operands - 1; i >= 0; --i) | |
111 | 1668 resolve_subreg_use (recog_data.operand_loc[i], insn); |
0 | 1669 |
1670 resolve_reg_notes (insn); | |
1671 | |
1672 if (num_validated_changes () > 0) | |
1673 { | |
1674 for (i = recog_data.n_dups - 1; i >= 0; --i) | |
1675 { | |
1676 rtx *pl = recog_data.dup_loc[i]; | |
1677 int dup_num = recog_data.dup_num[i]; | |
1678 rtx *px = recog_data.operand_loc[dup_num]; | |
1679 | |
1680 validate_unshare_change (insn, pl, *px, 1); | |
1681 } | |
1682 | |
1683 i = apply_change_group (); | |
1684 gcc_assert (i); | |
1685 } | |
1686 } | |
1687 } | |
1688 } | |
1689 | |
1690 /* If we had insns to split that caused control flow insns in the middle | |
1691 of a basic block, split those blocks now. Note that we only handle | |
1692 the case where splitting a load has caused multiple possibly trapping | |
1693 loads to appear. */ | |
111 | 1694 EXECUTE_IF_SET_IN_BITMAP (sub_blocks, 0, i, sbi) |
0 | 1695 { |
111 | 1696 rtx_insn *insn, *end; |
0 | 1697 edge fallthru; |
1698 | |
111 | 1699 bb = BASIC_BLOCK_FOR_FN (cfun, i); |
0 | 1700 insn = BB_HEAD (bb); |
1701 end = BB_END (bb); | |
1702 | |
1703 while (insn != end) | |
1704 { | |
1705 if (control_flow_insn_p (insn)) | |
1706 { | |
1707 /* Split the block after insn. There will be a fallthru | |
1708 edge, which is OK so we keep it. We have to create the | |
1709 exception edges ourselves. */ | |
1710 fallthru = split_block (bb, insn); | |
1711 rtl_make_eh_edge (NULL, bb, BB_END (bb)); | |
1712 bb = fallthru->dest; | |
1713 insn = BB_HEAD (bb); | |
1714 } | |
1715 else | |
1716 insn = NEXT_INSN (insn); | |
1717 } | |
1718 } | |
1719 } | |
1720 | |
1721 { | |
1722 unsigned int i; | |
1723 bitmap b; | |
1724 | |
111 | 1725 FOR_EACH_VEC_ELT (reg_copy_graph, i, b) |
0 | 1726 if (b) |
1727 BITMAP_FREE (b); | |
1728 } | |
1729 | |
111 | 1730 reg_copy_graph.release (); |
0 | 1731 |
1732 BITMAP_FREE (decomposable_context); | |
1733 BITMAP_FREE (non_decomposable_context); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1734 BITMAP_FREE (subreg_context); |
0 | 1735 } |
1736 | |
1737 /* Implement first lower subreg pass. */ | |
1738 | |
111 | 1739 namespace { |
1740 | |
1741 const pass_data pass_data_lower_subreg = | |
1742 { | |
1743 RTL_PASS, /* type */ | |
1744 "subreg1", /* name */ | |
1745 OPTGROUP_NONE, /* optinfo_flags */ | |
1746 TV_LOWER_SUBREG, /* tv_id */ | |
1747 0, /* properties_required */ | |
1748 0, /* properties_provided */ | |
1749 0, /* properties_destroyed */ | |
1750 0, /* todo_flags_start */ | |
1751 0, /* todo_flags_finish */ | |
1752 }; | |
1753 | |
1754 class pass_lower_subreg : public rtl_opt_pass | |
0 | 1755 { |
111 | 1756 public: |
1757 pass_lower_subreg (gcc::context *ctxt) | |
1758 : rtl_opt_pass (pass_data_lower_subreg, ctxt) | |
1759 {} | |
1760 | |
1761 /* opt_pass methods: */ | |
1762 virtual bool gate (function *) { return flag_split_wide_types != 0; } | |
1763 virtual unsigned int execute (function *) | |
1764 { | |
1765 decompose_multiword_subregs (false); | |
1766 return 0; | |
1767 } | |
1768 | |
1769 }; // class pass_lower_subreg | |
1770 | |
1771 } // anon namespace | |
1772 | |
1773 rtl_opt_pass * | |
1774 make_pass_lower_subreg (gcc::context *ctxt) | |
1775 { | |
1776 return new pass_lower_subreg (ctxt); | |
0 | 1777 } |
1778 | |
1779 /* Implement second lower subreg pass. */ | |
1780 | |
111 | 1781 namespace { |
0 | 1782 |
111 | 1783 const pass_data pass_data_lower_subreg2 = |
0 | 1784 { |
111 | 1785 RTL_PASS, /* type */ |
1786 "subreg2", /* name */ | |
1787 OPTGROUP_NONE, /* optinfo_flags */ | |
1788 TV_LOWER_SUBREG, /* tv_id */ | |
1789 0, /* properties_required */ | |
1790 0, /* properties_provided */ | |
1791 0, /* properties_destroyed */ | |
1792 0, /* todo_flags_start */ | |
1793 TODO_df_finish, /* todo_flags_finish */ | |
0 | 1794 }; |
1795 | |
111 | 1796 class pass_lower_subreg2 : public rtl_opt_pass |
0 | 1797 { |
111 | 1798 public: |
1799 pass_lower_subreg2 (gcc::context *ctxt) | |
1800 : rtl_opt_pass (pass_data_lower_subreg2, ctxt) | |
1801 {} | |
1802 | |
1803 /* opt_pass methods: */ | |
145 | 1804 virtual bool gate (function *) { return flag_split_wide_types |
1805 && flag_split_wide_types_early; } | |
111 | 1806 virtual unsigned int execute (function *) |
1807 { | |
1808 decompose_multiword_subregs (true); | |
1809 return 0; | |
1810 } | |
1811 | |
1812 }; // class pass_lower_subreg2 | |
1813 | |
1814 } // anon namespace | |
1815 | |
1816 rtl_opt_pass * | |
1817 make_pass_lower_subreg2 (gcc::context *ctxt) | |
1818 { | |
1819 return new pass_lower_subreg2 (ctxt); | |
1820 } | |
145 | 1821 |
1822 /* Implement third lower subreg pass. */ | |
1823 | |
1824 namespace { | |
1825 | |
1826 const pass_data pass_data_lower_subreg3 = | |
1827 { | |
1828 RTL_PASS, /* type */ | |
1829 "subreg3", /* name */ | |
1830 OPTGROUP_NONE, /* optinfo_flags */ | |
1831 TV_LOWER_SUBREG, /* tv_id */ | |
1832 0, /* properties_required */ | |
1833 0, /* properties_provided */ | |
1834 0, /* properties_destroyed */ | |
1835 0, /* todo_flags_start */ | |
1836 TODO_df_finish, /* todo_flags_finish */ | |
1837 }; | |
1838 | |
1839 class pass_lower_subreg3 : public rtl_opt_pass | |
1840 { | |
1841 public: | |
1842 pass_lower_subreg3 (gcc::context *ctxt) | |
1843 : rtl_opt_pass (pass_data_lower_subreg3, ctxt) | |
1844 {} | |
1845 | |
1846 /* opt_pass methods: */ | |
1847 virtual bool gate (function *) { return flag_split_wide_types | |
1848 && !flag_split_wide_types_early; } | |
1849 virtual unsigned int execute (function *) | |
1850 { | |
1851 decompose_multiword_subregs (true); | |
1852 return 0; | |
1853 } | |
1854 | |
1855 }; // class pass_lower_subreg3 | |
1856 | |
1857 } // anon namespace | |
1858 | |
1859 rtl_opt_pass * | |
1860 make_pass_lower_subreg3 (gcc::context *ctxt) | |
1861 { | |
1862 return new pass_lower_subreg3 (ctxt); | |
1863 } |