]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/lower-subreg.c
* gfortran.dg/c_kind_params.f90: Check for stdint.h.
[thirdparty/gcc.git] / gcc / lower-subreg.c
CommitLineData
e53a16e7
ILT
1/* Decompose multiword subregs.
2 Copyright (C) 2007 Free Software Foundation, Inc.
3 Contributed by Richard Henderson <rth@redhat.com>
4 Ian Lance Taylor <iant@google.com>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
9dcd6f09 10Software Foundation; either version 3, or (at your option) any later
e53a16e7
ILT
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
9dcd6f09
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
e53a16e7
ILT
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "machmode.h"
26#include "tm.h"
27#include "rtl.h"
28#include "tm_p.h"
29#include "timevar.h"
30#include "flags.h"
31#include "insn-config.h"
32#include "obstack.h"
33#include "basic-block.h"
34#include "recog.h"
35#include "bitmap.h"
36#include "expr.h"
7984c787 37#include "except.h"
e53a16e7
ILT
38#include "regs.h"
39#include "tree-pass.h"
6fb5fa3c 40#include "df.h"
e53a16e7
ILT
41
42#ifdef STACK_GROWS_DOWNWARD
43# undef STACK_GROWS_DOWNWARD
44# define STACK_GROWS_DOWNWARD 1
45#else
46# define STACK_GROWS_DOWNWARD 0
47#endif
48
49DEF_VEC_P (bitmap);
50DEF_VEC_ALLOC_P (bitmap,heap);
51
52/* Decompose multi-word pseudo-registers into individual
53 pseudo-registers when possible. This is possible when all the uses
54 of a multi-word register are via SUBREG, or are copies of the
55 register to another location. Breaking apart the register permits
56 more CSE and permits better register allocation. */
57
58/* Bit N in this bitmap is set if regno N is used in a context in
59 which we can decompose it. */
60static bitmap decomposable_context;
61
62/* Bit N in this bitmap is set if regno N is used in a context in
63 which it can not be decomposed. */
64static bitmap non_decomposable_context;
65
66/* Bit N in the bitmap in element M of this array is set if there is a
67 copy from reg M to reg N. */
68static VEC(bitmap,heap) *reg_copy_graph;
69
2b54c30f
ILT
70/* Return whether X is a simple object which we can take a word_mode
71 subreg of. */
72
73static bool
74simple_move_operand (rtx x)
75{
76 if (GET_CODE (x) == SUBREG)
77 x = SUBREG_REG (x);
78
79 if (!OBJECT_P (x))
80 return false;
81
82 if (GET_CODE (x) == LABEL_REF
83 || GET_CODE (x) == SYMBOL_REF
7e0c3f57
ILT
84 || GET_CODE (x) == HIGH
85 || GET_CODE (x) == CONST)
2b54c30f
ILT
86 return false;
87
88 if (MEM_P (x)
89 && (MEM_VOLATILE_P (x)
90 || mode_dependent_address_p (XEXP (x, 0))))
91 return false;
92
93 return true;
94}
95
e53a16e7
ILT
96/* If INSN is a single set between two objects, return the single set.
97 Such an insn can always be decomposed. INSN should have been
98 passed to recog and extract_insn before this is called. */
99
100static rtx
101simple_move (rtx insn)
102{
103 rtx x;
104 rtx set;
105 enum machine_mode mode;
106
107 if (recog_data.n_operands != 2)
108 return NULL_RTX;
109
110 set = single_set (insn);
111 if (!set)
112 return NULL_RTX;
113
114 x = SET_DEST (set);
115 if (x != recog_data.operand[0] && x != recog_data.operand[1])
116 return NULL_RTX;
2b54c30f 117 if (!simple_move_operand (x))
e53a16e7
ILT
118 return NULL_RTX;
119
120 x = SET_SRC (set);
121 if (x != recog_data.operand[0] && x != recog_data.operand[1])
122 return NULL_RTX;
2b54c30f
ILT
123 /* For the src we can handle ASM_OPERANDS, and it is beneficial for
124 things like x86 rdtsc which returns a DImode value. */
125 if (GET_CODE (x) != ASM_OPERANDS
126 && !simple_move_operand (x))
e53a16e7
ILT
127 return NULL_RTX;
128
129 /* We try to decompose in integer modes, to avoid generating
130 inefficient code copying between integer and floating point
131 registers. That means that we can't decompose if this is a
132 non-integer mode for which there is no integer mode of the same
133 size. */
134 mode = GET_MODE (SET_SRC (set));
135 if (!SCALAR_INT_MODE_P (mode)
136 && (mode_for_size (GET_MODE_SIZE (mode) * BITS_PER_UNIT, MODE_INT, 0)
137 == BLKmode))
138 return NULL_RTX;
139
1f64a081
ILT
140 /* Reject PARTIAL_INT modes. They are used for processor specific
141 purposes and it's probably best not to tamper with them. */
142 if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
143 return NULL_RTX;
144
e53a16e7
ILT
145 return set;
146}
147
148/* If SET is a copy from one multi-word pseudo-register to another,
149 record that in reg_copy_graph. Return whether it is such a
150 copy. */
151
152static bool
153find_pseudo_copy (rtx set)
154{
155 rtx dest = SET_DEST (set);
156 rtx src = SET_SRC (set);
157 unsigned int rd, rs;
158 bitmap b;
159
160 if (!REG_P (dest) || !REG_P (src))
161 return false;
162
163 rd = REGNO (dest);
164 rs = REGNO (src);
165 if (HARD_REGISTER_NUM_P (rd) || HARD_REGISTER_NUM_P (rs))
166 return false;
167
168 if (GET_MODE_SIZE (GET_MODE (dest)) <= UNITS_PER_WORD)
169 return false;
170
171 b = VEC_index (bitmap, reg_copy_graph, rs);
172 if (b == NULL)
173 {
174 b = BITMAP_ALLOC (NULL);
175 VEC_replace (bitmap, reg_copy_graph, rs, b);
176 }
177
178 bitmap_set_bit (b, rd);
179
180 return true;
181}
182
183/* Look through the registers in DECOMPOSABLE_CONTEXT. For each case
184 where they are copied to another register, add the register to
185 which they are copied to DECOMPOSABLE_CONTEXT. Use
186 NON_DECOMPOSABLE_CONTEXT to limit this--we don't bother to track
187 copies of registers which are in NON_DECOMPOSABLE_CONTEXT. */
188
189static void
190propagate_pseudo_copies (void)
191{
192 bitmap queue, propagate;
193
194 queue = BITMAP_ALLOC (NULL);
195 propagate = BITMAP_ALLOC (NULL);
196
197 bitmap_copy (queue, decomposable_context);
198 do
199 {
200 bitmap_iterator iter;
201 unsigned int i;
202
203 bitmap_clear (propagate);
204
205 EXECUTE_IF_SET_IN_BITMAP (queue, 0, i, iter)
206 {
207 bitmap b = VEC_index (bitmap, reg_copy_graph, i);
208 if (b)
209 bitmap_ior_and_compl_into (propagate, b, non_decomposable_context);
210 }
211
212 bitmap_and_compl (queue, propagate, decomposable_context);
213 bitmap_ior_into (decomposable_context, propagate);
214 }
215 while (!bitmap_empty_p (queue));
216
217 BITMAP_FREE (queue);
218 BITMAP_FREE (propagate);
219}
220
221/* A pointer to one of these values is passed to
222 find_decomposable_subregs via for_each_rtx. */
223
224enum classify_move_insn
225{
226 /* Not a simple move from one location to another. */
227 NOT_SIMPLE_MOVE,
228 /* A simple move from one pseudo-register to another with no
229 REG_RETVAL note. */
230 SIMPLE_PSEUDO_REG_MOVE,
231 /* A simple move involving a non-pseudo-register, or from one
232 pseudo-register to another with a REG_RETVAL note. */
233 SIMPLE_MOVE
234};
235
236/* This is called via for_each_rtx. If we find a SUBREG which we
237 could use to decompose a pseudo-register, set a bit in
238 DECOMPOSABLE_CONTEXT. If we find an unadorned register which is
239 not a simple pseudo-register copy, DATA will point at the type of
240 move, and we set a bit in DECOMPOSABLE_CONTEXT or
241 NON_DECOMPOSABLE_CONTEXT as appropriate. */
242
243static int
244find_decomposable_subregs (rtx *px, void *data)
245{
246 enum classify_move_insn *pcmi = (enum classify_move_insn *) data;
247 rtx x = *px;
248
249 if (x == NULL_RTX)
250 return 0;
251
252 if (GET_CODE (x) == SUBREG)
253 {
254 rtx inner = SUBREG_REG (x);
255 unsigned int regno, outer_size, inner_size, outer_words, inner_words;
256
257 if (!REG_P (inner))
258 return 0;
259
260 regno = REGNO (inner);
261 if (HARD_REGISTER_NUM_P (regno))
262 return -1;
263
264 outer_size = GET_MODE_SIZE (GET_MODE (x));
265 inner_size = GET_MODE_SIZE (GET_MODE (inner));
266 outer_words = (outer_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
267 inner_words = (inner_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
268
269 /* We only try to decompose single word subregs of multi-word
270 registers. When we find one, we return -1 to avoid iterating
271 over the inner register.
272
273 ??? This doesn't allow, e.g., DImode subregs of TImode values
274 on 32-bit targets. We would need to record the way the
275 pseudo-register was used, and only decompose if all the uses
276 were the same number and size of pieces. Hopefully this
277 doesn't happen much. */
278
279 if (outer_words == 1 && inner_words > 1)
280 {
281 bitmap_set_bit (decomposable_context, regno);
282 return -1;
283 }
03743286
ILT
284
285 /* If this is a cast from one mode to another, where the modes
286 have the same size, and they are not tieable, then mark this
287 register as non-decomposable. If we decompose it we are
288 likely to mess up whatever the backend is trying to do. */
289 if (outer_words > 1
290 && outer_size == inner_size
291 && !MODES_TIEABLE_P (GET_MODE (x), GET_MODE (inner)))
292 {
293 bitmap_set_bit (non_decomposable_context, regno);
294 return -1;
295 }
e53a16e7 296 }
2b54c30f 297 else if (REG_P (x))
e53a16e7
ILT
298 {
299 unsigned int regno;
300
301 /* We will see an outer SUBREG before we see the inner REG, so
302 when we see a plain REG here it means a direct reference to
303 the register.
304
305 If this is not a simple copy from one location to another,
306 then we can not decompose this register. If this is a simple
307 copy from one pseudo-register to another, with no REG_RETVAL
308 note, and the mode is right, then we mark the register as
309 decomposable. Otherwise we don't say anything about this
310 register--it could be decomposed, but whether that would be
311 profitable depends upon how it is used elsewhere.
312
313 We only set bits in the bitmap for multi-word
314 pseudo-registers, since those are the only ones we care about
315 and it keeps the size of the bitmaps down. */
316
317 regno = REGNO (x);
318 if (!HARD_REGISTER_NUM_P (regno)
319 && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
320 {
321 switch (*pcmi)
322 {
323 case NOT_SIMPLE_MOVE:
324 bitmap_set_bit (non_decomposable_context, regno);
325 break;
326 case SIMPLE_PSEUDO_REG_MOVE:
327 if (MODES_TIEABLE_P (GET_MODE (x), word_mode))
328 bitmap_set_bit (decomposable_context, regno);
329 break;
330 case SIMPLE_MOVE:
331 break;
332 default:
333 gcc_unreachable ();
334 }
335 }
336 }
2b54c30f
ILT
337 else if (MEM_P (x))
338 {
339 enum classify_move_insn cmi_mem = NOT_SIMPLE_MOVE;
340
341 /* Any registers used in a MEM do not participate in a
342 SIMPLE_MOVE or SIMPLE_PSEUDO_REG_MOVE. Do our own recursion
343 here, and return -1 to block the parent's recursion. */
344 for_each_rtx (&XEXP (x, 0), find_decomposable_subregs, &cmi_mem);
345 return -1;
346 }
e53a16e7
ILT
347
348 return 0;
349}
350
351/* Decompose REGNO into word-sized components. We smash the REG node
352 in place. This ensures that (1) something goes wrong quickly if we
353 fail to make some replacement, and (2) the debug information inside
354 the symbol table is automatically kept up to date. */
355
356static void
357decompose_register (unsigned int regno)
358{
359 rtx reg;
360 unsigned int words, i;
361 rtvec v;
362
363 reg = regno_reg_rtx[regno];
364
365 regno_reg_rtx[regno] = NULL_RTX;
e53a16e7
ILT
366
367 words = GET_MODE_SIZE (GET_MODE (reg));
368 words = (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
369
370 v = rtvec_alloc (words);
371 for (i = 0; i < words; ++i)
372 RTVEC_ELT (v, i) = gen_reg_rtx_offset (reg, word_mode, i * UNITS_PER_WORD);
373
374 PUT_CODE (reg, CONCATN);
375 XVEC (reg, 0) = v;
376
377 if (dump_file)
378 {
379 fprintf (dump_file, "; Splitting reg %u ->", regno);
380 for (i = 0; i < words; ++i)
381 fprintf (dump_file, " %u", REGNO (XVECEXP (reg, 0, i)));
382 fputc ('\n', dump_file);
383 }
384}
385
386/* Get a SUBREG of a CONCATN. */
387
388static rtx
389simplify_subreg_concatn (enum machine_mode outermode, rtx op,
390 unsigned int byte)
391{
392 unsigned int inner_size;
393 enum machine_mode innermode;
394 rtx part;
395 unsigned int final_offset;
396
397 gcc_assert (GET_CODE (op) == CONCATN);
398 gcc_assert (byte % GET_MODE_SIZE (outermode) == 0);
399
400 innermode = GET_MODE (op);
401 gcc_assert (byte < GET_MODE_SIZE (innermode));
402 gcc_assert (GET_MODE_SIZE (outermode) <= GET_MODE_SIZE (innermode));
403
404 inner_size = GET_MODE_SIZE (innermode) / XVECLEN (op, 0);
405 part = XVECEXP (op, 0, byte / inner_size);
406 final_offset = byte % inner_size;
407 if (final_offset + GET_MODE_SIZE (outermode) > inner_size)
408 return NULL_RTX;
409
410 return simplify_gen_subreg (outermode, part, GET_MODE (part), final_offset);
411}
412
413/* Wrapper around simplify_gen_subreg which handles CONCATN. */
414
415static rtx
416simplify_gen_subreg_concatn (enum machine_mode outermode, rtx op,
417 enum machine_mode innermode, unsigned int byte)
418{
0e6c5b58
ILT
419 rtx ret;
420
e53a16e7
ILT
421 /* We have to handle generating a SUBREG of a SUBREG of a CONCATN.
422 If OP is a SUBREG of a CONCATN, then it must be a simple mode
423 change with the same size and offset 0, or it must extract a
424 part. We shouldn't see anything else here. */
425 if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == CONCATN)
426 {
427 rtx op2;
428
429 if ((GET_MODE_SIZE (GET_MODE (op))
430 == GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))))
431 && SUBREG_BYTE (op) == 0)
432 return simplify_gen_subreg_concatn (outermode, SUBREG_REG (op),
433 GET_MODE (SUBREG_REG (op)), byte);
434
435 op2 = simplify_subreg_concatn (GET_MODE (op), SUBREG_REG (op),
436 SUBREG_BYTE (op));
437 if (op2 == NULL_RTX)
438 {
439 /* We don't handle paradoxical subregs here. */
440 gcc_assert (GET_MODE_SIZE (outermode)
441 <= GET_MODE_SIZE (GET_MODE (op)));
442 gcc_assert (GET_MODE_SIZE (GET_MODE (op))
443 <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))));
444 op2 = simplify_subreg_concatn (outermode, SUBREG_REG (op),
445 byte + SUBREG_BYTE (op));
446 gcc_assert (op2 != NULL_RTX);
447 return op2;
448 }
449
450 op = op2;
451 gcc_assert (op != NULL_RTX);
452 gcc_assert (innermode == GET_MODE (op));
453 }
0e6c5b58 454
e53a16e7
ILT
455 if (GET_CODE (op) == CONCATN)
456 return simplify_subreg_concatn (outermode, op, byte);
0e6c5b58
ILT
457
458 ret = simplify_gen_subreg (outermode, op, innermode, byte);
459
460 /* If we see an insn like (set (reg:DI) (subreg:DI (reg:SI) 0)) then
461 resolve_simple_move will ask for the high part of the paradoxical
462 subreg, which does not have a value. Just return a zero. */
463 if (ret == NULL_RTX
464 && GET_CODE (op) == SUBREG
465 && SUBREG_BYTE (op) == 0
466 && (GET_MODE_SIZE (innermode)
467 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))))
468 return CONST0_RTX (outermode);
469
470 gcc_assert (ret != NULL_RTX);
471 return ret;
e53a16e7
ILT
472}
473
474/* Return whether we should resolve X into the registers into which it
475 was decomposed. */
476
477static bool
478resolve_reg_p (rtx x)
479{
480 return GET_CODE (x) == CONCATN;
481}
482
483/* Return whether X is a SUBREG of a register which we need to
484 resolve. */
485
486static bool
487resolve_subreg_p (rtx x)
488{
489 if (GET_CODE (x) != SUBREG)
490 return false;
491 return resolve_reg_p (SUBREG_REG (x));
492}
493
494/* This is called via for_each_rtx. Look for SUBREGs which need to be
495 decomposed. */
496
497static int
498resolve_subreg_use (rtx *px, void *data)
499{
500 rtx insn = (rtx) data;
501 rtx x = *px;
502
503 if (x == NULL_RTX)
504 return 0;
505
506 if (resolve_subreg_p (x))
507 {
508 x = simplify_subreg_concatn (GET_MODE (x), SUBREG_REG (x),
509 SUBREG_BYTE (x));
510
511 /* It is possible for a note to contain a reference which we can
512 decompose. In this case, return 1 to the caller to indicate
513 that the note must be removed. */
514 if (!x)
515 {
30d18db4 516 gcc_assert (!insn);
e53a16e7
ILT
517 return 1;
518 }
519
520 validate_change (insn, px, x, 1);
521 return -1;
522 }
523
524 if (resolve_reg_p (x))
525 {
526 /* Return 1 to the caller to indicate that we found a direct
527 reference to a register which is being decomposed. This can
e0892570
AK
528 happen inside notes, multiword shift or zero-extend
529 instructions. */
e53a16e7
ILT
530 return 1;
531 }
532
533 return 0;
534}
535
73663bb7
ILT
536/* We are deleting INSN. Move any EH_REGION notes to INSNS. */
537
538static void
539move_eh_region_note (rtx insn, rtx insns)
540{
541 rtx note, p;
542
543 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
544 if (note == NULL_RTX)
545 return;
546
547 gcc_assert (CALL_P (insn)
548 || (flag_non_call_exceptions && may_trap_p (PATTERN (insn))));
549
550 for (p = insns; p != NULL_RTX; p = NEXT_INSN (p))
551 {
552 if (CALL_P (p)
553 || (flag_non_call_exceptions
554 && INSN_P (p)
555 && may_trap_p (PATTERN (p))))
556 REG_NOTES (p) = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (note, 0),
557 REG_NOTES (p));
558 }
559}
560
e53a16e7
ILT
561/* If there is a REG_LIBCALL note on OLD_START, move it to NEW_START,
562 and link the corresponding REG_RETVAL note to NEW_START. */
563
564static void
565move_libcall_note (rtx old_start, rtx new_start)
566{
567 rtx note0, note1, end;
568
569 note0 = find_reg_note (old_start, REG_LIBCALL, NULL);
570 if (note0 == NULL_RTX)
571 return;
572
573 remove_note (old_start, note0);
574 end = XEXP (note0, 0);
575 note1 = find_reg_note (end, REG_RETVAL, NULL);
576
577 XEXP (note0, 1) = REG_NOTES (new_start);
578 REG_NOTES (new_start) = note0;
579 XEXP (note1, 0) = new_start;
580}
581
582/* Remove any REG_RETVAL note, the corresponding REG_LIBCALL note, and
583 any markers for a no-conflict block. We have decomposed the
584 registers so the non-conflict is now obvious. */
585
586static void
587remove_retval_note (rtx insn1)
588{
589 rtx note0, insn0, note1, insn;
590
591 note1 = find_reg_note (insn1, REG_RETVAL, NULL);
592 if (note1 == NULL_RTX)
593 return;
594
595 insn0 = XEXP (note1, 0);
596 note0 = find_reg_note (insn0, REG_LIBCALL, NULL);
597
598 remove_note (insn0, note0);
599 remove_note (insn1, note1);
600
601 for (insn = insn0; insn != insn1; insn = NEXT_INSN (insn))
602 {
603 while (1)
604 {
605 rtx note;
606
607 note = find_reg_note (insn, REG_NO_CONFLICT, NULL);
608 if (note == NULL_RTX)
609 break;
610 remove_note (insn, note);
611 }
612 }
613}
614
615/* Resolve any decomposed registers which appear in register notes on
616 INSN. */
617
618static void
619resolve_reg_notes (rtx insn)
620{
621 rtx *pnote, note;
622
623 note = find_reg_equal_equiv_note (insn);
624 if (note)
625 {
6fb5fa3c 626 int old_count = num_validated_changes ();
e53a16e7
ILT
627 if (for_each_rtx (&XEXP (note, 0), resolve_subreg_use, NULL))
628 {
629 remove_note (insn, note);
630 remove_retval_note (insn);
631 }
6fb5fa3c
DB
632 else
633 if (old_count != num_validated_changes ())
634 df_notes_rescan (insn);
e53a16e7
ILT
635 }
636
637 pnote = &REG_NOTES (insn);
638 while (*pnote != NULL_RTX)
639 {
640 bool delete = false;
641
642 note = *pnote;
643 switch (REG_NOTE_KIND (note))
644 {
645 case REG_NO_CONFLICT:
6fb5fa3c
DB
646 case REG_DEAD:
647 case REG_UNUSED:
e53a16e7
ILT
648 if (resolve_reg_p (XEXP (note, 0)))
649 delete = true;
650 break;
651
652 default:
653 break;
654 }
655
656 if (delete)
657 *pnote = XEXP (note, 1);
658 else
659 pnote = &XEXP (note, 1);
660 }
661}
662
2b54c30f 663/* Return whether X can be decomposed into subwords. */
e53a16e7
ILT
664
665static bool
2b54c30f 666can_decompose_p (rtx x)
e53a16e7
ILT
667{
668 if (REG_P (x))
669 {
670 unsigned int regno = REGNO (x);
671
672 if (HARD_REGISTER_NUM_P (regno))
2b54c30f
ILT
673 return (validate_subreg (word_mode, GET_MODE (x), x, UNITS_PER_WORD)
674 && HARD_REGNO_MODE_OK (regno, word_mode));
e53a16e7 675 else
2b54c30f 676 return !bitmap_bit_p (non_decomposable_context, regno);
e53a16e7
ILT
677 }
678
2b54c30f 679 return true;
e53a16e7
ILT
680}
681
682/* Decompose the registers used in a simple move SET within INSN. If
683 we don't change anything, return INSN, otherwise return the start
684 of the sequence of moves. */
685
686static rtx
687resolve_simple_move (rtx set, rtx insn)
688{
689 rtx src, dest, real_dest, insns;
690 enum machine_mode orig_mode, dest_mode;
691 unsigned int words;
692 bool pushing;
693
694 src = SET_SRC (set);
695 dest = SET_DEST (set);
696 orig_mode = GET_MODE (dest);
697
698 words = (GET_MODE_SIZE (orig_mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
699 if (words <= 1)
700 return insn;
701
702 start_sequence ();
703
704 /* We have to handle copying from a SUBREG of a decomposed reg where
705 the SUBREG is larger than word size. Rather than assume that we
706 can take a word_mode SUBREG of the destination, we copy to a new
707 register and then copy that to the destination. */
708
709 real_dest = NULL_RTX;
710
711 if (GET_CODE (src) == SUBREG
712 && resolve_reg_p (SUBREG_REG (src))
713 && (SUBREG_BYTE (src) != 0
714 || (GET_MODE_SIZE (orig_mode)
715 != GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))))
716 {
717 real_dest = dest;
718 dest = gen_reg_rtx (orig_mode);
719 if (REG_P (real_dest))
720 REG_ATTRS (dest) = REG_ATTRS (real_dest);
721 }
722
723 /* Similarly if we are copying to a SUBREG of a decomposed reg where
724 the SUBREG is larger than word size. */
725
726 if (GET_CODE (dest) == SUBREG
727 && resolve_reg_p (SUBREG_REG (dest))
728 && (SUBREG_BYTE (dest) != 0
729 || (GET_MODE_SIZE (orig_mode)
730 != GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))))
731 {
732 rtx reg, minsn, smove;
733
734 reg = gen_reg_rtx (orig_mode);
735 minsn = emit_move_insn (reg, src);
736 smove = single_set (minsn);
737 gcc_assert (smove != NULL_RTX);
738 resolve_simple_move (smove, minsn);
739 src = reg;
740 }
741
742 /* If we didn't have any big SUBREGS of decomposed registers, and
743 neither side of the move is a register we are decomposing, then
744 we don't have to do anything here. */
745
746 if (src == SET_SRC (set)
747 && dest == SET_DEST (set)
748 && !resolve_reg_p (src)
749 && !resolve_subreg_p (src)
750 && !resolve_reg_p (dest)
751 && !resolve_subreg_p (dest))
752 {
753 end_sequence ();
754 return insn;
755 }
756
30d18db4
ILT
757 /* It's possible for the code to use a subreg of a decomposed
758 register while forming an address. We need to handle that before
759 passing the address to emit_move_insn. We pass NULL_RTX as the
760 insn parameter to resolve_subreg_use because we can not validate
761 the insn yet. */
762 if (MEM_P (src) || MEM_P (dest))
763 {
764 int acg;
765
766 if (MEM_P (src))
767 for_each_rtx (&XEXP (src, 0), resolve_subreg_use, NULL_RTX);
768 if (MEM_P (dest))
769 for_each_rtx (&XEXP (dest, 0), resolve_subreg_use, NULL_RTX);
770 acg = apply_change_group ();
771 gcc_assert (acg);
772 }
773
e53a16e7
ILT
774 /* If SRC is a register which we can't decompose, or has side
775 effects, we need to move via a temporary register. */
776
2b54c30f 777 if (!can_decompose_p (src)
e53a16e7
ILT
778 || side_effects_p (src)
779 || GET_CODE (src) == ASM_OPERANDS)
780 {
781 rtx reg;
782
783 reg = gen_reg_rtx (orig_mode);
784 emit_move_insn (reg, src);
785 src = reg;
786 }
787
788 /* If DEST is a register which we can't decompose, or has side
789 effects, we need to first move to a temporary register. We
790 handle the common case of pushing an operand directly. We also
791 go through a temporary register if it holds a floating point
792 value. This gives us better code on systems which can't move
793 data easily between integer and floating point registers. */
794
795 dest_mode = orig_mode;
796 pushing = push_operand (dest, dest_mode);
2b54c30f 797 if (!can_decompose_p (dest)
e53a16e7
ILT
798 || (side_effects_p (dest) && !pushing)
799 || (!SCALAR_INT_MODE_P (dest_mode)
800 && !resolve_reg_p (dest)
801 && !resolve_subreg_p (dest)))
802 {
803 if (real_dest == NULL_RTX)
804 real_dest = dest;
805 if (!SCALAR_INT_MODE_P (dest_mode))
806 {
807 dest_mode = mode_for_size (GET_MODE_SIZE (dest_mode) * BITS_PER_UNIT,
808 MODE_INT, 0);
809 gcc_assert (dest_mode != BLKmode);
810 }
811 dest = gen_reg_rtx (dest_mode);
812 if (REG_P (real_dest))
813 REG_ATTRS (dest) = REG_ATTRS (real_dest);
814 }
815
816 if (pushing)
817 {
818 unsigned int i, j, jinc;
819
820 gcc_assert (GET_MODE_SIZE (orig_mode) % UNITS_PER_WORD == 0);
821 gcc_assert (GET_CODE (XEXP (dest, 0)) != PRE_MODIFY);
822 gcc_assert (GET_CODE (XEXP (dest, 0)) != POST_MODIFY);
823
824 if (WORDS_BIG_ENDIAN == STACK_GROWS_DOWNWARD)
825 {
826 j = 0;
827 jinc = 1;
828 }
829 else
830 {
831 j = words - 1;
832 jinc = -1;
833 }
834
835 for (i = 0; i < words; ++i, j += jinc)
836 {
837 rtx temp;
838
839 temp = copy_rtx (XEXP (dest, 0));
840 temp = adjust_automodify_address_nv (dest, word_mode, temp,
841 j * UNITS_PER_WORD);
842 emit_move_insn (temp,
843 simplify_gen_subreg_concatn (word_mode, src,
844 orig_mode,
845 j * UNITS_PER_WORD));
846 }
847 }
848 else
849 {
850 unsigned int i;
851
852 if (REG_P (dest) && !HARD_REGISTER_NUM_P (REGNO (dest)))
853 emit_insn (gen_rtx_CLOBBER (VOIDmode, dest));
854
855 for (i = 0; i < words; ++i)
856 emit_move_insn (simplify_gen_subreg_concatn (word_mode, dest,
857 dest_mode,
858 i * UNITS_PER_WORD),
859 simplify_gen_subreg_concatn (word_mode, src,
860 orig_mode,
861 i * UNITS_PER_WORD));
862 }
863
864 if (real_dest != NULL_RTX)
865 {
866 rtx mdest, minsn, smove;
867
868 if (dest_mode == orig_mode)
869 mdest = dest;
870 else
871 mdest = simplify_gen_subreg (orig_mode, dest, GET_MODE (dest), 0);
872 minsn = emit_move_insn (real_dest, mdest);
873
874 smove = single_set (minsn);
875 gcc_assert (smove != NULL_RTX);
876
877 resolve_simple_move (smove, minsn);
878 }
879
880 insns = get_insns ();
881 end_sequence ();
882
73663bb7
ILT
883 move_eh_region_note (insn, insns);
884
e53a16e7
ILT
885 emit_insn_before (insns, insn);
886
887 move_libcall_note (insn, insns);
888 remove_retval_note (insn);
889 delete_insn (insn);
890
891 return insns;
892}
893
894/* Change a CLOBBER of a decomposed register into a CLOBBER of the
895 component registers. Return whether we changed something. */
896
897static bool
898resolve_clobber (rtx pat, rtx insn)
899{
900 rtx reg;
901 enum machine_mode orig_mode;
902 unsigned int words, i;
7e0c3f57 903 int ret;
e53a16e7
ILT
904
905 reg = XEXP (pat, 0);
9a5a8e58 906 if (!resolve_reg_p (reg) && !resolve_subreg_p (reg))
e53a16e7
ILT
907 return false;
908
99266904
ILT
909 /* If this clobber has a REG_LIBCALL note, then it is the initial
910 clobber added by emit_no_conflict_block. We were able to
911 decompose the register, so we no longer need the clobber. */
912 if (find_reg_note (insn, REG_LIBCALL, NULL_RTX) != NULL_RTX)
913 {
914 delete_insn (insn);
915 return true;
916 }
917
e53a16e7
ILT
918 orig_mode = GET_MODE (reg);
919 words = GET_MODE_SIZE (orig_mode);
920 words = (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
921
7e0c3f57
ILT
922 ret = validate_change (NULL_RTX, &XEXP (pat, 0),
923 simplify_gen_subreg_concatn (word_mode, reg,
924 orig_mode, 0),
925 0);
6fb5fa3c 926 df_insn_rescan (insn);
7e0c3f57
ILT
927 gcc_assert (ret != 0);
928
e53a16e7
ILT
929 for (i = words - 1; i > 0; --i)
930 {
931 rtx x;
932
9a5a8e58
ILT
933 x = simplify_gen_subreg_concatn (word_mode, reg, orig_mode,
934 i * UNITS_PER_WORD);
e53a16e7
ILT
935 x = gen_rtx_CLOBBER (VOIDmode, x);
936 emit_insn_after (x, insn);
937 }
938
939 return true;
940}
941
942/* A USE of a decomposed register is no longer meaningful. Return
943 whether we changed something. */
944
945static bool
946resolve_use (rtx pat, rtx insn)
947{
948 if (resolve_reg_p (XEXP (pat, 0)) || resolve_subreg_p (XEXP (pat, 0)))
949 {
950 delete_insn (insn);
951 return true;
952 }
953 return false;
954}
955
e0892570
AK
956/* Checks if INSN is a decomposable multiword-shift or zero-extend and
957 sets the decomposable_context bitmap accordingly. A non-zero value
958 is returned if a decomposable insn has been found. */
959
960static int
961find_decomposable_shift_zext (rtx insn)
962{
963 rtx set;
964 rtx op;
965 rtx op_operand;
966
967 set = single_set (insn);
968 if (!set)
969 return 0;
970
971 op = SET_SRC (set);
972 if (GET_CODE (op) != ASHIFT
973 && GET_CODE (op) != LSHIFTRT
974 && GET_CODE (op) != ZERO_EXTEND)
975 return 0;
976
977 op_operand = XEXP (op, 0);
978 if (!REG_P (SET_DEST (set)) || !REG_P (op_operand)
979 || HARD_REGISTER_NUM_P (REGNO (SET_DEST (set)))
980 || HARD_REGISTER_NUM_P (REGNO (op_operand))
981 || !SCALAR_INT_MODE_P (GET_MODE (op)))
982 return 0;
983
984 if (GET_CODE (op) == ZERO_EXTEND)
985 {
986 if (GET_MODE (op_operand) != word_mode
987 || GET_MODE_BITSIZE (GET_MODE (op)) != 2 * BITS_PER_WORD)
988 return 0;
989 }
990 else /* left or right shift */
991 {
992 if (GET_CODE (XEXP (op, 1)) != CONST_INT
993 || INTVAL (XEXP (op, 1)) < BITS_PER_WORD
994 || GET_MODE_BITSIZE (GET_MODE (op_operand)) != 2 * BITS_PER_WORD)
995 return 0;
996 }
997
998 bitmap_set_bit (decomposable_context, REGNO (SET_DEST (set)));
999
1000 if (GET_CODE (op) != ZERO_EXTEND)
1001 bitmap_set_bit (decomposable_context, REGNO (op_operand));
1002
1003 return 1;
1004}
1005
1006/* Decompose a more than word wide shift (in INSN) of a multiword
1007 pseudo or a multiword zero-extend of a wordmode pseudo into a move
1008 and 'set to zero' insn. Return a pointer to the new insn when a
1009 replacement was done. */
1010
1011static rtx
1012resolve_shift_zext (rtx insn)
1013{
1014 rtx set;
1015 rtx op;
1016 rtx op_operand;
1017 rtx insns;
1018 rtx src_reg, dest_reg, dest_zero;
1019 int src_reg_num, dest_reg_num, offset1, offset2, src_offset;
1020
1021 set = single_set (insn);
1022 if (!set)
1023 return NULL_RTX;
1024
1025 op = SET_SRC (set);
1026 if (GET_CODE (op) != ASHIFT
1027 && GET_CODE (op) != LSHIFTRT
1028 && GET_CODE (op) != ZERO_EXTEND)
1029 return NULL_RTX;
1030
1031 op_operand = XEXP (op, 0);
1032
1033 if (!resolve_reg_p (SET_DEST (set)) && !resolve_reg_p (op_operand))
1034 return NULL_RTX;
1035
1036 /* src_reg_num is the number of the word mode register which we
1037 are operating on. For a left shift and a zero_extend on little
1038 endian machines this is register 0. */
1039 src_reg_num = GET_CODE (op) == LSHIFTRT ? 1 : 0;
1040
1041 if (WORDS_BIG_ENDIAN)
1042 src_reg_num = 1 - src_reg_num;
1043
1044 if (GET_CODE (op) == ZERO_EXTEND)
1045 dest_reg_num = src_reg_num;
1046 else
1047 dest_reg_num = 1 - src_reg_num;
1048
1049 offset1 = UNITS_PER_WORD * dest_reg_num;
1050 offset2 = UNITS_PER_WORD * (1 - dest_reg_num);
1051 src_offset = UNITS_PER_WORD * src_reg_num;
1052
1053 if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
1054 {
1055 offset1 += UNITS_PER_WORD - 1;
1056 offset2 += UNITS_PER_WORD - 1;
1057 src_offset += UNITS_PER_WORD - 1;
1058 }
1059
1060 start_sequence ();
1061
1062 dest_reg = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
1063 GET_MODE (SET_DEST (set)),
1064 offset1);
1065 dest_zero = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
1066 GET_MODE (SET_DEST (set)),
1067 offset2);
1068 src_reg = simplify_gen_subreg_concatn (word_mode, op_operand,
1069 GET_MODE (op_operand),
1070 src_offset);
1071 if (GET_CODE (op) != ZERO_EXTEND)
1072 {
1073 int shift_count = INTVAL (XEXP (op, 1));
1074 if (shift_count > BITS_PER_WORD)
1075 src_reg = expand_shift (GET_CODE (op) == ASHIFT ?
1076 LSHIFT_EXPR : RSHIFT_EXPR,
1077 word_mode, src_reg,
1078 build_int_cst (NULL_TREE,
1079 shift_count - BITS_PER_WORD),
1080 dest_reg, 1);
1081 }
1082
1083 if (dest_reg != src_reg)
1084 emit_move_insn (dest_reg, src_reg);
1085 emit_move_insn (dest_zero, CONST0_RTX (word_mode));
1086 insns = get_insns ();
1087
1088 end_sequence ();
1089
1090 emit_insn_before (insns, insn);
1091
1092 if (dump_file)
1093 {
1094 rtx in;
1095 fprintf (dump_file, "; Replacing insn: %d with insns: ", INSN_UID (insn));
1096 for (in = insns; in != insn; in = NEXT_INSN (in))
1097 fprintf (dump_file, "%d ", INSN_UID (in));
1098 fprintf (dump_file, "\n");
1099 }
1100
1101 delete_insn (insn);
1102 return insns;
1103}
1104
e53a16e7
ILT
1105/* Look for registers which are always accessed via word-sized SUBREGs
1106 or via copies. Decompose these registers into several word-sized
1107 pseudo-registers. */
1108
1109static void
6fb5fa3c 1110decompose_multiword_subregs (void)
e53a16e7
ILT
1111{
1112 unsigned int max;
1113 basic_block bb;
1114
6fb5fa3c
DB
1115 if (df)
1116 df_set_flags (DF_DEFER_INSN_RESCAN);
1117
e53a16e7
ILT
1118 max = max_reg_num ();
1119
1120 /* First see if there are any multi-word pseudo-registers. If there
1121 aren't, there is nothing we can do. This should speed up this
1122 pass in the normal case, since it should be faster than scanning
1123 all the insns. */
1124 {
1125 unsigned int i;
1126
1127 for (i = FIRST_PSEUDO_REGISTER; i < max; ++i)
1128 {
1129 if (regno_reg_rtx[i] != NULL
1130 && GET_MODE_SIZE (GET_MODE (regno_reg_rtx[i])) > UNITS_PER_WORD)
1131 break;
1132 }
1133 if (i == max)
1134 return;
1135 }
1136
1137 /* FIXME: When the dataflow branch is merged, we can change this
1138 code to look for each multi-word pseudo-register and to find each
1139 insn which sets or uses that register. That should be faster
1140 than scanning all the insns. */
1141
1142 decomposable_context = BITMAP_ALLOC (NULL);
1143 non_decomposable_context = BITMAP_ALLOC (NULL);
1144
1145 reg_copy_graph = VEC_alloc (bitmap, heap, max);
1146 VEC_safe_grow (bitmap, heap, reg_copy_graph, max);
1147 memset (VEC_address (bitmap, reg_copy_graph), 0, sizeof (bitmap) * max);
1148
1149 FOR_EACH_BB (bb)
1150 {
1151 rtx insn;
1152
1153 FOR_BB_INSNS (bb, insn)
1154 {
1155 rtx set;
1156 enum classify_move_insn cmi;
1157 int i, n;
1158
1159 if (!INSN_P (insn)
1160 || GET_CODE (PATTERN (insn)) == CLOBBER
1161 || GET_CODE (PATTERN (insn)) == USE)
1162 continue;
1163
e0892570
AK
1164 if (find_decomposable_shift_zext (insn))
1165 continue;
1166
e53a16e7
ILT
1167 recog_memoized (insn);
1168 extract_insn (insn);
1169
1170 set = simple_move (insn);
1171
1172 if (!set)
1173 cmi = NOT_SIMPLE_MOVE;
1174 else
1175 {
1176 bool retval;
1177
1178 retval = find_reg_note (insn, REG_RETVAL, NULL_RTX) != NULL_RTX;
1179
1180 if (find_pseudo_copy (set) && !retval)
1181 cmi = SIMPLE_PSEUDO_REG_MOVE;
1182 else if (retval
1183 && REG_P (SET_SRC (set))
1184 && HARD_REGISTER_P (SET_SRC (set)))
1185 {
1186 rtx note;
1187
1188 /* We don't want to decompose an assignment which
1189 copies the value returned by a libcall to a
1190 pseudo-register. Doing that will lose the RETVAL
1191 note with no real gain. */
1192 cmi = NOT_SIMPLE_MOVE;
1193
1194 /* If we have a RETVAL note, there should be an
1195 EQUAL note. We don't want to decompose any
1196 registers which that EQUAL note refers to
1197 directly. If we do, we will no longer know the
1198 value of the libcall. */
1199 note = find_reg_equal_equiv_note (insn);
1200 if (note != NULL_RTX)
1201 for_each_rtx (&XEXP (note, 0), find_decomposable_subregs,
1202 &cmi);
1203 }
1204 else
1205 cmi = SIMPLE_MOVE;
1206 }
1207
1208 n = recog_data.n_operands;
1209 for (i = 0; i < n; ++i)
1210 {
1211 for_each_rtx (&recog_data.operand[i],
1212 find_decomposable_subregs,
1213 &cmi);
1214
1215 /* We handle ASM_OPERANDS as a special case to support
1216 things like x86 rdtsc which returns a DImode value.
1217 We can decompose the output, which will certainly be
1218 operand 0, but not the inputs. */
1219
1220 if (cmi == SIMPLE_MOVE
1221 && GET_CODE (SET_SRC (set)) == ASM_OPERANDS)
1222 {
1223 gcc_assert (i == 0);
1224 cmi = NOT_SIMPLE_MOVE;
1225 }
1226 }
1227 }
1228 }
1229
1230 bitmap_and_compl_into (decomposable_context, non_decomposable_context);
1231 if (!bitmap_empty_p (decomposable_context))
1232 {
73663bb7 1233 sbitmap sub_blocks;
7984c787
SB
1234 unsigned int i;
1235 sbitmap_iterator sbi;
e53a16e7
ILT
1236 bitmap_iterator iter;
1237 unsigned int regno;
1238
1239 propagate_pseudo_copies ();
1240
73663bb7
ILT
1241 sub_blocks = sbitmap_alloc (last_basic_block);
1242 sbitmap_zero (sub_blocks);
e53a16e7
ILT
1243
1244 EXECUTE_IF_SET_IN_BITMAP (decomposable_context, 0, regno, iter)
1245 decompose_register (regno);
1246
1247 FOR_EACH_BB (bb)
1248 {
1249 rtx insn;
1250
1251 FOR_BB_INSNS (bb, insn)
1252 {
1253 rtx next, pat;
1254 bool changed;
1255
1256 if (!INSN_P (insn))
1257 continue;
1258
1259 next = NEXT_INSN (insn);
1260 changed = false;
1261
1262 pat = PATTERN (insn);
1263 if (GET_CODE (pat) == CLOBBER)
1264 {
1265 if (resolve_clobber (pat, insn))
1266 changed = true;
1267 }
1268 else if (GET_CODE (pat) == USE)
1269 {
1270 if (resolve_use (pat, insn))
1271 changed = true;
1272 }
1273 else
1274 {
1275 rtx set;
1276 int i;
1277
1278 recog_memoized (insn);
1279 extract_insn (insn);
1280
1281 set = simple_move (insn);
1282 if (set)
1283 {
1284 rtx orig_insn = insn;
73663bb7 1285 bool cfi = control_flow_insn_p (insn);
e53a16e7 1286
7984c787
SB
1287 /* We can end up splitting loads to multi-word pseudos
1288 into separate loads to machine word size pseudos.
1289 When this happens, we first had one load that can
1290 throw, and after resolve_simple_move we'll have a
1291 bunch of loads (at least two). All those loads may
1292 trap if we can have non-call exceptions, so they
1293 all will end the current basic block. We split the
1294 block after the outer loop over all insns, but we
1295 make sure here that we will be able to split the
1296 basic block and still produce the correct control
1297 flow graph for it. */
1298 gcc_assert (!cfi
1299 || (flag_non_call_exceptions
1300 && can_throw_internal (insn)));
1301
e53a16e7
ILT
1302 insn = resolve_simple_move (set, insn);
1303 if (insn != orig_insn)
1304 {
1305 changed = true;
1306
1570a704
ILT
1307 remove_retval_note (insn);
1308
e53a16e7
ILT
1309 recog_memoized (insn);
1310 extract_insn (insn);
73663bb7
ILT
1311
1312 if (cfi)
1313 SET_BIT (sub_blocks, bb->index);
e53a16e7
ILT
1314 }
1315 }
e0892570
AK
1316 else
1317 {
1318 rtx decomposed_shift;
1319
1320 decomposed_shift = resolve_shift_zext (insn);
1321 if (decomposed_shift != NULL_RTX)
1322 {
1323 changed = true;
1324 insn = decomposed_shift;
1325 recog_memoized (insn);
1326 extract_insn (insn);
1327 }
1328 }
e53a16e7
ILT
1329
1330 for (i = recog_data.n_operands - 1; i >= 0; --i)
1331 for_each_rtx (recog_data.operand_loc[i],
1332 resolve_subreg_use,
1333 insn);
1334
1335 resolve_reg_notes (insn);
1336
1337 if (num_validated_changes () > 0)
1338 {
1339 for (i = recog_data.n_dups - 1; i >= 0; --i)
1340 {
1341 rtx *pl = recog_data.dup_loc[i];
1342 int dup_num = recog_data.dup_num[i];
1343 rtx *px = recog_data.operand_loc[dup_num];
1344
1345 validate_change (insn, pl, *px, 1);
1346 }
1347
1348 i = apply_change_group ();
1349 gcc_assert (i);
1350
1570a704
ILT
1351 remove_retval_note (insn);
1352
e53a16e7
ILT
1353 changed = true;
1354 }
1355 }
e53a16e7
ILT
1356 }
1357 }
1358
7984c787
SB
1359 /* If we had insns to split that caused control flow insns in the middle
1360 of a basic block, split those blocks now. Note that we only handle
1361 the case where splitting a load has caused multiple possibly trapping
1362 loads to appear. */
1363 EXECUTE_IF_SET_IN_SBITMAP (sub_blocks, 0, i, sbi)
1364 {
1365 rtx insn, end;
1366 edge fallthru;
1367
1368 bb = BASIC_BLOCK (i);
1369 insn = BB_HEAD (bb);
1370 end = BB_END (bb);
1371
1372 while (insn != end)
1373 {
1374 if (control_flow_insn_p (insn))
1375 {
1376 /* Split the block after insn. There will be a fallthru
1377 edge, which is OK so we keep it. We have to create the
1378 exception edges ourselves. */
1379 fallthru = split_block (bb, insn);
1380 rtl_make_eh_edge (NULL, bb, BB_END (bb));
1381 bb = fallthru->dest;
1382 insn = BB_HEAD (bb);
1383 }
1384 else
1385 insn = NEXT_INSN (insn);
1386 }
1387 }
73663bb7 1388
73663bb7 1389 sbitmap_free (sub_blocks);
e53a16e7
ILT
1390 }
1391
1392 {
1393 unsigned int i;
1394 bitmap b;
1395
1396 for (i = 0; VEC_iterate (bitmap, reg_copy_graph, i, b); ++i)
1397 if (b)
1398 BITMAP_FREE (b);
1399 }
1400
1401 VEC_free (bitmap, heap, reg_copy_graph);
1402
1403 BITMAP_FREE (decomposable_context);
1404 BITMAP_FREE (non_decomposable_context);
1405}
1406\f
1407/* Gate function for lower subreg pass. */
1408
1409static bool
1410gate_handle_lower_subreg (void)
1411{
1412 return flag_split_wide_types != 0;
1413}
1414
1415/* Implement first lower subreg pass. */
1416
1417static unsigned int
1418rest_of_handle_lower_subreg (void)
1419{
6fb5fa3c 1420 decompose_multiword_subregs ();
e53a16e7
ILT
1421 return 0;
1422}
1423
1424/* Implement second lower subreg pass. */
1425
1426static unsigned int
1427rest_of_handle_lower_subreg2 (void)
1428{
6fb5fa3c 1429 decompose_multiword_subregs ();
e53a16e7
ILT
1430 return 0;
1431}
1432
1433struct tree_opt_pass pass_lower_subreg =
1434{
1435 "subreg", /* name */
1436 gate_handle_lower_subreg, /* gate */
1437 rest_of_handle_lower_subreg, /* execute */
1438 NULL, /* sub */
1439 NULL, /* next */
1440 0, /* static_pass_number */
1441 TV_LOWER_SUBREG, /* tv_id */
1442 0, /* properties_required */
1443 0, /* properties_provided */
1444 0, /* properties_destroyed */
1445 0, /* todo_flags_start */
1446 TODO_dump_func |
73663bb7
ILT
1447 TODO_ggc_collect |
1448 TODO_verify_flow, /* todo_flags_finish */
e53a16e7
ILT
1449 'u' /* letter */
1450};
1451
1452struct tree_opt_pass pass_lower_subreg2 =
1453{
1454 "subreg2", /* name */
1455 gate_handle_lower_subreg, /* gate */
1456 rest_of_handle_lower_subreg2, /* execute */
1457 NULL, /* sub */
1458 NULL, /* next */
1459 0, /* static_pass_number */
1460 TV_LOWER_SUBREG, /* tv_id */
1461 0, /* properties_required */
1462 0, /* properties_provided */
1463 0, /* properties_destroyed */
1464 0, /* todo_flags_start */
6fb5fa3c 1465 TODO_df_finish |
e53a16e7 1466 TODO_dump_func |
73663bb7
ILT
1467 TODO_ggc_collect |
1468 TODO_verify_flow, /* todo_flags_finish */
e53a16e7
ILT
1469 'U' /* letter */
1470};