OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [lower-subreg.c] - Blame information for rev 849

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.