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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ira-emit.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* Integrated Register Allocator.  Changing code and generating moves.
2
   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
3
   Free Software Foundation, Inc.
4
   Contributed by Vladimir Makarov <vmakarov@redhat.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
/* When we have more one region, we need to change the original RTL
23
   code after coloring.  Let us consider two allocnos representing the
24
   same pseudo-register outside and inside a region respectively.
25
   They can get different hard-registers.  The reload pass works on
26
   pseudo registers basis and there is no way to say the reload that
27
   pseudo could be in different registers and it is even more
28
   difficult to say in what places of the code the pseudo should have
29
   particular hard-registers.  So in this case IRA has to create and
30
   use a new pseudo-register inside the region and adds code to move
31
   allocno values on the region's borders.  This is done by the code
32
   in this file.
33
 
34
   The code makes top-down traversal of the regions and generate new
35
   pseudos and the move code on the region borders.  In some
36
   complicated cases IRA can create a new pseudo used temporarily to
37
   move allocno values when a swap of values stored in two
38
   hard-registers is needed (e.g. two allocnos representing different
39
   pseudos outside region got respectively hard registers 1 and 2 and
40
   the corresponding allocnos inside the region got respectively hard
41
   registers 2 and 1).  At this stage, the new pseudo is marked as
42
   spilled.
43
 
44
   IRA still creates the pseudo-register and the moves on the region
45
   borders even when the both corresponding allocnos were assigned to
46
   the same hard-register.  It is done because, if the reload pass for
47
   some reason spills a pseudo-register representing the original
48
   pseudo outside or inside the region, the effect will be smaller
49
   because another pseudo will still be in the hard-register.  In most
50
   cases, this is better then spilling the original pseudo in its
51
   whole live-range.  If reload does not change the allocation for the
52
   two pseudo-registers, the trivial move will be removed by
53
   post-reload optimizations.
54
 
55
   IRA does not generate a new pseudo and moves for the allocno values
56
   if the both allocnos representing an original pseudo inside and
57
   outside region assigned to the same hard register when the register
58
   pressure in the region for the corresponding pressure class is less
59
   than number of available hard registers for given pressure class.
60
 
61
   IRA also does some optimizations to remove redundant moves which is
62
   transformed into stores by the reload pass on CFG edges
63
   representing exits from the region.
64
 
65
   IRA tries to reduce duplication of code generated on CFG edges
66
   which are enters and exits to/from regions by moving some code to
67
   the edge sources or destinations when it is possible.  */
68
 
69
#include "config.h"
70
#include "system.h"
71
#include "coretypes.h"
72
#include "tm.h"
73
#include "regs.h"
74
#include "rtl.h"
75
#include "tm_p.h"
76
#include "target.h"
77
#include "flags.h"
78
#include "obstack.h"
79
#include "bitmap.h"
80
#include "hard-reg-set.h"
81
#include "basic-block.h"
82
#include "expr.h"
83
#include "recog.h"
84
#include "params.h"
85
#include "timevar.h"
86
#include "tree-pass.h"
87
#include "output.h"
88
#include "reload.h"
89
#include "df.h"
90
#include "ira-int.h"
91
 
92
 
93
/* Data used to emit live range split insns and to flattening IR.  */
94
ira_emit_data_t ira_allocno_emit_data;
95
 
96
/* Definitions for vectors of pointers.  */
97
typedef void *void_p;
98
DEF_VEC_P (void_p);
99
DEF_VEC_ALLOC_P (void_p,heap);
100
 
101
/* Pointers to data allocated for allocnos being created during
102
   emitting.  Usually there are quite few such allocnos because they
103
   are created only for resolving loop in register shuffling.  */
104
static VEC(void_p, heap) *new_allocno_emit_data_vec;
105
 
106
/* Allocate and initiate the emit data.  */
107
void
108
ira_initiate_emit_data (void)
109
{
110
  ira_allocno_t a;
111
  ira_allocno_iterator ai;
112
 
113
  ira_allocno_emit_data
114
    = (ira_emit_data_t) ira_allocate (ira_allocnos_num
115
                                      * sizeof (struct ira_emit_data));
116
  memset (ira_allocno_emit_data, 0,
117
          ira_allocnos_num * sizeof (struct ira_emit_data));
118
  FOR_EACH_ALLOCNO (a, ai)
119
    ALLOCNO_ADD_DATA (a) = ira_allocno_emit_data + ALLOCNO_NUM (a);
120
  new_allocno_emit_data_vec = VEC_alloc (void_p, heap, 50);
121
 
122
}
123
 
124
/* Free the emit data.  */
125
void
126
ira_finish_emit_data (void)
127
{
128
  void_p p;
129
  ira_allocno_t a;
130
  ira_allocno_iterator ai;
131
 
132
  ira_free (ira_allocno_emit_data);
133
  FOR_EACH_ALLOCNO (a, ai)
134
    ALLOCNO_ADD_DATA (a) = NULL;
135
  for (;VEC_length (void_p, new_allocno_emit_data_vec) != 0;)
136
    {
137
      p = VEC_pop (void_p, new_allocno_emit_data_vec);
138
      ira_free (p);
139
    }
140
  VEC_free (void_p, heap, new_allocno_emit_data_vec);
141
}
142
 
143
/* Create and return a new allocno with given REGNO and
144
   LOOP_TREE_NODE.  Allocate emit data for it.  */
145
static ira_allocno_t
146
create_new_allocno (int regno, ira_loop_tree_node_t loop_tree_node)
147
{
148
  ira_allocno_t a;
149
 
150
  a = ira_create_allocno (regno, false, loop_tree_node);
151
  ALLOCNO_ADD_DATA (a) = ira_allocate (sizeof (struct ira_emit_data));
152
  memset (ALLOCNO_ADD_DATA (a), 0, sizeof (struct ira_emit_data));
153
  VEC_safe_push (void_p, heap, new_allocno_emit_data_vec, ALLOCNO_ADD_DATA (a));
154
  return a;
155
}
156
 
157
 
158
 
159
/* See comments below.  */
160
typedef struct move *move_t;
161
 
162
/* The structure represents an allocno move.  Both allocnos have the
163
   same origional regno but different allocation.  */
164
struct move
165
{
166
  /* The allocnos involved in the move.  */
167
  ira_allocno_t from, to;
168
  /* The next move in the move sequence.  */
169
  move_t next;
170
  /* Used for finding dependencies.  */
171
  bool visited_p;
172
  /* The size of the following array. */
173
  int deps_num;
174
  /* Moves on which given move depends on.  Dependency can be cyclic.
175
     It means we need a temporary to generates the moves.  Sequence
176
     A1->A2, B1->B2 where A1 and B2 are assigned to reg R1 and A2 and
177
     B1 are assigned to reg R2 is an example of the cyclic
178
     dependencies.  */
179
  move_t *deps;
180
  /* First insn generated for the move.  */
181
  rtx insn;
182
};
183
 
184
/* Array of moves (indexed by BB index) which should be put at the
185
   start/end of the corresponding basic blocks.  */
186
static move_t *at_bb_start, *at_bb_end;
187
 
188
/* Max regno before renaming some pseudo-registers.  For example, the
189
   same pseudo-register can be renamed in a loop if its allocation is
190
   different outside the loop.  */
191
static int max_regno_before_changing;
192
 
193
/* Return new move of allocnos TO and FROM.  */
194
static move_t
195
create_move (ira_allocno_t to, ira_allocno_t from)
196
{
197
  move_t move;
198
 
199
  move = (move_t) ira_allocate (sizeof (struct move));
200
  move->deps = NULL;
201
  move->deps_num = 0;
202
  move->to = to;
203
  move->from = from;
204
  move->next = NULL;
205
  move->insn = NULL_RTX;
206
  move->visited_p = false;
207
  return move;
208
}
209
 
210
/* Free memory for MOVE and its dependencies.  */
211
static void
212
free_move (move_t move)
213
{
214
  if (move->deps != NULL)
215
    ira_free (move->deps);
216
  ira_free (move);
217
}
218
 
219
/* Free memory for list of the moves given by its HEAD.  */
220
static void
221
free_move_list (move_t head)
222
{
223
  move_t next;
224
 
225
  for (; head != NULL; head = next)
226
    {
227
      next = head->next;
228
      free_move (head);
229
    }
230
}
231
 
232
/* Return TRUE if the move list LIST1 and LIST2 are equal (two
233
   moves are equal if they involve the same allocnos).  */
234
static bool
235
eq_move_lists_p (move_t list1, move_t list2)
236
{
237
  for (; list1 != NULL && list2 != NULL;
238
       list1 = list1->next, list2 = list2->next)
239
    if (list1->from != list2->from || list1->to != list2->to)
240
      return false;
241
  return list1 == list2;
242
}
243
 
244
/* Print move list LIST into file F.  */
245
static void
246
print_move_list (FILE *f, move_t list)
247
{
248
  for (; list != NULL; list = list->next)
249
    fprintf (f, " a%dr%d->a%dr%d",
250
             ALLOCNO_NUM (list->from), ALLOCNO_REGNO (list->from),
251
             ALLOCNO_NUM (list->to), ALLOCNO_REGNO (list->to));
252
  fprintf (f, "\n");
253
}
254
 
255
extern void ira_debug_move_list (move_t list);
256
 
257
/* Print move list LIST into stderr.  */
258
void
259
ira_debug_move_list (move_t list)
260
{
261
  print_move_list (stderr, list);
262
}
263
 
264
/* This recursive function changes pseudo-registers in *LOC if it is
265
   necessary.  The function returns TRUE if a change was done.  */
266
static bool
267
change_regs (rtx *loc)
268
{
269
  int i, regno, result = false;
270
  const char *fmt;
271
  enum rtx_code code;
272
  rtx reg;
273
 
274
  if (*loc == NULL_RTX)
275
    return false;
276
  code = GET_CODE (*loc);
277
  if (code == REG)
278
    {
279
      regno = REGNO (*loc);
280
      if (regno < FIRST_PSEUDO_REGISTER)
281
        return false;
282
      if (regno >= max_regno_before_changing)
283
        /* It is a shared register which was changed already.  */
284
        return false;
285
      if (ira_curr_regno_allocno_map[regno] == NULL)
286
        return false;
287
      reg = allocno_emit_reg (ira_curr_regno_allocno_map[regno]);
288
      if (reg == *loc)
289
        return false;
290
      *loc = reg;
291
      return true;
292
    }
293
 
294
  fmt = GET_RTX_FORMAT (code);
295
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
296
    {
297
      if (fmt[i] == 'e')
298
        result = change_regs (&XEXP (*loc, i)) || result;
299
      else if (fmt[i] == 'E')
300
        {
301
          int j;
302
 
303
          for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
304
            result = change_regs (&XVECEXP (*loc, i, j)) || result;
305
        }
306
    }
307
  return result;
308
}
309
 
310
/* Attach MOVE to the edge E.  The move is attached to the head of the
311
   list if HEAD_P is TRUE.  */
312
static void
313
add_to_edge_list (edge e, move_t move, bool head_p)
314
{
315
  move_t last;
316
 
317
  if (head_p || e->aux == NULL)
318
    {
319
      move->next = (move_t) e->aux;
320
      e->aux = move;
321
    }
322
  else
323
    {
324
      for (last = (move_t) e->aux; last->next != NULL; last = last->next)
325
        ;
326
      last->next = move;
327
      move->next = NULL;
328
    }
329
}
330
 
331
/* Create and return new pseudo-register with the same attributes as
332
   ORIGINAL_REG.  */
333
static rtx
334
create_new_reg (rtx original_reg)
335
{
336
  rtx new_reg;
337
 
338
  new_reg = gen_reg_rtx (GET_MODE (original_reg));
339
  ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original_reg);
340
  REG_USERVAR_P (new_reg) = REG_USERVAR_P (original_reg);
341
  REG_POINTER (new_reg) = REG_POINTER (original_reg);
342
  REG_ATTRS (new_reg) = REG_ATTRS (original_reg);
343
  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
344
    fprintf (ira_dump_file, "      Creating newreg=%i from oldreg=%i\n",
345
             REGNO (new_reg), REGNO (original_reg));
346
  return new_reg;
347
}
348
 
349
/* Return TRUE if loop given by SUBNODE inside the loop given by
350
   NODE.  */
351
static bool
352
subloop_tree_node_p (ira_loop_tree_node_t subnode, ira_loop_tree_node_t node)
353
{
354
  for (; subnode != NULL; subnode = subnode->parent)
355
    if (subnode == node)
356
      return true;
357
  return false;
358
}
359
 
360
/* Set up member `reg' to REG for allocnos which has the same regno as
361
   ALLOCNO and which are inside the loop corresponding to ALLOCNO. */
362
static void
363
set_allocno_reg (ira_allocno_t allocno, rtx reg)
364
{
365
  int regno;
366
  ira_allocno_t a;
367
  ira_loop_tree_node_t node;
368
 
369
  node = ALLOCNO_LOOP_TREE_NODE (allocno);
370
  for (a = ira_regno_allocno_map[ALLOCNO_REGNO (allocno)];
371
       a != NULL;
372
       a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
373
    if (subloop_tree_node_p (ALLOCNO_LOOP_TREE_NODE (a), node))
374
      ALLOCNO_EMIT_DATA (a)->reg = reg;
375
  for (a = ALLOCNO_CAP (allocno); a != NULL; a = ALLOCNO_CAP (a))
376
    ALLOCNO_EMIT_DATA (a)->reg = reg;
377
  regno = ALLOCNO_REGNO (allocno);
378
  for (a = allocno;;)
379
    {
380
      if (a == NULL || (a = ALLOCNO_CAP (a)) == NULL)
381
        {
382
          node = node->parent;
383
          if (node == NULL)
384
            break;
385
          a = node->regno_allocno_map[regno];
386
        }
387
      if (a == NULL)
388
        continue;
389
      if (ALLOCNO_EMIT_DATA (a)->child_renamed_p)
390
        break;
391
      ALLOCNO_EMIT_DATA (a)->child_renamed_p = true;
392
    }
393
}
394
 
395
/* Return true if there is an entry to given loop not from its parent
396
   (or grandparent) block.  For example, it is possible for two
397
   adjacent loops inside another loop.  */
398
static bool
399
entered_from_non_parent_p (ira_loop_tree_node_t loop_node)
400
{
401
  ira_loop_tree_node_t bb_node, src_loop_node, parent;
402
  edge e;
403
  edge_iterator ei;
404
 
405
  for (bb_node = loop_node->children;
406
       bb_node != NULL;
407
       bb_node = bb_node->next)
408
    if (bb_node->bb != NULL)
409
      {
410
        FOR_EACH_EDGE (e, ei, bb_node->bb->preds)
411
          if (e->src != ENTRY_BLOCK_PTR
412
              && (src_loop_node = IRA_BB_NODE (e->src)->parent) != loop_node)
413
            {
414
              for (parent = src_loop_node->parent;
415
                   parent != NULL;
416
                   parent = parent->parent)
417
                if (parent == loop_node)
418
                  break;
419
              if (parent != NULL)
420
                /* That is an exit from a nested loop -- skip it.  */
421
                continue;
422
              for (parent = loop_node->parent;
423
                   parent != NULL;
424
                   parent = parent->parent)
425
                if (src_loop_node == parent)
426
                  break;
427
              if (parent == NULL)
428
                return true;
429
            }
430
      }
431
  return false;
432
}
433
 
434
/* Set up ENTERED_FROM_NON_PARENT_P for each loop region.  */
435
static void
436
setup_entered_from_non_parent_p (void)
437
{
438
  unsigned int i;
439
  loop_p loop;
440
 
441
  ira_assert (current_loops != NULL);
442
  FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
443
    if (ira_loop_nodes[i].regno_allocno_map != NULL)
444
      ira_loop_nodes[i].entered_from_non_parent_p
445
        = entered_from_non_parent_p (&ira_loop_nodes[i]);
446
}
447
 
448
/* Return TRUE if move of SRC_ALLOCNO (assigned to hard register) to
449
   DEST_ALLOCNO (assigned to memory) can be removed beacuse it does
450
   not change value of the destination.  One possible reason for this
451
   is the situation when SRC_ALLOCNO is not modified in the
452
   corresponding loop.  */
453
static bool
454
store_can_be_removed_p (ira_allocno_t src_allocno, ira_allocno_t dest_allocno)
455
{
456
  int regno, orig_regno;
457
  ira_allocno_t a;
458
  ira_loop_tree_node_t node;
459
 
460
  ira_assert (ALLOCNO_CAP_MEMBER (src_allocno) == NULL
461
              && ALLOCNO_CAP_MEMBER (dest_allocno) == NULL);
462
  orig_regno = ALLOCNO_REGNO (src_allocno);
463
  regno = REGNO (allocno_emit_reg (dest_allocno));
464
  for (node = ALLOCNO_LOOP_TREE_NODE (src_allocno);
465
       node != NULL;
466
       node = node->parent)
467
    {
468
      a = node->regno_allocno_map[orig_regno];
469
      ira_assert (a != NULL);
470
      if (REGNO (allocno_emit_reg (a)) == (unsigned) regno)
471
        /* We achieved the destination and everything is ok.  */
472
        return true;
473
      else if (bitmap_bit_p (node->modified_regnos, orig_regno))
474
        return false;
475
      else if (node->entered_from_non_parent_p)
476
        /* If there is a path from a destination loop block to the
477
           source loop header containing basic blocks of non-parents
478
           (grandparents) of the source loop, we should have checked
479
           modifications of the pseudo on this path too to decide
480
           about possibility to remove the store.  It could be done by
481
           solving a data-flow problem.  Unfortunately such global
482
           solution would complicate IR flattening.  Therefore we just
483
           prohibit removal of the store in such complicated case.  */
484
        return false;
485
    }
486
  /* It is actually a loop entry -- do not remove the store.  */
487
  return false;
488
}
489
 
490
/* Generate and attach moves to the edge E.  This looks at the final
491
   regnos of allocnos living on the edge with the same original regno
492
   to figure out when moves should be generated.  */
493
static void
494
generate_edge_moves (edge e)
495
{
496
  ira_loop_tree_node_t src_loop_node, dest_loop_node;
497
  unsigned int regno;
498
  bitmap_iterator bi;
499
  ira_allocno_t src_allocno, dest_allocno, *src_map, *dest_map;
500
  move_t move;
501
 
502
  src_loop_node = IRA_BB_NODE (e->src)->parent;
503
  dest_loop_node = IRA_BB_NODE (e->dest)->parent;
504
  e->aux = NULL;
505
  if (src_loop_node == dest_loop_node)
506
    return;
507
  src_map = src_loop_node->regno_allocno_map;
508
  dest_map = dest_loop_node->regno_allocno_map;
509
  EXECUTE_IF_SET_IN_REG_SET (DF_LR_IN (e->dest),
510
                             FIRST_PSEUDO_REGISTER, regno, bi)
511
    if (bitmap_bit_p (DF_LR_OUT (e->src), regno))
512
      {
513
        src_allocno = src_map[regno];
514
        dest_allocno = dest_map[regno];
515
        if (REGNO (allocno_emit_reg (src_allocno))
516
            == REGNO (allocno_emit_reg (dest_allocno)))
517
          continue;
518
        /* Remove unnecessary stores at the region exit.  We should do
519
           this for readonly memory for sure and this is guaranteed by
520
           that we never generate moves on region borders (see
521
           checking ira_reg_equiv_invariant_p in function
522
           change_loop).  */
523
        if (ALLOCNO_HARD_REGNO (dest_allocno) < 0
524
            && ALLOCNO_HARD_REGNO (src_allocno) >= 0
525
            && store_can_be_removed_p (src_allocno, dest_allocno))
526
          {
527
            ALLOCNO_EMIT_DATA (src_allocno)->mem_optimized_dest = dest_allocno;
528
            ALLOCNO_EMIT_DATA (dest_allocno)->mem_optimized_dest_p = true;
529
            if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
530
              fprintf (ira_dump_file, "      Remove r%d:a%d->a%d(mem)\n",
531
                       regno, ALLOCNO_NUM (src_allocno),
532
                       ALLOCNO_NUM (dest_allocno));
533
            continue;
534
          }
535
        move = create_move (dest_allocno, src_allocno);
536
        add_to_edge_list (e, move, true);
537
    }
538
}
539
 
540
/* Bitmap of allocnos local for the current loop.  */
541
static bitmap local_allocno_bitmap;
542
 
543
/* This bitmap is used to find that we need to generate and to use a
544
   new pseudo-register when processing allocnos with the same original
545
   regno.  */
546
static bitmap used_regno_bitmap;
547
 
548
/* This bitmap contains regnos of allocnos which were renamed locally
549
   because the allocnos correspond to disjoint live ranges in loops
550
   with a common parent.  */
551
static bitmap renamed_regno_bitmap;
552
 
553
/* Change (if necessary) pseudo-registers inside loop given by loop
554
   tree node NODE.  */
555
static void
556
change_loop (ira_loop_tree_node_t node)
557
{
558
  bitmap_iterator bi;
559
  unsigned int i;
560
  int regno;
561
  bool used_p;
562
  ira_allocno_t allocno, parent_allocno, *map;
563
  rtx insn, original_reg;
564
  enum reg_class aclass, pclass;
565
  ira_loop_tree_node_t parent;
566
 
567
  if (node != ira_loop_tree_root)
568
    {
569
      ira_assert (current_loops != NULL);
570
 
571
      if (node->bb != NULL)
572
        {
573
          FOR_BB_INSNS (node->bb, insn)
574
            if (INSN_P (insn) && change_regs (&insn))
575
              {
576
                df_insn_rescan (insn);
577
                df_notes_rescan (insn);
578
              }
579
          return;
580
        }
581
 
582
      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
583
        fprintf (ira_dump_file,
584
                 "      Changing RTL for loop %d (header bb%d)\n",
585
                 node->loop_num, node->loop->header->index);
586
 
587
      parent = ira_curr_loop_tree_node->parent;
588
      map = parent->regno_allocno_map;
589
      EXECUTE_IF_SET_IN_REG_SET (ira_curr_loop_tree_node->border_allocnos,
590
                                 0, i, bi)
591
        {
592
          allocno = ira_allocnos[i];
593
          regno = ALLOCNO_REGNO (allocno);
594
          aclass = ALLOCNO_CLASS (allocno);
595
          pclass = ira_pressure_class_translate[aclass];
596
          parent_allocno = map[regno];
597
          ira_assert (regno < ira_reg_equiv_len);
598
          /* We generate the same hard register move because the
599
             reload pass can put an allocno into memory in this case
600
             we will have live range splitting.  If it does not happen
601
             such the same hard register moves will be removed.  The
602
             worst case when the both allocnos are put into memory by
603
             the reload is very rare.  */
604
          if (parent_allocno != NULL
605
              && (ALLOCNO_HARD_REGNO (allocno)
606
                  == ALLOCNO_HARD_REGNO (parent_allocno))
607
              && (ALLOCNO_HARD_REGNO (allocno) < 0
608
                  || (parent->reg_pressure[pclass] + 1
609
                      <= ira_available_class_regs[pclass])
610
                  || TEST_HARD_REG_BIT (ira_prohibited_mode_move_regs
611
                                        [ALLOCNO_MODE (allocno)],
612
                                        ALLOCNO_HARD_REGNO (allocno))
613
                  /* don't create copies because reload can spill an
614
                     allocno set by copy although the allocno will not
615
                     get memory slot.  */
616
                  || ira_reg_equiv_invariant_p[regno]
617
                  || ira_reg_equiv_const[regno] != NULL_RTX))
618
            continue;
619
          original_reg = allocno_emit_reg (allocno);
620
          if (parent_allocno == NULL
621
              || (REGNO (allocno_emit_reg (parent_allocno))
622
                  == REGNO (original_reg)))
623
            {
624
              if (internal_flag_ira_verbose > 3 && ira_dump_file)
625
                fprintf (ira_dump_file, "  %i vs parent %i:",
626
                         ALLOCNO_HARD_REGNO (allocno),
627
                         ALLOCNO_HARD_REGNO (parent_allocno));
628
              set_allocno_reg (allocno, create_new_reg (original_reg));
629
            }
630
        }
631
    }
632
  /* Rename locals: Local allocnos with same regno in different loops
633
     might get the different hard register.  So we need to change
634
     ALLOCNO_REG.  */
635
  bitmap_and_compl (local_allocno_bitmap,
636
                    ira_curr_loop_tree_node->all_allocnos,
637
                    ira_curr_loop_tree_node->border_allocnos);
638
  EXECUTE_IF_SET_IN_REG_SET (local_allocno_bitmap, 0, i, bi)
639
    {
640
      allocno = ira_allocnos[i];
641
      regno = ALLOCNO_REGNO (allocno);
642
      if (ALLOCNO_CAP_MEMBER (allocno) != NULL)
643
        continue;
644
      used_p = !bitmap_set_bit (used_regno_bitmap, regno);
645
      ALLOCNO_EMIT_DATA (allocno)->somewhere_renamed_p = true;
646
      if (! used_p)
647
        continue;
648
      bitmap_set_bit (renamed_regno_bitmap, regno);
649
      set_allocno_reg (allocno, create_new_reg (allocno_emit_reg (allocno)));
650
    }
651
}
652
 
653
/* Process to set up flag somewhere_renamed_p.  */
654
static void
655
set_allocno_somewhere_renamed_p (void)
656
{
657
  unsigned int regno;
658
  ira_allocno_t allocno;
659
  ira_allocno_iterator ai;
660
 
661
  FOR_EACH_ALLOCNO (allocno, ai)
662
    {
663
      regno = ALLOCNO_REGNO (allocno);
664
      if (bitmap_bit_p (renamed_regno_bitmap, regno)
665
          && REGNO (allocno_emit_reg (allocno)) == regno)
666
        ALLOCNO_EMIT_DATA (allocno)->somewhere_renamed_p = true;
667
    }
668
}
669
 
670
/* Return TRUE if move lists on all edges given in vector VEC are
671
   equal.  */
672
static bool
673
eq_edge_move_lists_p (VEC(edge,gc) *vec)
674
{
675
  move_t list;
676
  int i;
677
 
678
  list = (move_t) EDGE_I (vec, 0)->aux;
679
  for (i = EDGE_COUNT (vec) - 1; i > 0; i--)
680
    if (! eq_move_lists_p (list, (move_t) EDGE_I (vec, i)->aux))
681
      return false;
682
  return true;
683
}
684
 
685
/* Look at all entry edges (if START_P) or exit edges of basic block
686
   BB and put move lists at the BB start or end if it is possible.  In
687
   other words, this decreases code duplication of allocno moves.  */
688
static void
689
unify_moves (basic_block bb, bool start_p)
690
{
691
  int i;
692
  edge e;
693
  move_t list;
694
  VEC(edge,gc) *vec;
695
 
696
  vec = (start_p ? bb->preds : bb->succs);
697
  if (EDGE_COUNT (vec) == 0 || ! eq_edge_move_lists_p (vec))
698
    return;
699
  e = EDGE_I (vec, 0);
700
  list = (move_t) e->aux;
701
  if (! start_p && control_flow_insn_p (BB_END (bb)))
702
    return;
703
  e->aux = NULL;
704
  for (i = EDGE_COUNT (vec) - 1; i > 0; i--)
705
    {
706
      e = EDGE_I (vec, i);
707
      free_move_list ((move_t) e->aux);
708
      e->aux = NULL;
709
    }
710
  if (start_p)
711
    at_bb_start[bb->index] = list;
712
  else
713
    at_bb_end[bb->index] = list;
714
}
715
 
716
/* Last move (in move sequence being processed) setting up the
717
   corresponding hard register.  */
718
static move_t hard_regno_last_set[FIRST_PSEUDO_REGISTER];
719
 
720
/* If the element value is equal to CURR_TICK then the corresponding
721
   element in `hard_regno_last_set' is defined and correct.  */
722
static int hard_regno_last_set_check[FIRST_PSEUDO_REGISTER];
723
 
724
/* Last move (in move sequence being processed) setting up the
725
   corresponding allocno.  */
726
static move_t *allocno_last_set;
727
 
728
/* If the element value is equal to CURR_TICK then the corresponding
729
   element in . `allocno_last_set' is defined and correct.  */
730
static int *allocno_last_set_check;
731
 
732
/* Definition of vector of moves.  */
733
DEF_VEC_P(move_t);
734
DEF_VEC_ALLOC_P(move_t, heap);
735
 
736
/* This vec contains moves sorted topologically (depth-first) on their
737
   dependency graph.  */
738
static VEC(move_t,heap) *move_vec;
739
 
740
/* The variable value is used to check correctness of values of
741
   elements of arrays `hard_regno_last_set' and
742
   `allocno_last_set_check'.  */
743
static int curr_tick;
744
 
745
/* This recursive function traverses dependencies of MOVE and produces
746
   topological sorting (in depth-first order).  */
747
static void
748
traverse_moves (move_t move)
749
{
750
  int i;
751
 
752
  if (move->visited_p)
753
    return;
754
  move->visited_p = true;
755
  for (i = move->deps_num - 1; i >= 0; i--)
756
    traverse_moves (move->deps[i]);
757
  VEC_safe_push (move_t, heap, move_vec, move);
758
}
759
 
760
/* Remove unnecessary moves in the LIST, makes topological sorting,
761
   and removes cycles on hard reg dependencies by introducing new
762
   allocnos assigned to memory and additional moves.  It returns the
763
   result move list.  */
764
static move_t
765
modify_move_list (move_t list)
766
{
767
  int i, n, nregs, hard_regno;
768
  ira_allocno_t to, from;
769
  move_t move, new_move, set_move, first, last;
770
 
771
  if (list == NULL)
772
    return NULL;
773
  /* Creat move deps.  */
774
  curr_tick++;
775
  for (move = list; move != NULL; move = move->next)
776
    {
777
      to = move->to;
778
      if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
779
        continue;
780
      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
781
      for (i = 0; i < nregs; i++)
782
        {
783
          hard_regno_last_set[hard_regno + i] = move;
784
          hard_regno_last_set_check[hard_regno + i] = curr_tick;
785
        }
786
    }
787
  for (move = list; move != NULL; move = move->next)
788
    {
789
      from = move->from;
790
      to = move->to;
791
      if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
792
        {
793
          nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
794
          for (n = i = 0; i < nregs; i++)
795
            if (hard_regno_last_set_check[hard_regno + i] == curr_tick
796
                && (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
797
                    != ALLOCNO_REGNO (from)))
798
              n++;
799
          move->deps = (move_t *) ira_allocate (n * sizeof (move_t));
800
          for (n = i = 0; i < nregs; i++)
801
            if (hard_regno_last_set_check[hard_regno + i] == curr_tick
802
                && (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
803
                    != ALLOCNO_REGNO (from)))
804
              move->deps[n++] = hard_regno_last_set[hard_regno + i];
805
          move->deps_num = n;
806
        }
807
    }
808
  /* Toplogical sorting:  */
809
  VEC_truncate (move_t, move_vec, 0);
810
  for (move = list; move != NULL; move = move->next)
811
    traverse_moves (move);
812
  last = NULL;
813
  for (i = (int) VEC_length (move_t, move_vec) - 1; i >= 0; i--)
814
    {
815
      move = VEC_index (move_t, move_vec, i);
816
      move->next = NULL;
817
      if (last != NULL)
818
        last->next = move;
819
      last = move;
820
    }
821
  first = VEC_last (move_t, move_vec);
822
  /* Removing cycles:  */
823
  curr_tick++;
824
  VEC_truncate (move_t, move_vec, 0);
825
  for (move = first; move != NULL; move = move->next)
826
    {
827
      from = move->from;
828
      to = move->to;
829
      if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
830
        {
831
          nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
832
          for (i = 0; i < nregs; i++)
833
            if (hard_regno_last_set_check[hard_regno + i] == curr_tick
834
                && ALLOCNO_HARD_REGNO
835
                   (hard_regno_last_set[hard_regno + i]->to) >= 0)
836
              {
837
                int n, j;
838
                ira_allocno_t new_allocno;
839
 
840
                set_move = hard_regno_last_set[hard_regno + i];
841
                /* It does not matter what loop_tree_node (of TO or
842
                   FROM) to use for the new allocno because of
843
                   subsequent IRA internal representation
844
                   flattening.  */
845
                new_allocno
846
                  = create_new_allocno (ALLOCNO_REGNO (set_move->to),
847
                                        ALLOCNO_LOOP_TREE_NODE (set_move->to));
848
                ALLOCNO_MODE (new_allocno) = ALLOCNO_MODE (set_move->to);
849
                ira_set_allocno_class (new_allocno,
850
                                       ALLOCNO_CLASS (set_move->to));
851
                ira_create_allocno_objects (new_allocno);
852
                ALLOCNO_ASSIGNED_P (new_allocno) = true;
853
                ALLOCNO_HARD_REGNO (new_allocno) = -1;
854
                ALLOCNO_EMIT_DATA (new_allocno)->reg
855
                  = create_new_reg (allocno_emit_reg (set_move->to));
856
 
857
                /* Make it possibly conflicting with all earlier
858
                   created allocnos.  Cases where temporary allocnos
859
                   created to remove the cycles are quite rare.  */
860
                n = ALLOCNO_NUM_OBJECTS (new_allocno);
861
                gcc_assert (n == ALLOCNO_NUM_OBJECTS (set_move->to));
862
                for (j = 0; j < n; j++)
863
                  {
864
                    ira_object_t new_obj = ALLOCNO_OBJECT (new_allocno, j);
865
 
866
                    OBJECT_MIN (new_obj) = 0;
867
                    OBJECT_MAX (new_obj) = ira_objects_num - 1;
868
                  }
869
 
870
                new_move = create_move (set_move->to, new_allocno);
871
                set_move->to = new_allocno;
872
                VEC_safe_push (move_t, heap, move_vec, new_move);
873
                ira_move_loops_num++;
874
                if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
875
                  fprintf (ira_dump_file,
876
                           "    Creating temporary allocno a%dr%d\n",
877
                           ALLOCNO_NUM (new_allocno),
878
                           REGNO (allocno_emit_reg (new_allocno)));
879
              }
880
        }
881
      if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
882
        continue;
883
      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
884
      for (i = 0; i < nregs; i++)
885
        {
886
          hard_regno_last_set[hard_regno + i] = move;
887
          hard_regno_last_set_check[hard_regno + i] = curr_tick;
888
        }
889
    }
890
  for (i = (int) VEC_length (move_t, move_vec) - 1; i >= 0; i--)
891
    {
892
      move = VEC_index (move_t, move_vec, i);
893
      move->next = NULL;
894
      last->next = move;
895
      last = move;
896
    }
897
  return first;
898
}
899
 
900
/* Generate RTX move insns from the move list LIST.  This updates
901
   allocation cost using move execution frequency FREQ.  */
902
static rtx
903
emit_move_list (move_t list, int freq)
904
{
905
  int cost, regno;
906
  rtx result, insn, set, to;
907
  enum machine_mode mode;
908
  enum reg_class aclass;
909
 
910
  start_sequence ();
911
  for (; list != NULL; list = list->next)
912
    {
913
      start_sequence ();
914
      emit_move_insn (allocno_emit_reg (list->to),
915
                      allocno_emit_reg (list->from));
916
      list->insn = get_insns ();
917
      end_sequence ();
918
      for (insn = list->insn; insn != NULL_RTX; insn = NEXT_INSN (insn))
919
        {
920
          /* The reload needs to have set up insn codes.  If the
921
             reload sets up insn codes by itself, it may fail because
922
             insns will have hard registers instead of pseudos and
923
             there may be no machine insn with given hard
924
             registers.  */
925
          recog_memoized (insn);
926
          /* Add insn to equiv init insn list if it is necessary.
927
             Otherwise reload will not remove this insn if it decides
928
             to use the equivalence.  */
929
          if ((set = single_set (insn)) != NULL_RTX)
930
            {
931
              to = SET_DEST (set);
932
              if (GET_CODE (to) == SUBREG)
933
                to = SUBREG_REG (to);
934
              ira_assert (REG_P (to));
935
              regno = REGNO (to);
936
              if (regno >= ira_reg_equiv_len
937
                  || (! ira_reg_equiv_invariant_p[regno]
938
                      && ira_reg_equiv_const[regno] == NULL_RTX))
939
                continue; /* regno has no equivalence.  */
940
              ira_assert ((int) VEC_length (reg_equivs_t, reg_equivs)
941
                          >= ira_reg_equiv_len);
942
              reg_equiv_init (regno)
943
                = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init (regno));
944
            }
945
        }
946
      emit_insn (list->insn);
947
      mode = ALLOCNO_MODE (list->to);
948
      aclass = ALLOCNO_CLASS (list->to);
949
      cost = 0;
950
      if (ALLOCNO_HARD_REGNO (list->to) < 0)
951
        {
952
          if (ALLOCNO_HARD_REGNO (list->from) >= 0)
953
            {
954
              cost = ira_memory_move_cost[mode][aclass][0] * freq;
955
              ira_store_cost += cost;
956
            }
957
        }
958
      else if (ALLOCNO_HARD_REGNO (list->from) < 0)
959
        {
960
          if (ALLOCNO_HARD_REGNO (list->to) >= 0)
961
            {
962
              cost = ira_memory_move_cost[mode][aclass][0] * freq;
963
              ira_load_cost += cost;
964
            }
965
        }
966
      else
967
        {
968
          ira_init_register_move_cost_if_necessary (mode);
969
          cost = ira_register_move_cost[mode][aclass][aclass] * freq;
970
          ira_shuffle_cost += cost;
971
        }
972
      ira_overall_cost += cost;
973
    }
974
  result = get_insns ();
975
  end_sequence ();
976
  return result;
977
}
978
 
979
/* Generate RTX move insns from move lists attached to basic blocks
980
   and edges.  */
981
static void
982
emit_moves (void)
983
{
984
  basic_block bb;
985
  edge_iterator ei;
986
  edge e;
987
  rtx insns, tmp;
988
 
989
  FOR_EACH_BB (bb)
990
    {
991
      if (at_bb_start[bb->index] != NULL)
992
        {
993
          at_bb_start[bb->index] = modify_move_list (at_bb_start[bb->index]);
994
          insns = emit_move_list (at_bb_start[bb->index],
995
                                  REG_FREQ_FROM_BB (bb));
996
          tmp = BB_HEAD (bb);
997
          if (LABEL_P (tmp))
998
            tmp = NEXT_INSN (tmp);
999
          if (NOTE_INSN_BASIC_BLOCK_P (tmp))
1000
            tmp = NEXT_INSN (tmp);
1001
          if (tmp == BB_HEAD (bb))
1002
            emit_insn_before (insns, tmp);
1003
          else if (tmp != NULL_RTX)
1004
            emit_insn_after (insns, PREV_INSN (tmp));
1005
          else
1006
            emit_insn_after (insns, get_last_insn ());
1007
        }
1008
 
1009
      if (at_bb_end[bb->index] != NULL)
1010
        {
1011
          at_bb_end[bb->index] = modify_move_list (at_bb_end[bb->index]);
1012
          insns = emit_move_list (at_bb_end[bb->index], REG_FREQ_FROM_BB (bb));
1013
          ira_assert (! control_flow_insn_p (BB_END (bb)));
1014
          emit_insn_after (insns, BB_END (bb));
1015
        }
1016
 
1017
      FOR_EACH_EDGE (e, ei, bb->succs)
1018
        {
1019
          if (e->aux == NULL)
1020
            continue;
1021
          ira_assert ((e->flags & EDGE_ABNORMAL) == 0
1022
                      || ! EDGE_CRITICAL_P (e));
1023
          e->aux = modify_move_list ((move_t) e->aux);
1024
          insert_insn_on_edge
1025
            (emit_move_list ((move_t) e->aux,
1026
                             REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e))),
1027
             e);
1028
          if (e->src->next_bb != e->dest)
1029
            ira_additional_jumps_num++;
1030
        }
1031
    }
1032
}
1033
 
1034
/* Update costs of A and corresponding allocnos on upper levels on the
1035
   loop tree from reading (if READ_P) or writing A on an execution
1036
   path with FREQ.  */
1037
static void
1038
update_costs (ira_allocno_t a, bool read_p, int freq)
1039
{
1040
  ira_loop_tree_node_t parent;
1041
 
1042
  for (;;)
1043
    {
1044
      ALLOCNO_NREFS (a)++;
1045
      ALLOCNO_FREQ (a) += freq;
1046
      ALLOCNO_MEMORY_COST (a)
1047
        += (ira_memory_move_cost[ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)]
1048
            [read_p ? 1 : 0] * freq);
1049
      if (ALLOCNO_CAP (a) != NULL)
1050
        a = ALLOCNO_CAP (a);
1051
      else if ((parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) == NULL
1052
               || (a = parent->regno_allocno_map[ALLOCNO_REGNO (a)]) == NULL)
1053
        break;
1054
    }
1055
}
1056
 
1057
/* Process moves from LIST with execution FREQ to add ranges, copies,
1058
   and modify costs for allocnos involved in the moves.  All regnos
1059
   living through the list is in LIVE_THROUGH, and the loop tree node
1060
   used to find corresponding allocnos is NODE.  */
1061
static void
1062
add_range_and_copies_from_move_list (move_t list, ira_loop_tree_node_t node,
1063
                                     bitmap live_through, int freq)
1064
{
1065
  int start, n;
1066
  unsigned int regno;
1067
  move_t move;
1068
  ira_allocno_t a;
1069
  ira_copy_t cp;
1070
  live_range_t r;
1071
  bitmap_iterator bi;
1072
  HARD_REG_SET hard_regs_live;
1073
 
1074
  if (list == NULL)
1075
    return;
1076
  n = 0;
1077
  EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
1078
    n++;
1079
  REG_SET_TO_HARD_REG_SET (hard_regs_live, live_through);
1080
  /* This is a trick to guarantee that new ranges is not merged with
1081
     the old ones.  */
1082
  ira_max_point++;
1083
  start = ira_max_point;
1084
  for (move = list; move != NULL; move = move->next)
1085
    {
1086
      ira_allocno_t from = move->from;
1087
      ira_allocno_t to = move->to;
1088
      int nr, i;
1089
 
1090
      bitmap_clear_bit (live_through, ALLOCNO_REGNO (from));
1091
      bitmap_clear_bit (live_through, ALLOCNO_REGNO (to));
1092
 
1093
      nr = ALLOCNO_NUM_OBJECTS (to);
1094
      for (i = 0; i < nr; i++)
1095
        {
1096
          ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
1097
          if (OBJECT_CONFLICT_ARRAY (to_obj) == NULL)
1098
            {
1099
              if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1100
                fprintf (ira_dump_file, "    Allocate conflicts for a%dr%d\n",
1101
                         ALLOCNO_NUM (to), REGNO (allocno_emit_reg (to)));
1102
              ira_allocate_object_conflicts (to_obj, n);
1103
            }
1104
        }
1105
      ior_hard_reg_conflicts (from, &hard_regs_live);
1106
      ior_hard_reg_conflicts (to, &hard_regs_live);
1107
 
1108
      update_costs (from, true, freq);
1109
      update_costs (to, false, freq);
1110
      cp = ira_add_allocno_copy (from, to, freq, false, move->insn, NULL);
1111
      if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1112
        fprintf (ira_dump_file, "    Adding cp%d:a%dr%d-a%dr%d\n",
1113
                 cp->num, ALLOCNO_NUM (cp->first),
1114
                 REGNO (allocno_emit_reg (cp->first)),
1115
                 ALLOCNO_NUM (cp->second),
1116
                 REGNO (allocno_emit_reg (cp->second)));
1117
 
1118
      nr = ALLOCNO_NUM_OBJECTS (from);
1119
      for (i = 0; i < nr; i++)
1120
        {
1121
          ira_object_t from_obj = ALLOCNO_OBJECT (from, i);
1122
          r = OBJECT_LIVE_RANGES (from_obj);
1123
          if (r == NULL || r->finish >= 0)
1124
            {
1125
              ira_add_live_range_to_object (from_obj, start, ira_max_point);
1126
              if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1127
                fprintf (ira_dump_file,
1128
                         "    Adding range [%d..%d] to allocno a%dr%d\n",
1129
                         start, ira_max_point, ALLOCNO_NUM (from),
1130
                         REGNO (allocno_emit_reg (from)));
1131
            }
1132
          else
1133
            {
1134
              r->finish = ira_max_point;
1135
              if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1136
                fprintf (ira_dump_file,
1137
                         "    Adding range [%d..%d] to allocno a%dr%d\n",
1138
                         r->start, ira_max_point, ALLOCNO_NUM (from),
1139
                         REGNO (allocno_emit_reg (from)));
1140
            }
1141
        }
1142
      ira_max_point++;
1143
      nr = ALLOCNO_NUM_OBJECTS (to);
1144
      for (i = 0; i < nr; i++)
1145
        {
1146
          ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
1147
          ira_add_live_range_to_object (to_obj, ira_max_point, -1);
1148
        }
1149
      ira_max_point++;
1150
    }
1151
  for (move = list; move != NULL; move = move->next)
1152
    {
1153
      int nr, i;
1154
      nr = ALLOCNO_NUM_OBJECTS (move->to);
1155
      for (i = 0; i < nr; i++)
1156
        {
1157
          ira_object_t to_obj = ALLOCNO_OBJECT (move->to, i);
1158
          r = OBJECT_LIVE_RANGES (to_obj);
1159
          if (r->finish < 0)
1160
            {
1161
              r->finish = ira_max_point - 1;
1162
              if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1163
                fprintf (ira_dump_file,
1164
                         "    Adding range [%d..%d] to allocno a%dr%d\n",
1165
                         r->start, r->finish, ALLOCNO_NUM (move->to),
1166
                         REGNO (allocno_emit_reg (move->to)));
1167
            }
1168
        }
1169
    }
1170
  EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
1171
    {
1172
      ira_allocno_t to;
1173
      int nr, i;
1174
 
1175
      a = node->regno_allocno_map[regno];
1176
      if ((to = ALLOCNO_EMIT_DATA (a)->mem_optimized_dest) != NULL)
1177
        a = to;
1178
      nr = ALLOCNO_NUM_OBJECTS (a);
1179
      for (i = 0; i < nr; i++)
1180
        {
1181
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
1182
          ira_add_live_range_to_object (obj, start, ira_max_point - 1);
1183
        }
1184
      if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
1185
        fprintf
1186
          (ira_dump_file,
1187
           "    Adding range [%d..%d] to live through %s allocno a%dr%d\n",
1188
           start, ira_max_point - 1,
1189
           to != NULL ? "upper level" : "",
1190
           ALLOCNO_NUM (a), REGNO (allocno_emit_reg (a)));
1191
    }
1192
}
1193
 
1194
/* Process all move list to add ranges, conflicts, copies, and modify
1195
   costs for allocnos involved in the moves.  */
1196
static void
1197
add_ranges_and_copies (void)
1198
{
1199
  basic_block bb;
1200
  edge_iterator ei;
1201
  edge e;
1202
  ira_loop_tree_node_t node;
1203
  bitmap live_through;
1204
 
1205
  live_through = ira_allocate_bitmap ();
1206
  FOR_EACH_BB (bb)
1207
    {
1208
      /* It does not matter what loop_tree_node (of source or
1209
         destination block) to use for searching allocnos by their
1210
         regnos because of subsequent IR flattening.  */
1211
      node = IRA_BB_NODE (bb)->parent;
1212
      bitmap_copy (live_through, DF_LR_IN (bb));
1213
      add_range_and_copies_from_move_list
1214
        (at_bb_start[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
1215
      bitmap_copy (live_through, DF_LR_OUT (bb));
1216
      add_range_and_copies_from_move_list
1217
        (at_bb_end[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
1218
      FOR_EACH_EDGE (e, ei, bb->succs)
1219
        {
1220
          bitmap_and (live_through, DF_LR_IN (e->dest), DF_LR_OUT (bb));
1221
          add_range_and_copies_from_move_list
1222
            ((move_t) e->aux, node, live_through,
1223
             REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e)));
1224
        }
1225
    }
1226
  ira_free_bitmap (live_through);
1227
}
1228
 
1229
/* The entry function changes code and generates shuffling allocnos on
1230
   region borders for the regional (LOOPS_P is TRUE in this case)
1231
   register allocation.  */
1232
void
1233
ira_emit (bool loops_p)
1234
{
1235
  basic_block bb;
1236
  rtx insn;
1237
  edge_iterator ei;
1238
  edge e;
1239
  ira_allocno_t a;
1240
  ira_allocno_iterator ai;
1241
 
1242
  FOR_EACH_ALLOCNO (a, ai)
1243
    ALLOCNO_EMIT_DATA (a)->reg = regno_reg_rtx[ALLOCNO_REGNO (a)];
1244
  if (! loops_p)
1245
    return;
1246
  at_bb_start = (move_t *) ira_allocate (sizeof (move_t) * last_basic_block);
1247
  memset (at_bb_start, 0, sizeof (move_t) * last_basic_block);
1248
  at_bb_end = (move_t *) ira_allocate (sizeof (move_t) * last_basic_block);
1249
  memset (at_bb_end, 0, sizeof (move_t) * last_basic_block);
1250
  local_allocno_bitmap = ira_allocate_bitmap ();
1251
  used_regno_bitmap = ira_allocate_bitmap ();
1252
  renamed_regno_bitmap = ira_allocate_bitmap ();
1253
  max_regno_before_changing = max_reg_num ();
1254
  ira_traverse_loop_tree (true, ira_loop_tree_root, change_loop, NULL);
1255
  set_allocno_somewhere_renamed_p ();
1256
  ira_free_bitmap (used_regno_bitmap);
1257
  ira_free_bitmap (renamed_regno_bitmap);
1258
  ira_free_bitmap (local_allocno_bitmap);
1259
  setup_entered_from_non_parent_p ();
1260
  FOR_EACH_BB (bb)
1261
    {
1262
      at_bb_start[bb->index] = NULL;
1263
      at_bb_end[bb->index] = NULL;
1264
      FOR_EACH_EDGE (e, ei, bb->succs)
1265
        if (e->dest != EXIT_BLOCK_PTR)
1266
          generate_edge_moves (e);
1267
    }
1268
  allocno_last_set
1269
    = (move_t *) ira_allocate (sizeof (move_t) * max_reg_num ());
1270
  allocno_last_set_check
1271
    = (int *) ira_allocate (sizeof (int) * max_reg_num ());
1272
  memset (allocno_last_set_check, 0, sizeof (int) * max_reg_num ());
1273
  memset (hard_regno_last_set_check, 0, sizeof (hard_regno_last_set_check));
1274
  curr_tick = 0;
1275
  FOR_EACH_BB (bb)
1276
    unify_moves (bb, true);
1277
  FOR_EACH_BB (bb)
1278
    unify_moves (bb, false);
1279
  move_vec = VEC_alloc (move_t, heap, ira_allocnos_num);
1280
  emit_moves ();
1281
  add_ranges_and_copies ();
1282
  /* Clean up: */
1283
  FOR_EACH_BB (bb)
1284
    {
1285
      free_move_list (at_bb_start[bb->index]);
1286
      free_move_list (at_bb_end[bb->index]);
1287
      FOR_EACH_EDGE (e, ei, bb->succs)
1288
        {
1289
          free_move_list ((move_t) e->aux);
1290
          e->aux = NULL;
1291
        }
1292
    }
1293
  VEC_free (move_t, heap, move_vec);
1294
  ira_free (allocno_last_set_check);
1295
  ira_free (allocno_last_set);
1296
  commit_edge_insertions ();
1297
  /* Fix insn codes.  It is necessary to do it before reload because
1298
     reload assumes initial insn codes defined.  The insn codes can be
1299
     invalidated by CFG infrastructure for example in jump
1300
     redirection.  */
1301
  FOR_EACH_BB (bb)
1302
    FOR_BB_INSNS_REVERSE (bb, insn)
1303
      if (INSN_P (insn))
1304
        recog_memoized (insn);
1305
  ira_free (at_bb_end);
1306
  ira_free (at_bb_start);
1307
}

powered by: WebSVN 2.1.0

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