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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ira-color.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
/* IRA allocation based on graph coloring.
2
   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
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
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "rtl.h"
27
#include "tm_p.h"
28
#include "target.h"
29
#include "regs.h"
30
#include "flags.h"
31
#include "sbitmap.h"
32
#include "bitmap.h"
33
#include "hard-reg-set.h"
34
#include "basic-block.h"
35
#include "expr.h"
36
#include "diagnostic-core.h"
37
#include "reload.h"
38
#include "params.h"
39
#include "df.h"
40
#include "ira-int.h"
41
 
42
typedef struct allocno_hard_regs *allocno_hard_regs_t;
43
 
44
/* The structure contains information about hard registers can be
45
   assigned to allocnos.  Usually it is allocno profitable hard
46
   registers but in some cases this set can be a bit different.  Major
47
   reason of the difference is a requirement to use hard register sets
48
   that form a tree or a forest (set of trees), i.e. hard register set
49
   of a node should contain hard register sets of its subnodes.  */
50
struct allocno_hard_regs
51
{
52
  /* Hard registers can be assigned to an allocno.  */
53
  HARD_REG_SET set;
54
  /* Overall (spilling) cost of all allocnos with given register
55
     set.  */
56
  HOST_WIDEST_INT cost;
57
};
58
 
59
typedef struct allocno_hard_regs_node *allocno_hard_regs_node_t;
60
 
61
/* A node representing allocno hard registers.  Such nodes form a
62
   forest (set of trees).  Each subnode of given node in the forest
63
   refers for hard register set (usually allocno profitable hard
64
   register set) which is a subset of one referred from given
65
   node.  */
66
struct allocno_hard_regs_node
67
{
68
  /* Set up number of the node in preorder traversing of the forest.  */
69
  int preorder_num;
70
  /* Used for different calculation like finding conflict size of an
71
     allocno.  */
72
  int check;
73
  /* Used for calculation of conflict size of an allocno.  The
74
     conflict size of the allocno is maximal number of given allocno
75
     hard registers needed for allocation of the conflicting allocnos.
76
     Given allocno is trivially colored if this number plus the number
77
     of hard registers needed for given allocno is not greater than
78
     the number of given allocno hard register set.  */
79
  int conflict_size;
80
  /* The number of hard registers given by member hard_regs.  */
81
  int hard_regs_num;
82
  /* The following member is used to form the final forest.  */
83
  bool used_p;
84
  /* Pointer to the corresponding profitable hard registers.  */
85
  allocno_hard_regs_t hard_regs;
86
  /* Parent, first subnode, previous and next node with the same
87
     parent in the forest.  */
88
  allocno_hard_regs_node_t parent, first, prev, next;
89
};
90
 
91
/* To decrease footprint of ira_allocno structure we store all data
92
   needed only for coloring in the following structure.  */
93
struct allocno_color_data
94
{
95
  /* TRUE value means that the allocno was not removed yet from the
96
     conflicting graph during colouring.  */
97
  unsigned int in_graph_p : 1;
98
  /* TRUE if it is put on the stack to make other allocnos
99
     colorable.  */
100
  unsigned int may_be_spilled_p : 1;
101
  /* TRUE if the allocno is trivially colorable.  */
102
  unsigned int colorable_p : 1;
103
  /* Number of hard registers of the allocno class really
104
     available for the allocno allocation.  It is number of the
105
     profitable hard regs.  */
106
  int available_regs_num;
107
  /* Allocnos in a bucket (used in coloring) chained by the following
108
     two members.  */
109
  ira_allocno_t next_bucket_allocno;
110
  ira_allocno_t prev_bucket_allocno;
111
  /* Used for temporary purposes.  */
112
  int temp;
113
  /* Used to exclude repeated processing.  */
114
  int last_process;
115
  /* Profitable hard regs available for this pseudo allocation.  It
116
     means that the set excludes unavailable hard regs and hard regs
117
     conflicting with given pseudo.  They should be of the allocno
118
     class.  */
119
  HARD_REG_SET profitable_hard_regs;
120
  /* The allocno hard registers node.  */
121
  allocno_hard_regs_node_t hard_regs_node;
122
  /* Array of structures allocno_hard_regs_subnode representing
123
     given allocno hard registers node (the 1st element in the array)
124
     and all its subnodes in the tree (forest) of allocno hard
125
     register nodes (see comments above).  */
126
  int hard_regs_subnodes_start;
127
  /* The length of the previous array. */
128
  int hard_regs_subnodes_num;
129
};
130
 
131
/* See above.  */
132
typedef struct allocno_color_data *allocno_color_data_t;
133
 
134
/* Container for storing allocno data concerning coloring.  */
135
static allocno_color_data_t allocno_color_data;
136
 
137
/* Macro to access the data concerning coloring.  */
138
#define ALLOCNO_COLOR_DATA(a) ((allocno_color_data_t) ALLOCNO_ADD_DATA (a))
139
 
140
/* Used for finding allocno colorability to exclude repeated allocno
141
   processing and for updating preferencing to exclude repeated
142
   allocno processing during assignment.  */
143
static int curr_allocno_process;
144
 
145
/* This file contains code for regional graph coloring, spill/restore
146
   code placement optimization, and code helping the reload pass to do
147
   a better job.  */
148
 
149
/* Bitmap of allocnos which should be colored.  */
150
static bitmap coloring_allocno_bitmap;
151
 
152
/* Bitmap of allocnos which should be taken into account during
153
   coloring.  In general case it contains allocnos from
154
   coloring_allocno_bitmap plus other already colored conflicting
155
   allocnos.  */
156
static bitmap consideration_allocno_bitmap;
157
 
158
/* All allocnos sorted according their priorities.  */
159
static ira_allocno_t *sorted_allocnos;
160
 
161
/* Vec representing the stack of allocnos used during coloring.  */
162
static VEC(ira_allocno_t,heap) *allocno_stack_vec;
163
 
164
/* Helper for qsort comparison callbacks - return a positive integer if
165
   X > Y, or a negative value otherwise.  Use a conditional expression
166
   instead of a difference computation to insulate from possible overflow
167
   issues, e.g. X - Y < 0 for some X > 0 and Y < 0.  */
168
#define SORTGT(x,y) (((x) > (y)) ? 1 : -1)
169
 
170
 
171
 
172
/* Definition of vector of allocno hard registers.  */
173
DEF_VEC_P(allocno_hard_regs_t);
174
DEF_VEC_ALLOC_P(allocno_hard_regs_t, heap);
175
 
176
/* Vector of unique allocno hard registers.  */
177
static VEC(allocno_hard_regs_t, heap) *allocno_hard_regs_vec;
178
 
179
/* Returns hash value for allocno hard registers V.  */
180
static hashval_t
181
allocno_hard_regs_hash (const void *v)
182
{
183
  const struct allocno_hard_regs *hv = (const struct allocno_hard_regs *) v;
184
 
185
  return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
186
}
187
 
188
/* Compares allocno hard registers V1 and V2.  */
189
static int
190
allocno_hard_regs_eq (const void *v1, const void *v2)
191
{
192
  const struct allocno_hard_regs *hv1 = (const struct allocno_hard_regs *) v1;
193
  const struct allocno_hard_regs *hv2 = (const struct allocno_hard_regs *) v2;
194
 
195
  return hard_reg_set_equal_p (hv1->set, hv2->set);
196
}
197
 
198
/* Hash table of unique allocno hard registers.  */
199
static htab_t allocno_hard_regs_htab;
200
 
201
/* Return allocno hard registers in the hash table equal to HV.  */
202
static allocno_hard_regs_t
203
find_hard_regs (allocno_hard_regs_t hv)
204
{
205
  return (allocno_hard_regs_t) htab_find (allocno_hard_regs_htab, hv);
206
}
207
 
208
/* Insert allocno hard registers HV in the hash table (if it is not
209
   there yet) and return the value which in the table.  */
210
static allocno_hard_regs_t
211
insert_hard_regs (allocno_hard_regs_t hv)
212
{
213
  PTR *slot = htab_find_slot (allocno_hard_regs_htab, hv, INSERT);
214
 
215
  if (*slot == NULL)
216
    *slot = hv;
217
  return (allocno_hard_regs_t) *slot;
218
}
219
 
220
/* Initialize data concerning allocno hard registers.  */
221
static void
222
init_allocno_hard_regs (void)
223
{
224
  allocno_hard_regs_vec = VEC_alloc (allocno_hard_regs_t, heap, 200);
225
  allocno_hard_regs_htab
226
    = htab_create (200, allocno_hard_regs_hash, allocno_hard_regs_eq, NULL);
227
}
228
 
229
/* Add (or update info about) allocno hard registers with SET and
230
   COST.  */
231
static allocno_hard_regs_t
232
add_allocno_hard_regs (HARD_REG_SET set, HOST_WIDEST_INT cost)
233
{
234
  struct allocno_hard_regs temp;
235
  allocno_hard_regs_t hv;
236
 
237
  gcc_assert (! hard_reg_set_empty_p (set));
238
  COPY_HARD_REG_SET (temp.set, set);
239
  if ((hv = find_hard_regs (&temp)) != NULL)
240
    hv->cost += cost;
241
  else
242
    {
243
      hv = ((struct allocno_hard_regs *)
244
            ira_allocate (sizeof (struct allocno_hard_regs)));
245
      COPY_HARD_REG_SET (hv->set, set);
246
      hv->cost = cost;
247
      VEC_safe_push (allocno_hard_regs_t, heap, allocno_hard_regs_vec, hv);
248
      insert_hard_regs (hv);
249
    }
250
  return hv;
251
}
252
 
253
/* Finalize data concerning allocno hard registers.  */
254
static void
255
finish_allocno_hard_regs (void)
256
{
257
  int i;
258
  allocno_hard_regs_t hv;
259
 
260
  for (i = 0;
261
       VEC_iterate (allocno_hard_regs_t, allocno_hard_regs_vec, i, hv);
262
       i++)
263
    ira_free (hv);
264
  htab_delete (allocno_hard_regs_htab);
265
  VEC_free (allocno_hard_regs_t, heap, allocno_hard_regs_vec);
266
}
267
 
268
/* Sort hard regs according to their frequency of usage. */
269
static int
270
allocno_hard_regs_compare (const void *v1p, const void *v2p)
271
{
272
  allocno_hard_regs_t hv1 = *(const allocno_hard_regs_t *) v1p;
273
  allocno_hard_regs_t hv2 = *(const allocno_hard_regs_t *) v2p;
274
 
275
  if (hv2->cost > hv1->cost)
276
    return 1;
277
  else if (hv2->cost < hv1->cost)
278
    return -1;
279
  else
280
    return 0;
281
}
282
 
283
 
284
 
285
/* Used for finding a common ancestor of two allocno hard registers
286
   nodes in the forest.  We use the current value of
287
   'node_check_tick' to mark all nodes from one node to the top and
288
   then walking up from another node until we find a marked node.
289
 
290
   It is also used to figure out allocno colorability as a mark that
291
   we already reset value of member 'conflict_size' for the forest
292
   node corresponding to the processed allocno.  */
293
static int node_check_tick;
294
 
295
/* Roots of the forest containing hard register sets can be assigned
296
   to allocnos.  */
297
static allocno_hard_regs_node_t hard_regs_roots;
298
 
299
/* Definition of vector of allocno hard register nodes.  */
300
DEF_VEC_P(allocno_hard_regs_node_t);
301
DEF_VEC_ALLOC_P(allocno_hard_regs_node_t, heap);
302
 
303
/* Vector used to create the forest.  */
304
static VEC(allocno_hard_regs_node_t, heap) *hard_regs_node_vec;
305
 
306
/* Create and return allocno hard registers node containing allocno
307
   hard registers HV.  */
308
static allocno_hard_regs_node_t
309
create_new_allocno_hard_regs_node (allocno_hard_regs_t hv)
310
{
311
  allocno_hard_regs_node_t new_node;
312
 
313
  new_node = ((struct allocno_hard_regs_node *)
314
              ira_allocate (sizeof (struct allocno_hard_regs_node)));
315
  new_node->check = 0;
316
  new_node->hard_regs = hv;
317
  new_node->hard_regs_num = hard_reg_set_size (hv->set);
318
  new_node->first = NULL;
319
  new_node->used_p = false;
320
  return new_node;
321
}
322
 
323
/* Add allocno hard registers node NEW_NODE to the forest on its level
324
   given by ROOTS.  */
325
static void
326
add_new_allocno_hard_regs_node_to_forest (allocno_hard_regs_node_t *roots,
327
                                          allocno_hard_regs_node_t new_node)
328
{
329
  new_node->next = *roots;
330
  if (new_node->next != NULL)
331
    new_node->next->prev = new_node;
332
  new_node->prev = NULL;
333
  *roots = new_node;
334
}
335
 
336
/* Add allocno hard registers HV (or its best approximation if it is
337
   not possible) to the forest on its level given by ROOTS.  */
338
static void
339
add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots,
340
                                 allocno_hard_regs_t hv)
341
{
342
  unsigned int i, start;
343
  allocno_hard_regs_node_t node, prev, new_node;
344
  HARD_REG_SET temp_set;
345
  allocno_hard_regs_t hv2;
346
 
347
  start = VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec);
348
  for (node = *roots; node != NULL; node = node->next)
349
    {
350
      if (hard_reg_set_equal_p (hv->set, node->hard_regs->set))
351
        return;
352
      if (hard_reg_set_subset_p (hv->set, node->hard_regs->set))
353
        {
354
          add_allocno_hard_regs_to_forest (&node->first, hv);
355
          return;
356
        }
357
      if (hard_reg_set_subset_p (node->hard_regs->set, hv->set))
358
        VEC_safe_push (allocno_hard_regs_node_t, heap,
359
                       hard_regs_node_vec, node);
360
      else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set))
361
        {
362
          COPY_HARD_REG_SET (temp_set, hv->set);
363
          AND_HARD_REG_SET (temp_set, node->hard_regs->set);
364
          hv2 = add_allocno_hard_regs (temp_set, hv->cost);
365
          add_allocno_hard_regs_to_forest (&node->first, hv2);
366
        }
367
    }
368
  if (VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec)
369
      > start + 1)
370
    {
371
      /* Create a new node which contains nodes in hard_regs_node_vec.  */
372
      CLEAR_HARD_REG_SET (temp_set);
373
      for (i = start;
374
           i < VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec);
375
           i++)
376
        {
377
          node = VEC_index (allocno_hard_regs_node_t, hard_regs_node_vec, i);
378
          IOR_HARD_REG_SET (temp_set, node->hard_regs->set);
379
        }
380
      hv = add_allocno_hard_regs (temp_set, hv->cost);
381
      new_node = create_new_allocno_hard_regs_node (hv);
382
      prev = NULL;
383
      for (i = start;
384
           i < VEC_length (allocno_hard_regs_node_t, hard_regs_node_vec);
385
           i++)
386
        {
387
          node = VEC_index (allocno_hard_regs_node_t, hard_regs_node_vec, i);
388
          if (node->prev == NULL)
389
            *roots = node->next;
390
          else
391
            node->prev->next = node->next;
392
          if (node->next != NULL)
393
            node->next->prev = node->prev;
394
          if (prev == NULL)
395
            new_node->first = node;
396
          else
397
            prev->next = node;
398
          node->prev = prev;
399
          node->next = NULL;
400
          prev = node;
401
        }
402
      add_new_allocno_hard_regs_node_to_forest (roots, new_node);
403
    }
404
  VEC_truncate (allocno_hard_regs_node_t, hard_regs_node_vec, start);
405
}
406
 
407
/* Add allocno hard registers nodes starting with the forest level
408
   given by FIRST which contains biggest set inside SET.  */
409
static void
410
collect_allocno_hard_regs_cover (allocno_hard_regs_node_t first,
411
                                 HARD_REG_SET set)
412
{
413
  allocno_hard_regs_node_t node;
414
 
415
  ira_assert (first != NULL);
416
  for (node = first; node != NULL; node = node->next)
417
    if (hard_reg_set_subset_p (node->hard_regs->set, set))
418
      VEC_safe_push (allocno_hard_regs_node_t, heap, hard_regs_node_vec,
419
                     node);
420
    else if (hard_reg_set_intersect_p (set, node->hard_regs->set))
421
      collect_allocno_hard_regs_cover (node->first, set);
422
}
423
 
424
/* Set up field parent as PARENT in all allocno hard registers nodes
425
   in forest given by FIRST.  */
426
static void
427
setup_allocno_hard_regs_nodes_parent (allocno_hard_regs_node_t first,
428
                                      allocno_hard_regs_node_t parent)
429
{
430
  allocno_hard_regs_node_t node;
431
 
432
  for (node = first; node != NULL; node = node->next)
433
    {
434
      node->parent = parent;
435
      setup_allocno_hard_regs_nodes_parent (node->first, node);
436
    }
437
}
438
 
439
/* Return allocno hard registers node which is a first common ancestor
440
   node of FIRST and SECOND in the forest.  */
441
static allocno_hard_regs_node_t
442
first_common_ancestor_node (allocno_hard_regs_node_t first,
443
                            allocno_hard_regs_node_t second)
444
{
445
  allocno_hard_regs_node_t node;
446
 
447
  node_check_tick++;
448
  for (node = first; node != NULL; node = node->parent)
449
    node->check = node_check_tick;
450
  for (node = second; node != NULL; node = node->parent)
451
    if (node->check == node_check_tick)
452
      return node;
453
  return first_common_ancestor_node (second, first);
454
}
455
 
456
/* Print hard reg set SET to F.  */
457
static void
458
print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p)
459
{
460
  int i, start;
461
 
462
  for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
463
    {
464
      if (TEST_HARD_REG_BIT (set, i))
465
        {
466
          if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
467
            start = i;
468
        }
469
      if (start >= 0
470
          && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
471
        {
472
          if (start == i - 1)
473
            fprintf (f, " %d", start);
474
          else if (start == i - 2)
475
            fprintf (f, " %d %d", start, start + 1);
476
          else
477
            fprintf (f, " %d-%d", start, i - 1);
478
          start = -1;
479
        }
480
    }
481
  if (new_line_p)
482
    fprintf (f, "\n");
483
}
484
 
485
/* Print allocno hard register subforest given by ROOTS and its LEVEL
486
   to F.  */
487
static void
488
print_hard_regs_subforest (FILE *f, allocno_hard_regs_node_t roots,
489
                           int level)
490
{
491
  int i;
492
  allocno_hard_regs_node_t node;
493
 
494
  for (node = roots; node != NULL; node = node->next)
495
    {
496
      fprintf (f, "    ");
497
      for (i = 0; i < level * 2; i++)
498
        fprintf (f, " ");
499
      fprintf (f, "%d:(", node->preorder_num);
500
      print_hard_reg_set (f, node->hard_regs->set, false);
501
      fprintf (f, ")@" HOST_WIDEST_INT_PRINT_DEC "\n", node->hard_regs->cost);
502
      print_hard_regs_subforest (f, node->first, level + 1);
503
    }
504
}
505
 
506
/* Print the allocno hard register forest to F.  */
507
static void
508
print_hard_regs_forest (FILE *f)
509
{
510
  fprintf (f, "    Hard reg set forest:\n");
511
  print_hard_regs_subforest (f, hard_regs_roots, 1);
512
}
513
 
514
/* Print the allocno hard register forest to stderr.  */
515
void
516
ira_debug_hard_regs_forest (void)
517
{
518
  print_hard_regs_forest (stderr);
519
}
520
 
521
/* Remove unused allocno hard registers nodes from forest given by its
522
   *ROOTS.  */
523
static void
524
remove_unused_allocno_hard_regs_nodes (allocno_hard_regs_node_t *roots)
525
{
526
  allocno_hard_regs_node_t node, prev, next, last;
527
 
528
  for (prev = NULL, node = *roots; node != NULL; node = next)
529
    {
530
      next = node->next;
531
      if (node->used_p)
532
        {
533
          remove_unused_allocno_hard_regs_nodes (&node->first);
534
          prev = node;
535
        }
536
      else
537
        {
538
          for (last = node->first;
539
               last != NULL && last->next != NULL;
540
               last = last->next)
541
            ;
542
          if (last != NULL)
543
            {
544
              if (prev == NULL)
545
                *roots = node->first;
546
              else
547
                prev->next = node->first;
548
              if (next != NULL)
549
                next->prev = last;
550
              last->next = next;
551
              next = node->first;
552
            }
553
          else
554
            {
555
              if (prev == NULL)
556
                *roots = next;
557
              else
558
                prev->next = next;
559
              if (next != NULL)
560
                next->prev = prev;
561
            }
562
          ira_free (node);
563
        }
564
    }
565
}
566
 
567
/* Set up fields preorder_num starting with START_NUM in all allocno
568
   hard registers nodes in forest given by FIRST.  Return biggest set
569
   PREORDER_NUM increased by 1.  */
570
static int
571
enumerate_allocno_hard_regs_nodes (allocno_hard_regs_node_t first,
572
                                   allocno_hard_regs_node_t parent,
573
                                   int start_num)
574
{
575
  allocno_hard_regs_node_t node;
576
 
577
  for (node = first; node != NULL; node = node->next)
578
    {
579
      node->preorder_num = start_num++;
580
      node->parent = parent;
581
      start_num = enumerate_allocno_hard_regs_nodes (node->first, node,
582
                                                     start_num);
583
    }
584
  return start_num;
585
}
586
 
587
/* Number of allocno hard registers nodes in the forest.  */
588
static int allocno_hard_regs_nodes_num;
589
 
590
/* Table preorder number of allocno hard registers node in the forest
591
   -> the allocno hard registers node.  */
592
static allocno_hard_regs_node_t *allocno_hard_regs_nodes;
593
 
594
/* See below.  */
595
typedef struct allocno_hard_regs_subnode *allocno_hard_regs_subnode_t;
596
 
597
/* The structure is used to describes all subnodes (not only immediate
598
   ones) in the mentioned above tree for given allocno hard register
599
   node.  The usage of such data accelerates calculation of
600
   colorability of given allocno.  */
601
struct allocno_hard_regs_subnode
602
{
603
  /* The conflict size of conflicting allocnos whose hard register
604
     sets are equal sets (plus supersets if given node is given
605
     allocno hard registers node) of one in the given node.  */
606
  int left_conflict_size;
607
  /* The summary conflict size of conflicting allocnos whose hard
608
     register sets are strict subsets of one in the given node.
609
     Overall conflict size is
610
     left_conflict_subnodes_size
611
       + MIN (max_node_impact - left_conflict_subnodes_size,
612
              left_conflict_size)
613
  */
614
  short left_conflict_subnodes_size;
615
  short max_node_impact;
616
};
617
 
618
/* Container for hard regs subnodes of all allocnos.  */
619
static allocno_hard_regs_subnode_t allocno_hard_regs_subnodes;
620
 
621
/* Table (preorder number of allocno hard registers node in the
622
   forest, preorder number of allocno hard registers subnode) -> index
623
   of the subnode relative to the node.  -1 if it is not a
624
   subnode.  */
625
static int *allocno_hard_regs_subnode_index;
626
 
627
/* Setup arrays ALLOCNO_HARD_REGS_NODES and
628
   ALLOCNO_HARD_REGS_SUBNODE_INDEX.  */
629
static void
630
setup_allocno_hard_regs_subnode_index (allocno_hard_regs_node_t first)
631
{
632
  allocno_hard_regs_node_t node, parent;
633
  int index;
634
 
635
  for (node = first; node != NULL; node = node->next)
636
    {
637
      allocno_hard_regs_nodes[node->preorder_num] = node;
638
      for (parent = node; parent != NULL; parent = parent->parent)
639
        {
640
          index = parent->preorder_num * allocno_hard_regs_nodes_num;
641
          allocno_hard_regs_subnode_index[index + node->preorder_num]
642
            = node->preorder_num - parent->preorder_num;
643
        }
644
      setup_allocno_hard_regs_subnode_index (node->first);
645
    }
646
}
647
 
648
/* Count all allocno hard registers nodes in tree ROOT.  */
649
static int
650
get_allocno_hard_regs_subnodes_num (allocno_hard_regs_node_t root)
651
{
652
  int len = 1;
653
 
654
  for (root = root->first; root != NULL; root = root->next)
655
    len += get_allocno_hard_regs_subnodes_num (root);
656
  return len;
657
}
658
 
659
/* Build the forest of allocno hard registers nodes and assign each
660
   allocno a node from the forest.  */
661
static void
662
form_allocno_hard_regs_nodes_forest (void)
663
{
664
  unsigned int i, j, size, len;
665
  int start;
666
  ira_allocno_t a;
667
  allocno_hard_regs_t hv;
668
  bitmap_iterator bi;
669
  HARD_REG_SET temp;
670
  allocno_hard_regs_node_t node, allocno_hard_regs_node;
671
  allocno_color_data_t allocno_data;
672
 
673
  node_check_tick = 0;
674
  init_allocno_hard_regs ();
675
  hard_regs_roots = NULL;
676
  hard_regs_node_vec = VEC_alloc (allocno_hard_regs_node_t, heap, 100);
677
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
678
    if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, i))
679
      {
680
        CLEAR_HARD_REG_SET (temp);
681
        SET_HARD_REG_BIT (temp, i);
682
        hv = add_allocno_hard_regs (temp, 0);
683
        node = create_new_allocno_hard_regs_node (hv);
684
        add_new_allocno_hard_regs_node_to_forest (&hard_regs_roots, node);
685
      }
686
  start = VEC_length (allocno_hard_regs_t, allocno_hard_regs_vec);
687
  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
688
    {
689
      a = ira_allocnos[i];
690
      allocno_data = ALLOCNO_COLOR_DATA (a);
691
 
692
      if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
693
        continue;
694
      hv = (add_allocno_hard_regs
695
            (allocno_data->profitable_hard_regs,
696
             ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)));
697
    }
698
  SET_HARD_REG_SET (temp);
699
  AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
700
  add_allocno_hard_regs (temp, 0);
701
  qsort (VEC_address (allocno_hard_regs_t, allocno_hard_regs_vec) + start,
702
         VEC_length (allocno_hard_regs_t, allocno_hard_regs_vec) - start,
703
         sizeof (allocno_hard_regs_t), allocno_hard_regs_compare);
704
  for (i = start;
705
       VEC_iterate (allocno_hard_regs_t, allocno_hard_regs_vec, i, hv);
706
       i++)
707
    {
708
      add_allocno_hard_regs_to_forest (&hard_regs_roots, hv);
709
      ira_assert (VEC_length (allocno_hard_regs_node_t,
710
                              hard_regs_node_vec) == 0);
711
    }
712
  /* We need to set up parent fields for right work of
713
     first_common_ancestor_node. */
714
  setup_allocno_hard_regs_nodes_parent (hard_regs_roots, NULL);
715
  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
716
    {
717
      a = ira_allocnos[i];
718
      allocno_data = ALLOCNO_COLOR_DATA (a);
719
      if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
720
        continue;
721
      VEC_truncate (allocno_hard_regs_node_t, hard_regs_node_vec, 0);
722
      collect_allocno_hard_regs_cover (hard_regs_roots,
723
                                       allocno_data->profitable_hard_regs);
724
      allocno_hard_regs_node = NULL;
725
      for (j = 0;
726
           VEC_iterate (allocno_hard_regs_node_t, hard_regs_node_vec,
727
                        j, node);
728
           j++)
729
        allocno_hard_regs_node
730
          = (j == 0
731
             ? node
732
             : first_common_ancestor_node (node, allocno_hard_regs_node));
733
      /* That is a temporary storage.  */
734
      allocno_hard_regs_node->used_p = true;
735
      allocno_data->hard_regs_node = allocno_hard_regs_node;
736
    }
737
  ira_assert (hard_regs_roots->next == NULL);
738
  hard_regs_roots->used_p = true;
739
  remove_unused_allocno_hard_regs_nodes (&hard_regs_roots);
740
  allocno_hard_regs_nodes_num
741
    = enumerate_allocno_hard_regs_nodes (hard_regs_roots, NULL, 0);
742
  allocno_hard_regs_nodes
743
    = ((allocno_hard_regs_node_t *)
744
       ira_allocate (allocno_hard_regs_nodes_num
745
                     * sizeof (allocno_hard_regs_node_t)));
746
  size = allocno_hard_regs_nodes_num * allocno_hard_regs_nodes_num;
747
  allocno_hard_regs_subnode_index
748
    = (int *) ira_allocate (size * sizeof (int));
749
  for (i = 0; i < size; i++)
750
    allocno_hard_regs_subnode_index[i] = -1;
751
  setup_allocno_hard_regs_subnode_index (hard_regs_roots);
752
  start = 0;
753
  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
754
    {
755
      a = ira_allocnos[i];
756
      allocno_data = ALLOCNO_COLOR_DATA (a);
757
      if (hard_reg_set_empty_p (allocno_data->profitable_hard_regs))
758
        continue;
759
      len = get_allocno_hard_regs_subnodes_num (allocno_data->hard_regs_node);
760
      allocno_data->hard_regs_subnodes_start = start;
761
      allocno_data->hard_regs_subnodes_num = len;
762
      start += len;
763
    }
764
  allocno_hard_regs_subnodes
765
    = ((allocno_hard_regs_subnode_t)
766
       ira_allocate (sizeof (struct allocno_hard_regs_subnode) * start));
767
  VEC_free (allocno_hard_regs_node_t, heap, hard_regs_node_vec);
768
}
769
 
770
/* Free tree of allocno hard registers nodes given by its ROOT.  */
771
static void
772
finish_allocno_hard_regs_nodes_tree (allocno_hard_regs_node_t root)
773
{
774
  allocno_hard_regs_node_t child, next;
775
 
776
  for (child = root->first; child != NULL; child = next)
777
    {
778
      next = child->next;
779
      finish_allocno_hard_regs_nodes_tree (child);
780
    }
781
  ira_free (root);
782
}
783
 
784
/* Finish work with the forest of allocno hard registers nodes.  */
785
static void
786
finish_allocno_hard_regs_nodes_forest (void)
787
{
788
  allocno_hard_regs_node_t node, next;
789
 
790
  ira_free (allocno_hard_regs_subnodes);
791
  for (node = hard_regs_roots; node != NULL; node = next)
792
    {
793
      next = node->next;
794
      finish_allocno_hard_regs_nodes_tree (node);
795
    }
796
  ira_free (allocno_hard_regs_nodes);
797
  ira_free (allocno_hard_regs_subnode_index);
798
  finish_allocno_hard_regs ();
799
}
800
 
801
/* Set up left conflict sizes and left conflict subnodes sizes of hard
802
   registers subnodes of allocno A.  Return TRUE if allocno A is
803
   trivially colorable.  */
804
static bool
805
setup_left_conflict_sizes_p (ira_allocno_t a)
806
{
807
  int i, k, nobj, start;
808
  int conflict_size, left_conflict_subnodes_size, node_preorder_num;
809
  allocno_color_data_t data;
810
  HARD_REG_SET profitable_hard_regs;
811
  allocno_hard_regs_subnode_t subnodes;
812
  allocno_hard_regs_node_t node;
813
  HARD_REG_SET node_set;
814
 
815
  nobj = ALLOCNO_NUM_OBJECTS (a);
816
  conflict_size = 0;
817
  data = ALLOCNO_COLOR_DATA (a);
818
  subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
819
  COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs);
820
  node = data->hard_regs_node;
821
  node_preorder_num = node->preorder_num;
822
  COPY_HARD_REG_SET (node_set, node->hard_regs->set);
823
  node_check_tick++;
824
  curr_allocno_process++;
825
  for (k = 0; k < nobj; k++)
826
    {
827
      ira_object_t obj = ALLOCNO_OBJECT (a, k);
828
      ira_object_t conflict_obj;
829
      ira_object_conflict_iterator oci;
830
 
831
      FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
832
        {
833
          int size;
834
          ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
835
          allocno_hard_regs_node_t conflict_node, temp_node;
836
          HARD_REG_SET conflict_node_set;
837
          allocno_color_data_t conflict_data;
838
 
839
          conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
840
          if (! ALLOCNO_COLOR_DATA (conflict_a)->in_graph_p
841
              || conflict_data->last_process == curr_allocno_process
842
              || ! hard_reg_set_intersect_p (profitable_hard_regs,
843
                                             conflict_data
844
                                             ->profitable_hard_regs))
845
            continue;
846
          conflict_data->last_process = curr_allocno_process;
847
          conflict_node = conflict_data->hard_regs_node;
848
          COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set);
849
          if (hard_reg_set_subset_p (node_set, conflict_node_set))
850
            temp_node = node;
851
          else
852
            {
853
              ira_assert (hard_reg_set_subset_p (conflict_node_set, node_set));
854
              temp_node = conflict_node;
855
            }
856
          if (temp_node->check != node_check_tick)
857
            {
858
              temp_node->check = node_check_tick;
859
              temp_node->conflict_size = 0;
860
            }
861
          size = (ira_reg_class_max_nregs
862
                  [ALLOCNO_CLASS (conflict_a)][ALLOCNO_MODE (conflict_a)]);
863
          if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
864
            /* We will deal with the subwords individually.  */
865
            size = 1;
866
          temp_node->conflict_size += size;
867
        }
868
    }
869
  for (i = 0; i < data->hard_regs_subnodes_num; i++)
870
    {
871
      allocno_hard_regs_node_t temp_node;
872
 
873
      temp_node = allocno_hard_regs_nodes[i + node_preorder_num];
874
      ira_assert (temp_node->preorder_num == i + node_preorder_num);
875
      subnodes[i].left_conflict_size = (temp_node->check != node_check_tick
876
                                        ? 0 : temp_node->conflict_size);
877
      if (hard_reg_set_subset_p (temp_node->hard_regs->set,
878
                                 profitable_hard_regs))
879
        subnodes[i].max_node_impact = temp_node->hard_regs_num;
880
      else
881
        {
882
          HARD_REG_SET temp_set;
883
          int j, n, hard_regno;
884
          enum reg_class aclass;
885
 
886
          COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set);
887
          AND_HARD_REG_SET (temp_set, profitable_hard_regs);
888
          aclass = ALLOCNO_CLASS (a);
889
          for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--)
890
            {
891
              hard_regno = ira_class_hard_regs[aclass][j];
892
              if (TEST_HARD_REG_BIT (temp_set, hard_regno))
893
                n++;
894
            }
895
          subnodes[i].max_node_impact = n;
896
        }
897
      subnodes[i].left_conflict_subnodes_size = 0;
898
    }
899
  start = node_preorder_num * allocno_hard_regs_nodes_num;
900
  for (i = data->hard_regs_subnodes_num - 1; i >= 0; i--)
901
    {
902
      int size, parent_i;
903
      allocno_hard_regs_node_t parent;
904
 
905
      size = (subnodes[i].left_conflict_subnodes_size
906
              + MIN (subnodes[i].max_node_impact
907
                     - subnodes[i].left_conflict_subnodes_size,
908
                     subnodes[i].left_conflict_size));
909
      parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
910
      if (parent == NULL)
911
        continue;
912
      parent_i
913
        = allocno_hard_regs_subnode_index[start + parent->preorder_num];
914
      if (parent_i < 0)
915
        continue;
916
      subnodes[parent_i].left_conflict_subnodes_size += size;
917
    }
918
  left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size;
919
  conflict_size
920
    += (left_conflict_subnodes_size
921
        + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size,
922
               subnodes[0].left_conflict_size));
923
  conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
924
  data->colorable_p = conflict_size <= data->available_regs_num;
925
  return data->colorable_p;
926
}
927
 
928
/* Update left conflict sizes of hard registers subnodes of allocno A
929
   after removing allocno REMOVED_A with SIZE from the conflict graph.
930
   Return TRUE if A is trivially colorable.  */
931
static bool
932
update_left_conflict_sizes_p (ira_allocno_t a,
933
                              ira_allocno_t removed_a, int size)
934
{
935
  int i, conflict_size, before_conflict_size, diff, start;
936
  int node_preorder_num, parent_i;
937
  allocno_hard_regs_node_t node, removed_node, parent;
938
  allocno_hard_regs_subnode_t subnodes;
939
  allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
940
 
941
  ira_assert (! data->colorable_p);
942
  node = data->hard_regs_node;
943
  node_preorder_num = node->preorder_num;
944
  removed_node = ALLOCNO_COLOR_DATA (removed_a)->hard_regs_node;
945
  ira_assert (hard_reg_set_subset_p (removed_node->hard_regs->set,
946
                               node->hard_regs->set)
947
              || hard_reg_set_subset_p (node->hard_regs->set,
948
                                        removed_node->hard_regs->set));
949
  start = node_preorder_num * allocno_hard_regs_nodes_num;
950
  i = allocno_hard_regs_subnode_index[start + removed_node->preorder_num];
951
  if (i < 0)
952
    i = 0;
953
  subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start;
954
  before_conflict_size
955
    = (subnodes[i].left_conflict_subnodes_size
956
       + MIN (subnodes[i].max_node_impact
957
              - subnodes[i].left_conflict_subnodes_size,
958
              subnodes[i].left_conflict_size));
959
  subnodes[i].left_conflict_size -= size;
960
  for (;;)
961
    {
962
      conflict_size
963
        = (subnodes[i].left_conflict_subnodes_size
964
           + MIN (subnodes[i].max_node_impact
965
                  - subnodes[i].left_conflict_subnodes_size,
966
                  subnodes[i].left_conflict_size));
967
      if ((diff = before_conflict_size - conflict_size) == 0)
968
        break;
969
      ira_assert (conflict_size < before_conflict_size);
970
      parent = allocno_hard_regs_nodes[i + node_preorder_num]->parent;
971
      if (parent == NULL)
972
        break;
973
      parent_i
974
        = allocno_hard_regs_subnode_index[start + parent->preorder_num];
975
      if (parent_i < 0)
976
        break;
977
      i = parent_i;
978
      before_conflict_size
979
        = (subnodes[i].left_conflict_subnodes_size
980
           + MIN (subnodes[i].max_node_impact
981
                  - subnodes[i].left_conflict_subnodes_size,
982
                  subnodes[i].left_conflict_size));
983
      subnodes[i].left_conflict_subnodes_size -= diff;
984
    }
985
  if (i != 0
986
      || (conflict_size
987
          + ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
988
          > data->available_regs_num))
989
    return false;
990
  data->colorable_p = true;
991
  return true;
992
}
993
 
994
/* Return true if allocno A has empty profitable hard regs.  */
995
static bool
996
empty_profitable_hard_regs (ira_allocno_t a)
997
{
998
  allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
999
 
1000
  return hard_reg_set_empty_p (data->profitable_hard_regs);
1001
}
1002
 
1003
/* Set up profitable hard registers for each allocno being
1004
   colored.  */
1005
static void
1006
setup_profitable_hard_regs (void)
1007
{
1008
  unsigned int i;
1009
  int j, k, nobj, hard_regno, nregs, class_size;
1010
  ira_allocno_t a;
1011
  bitmap_iterator bi;
1012
  enum reg_class aclass;
1013
  enum machine_mode mode;
1014
  allocno_color_data_t data;
1015
 
1016
  /* Initial set up from allocno classes and explicitly conflicting
1017
     hard regs.  */
1018
  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1019
    {
1020
      a = ira_allocnos[i];
1021
      if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS)
1022
        continue;
1023
      data = ALLOCNO_COLOR_DATA (a);
1024
      if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
1025
          && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a))
1026
        CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1027
      else
1028
        {
1029
          COPY_HARD_REG_SET (data->profitable_hard_regs,
1030
                             reg_class_contents[aclass]);
1031
          AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
1032
                                  ira_no_alloc_regs);
1033
          nobj = ALLOCNO_NUM_OBJECTS (a);
1034
          for (k = 0; k < nobj; k++)
1035
            {
1036
              ira_object_t obj = ALLOCNO_OBJECT (a, k);
1037
 
1038
              AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
1039
                                      OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1040
            }
1041
        }
1042
    }
1043
  /* Exclude hard regs already assigned for conflicting objects.  */
1044
  EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, i, bi)
1045
    {
1046
      a = ira_allocnos[i];
1047
      if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1048
          || ! ALLOCNO_ASSIGNED_P (a)
1049
          || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
1050
        continue;
1051
      mode = ALLOCNO_MODE (a);
1052
      nregs = hard_regno_nregs[hard_regno][mode];
1053
      nobj = ALLOCNO_NUM_OBJECTS (a);
1054
      for (k = 0; k < nobj; k++)
1055
        {
1056
          ira_object_t obj = ALLOCNO_OBJECT (a, k);
1057
          ira_object_t conflict_obj;
1058
          ira_object_conflict_iterator oci;
1059
 
1060
          FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1061
            {
1062
              ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1063
 
1064
              /* We can process the conflict allocno repeatedly with
1065
                 the same result.  */
1066
              if (nregs == nobj && nregs > 1)
1067
                {
1068
                  int num = OBJECT_SUBWORD (conflict_obj);
1069
 
1070
                  if (REG_WORDS_BIG_ENDIAN)
1071
                    CLEAR_HARD_REG_BIT
1072
                      (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1073
                       hard_regno + nobj - num - 1);
1074
                  else
1075
                    CLEAR_HARD_REG_BIT
1076
                      (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1077
                       hard_regno + num);
1078
                }
1079
              else
1080
                AND_COMPL_HARD_REG_SET
1081
                  (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs,
1082
                   ira_reg_mode_hard_regset[hard_regno][mode]);
1083
            }
1084
        }
1085
    }
1086
  /* Exclude too costly hard regs.  */
1087
  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
1088
    {
1089
      int min_cost = INT_MAX;
1090
      int *costs;
1091
 
1092
      a = ira_allocnos[i];
1093
      if ((aclass = ALLOCNO_CLASS (a)) == NO_REGS
1094
          || empty_profitable_hard_regs (a))
1095
        continue;
1096
      data = ALLOCNO_COLOR_DATA (a);
1097
      mode = ALLOCNO_MODE (a);
1098
      if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL
1099
          || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL)
1100
        {
1101
          class_size = ira_class_hard_regs_num[aclass];
1102
          for (j = 0; j < class_size; j++)
1103
            {
1104
              hard_regno = ira_class_hard_regs[aclass][j];
1105
              if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
1106
                                       hard_regno))
1107
                continue;
1108
              if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j])
1109
                CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
1110
                                    hard_regno);
1111
              else if (min_cost > costs[j])
1112
                min_cost = costs[j];
1113
            }
1114
        }
1115
      else if (ALLOCNO_UPDATED_MEMORY_COST (a)
1116
               < ALLOCNO_UPDATED_CLASS_COST (a))
1117
        CLEAR_HARD_REG_SET (data->profitable_hard_regs);
1118
      if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
1119
        ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
1120
    }
1121
}
1122
 
1123
 
1124
 
1125
/* This page contains functions used to choose hard registers for
1126
   allocnos.  */
1127
 
1128
/* Array whose element value is TRUE if the corresponding hard
1129
   register was already allocated for an allocno.  */
1130
static bool allocated_hardreg_p[FIRST_PSEUDO_REGISTER];
1131
 
1132
/* Describes one element in a queue of allocnos whose costs need to be
1133
   updated.  Each allocno in the queue is known to have an allocno
1134
   class.  */
1135
struct update_cost_queue_elem
1136
{
1137
  /* This element is in the queue iff CHECK == update_cost_check.  */
1138
  int check;
1139
 
1140
  /* COST_HOP_DIVISOR**N, where N is the length of the shortest path
1141
     connecting this allocno to the one being allocated.  */
1142
  int divisor;
1143
 
1144
  /* The next allocno in the queue, or null if this is the last element.  */
1145
  ira_allocno_t next;
1146
};
1147
 
1148
/* The first element in a queue of allocnos whose copy costs need to be
1149
   updated.  Null if the queue is empty.  */
1150
static ira_allocno_t update_cost_queue;
1151
 
1152
/* The last element in the queue described by update_cost_queue.
1153
   Not valid if update_cost_queue is null.  */
1154
static struct update_cost_queue_elem *update_cost_queue_tail;
1155
 
1156
/* A pool of elements in the queue described by update_cost_queue.
1157
   Elements are indexed by ALLOCNO_NUM.  */
1158
static struct update_cost_queue_elem *update_cost_queue_elems;
1159
 
1160
/* The current value of update_copy_cost call count.  */
1161
static int update_cost_check;
1162
 
1163
/* Allocate and initialize data necessary for function
1164
   update_copy_costs.  */
1165
static void
1166
initiate_cost_update (void)
1167
{
1168
  size_t size;
1169
 
1170
  size = ira_allocnos_num * sizeof (struct update_cost_queue_elem);
1171
  update_cost_queue_elems
1172
    = (struct update_cost_queue_elem *) ira_allocate (size);
1173
  memset (update_cost_queue_elems, 0, size);
1174
  update_cost_check = 0;
1175
}
1176
 
1177
/* Deallocate data used by function update_copy_costs.  */
1178
static void
1179
finish_cost_update (void)
1180
{
1181
  ira_free (update_cost_queue_elems);
1182
}
1183
 
1184
/* When we traverse allocnos to update hard register costs, the cost
1185
   divisor will be multiplied by the following macro value for each
1186
   hop from given allocno to directly connected allocnos.  */
1187
#define COST_HOP_DIVISOR 4
1188
 
1189
/* Start a new cost-updating pass.  */
1190
static void
1191
start_update_cost (void)
1192
{
1193
  update_cost_check++;
1194
  update_cost_queue = NULL;
1195
}
1196
 
1197
/* Add (ALLOCNO, DIVISOR) to the end of update_cost_queue, unless
1198
   ALLOCNO is already in the queue, or has NO_REGS class.  */
1199
static inline void
1200
queue_update_cost (ira_allocno_t allocno, int divisor)
1201
{
1202
  struct update_cost_queue_elem *elem;
1203
 
1204
  elem = &update_cost_queue_elems[ALLOCNO_NUM (allocno)];
1205
  if (elem->check != update_cost_check
1206
      && ALLOCNO_CLASS (allocno) != NO_REGS)
1207
    {
1208
      elem->check = update_cost_check;
1209
      elem->divisor = divisor;
1210
      elem->next = NULL;
1211
      if (update_cost_queue == NULL)
1212
        update_cost_queue = allocno;
1213
      else
1214
        update_cost_queue_tail->next = allocno;
1215
      update_cost_queue_tail = elem;
1216
    }
1217
}
1218
 
1219
/* Try to remove the first element from update_cost_queue.  Return false
1220
   if the queue was empty, otherwise make (*ALLOCNO, *DIVISOR) describe
1221
   the removed element.  */
1222
static inline bool
1223
get_next_update_cost (ira_allocno_t *allocno, int *divisor)
1224
{
1225
  struct update_cost_queue_elem *elem;
1226
 
1227
  if (update_cost_queue == NULL)
1228
    return false;
1229
 
1230
  *allocno = update_cost_queue;
1231
  elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
1232
  *divisor = elem->divisor;
1233
  update_cost_queue = elem->next;
1234
  return true;
1235
}
1236
 
1237
/* Update the cost of allocnos to increase chances to remove some
1238
   copies as the result of subsequent assignment.  */
1239
static void
1240
update_copy_costs (ira_allocno_t allocno, bool decr_p)
1241
{
1242
  int i, cost, update_cost, hard_regno, divisor;
1243
  enum machine_mode mode;
1244
  enum reg_class rclass, aclass;
1245
  ira_allocno_t another_allocno;
1246
  ira_copy_t cp, next_cp;
1247
 
1248
  hard_regno = ALLOCNO_HARD_REGNO (allocno);
1249
  ira_assert (hard_regno >= 0);
1250
 
1251
  aclass = ALLOCNO_CLASS (allocno);
1252
  if (aclass == NO_REGS)
1253
    return;
1254
  i = ira_class_hard_reg_index[aclass][hard_regno];
1255
  ira_assert (i >= 0);
1256
  rclass = REGNO_REG_CLASS (hard_regno);
1257
 
1258
  start_update_cost ();
1259
  divisor = 1;
1260
  do
1261
    {
1262
      mode = ALLOCNO_MODE (allocno);
1263
      ira_init_register_move_cost_if_necessary (mode);
1264
      for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1265
        {
1266
          if (cp->first == allocno)
1267
            {
1268
              next_cp = cp->next_first_allocno_copy;
1269
              another_allocno = cp->second;
1270
            }
1271
          else if (cp->second == allocno)
1272
            {
1273
              next_cp = cp->next_second_allocno_copy;
1274
              another_allocno = cp->first;
1275
            }
1276
          else
1277
            gcc_unreachable ();
1278
 
1279
          aclass = ALLOCNO_CLASS (another_allocno);
1280
          if (! TEST_HARD_REG_BIT (reg_class_contents[aclass],
1281
                                   hard_regno)
1282
              || ALLOCNO_ASSIGNED_P (another_allocno))
1283
            continue;
1284
 
1285
          cost = (cp->second == allocno
1286
                  ? ira_register_move_cost[mode][rclass][aclass]
1287
                  : ira_register_move_cost[mode][aclass][rclass]);
1288
          if (decr_p)
1289
            cost = -cost;
1290
 
1291
          update_cost = cp->freq * cost / divisor;
1292
          if (update_cost == 0)
1293
            continue;
1294
 
1295
          ira_allocate_and_set_or_copy_costs
1296
            (&ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno), aclass,
1297
             ALLOCNO_UPDATED_CLASS_COST (another_allocno),
1298
             ALLOCNO_HARD_REG_COSTS (another_allocno));
1299
          ira_allocate_and_set_or_copy_costs
1300
            (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1301
             aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1302
          i = ira_class_hard_reg_index[aclass][hard_regno];
1303
          if (i < 0)
1304
            continue;
1305
          ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno)[i] += update_cost;
1306
          ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno)[i]
1307
            += update_cost;
1308
 
1309
          queue_update_cost (another_allocno, divisor * COST_HOP_DIVISOR);
1310
        }
1311
    }
1312
  while (get_next_update_cost (&allocno, &divisor));
1313
}
1314
 
1315
/* This function updates COSTS (decrease if DECR_P) for hard_registers
1316
   of ACLASS by conflict costs of the unassigned allocnos
1317
   connected by copies with allocnos in update_cost_queue.  This
1318
   update increases chances to remove some copies.  */
1319
static void
1320
update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
1321
                                  bool decr_p)
1322
{
1323
  int i, cost, class_size, freq, mult, div, divisor;
1324
  int index, hard_regno;
1325
  int *conflict_costs;
1326
  bool cont_p;
1327
  enum reg_class another_aclass;
1328
  ira_allocno_t allocno, another_allocno;
1329
  ira_copy_t cp, next_cp;
1330
 
1331
  while (get_next_update_cost (&allocno, &divisor))
1332
    for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
1333
      {
1334
        if (cp->first == allocno)
1335
          {
1336
            next_cp = cp->next_first_allocno_copy;
1337
            another_allocno = cp->second;
1338
          }
1339
        else if (cp->second == allocno)
1340
          {
1341
            next_cp = cp->next_second_allocno_copy;
1342
            another_allocno = cp->first;
1343
          }
1344
        else
1345
          gcc_unreachable ();
1346
        another_aclass = ALLOCNO_CLASS (another_allocno);
1347
        if (! ira_reg_classes_intersect_p[aclass][another_aclass]
1348
            || ALLOCNO_ASSIGNED_P (another_allocno)
1349
            || ALLOCNO_COLOR_DATA (another_allocno)->may_be_spilled_p)
1350
          continue;
1351
        class_size = ira_class_hard_regs_num[another_aclass];
1352
        ira_allocate_and_copy_costs
1353
          (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
1354
           another_aclass, ALLOCNO_CONFLICT_HARD_REG_COSTS (another_allocno));
1355
        conflict_costs
1356
          = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno);
1357
        if (conflict_costs == NULL)
1358
          cont_p = true;
1359
        else
1360
          {
1361
            mult = cp->freq;
1362
            freq = ALLOCNO_FREQ (another_allocno);
1363
            if (freq == 0)
1364
              freq = 1;
1365
            div = freq * divisor;
1366
            cont_p = false;
1367
            for (i = class_size - 1; i >= 0; i--)
1368
              {
1369
                hard_regno = ira_class_hard_regs[another_aclass][i];
1370
                ira_assert (hard_regno >= 0);
1371
                index = ira_class_hard_reg_index[aclass][hard_regno];
1372
                if (index < 0)
1373
                  continue;
1374
                cost = conflict_costs [i] * mult / div;
1375
                if (cost == 0)
1376
                  continue;
1377
                cont_p = true;
1378
                if (decr_p)
1379
                  cost = -cost;
1380
                costs[index] += cost;
1381
              }
1382
          }
1383
        /* Probably 5 hops will be enough.  */
1384
        if (cont_p
1385
            && divisor <= (COST_HOP_DIVISOR
1386
                           * COST_HOP_DIVISOR
1387
                           * COST_HOP_DIVISOR
1388
                           * COST_HOP_DIVISOR))
1389
          queue_update_cost (another_allocno, divisor * COST_HOP_DIVISOR);
1390
      }
1391
}
1392
 
1393
/* Set up conflicting (through CONFLICT_REGS) for each object of
1394
   allocno A and the start allocno profitable regs (through
1395
   START_PROFITABLE_REGS).  Remember that the start profitable regs
1396
   exclude hard regs which can not hold value of mode of allocno A.
1397
   This covers mostly cases when multi-register value should be
1398
   aligned.  */
1399
static inline void
1400
get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p,
1401
                                        HARD_REG_SET *conflict_regs,
1402
                                        HARD_REG_SET *start_profitable_regs)
1403
{
1404
  int i, nwords;
1405
  ira_object_t obj;
1406
 
1407
  nwords = ALLOCNO_NUM_OBJECTS (a);
1408
  for (i = 0; i < nwords; i++)
1409
    {
1410
      obj = ALLOCNO_OBJECT (a, i);
1411
      COPY_HARD_REG_SET (conflict_regs[i],
1412
                         OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
1413
    }
1414
  if (retry_p)
1415
    {
1416
      COPY_HARD_REG_SET (*start_profitable_regs,
1417
                         reg_class_contents[ALLOCNO_CLASS (a)]);
1418
      AND_COMPL_HARD_REG_SET (*start_profitable_regs,
1419
                              ira_prohibited_class_mode_regs
1420
                              [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
1421
    }
1422
  else
1423
    COPY_HARD_REG_SET (*start_profitable_regs,
1424
                       ALLOCNO_COLOR_DATA (a)->profitable_hard_regs);
1425
}
1426
 
1427
/* Return true if HARD_REGNO is ok for assigning to allocno A with
1428
   PROFITABLE_REGS and whose objects have CONFLICT_REGS.  */
1429
static inline bool
1430
check_hard_reg_p (ira_allocno_t a, int hard_regno,
1431
                  HARD_REG_SET *conflict_regs, HARD_REG_SET profitable_regs)
1432
{
1433
  int j, nwords, nregs;
1434
  enum reg_class aclass;
1435
  enum machine_mode mode;
1436
 
1437
  aclass = ALLOCNO_CLASS (a);
1438
  mode = ALLOCNO_MODE (a);
1439
  if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode],
1440
                         hard_regno))
1441
    return false;
1442
  /* Checking only profitable hard regs.  */
1443
  if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
1444
    return false;
1445
  nregs = hard_regno_nregs[hard_regno][mode];
1446
  nwords = ALLOCNO_NUM_OBJECTS (a);
1447
  for (j = 0; j < nregs; j++)
1448
    {
1449
      int k;
1450
      int set_to_test_start = 0, set_to_test_end = nwords;
1451
 
1452
      if (nregs == nwords)
1453
        {
1454
          if (REG_WORDS_BIG_ENDIAN)
1455
            set_to_test_start = nwords - j - 1;
1456
          else
1457
            set_to_test_start = j;
1458
          set_to_test_end = set_to_test_start + 1;
1459
        }
1460
      for (k = set_to_test_start; k < set_to_test_end; k++)
1461
        if (TEST_HARD_REG_BIT (conflict_regs[k], hard_regno + j))
1462
          break;
1463
      if (k != set_to_test_end)
1464
        break;
1465
    }
1466
  return j == nregs;
1467
}
1468
#ifndef HONOR_REG_ALLOC_ORDER
1469
 
1470
/* Return number of registers needed to be saved and restored at
1471
   function prologue/epilogue if we allocate HARD_REGNO to hold value
1472
   of MODE.  */
1473
static int
1474
calculate_saved_nregs (int hard_regno, enum machine_mode mode)
1475
{
1476
  int i;
1477
  int nregs = 0;
1478
 
1479
  ira_assert (hard_regno >= 0);
1480
  for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
1481
    if (!allocated_hardreg_p[hard_regno + i]
1482
        && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
1483
        && !LOCAL_REGNO (hard_regno + i))
1484
      nregs++;
1485
  return nregs;
1486
}
1487
#endif
1488
 
1489
/* Choose a hard register for allocno A.  If RETRY_P is TRUE, it means
1490
   that the function called from function
1491
   `ira_reassign_conflict_allocnos' and `allocno_reload_assign'.  In
1492
   this case some allocno data are not defined or updated and we
1493
   should not touch these data.  The function returns true if we
1494
   managed to assign a hard register to the allocno.
1495
 
1496
   To assign a hard register, first of all we calculate all conflict
1497
   hard registers which can come from conflicting allocnos with
1498
   already assigned hard registers.  After that we find first free
1499
   hard register with the minimal cost.  During hard register cost
1500
   calculation we take conflict hard register costs into account to
1501
   give a chance for conflicting allocnos to get a better hard
1502
   register in the future.
1503
 
1504
   If the best hard register cost is bigger than cost of memory usage
1505
   for the allocno, we don't assign a hard register to given allocno
1506
   at all.
1507
 
1508
   If we assign a hard register to the allocno, we update costs of the
1509
   hard register for allocnos connected by copies to improve a chance
1510
   to coalesce insns represented by the copies when we assign hard
1511
   registers to the allocnos connected by the copies.  */
1512
static bool
1513
assign_hard_reg (ira_allocno_t a, bool retry_p)
1514
{
1515
  HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
1516
  int i, j, hard_regno, best_hard_regno, class_size;
1517
  int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word;
1518
  int *a_costs;
1519
  enum reg_class aclass;
1520
  enum machine_mode mode;
1521
  static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
1522
#ifndef HONOR_REG_ALLOC_ORDER
1523
  int saved_nregs;
1524
  enum reg_class rclass;
1525
  int add_cost;
1526
#endif
1527
#ifdef STACK_REGS
1528
  bool no_stack_reg_p;
1529
#endif
1530
 
1531
  ira_assert (! ALLOCNO_ASSIGNED_P (a));
1532
  get_conflict_and_start_profitable_regs (a, retry_p,
1533
                                          conflicting_regs,
1534
                                          &profitable_hard_regs);
1535
  aclass = ALLOCNO_CLASS (a);
1536
  class_size = ira_class_hard_regs_num[aclass];
1537
  best_hard_regno = -1;
1538
  memset (full_costs, 0, sizeof (int) * class_size);
1539
  mem_cost = 0;
1540
  memset (costs, 0, sizeof (int) * class_size);
1541
  memset (full_costs, 0, sizeof (int) * class_size);
1542
#ifdef STACK_REGS
1543
  no_stack_reg_p = false;
1544
#endif
1545
  if (! retry_p)
1546
    start_update_cost ();
1547
  mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
1548
 
1549
  ira_allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
1550
                               aclass, ALLOCNO_HARD_REG_COSTS (a));
1551
  a_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
1552
#ifdef STACK_REGS
1553
  no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
1554
#endif
1555
  cost = ALLOCNO_UPDATED_CLASS_COST (a);
1556
  for (i = 0; i < class_size; i++)
1557
    if (a_costs != NULL)
1558
      {
1559
        costs[i] += a_costs[i];
1560
        full_costs[i] += a_costs[i];
1561
      }
1562
    else
1563
      {
1564
        costs[i] += cost;
1565
        full_costs[i] += cost;
1566
      }
1567
  nwords = ALLOCNO_NUM_OBJECTS (a);
1568
  curr_allocno_process++;
1569
  for (word = 0; word < nwords; word++)
1570
    {
1571
      ira_object_t conflict_obj;
1572
      ira_object_t obj = ALLOCNO_OBJECT (a, word);
1573
      ira_object_conflict_iterator oci;
1574
 
1575
      /* Take preferences of conflicting allocnos into account.  */
1576
      FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1577
        {
1578
          ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1579
          enum reg_class conflict_aclass;
1580
 
1581
          /* Reload can give another class so we need to check all
1582
             allocnos.  */
1583
          if (!retry_p
1584
              && (!bitmap_bit_p (consideration_allocno_bitmap,
1585
                                 ALLOCNO_NUM (conflict_a))
1586
                  || ((!ALLOCNO_ASSIGNED_P (conflict_a)
1587
                       || ALLOCNO_HARD_REGNO (conflict_a) < 0)
1588
                      && !(hard_reg_set_intersect_p
1589
                           (profitable_hard_regs,
1590
                            ALLOCNO_COLOR_DATA
1591
                            (conflict_a)->profitable_hard_regs)))))
1592
            continue;
1593
          conflict_aclass = ALLOCNO_CLASS (conflict_a);
1594
          ira_assert (ira_reg_classes_intersect_p
1595
                      [aclass][conflict_aclass]);
1596
          if (ALLOCNO_ASSIGNED_P (conflict_a))
1597
            {
1598
              hard_regno = ALLOCNO_HARD_REGNO (conflict_a);
1599
              if (hard_regno >= 0
1600
                  && (ira_hard_reg_set_intersection_p
1601
                      (hard_regno, ALLOCNO_MODE (conflict_a),
1602
                       reg_class_contents[aclass])))
1603
                {
1604
                  int n_objects = ALLOCNO_NUM_OBJECTS (conflict_a);
1605
                  int conflict_nregs;
1606
 
1607
                  mode = ALLOCNO_MODE (conflict_a);
1608
                  conflict_nregs = hard_regno_nregs[hard_regno][mode];
1609
                  if (conflict_nregs == n_objects && conflict_nregs > 1)
1610
                    {
1611
                      int num = OBJECT_SUBWORD (conflict_obj);
1612
 
1613
                      if (REG_WORDS_BIG_ENDIAN)
1614
                        SET_HARD_REG_BIT (conflicting_regs[word],
1615
                                          hard_regno + n_objects - num - 1);
1616
                      else
1617
                        SET_HARD_REG_BIT (conflicting_regs[word],
1618
                                          hard_regno + num);
1619
                    }
1620
                  else
1621
                    IOR_HARD_REG_SET
1622
                      (conflicting_regs[word],
1623
                       ira_reg_mode_hard_regset[hard_regno][mode]);
1624
                  if (hard_reg_set_subset_p (profitable_hard_regs,
1625
                                             conflicting_regs[word]))
1626
                    goto fail;
1627
                }
1628
            }
1629
          else if (! retry_p
1630
                   && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
1631
                   /* Don't process the conflict allocno twice.  */
1632
                   && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
1633
                       != curr_allocno_process))
1634
            {
1635
              int k, *conflict_costs;
1636
 
1637
              ALLOCNO_COLOR_DATA (conflict_a)->last_process
1638
                = curr_allocno_process;
1639
              ira_allocate_and_copy_costs
1640
                (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a),
1641
                 conflict_aclass,
1642
                 ALLOCNO_CONFLICT_HARD_REG_COSTS (conflict_a));
1643
              conflict_costs
1644
                = ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_a);
1645
              if (conflict_costs != NULL)
1646
                for (j = class_size - 1; j >= 0; j--)
1647
                  {
1648
                    hard_regno = ira_class_hard_regs[aclass][j];
1649
                    ira_assert (hard_regno >= 0);
1650
                    k = ira_class_hard_reg_index[conflict_aclass][hard_regno];
1651
                    if (k < 0)
1652
                      continue;
1653
                    full_costs[j] -= conflict_costs[k];
1654
                  }
1655
              queue_update_cost (conflict_a, COST_HOP_DIVISOR);
1656
            }
1657
        }
1658
    }
1659
  if (! retry_p)
1660
    /* Take into account preferences of allocnos connected by copies to
1661
       the conflict allocnos.  */
1662
    update_conflict_hard_regno_costs (full_costs, aclass, true);
1663
 
1664
  /* Take preferences of allocnos connected by copies into
1665
     account.  */
1666
  if (! retry_p)
1667
    {
1668
      start_update_cost ();
1669
      queue_update_cost (a, COST_HOP_DIVISOR);
1670
      update_conflict_hard_regno_costs (full_costs, aclass, false);
1671
    }
1672
  min_cost = min_full_cost = INT_MAX;
1673
  /* We don't care about giving callee saved registers to allocnos no
1674
     living through calls because call clobbered registers are
1675
     allocated first (it is usual practice to put them first in
1676
     REG_ALLOC_ORDER).  */
1677
  mode = ALLOCNO_MODE (a);
1678
  for (i = 0; i < class_size; i++)
1679
    {
1680
      hard_regno = ira_class_hard_regs[aclass][i];
1681
#ifdef STACK_REGS
1682
      if (no_stack_reg_p
1683
          && FIRST_STACK_REG <= hard_regno && hard_regno <= LAST_STACK_REG)
1684
        continue;
1685
#endif
1686
      if (! check_hard_reg_p (a, hard_regno,
1687
                              conflicting_regs, profitable_hard_regs))
1688
        continue;
1689
      cost = costs[i];
1690
      full_cost = full_costs[i];
1691
#ifndef HONOR_REG_ALLOC_ORDER
1692
      if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
1693
        /* We need to save/restore the hard register in
1694
           epilogue/prologue.  Therefore we increase the cost.  */
1695
        {
1696
          rclass = REGNO_REG_CLASS (hard_regno);
1697
          add_cost = ((ira_memory_move_cost[mode][rclass][0]
1698
                       + ira_memory_move_cost[mode][rclass][1])
1699
                      * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
1700
          cost += add_cost;
1701
          full_cost += add_cost;
1702
        }
1703
#endif
1704
      if (min_cost > cost)
1705
        min_cost = cost;
1706
      if (min_full_cost > full_cost)
1707
        {
1708
          min_full_cost = full_cost;
1709
          best_hard_regno = hard_regno;
1710
          ira_assert (hard_regno >= 0);
1711
        }
1712
    }
1713
  if (min_full_cost > mem_cost)
1714
    {
1715
      if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1716
        fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
1717
                 mem_cost, min_full_cost);
1718
      best_hard_regno = -1;
1719
    }
1720
 fail:
1721
  if (best_hard_regno >= 0)
1722
    {
1723
      for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
1724
        allocated_hardreg_p[best_hard_regno + i] = true;
1725
    }
1726
  ALLOCNO_HARD_REGNO (a) = best_hard_regno;
1727
  ALLOCNO_ASSIGNED_P (a) = true;
1728
  if (best_hard_regno >= 0)
1729
    update_copy_costs (a, true);
1730
  ira_assert (ALLOCNO_CLASS (a) == aclass);
1731
  /* We don't need updated costs anymore: */
1732
  ira_free_allocno_updated_costs (a);
1733
  return best_hard_regno >= 0;
1734
}
1735
 
1736
 
1737
 
1738
/* This page contains the allocator based on the Chaitin-Briggs algorithm.  */
1739
 
1740
/* Bucket of allocnos that can colored currently without spilling.  */
1741
static ira_allocno_t colorable_allocno_bucket;
1742
 
1743
/* Bucket of allocnos that might be not colored currently without
1744
   spilling.  */
1745
static ira_allocno_t uncolorable_allocno_bucket;
1746
 
1747
/* The current number of allocnos in the uncolorable_bucket.  */
1748
static int uncolorable_allocnos_num;
1749
 
1750
/* Return the current spill priority of allocno A.  The less the
1751
   number, the more preferable the allocno for spilling.  */
1752
static inline int
1753
allocno_spill_priority (ira_allocno_t a)
1754
{
1755
  allocno_color_data_t data = ALLOCNO_COLOR_DATA (a);
1756
 
1757
  return (data->temp
1758
          / (ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
1759
             * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]
1760
             + 1));
1761
}
1762
 
1763
/* Add allocno A to bucket *BUCKET_PTR.  A should be not in a bucket
1764
   before the call.  */
1765
static void
1766
add_allocno_to_bucket (ira_allocno_t a, ira_allocno_t *bucket_ptr)
1767
{
1768
  ira_allocno_t first_a;
1769
  allocno_color_data_t data;
1770
 
1771
  if (bucket_ptr == &uncolorable_allocno_bucket
1772
      && ALLOCNO_CLASS (a) != NO_REGS)
1773
    {
1774
      uncolorable_allocnos_num++;
1775
      ira_assert (uncolorable_allocnos_num > 0);
1776
    }
1777
  first_a = *bucket_ptr;
1778
  data = ALLOCNO_COLOR_DATA (a);
1779
  data->next_bucket_allocno = first_a;
1780
  data->prev_bucket_allocno = NULL;
1781
  if (first_a != NULL)
1782
    ALLOCNO_COLOR_DATA (first_a)->prev_bucket_allocno = a;
1783
  *bucket_ptr = a;
1784
}
1785
 
1786
/* Compare two allocnos to define which allocno should be pushed first
1787
   into the coloring stack.  If the return is a negative number, the
1788
   allocno given by the first parameter will be pushed first.  In this
1789
   case such allocno has less priority than the second one and the
1790
   hard register will be assigned to it after assignment to the second
1791
   one.  As the result of such assignment order, the second allocno
1792
   has a better chance to get the best hard register.  */
1793
static int
1794
bucket_allocno_compare_func (const void *v1p, const void *v2p)
1795
{
1796
  ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
1797
  ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
1798
  int diff, a1_freq, a2_freq, a1_num, a2_num;
1799
  int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);
1800
 
1801
  /* Push pseudos requiring less hard registers first.  It means that
1802
     we will assign pseudos requiring more hard registers first
1803
     avoiding creation small holes in free hard register file into
1804
     which the pseudos requiring more hard registers can not fit.  */
1805
  if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)]
1806
               - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0)
1807
    return diff;
1808
  a1_freq = ALLOCNO_FREQ (a1);
1809
  a2_freq = ALLOCNO_FREQ (a2);
1810
  if ((diff = a1_freq - a2_freq) != 0)
1811
    return diff;
1812
  a1_num = ALLOCNO_COLOR_DATA (a1)->available_regs_num;
1813
  a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
1814
  if ((diff = a2_num - a1_num) != 0)
1815
    return diff;
1816
  return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
1817
}
1818
 
1819
/* Sort bucket *BUCKET_PTR and return the result through
1820
   BUCKET_PTR.  */
1821
static void
1822
sort_bucket (ira_allocno_t *bucket_ptr,
1823
             int (*compare_func) (const void *, const void *))
1824
{
1825
  ira_allocno_t a, head;
1826
  int n;
1827
 
1828
  for (n = 0, a = *bucket_ptr;
1829
       a != NULL;
1830
       a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
1831
    sorted_allocnos[n++] = a;
1832
  if (n <= 1)
1833
    return;
1834
  qsort (sorted_allocnos, n, sizeof (ira_allocno_t), compare_func);
1835
  head = NULL;
1836
  for (n--; n >= 0; n--)
1837
    {
1838
      a = sorted_allocnos[n];
1839
      ALLOCNO_COLOR_DATA (a)->next_bucket_allocno = head;
1840
      ALLOCNO_COLOR_DATA (a)->prev_bucket_allocno = NULL;
1841
      if (head != NULL)
1842
        ALLOCNO_COLOR_DATA (head)->prev_bucket_allocno = a;
1843
      head = a;
1844
    }
1845
  *bucket_ptr = head;
1846
}
1847
 
1848
/* Add ALLOCNO to bucket *BUCKET_PTR maintaining the order according
1849
   their priority.  ALLOCNO should be not in a bucket before the
1850
   call.  */
1851
static void
1852
add_allocno_to_ordered_bucket (ira_allocno_t allocno,
1853
                               ira_allocno_t *bucket_ptr)
1854
{
1855
  ira_allocno_t before, after;
1856
 
1857
  if (bucket_ptr == &uncolorable_allocno_bucket
1858
      && ALLOCNO_CLASS (allocno) != NO_REGS)
1859
    {
1860
      uncolorable_allocnos_num++;
1861
      ira_assert (uncolorable_allocnos_num > 0);
1862
    }
1863
  for (before = *bucket_ptr, after = NULL;
1864
       before != NULL;
1865
       after = before,
1866
         before = ALLOCNO_COLOR_DATA (before)->next_bucket_allocno)
1867
    if (bucket_allocno_compare_func (&allocno, &before) < 0)
1868
      break;
1869
  ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno = before;
1870
  ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno = after;
1871
  if (after == NULL)
1872
    *bucket_ptr = allocno;
1873
  else
1874
    ALLOCNO_COLOR_DATA (after)->next_bucket_allocno = allocno;
1875
  if (before != NULL)
1876
    ALLOCNO_COLOR_DATA (before)->prev_bucket_allocno = allocno;
1877
}
1878
 
1879
/* Delete ALLOCNO from bucket *BUCKET_PTR.  It should be there before
1880
   the call.  */
1881
static void
1882
delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
1883
{
1884
  ira_allocno_t prev_allocno, next_allocno;
1885
 
1886
  if (bucket_ptr == &uncolorable_allocno_bucket
1887
      && ALLOCNO_CLASS (allocno) != NO_REGS)
1888
    {
1889
      uncolorable_allocnos_num--;
1890
      ira_assert (uncolorable_allocnos_num >= 0);
1891
    }
1892
  prev_allocno = ALLOCNO_COLOR_DATA (allocno)->prev_bucket_allocno;
1893
  next_allocno = ALLOCNO_COLOR_DATA (allocno)->next_bucket_allocno;
1894
  if (prev_allocno != NULL)
1895
    ALLOCNO_COLOR_DATA (prev_allocno)->next_bucket_allocno = next_allocno;
1896
  else
1897
    {
1898
      ira_assert (*bucket_ptr == allocno);
1899
      *bucket_ptr = next_allocno;
1900
    }
1901
  if (next_allocno != NULL)
1902
    ALLOCNO_COLOR_DATA (next_allocno)->prev_bucket_allocno = prev_allocno;
1903
}
1904
 
1905
/* Put allocno A onto the coloring stack without removing it from its
1906
   bucket.  Pushing allocno to the coloring stack can result in moving
1907
   conflicting allocnos from the uncolorable bucket to the colorable
1908
   one.  */
1909
static void
1910
push_allocno_to_stack (ira_allocno_t a)
1911
{
1912
  enum reg_class aclass;
1913
  allocno_color_data_t data, conflict_data;
1914
  int size, i, n = ALLOCNO_NUM_OBJECTS (a);
1915
 
1916
  data = ALLOCNO_COLOR_DATA (a);
1917
  data->in_graph_p = false;
1918
  VEC_safe_push (ira_allocno_t, heap, allocno_stack_vec, a);
1919
  aclass = ALLOCNO_CLASS (a);
1920
  if (aclass == NO_REGS)
1921
    return;
1922
  size = ira_reg_class_max_nregs[aclass][ALLOCNO_MODE (a)];
1923
  if (n > 1)
1924
    {
1925
      /* We will deal with the subwords individually.  */
1926
      gcc_assert (size == ALLOCNO_NUM_OBJECTS (a));
1927
      size = 1;
1928
    }
1929
  for (i = 0; i < n; i++)
1930
    {
1931
      ira_object_t obj = ALLOCNO_OBJECT (a, i);
1932
      ira_object_t conflict_obj;
1933
      ira_object_conflict_iterator oci;
1934
 
1935
      FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
1936
        {
1937
          ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
1938
 
1939
          conflict_data = ALLOCNO_COLOR_DATA (conflict_a);
1940
          if (conflict_data->colorable_p
1941
              || ! conflict_data->in_graph_p
1942
              || ALLOCNO_ASSIGNED_P (conflict_a)
1943
              || !(hard_reg_set_intersect_p
1944
                   (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs,
1945
                    conflict_data->profitable_hard_regs)))
1946
            continue;
1947
          ira_assert (bitmap_bit_p (coloring_allocno_bitmap,
1948
                                    ALLOCNO_NUM (conflict_a)));
1949
          if (update_left_conflict_sizes_p (conflict_a, a, size))
1950
            {
1951
              delete_allocno_from_bucket
1952
                (conflict_a, &uncolorable_allocno_bucket);
1953
              add_allocno_to_ordered_bucket
1954
                (conflict_a, &colorable_allocno_bucket);
1955
              if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
1956
                {
1957
                  fprintf (ira_dump_file, "        Making");
1958
                  ira_print_expanded_allocno (conflict_a);
1959
                  fprintf (ira_dump_file, " colorable\n");
1960
                }
1961
            }
1962
 
1963
        }
1964
    }
1965
}
1966
 
1967
/* Put ALLOCNO onto the coloring stack and remove it from its bucket.
1968
   The allocno is in the colorable bucket if COLORABLE_P is TRUE.  */
1969
static void
1970
remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
1971
{
1972
  if (colorable_p)
1973
    delete_allocno_from_bucket (allocno, &colorable_allocno_bucket);
1974
  else
1975
    delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
1976
  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
1977
    {
1978
      fprintf (ira_dump_file, "      Pushing");
1979
      ira_print_expanded_allocno (allocno);
1980
      if (colorable_p)
1981
        fprintf (ira_dump_file, "(cost %d)\n",
1982
                 ALLOCNO_COLOR_DATA (allocno)->temp);
1983
      else
1984
        fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
1985
                 ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
1986
                 allocno_spill_priority (allocno),
1987
                 ALLOCNO_COLOR_DATA (allocno)->temp);
1988
    }
1989
  if (! colorable_p)
1990
    ALLOCNO_COLOR_DATA (allocno)->may_be_spilled_p = true;
1991
  push_allocno_to_stack (allocno);
1992
}
1993
 
1994
/* Put all allocnos from colorable bucket onto the coloring stack.  */
1995
static void
1996
push_only_colorable (void)
1997
{
1998
  sort_bucket (&colorable_allocno_bucket, bucket_allocno_compare_func);
1999
  for (;colorable_allocno_bucket != NULL;)
2000
    remove_allocno_from_bucket_and_push (colorable_allocno_bucket, true);
2001
}
2002
 
2003
/* Return the frequency of exit edges (if EXIT_P) or entry from/to the
2004
   loop given by its LOOP_NODE.  */
2005
int
2006
ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
2007
{
2008
  int freq, i;
2009
  edge_iterator ei;
2010
  edge e;
2011
  VEC (edge, heap) *edges;
2012
 
2013
  ira_assert (current_loops != NULL && loop_node->loop != NULL
2014
              && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
2015
  freq = 0;
2016
  if (! exit_p)
2017
    {
2018
      FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
2019
        if (e->src != loop_node->loop->latch
2020
            && (regno < 0
2021
                || (bitmap_bit_p (DF_LR_OUT (e->src), regno)
2022
                    && bitmap_bit_p (DF_LR_IN (e->dest), regno))))
2023
          freq += EDGE_FREQUENCY (e);
2024
    }
2025
  else
2026
    {
2027
      edges = get_loop_exit_edges (loop_node->loop);
2028
      FOR_EACH_VEC_ELT (edge, edges, i, e)
2029
        if (regno < 0
2030
            || (bitmap_bit_p (DF_LR_OUT (e->src), regno)
2031
                && bitmap_bit_p (DF_LR_IN (e->dest), regno)))
2032
          freq += EDGE_FREQUENCY (e);
2033
      VEC_free (edge, heap, edges);
2034
    }
2035
 
2036
  return REG_FREQ_FROM_EDGE_FREQ (freq);
2037
}
2038
 
2039
/* Calculate and return the cost of putting allocno A into memory.  */
2040
static int
2041
calculate_allocno_spill_cost (ira_allocno_t a)
2042
{
2043
  int regno, cost;
2044
  enum machine_mode mode;
2045
  enum reg_class rclass;
2046
  ira_allocno_t parent_allocno;
2047
  ira_loop_tree_node_t parent_node, loop_node;
2048
 
2049
  regno = ALLOCNO_REGNO (a);
2050
  cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_CLASS_COST (a);
2051
  if (ALLOCNO_CAP (a) != NULL)
2052
    return cost;
2053
  loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2054
  if ((parent_node = loop_node->parent) == NULL)
2055
    return cost;
2056
  if ((parent_allocno = parent_node->regno_allocno_map[regno]) == NULL)
2057
    return cost;
2058
  mode = ALLOCNO_MODE (a);
2059
  rclass = ALLOCNO_CLASS (a);
2060
  if (ALLOCNO_HARD_REGNO (parent_allocno) < 0)
2061
    cost -= (ira_memory_move_cost[mode][rclass][0]
2062
             * ira_loop_edge_freq (loop_node, regno, true)
2063
             + ira_memory_move_cost[mode][rclass][1]
2064
             * ira_loop_edge_freq (loop_node, regno, false));
2065
  else
2066
    {
2067
      ira_init_register_move_cost_if_necessary (mode);
2068
      cost += ((ira_memory_move_cost[mode][rclass][1]
2069
                * ira_loop_edge_freq (loop_node, regno, true)
2070
                + ira_memory_move_cost[mode][rclass][0]
2071
                * ira_loop_edge_freq (loop_node, regno, false))
2072
               - (ira_register_move_cost[mode][rclass][rclass]
2073
                  * (ira_loop_edge_freq (loop_node, regno, false)
2074
                     + ira_loop_edge_freq (loop_node, regno, true))));
2075
    }
2076
  return cost;
2077
}
2078
 
2079
/* Used for sorting allocnos for spilling.  */
2080
static inline int
2081
allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
2082
{
2083
  int pri1, pri2, diff;
2084
 
2085
  if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
2086
    return 1;
2087
  if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
2088
    return -1;
2089
  pri1 = allocno_spill_priority (a1);
2090
  pri2 = allocno_spill_priority (a2);
2091
  if ((diff = pri1 - pri2) != 0)
2092
    return diff;
2093
  if ((diff
2094
       = ALLOCNO_COLOR_DATA (a1)->temp - ALLOCNO_COLOR_DATA (a2)->temp) != 0)
2095
    return diff;
2096
  return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2097
}
2098
 
2099
/* Used for sorting allocnos for spilling.  */
2100
static int
2101
allocno_spill_sort_compare (const void *v1p, const void *v2p)
2102
{
2103
  ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2104
  ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2105
 
2106
  return allocno_spill_priority_compare (p1, p2);
2107
}
2108
 
2109
/* Push allocnos to the coloring stack.  The order of allocnos in the
2110
   stack defines the order for the subsequent coloring.  */
2111
static void
2112
push_allocnos_to_stack (void)
2113
{
2114
  ira_allocno_t a;
2115
  int cost;
2116
 
2117
  /* Calculate uncolorable allocno spill costs.  */
2118
  for (a = uncolorable_allocno_bucket;
2119
       a != NULL;
2120
       a = ALLOCNO_COLOR_DATA (a)->next_bucket_allocno)
2121
    if (ALLOCNO_CLASS (a) != NO_REGS)
2122
      {
2123
        cost = calculate_allocno_spill_cost (a);
2124
        /* ??? Remove cost of copies between the coalesced
2125
           allocnos.  */
2126
        ALLOCNO_COLOR_DATA (a)->temp = cost;
2127
      }
2128
  sort_bucket (&uncolorable_allocno_bucket, allocno_spill_sort_compare);
2129
  for (;;)
2130
    {
2131
      push_only_colorable ();
2132
      a = uncolorable_allocno_bucket;
2133
      if (a == NULL)
2134
        break;
2135
      remove_allocno_from_bucket_and_push (a, false);
2136
    }
2137
  ira_assert (colorable_allocno_bucket == NULL
2138
              && uncolorable_allocno_bucket == NULL);
2139
  ira_assert (uncolorable_allocnos_num == 0);
2140
}
2141
 
2142
/* Pop the coloring stack and assign hard registers to the popped
2143
   allocnos.  */
2144
static void
2145
pop_allocnos_from_stack (void)
2146
{
2147
  ira_allocno_t allocno;
2148
  enum reg_class aclass;
2149
 
2150
  for (;VEC_length (ira_allocno_t, allocno_stack_vec) != 0;)
2151
    {
2152
      allocno = VEC_pop (ira_allocno_t, allocno_stack_vec);
2153
      aclass = ALLOCNO_CLASS (allocno);
2154
      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2155
        {
2156
          fprintf (ira_dump_file, "      Popping");
2157
          ira_print_expanded_allocno (allocno);
2158
          fprintf (ira_dump_file, "  -- ");
2159
        }
2160
      if (aclass == NO_REGS)
2161
        {
2162
          ALLOCNO_HARD_REGNO (allocno) = -1;
2163
          ALLOCNO_ASSIGNED_P (allocno) = true;
2164
          ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (allocno) == NULL);
2165
          ira_assert
2166
            (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (allocno) == NULL);
2167
          if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2168
            fprintf (ira_dump_file, "assign memory\n");
2169
        }
2170
      else if (assign_hard_reg (allocno, false))
2171
        {
2172
          if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2173
            fprintf (ira_dump_file, "assign reg %d\n",
2174
                     ALLOCNO_HARD_REGNO (allocno));
2175
        }
2176
      else if (ALLOCNO_ASSIGNED_P (allocno))
2177
        {
2178
          if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2179
            fprintf (ira_dump_file, "spill\n");
2180
        }
2181
      ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2182
    }
2183
}
2184
 
2185
/* Set up number of available hard registers for allocno A.  */
2186
static void
2187
setup_allocno_available_regs_num (ira_allocno_t a)
2188
{
2189
  int i, n, hard_regno, hard_regs_num, nwords;
2190
  enum reg_class aclass;
2191
  allocno_color_data_t data;
2192
 
2193
  aclass = ALLOCNO_CLASS (a);
2194
  data = ALLOCNO_COLOR_DATA (a);
2195
  data->available_regs_num = 0;
2196
  if (aclass == NO_REGS)
2197
    return;
2198
  hard_regs_num = ira_class_hard_regs_num[aclass];
2199
  nwords = ALLOCNO_NUM_OBJECTS (a);
2200
  for (n = 0, i = hard_regs_num - 1; i >= 0; i--)
2201
    {
2202
      hard_regno = ira_class_hard_regs[aclass][i];
2203
      /* Checking only profitable hard regs.  */
2204
      if (TEST_HARD_REG_BIT (data->profitable_hard_regs, hard_regno))
2205
        n++;
2206
    }
2207
  data->available_regs_num = n;
2208
  if (internal_flag_ira_verbose <= 2 || ira_dump_file == NULL)
2209
    return;
2210
  fprintf
2211
    (ira_dump_file,
2212
     "      Allocno a%dr%d of %s(%d) has %d avail. regs ",
2213
     ALLOCNO_NUM (a), ALLOCNO_REGNO (a),
2214
     reg_class_names[aclass], ira_class_hard_regs_num[aclass], n);
2215
  print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false);
2216
  fprintf (ira_dump_file, ", %snode: ",
2217
           hard_reg_set_equal_p (data->profitable_hard_regs,
2218
                                 data->hard_regs_node->hard_regs->set)
2219
           ? "" : "^");
2220
  print_hard_reg_set (ira_dump_file,
2221
                      data->hard_regs_node->hard_regs->set, false);
2222
  for (i = 0; i < nwords; i++)
2223
    {
2224
      ira_object_t obj = ALLOCNO_OBJECT (a, i);
2225
 
2226
      if (nwords != 1)
2227
        {
2228
          if (i != 0)
2229
            fprintf (ira_dump_file, ", ");
2230
          fprintf (ira_dump_file, " obj %d", i);
2231
        }
2232
      fprintf (ira_dump_file, " (confl regs = ");
2233
      print_hard_reg_set (ira_dump_file, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
2234
                          false);
2235
      fprintf (ira_dump_file, ")");
2236
    }
2237
  fprintf (ira_dump_file, "\n");
2238
}
2239
 
2240
/* Put ALLOCNO in a bucket corresponding to its number and size of its
2241
   conflicting allocnos and hard registers.  */
2242
static void
2243
put_allocno_into_bucket (ira_allocno_t allocno)
2244
{
2245
  ALLOCNO_COLOR_DATA (allocno)->in_graph_p = true;
2246
  setup_allocno_available_regs_num (allocno);
2247
  if (setup_left_conflict_sizes_p (allocno))
2248
    add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
2249
  else
2250
    add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
2251
}
2252
 
2253
/* Map: allocno number -> allocno priority.  */
2254
static int *allocno_priorities;
2255
 
2256
/* Set up priorities for N allocnos in array
2257
   CONSIDERATION_ALLOCNOS.  */
2258
static void
2259
setup_allocno_priorities (ira_allocno_t *consideration_allocnos, int n)
2260
{
2261
  int i, length, nrefs, priority, max_priority, mult;
2262
  ira_allocno_t a;
2263
 
2264
  max_priority = 0;
2265
  for (i = 0; i < n; i++)
2266
    {
2267
      a = consideration_allocnos[i];
2268
      nrefs = ALLOCNO_NREFS (a);
2269
      ira_assert (nrefs >= 0);
2270
      mult = floor_log2 (ALLOCNO_NREFS (a)) + 1;
2271
      ira_assert (mult >= 0);
2272
      allocno_priorities[ALLOCNO_NUM (a)]
2273
        = priority
2274
        = (mult
2275
           * (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))
2276
           * ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]);
2277
      if (priority < 0)
2278
        priority = -priority;
2279
      if (max_priority < priority)
2280
        max_priority = priority;
2281
    }
2282
  mult = max_priority == 0 ? 1 : INT_MAX / max_priority;
2283
  for (i = 0; i < n; i++)
2284
    {
2285
      a = consideration_allocnos[i];
2286
      length = ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
2287
      if (ALLOCNO_NUM_OBJECTS (a) > 1)
2288
        length /= ALLOCNO_NUM_OBJECTS (a);
2289
      if (length <= 0)
2290
        length = 1;
2291
      allocno_priorities[ALLOCNO_NUM (a)]
2292
        = allocno_priorities[ALLOCNO_NUM (a)] * mult / length;
2293
    }
2294
}
2295
 
2296
/* Sort allocnos according to the profit of usage of a hard register
2297
   instead of memory for them. */
2298
static int
2299
allocno_cost_compare_func (const void *v1p, const void *v2p)
2300
{
2301
  ira_allocno_t p1 = *(const ira_allocno_t *) v1p;
2302
  ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
2303
  int c1, c2;
2304
 
2305
  c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_CLASS_COST (p1);
2306
  c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_CLASS_COST (p2);
2307
  if (c1 - c2)
2308
    return c1 - c2;
2309
 
2310
  /* If regs are equally good, sort by allocno numbers, so that the
2311
     results of qsort leave nothing to chance.  */
2312
  return ALLOCNO_NUM (p1) - ALLOCNO_NUM (p2);
2313
}
2314
 
2315
/* We used Chaitin-Briggs coloring to assign as many pseudos as
2316
   possible to hard registers.  Let us try to improve allocation with
2317
   cost point of view.  This function improves the allocation by
2318
   spilling some allocnos and assigning the freed hard registers to
2319
   other allocnos if it decreases the overall allocation cost.  */
2320
static void
2321
improve_allocation (void)
2322
{
2323
  unsigned int i;
2324
  int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords;
2325
  int check, spill_cost, min_cost, nregs, conflict_nregs, r, best;
2326
  bool try_p;
2327
  enum reg_class aclass;
2328
  enum machine_mode mode;
2329
  int *allocno_costs;
2330
  int costs[FIRST_PSEUDO_REGISTER];
2331
  HARD_REG_SET conflicting_regs[2], profitable_hard_regs;
2332
  ira_allocno_t a;
2333
  bitmap_iterator bi;
2334
 
2335
  /* Clear counts used to process conflicting allocnos only once for
2336
     each allocno.  */
2337
  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2338
    ALLOCNO_COLOR_DATA (ira_allocnos[i])->temp = 0;
2339
  check = n = 0;
2340
  /* Process each allocno and try to assign a hard register to it by
2341
     spilling some its conflicting allocnos.  */
2342
  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2343
    {
2344
      a = ira_allocnos[i];
2345
      ALLOCNO_COLOR_DATA (a)->temp = 0;
2346
      if (empty_profitable_hard_regs (a))
2347
        continue;
2348
      check++;
2349
      aclass = ALLOCNO_CLASS (a);
2350
      allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a);
2351
      if (allocno_costs == NULL)
2352
        allocno_costs = ALLOCNO_HARD_REG_COSTS (a);
2353
      if ((hregno = ALLOCNO_HARD_REGNO (a)) < 0)
2354
        base_cost = ALLOCNO_UPDATED_MEMORY_COST (a);
2355
      else if (allocno_costs == NULL)
2356
        /* It means that assigning a hard register is not profitable
2357
           (we don't waste memory for hard register costs in this
2358
           case).  */
2359
        continue;
2360
      else
2361
        base_cost = allocno_costs[ira_class_hard_reg_index[aclass][hregno]];
2362
      try_p = false;
2363
      get_conflict_and_start_profitable_regs (a, false,
2364
                                              conflicting_regs,
2365
                                              &profitable_hard_regs);
2366
      class_size = ira_class_hard_regs_num[aclass];
2367
      /* Set up cost improvement for usage of each profitable hard
2368
         register for allocno A.  */
2369
      for (j = 0; j < class_size; j++)
2370
        {
2371
          hregno = ira_class_hard_regs[aclass][j];
2372
          if (! check_hard_reg_p (a, hregno,
2373
                                  conflicting_regs, profitable_hard_regs))
2374
            continue;
2375
          ira_assert (ira_class_hard_reg_index[aclass][hregno] == j);
2376
          k = allocno_costs == NULL ? 0 : j;
2377
          costs[hregno] = (allocno_costs == NULL
2378
                           ? ALLOCNO_UPDATED_CLASS_COST (a) : allocno_costs[k]);
2379
          costs[hregno] -= base_cost;
2380
          if (costs[hregno] < 0)
2381
            try_p = true;
2382
        }
2383
      if (! try_p)
2384
        /* There is no chance to improve the allocation cost by
2385
           assigning hard register to allocno A even without spilling
2386
           conflicting allocnos.  */
2387
        continue;
2388
      mode = ALLOCNO_MODE (a);
2389
      nwords = ALLOCNO_NUM_OBJECTS (a);
2390
      /* Process each allocno conflicting with A and update the cost
2391
         improvement for profitable hard registers of A.  To use a
2392
         hard register for A we need to spill some conflicting
2393
         allocnos and that creates penalty for the cost
2394
         improvement.  */
2395
      for (word = 0; word < nwords; word++)
2396
        {
2397
          ira_object_t conflict_obj;
2398
          ira_object_t obj = ALLOCNO_OBJECT (a, word);
2399
          ira_object_conflict_iterator oci;
2400
 
2401
          FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2402
            {
2403
              ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2404
 
2405
              if (ALLOCNO_COLOR_DATA (conflict_a)->temp == check)
2406
                /* We already processed this conflicting allocno
2407
                   because we processed earlier another object of the
2408
                   conflicting allocno.  */
2409
                continue;
2410
              ALLOCNO_COLOR_DATA (conflict_a)->temp = check;
2411
              if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2412
                continue;
2413
              spill_cost = ALLOCNO_UPDATED_MEMORY_COST (conflict_a);
2414
              k = (ira_class_hard_reg_index
2415
                   [ALLOCNO_CLASS (conflict_a)][conflict_hregno]);
2416
              ira_assert (k >= 0);
2417
              if ((allocno_costs = ALLOCNO_UPDATED_HARD_REG_COSTS (conflict_a))
2418
                  != NULL)
2419
                spill_cost -= allocno_costs[k];
2420
              else if ((allocno_costs = ALLOCNO_HARD_REG_COSTS (conflict_a))
2421
                       != NULL)
2422
                spill_cost -= allocno_costs[k];
2423
              else
2424
                spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
2425
              conflict_nregs
2426
                = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2427
              for (r = conflict_hregno;
2428
                   r >= 0 && r + hard_regno_nregs[r][mode] > conflict_hregno;
2429
                   r--)
2430
                if (check_hard_reg_p (a, r,
2431
                                      conflicting_regs, profitable_hard_regs))
2432
                  costs[r] += spill_cost;
2433
              for (r = conflict_hregno + 1;
2434
                   r < conflict_hregno + conflict_nregs;
2435
                   r++)
2436
                if (check_hard_reg_p (a, r,
2437
                                      conflicting_regs, profitable_hard_regs))
2438
                  costs[r] += spill_cost;
2439
            }
2440
        }
2441
      min_cost = INT_MAX;
2442
      best = -1;
2443
      /* Now we choose hard register for A which results in highest
2444
         allocation cost improvement.  */
2445
      for (j = 0; j < class_size; j++)
2446
        {
2447
          hregno = ira_class_hard_regs[aclass][j];
2448
          if (check_hard_reg_p (a, hregno,
2449
                                conflicting_regs, profitable_hard_regs)
2450
              && min_cost > costs[hregno])
2451
            {
2452
              best = hregno;
2453
              min_cost = costs[hregno];
2454
            }
2455
        }
2456
      if (min_cost >= 0)
2457
        /* We are in a situation when assigning any hard register to A
2458
           by spilling some conflicting allocnos does not improve the
2459
           allocation cost.  */
2460
        continue;
2461
      nregs = hard_regno_nregs[best][mode];
2462
      /* Now spill conflicting allocnos which contain a hard register
2463
         of A when we assign the best chosen hard register to it.  */
2464
      for (word = 0; word < nwords; word++)
2465
        {
2466
          ira_object_t conflict_obj;
2467
          ira_object_t obj = ALLOCNO_OBJECT (a, word);
2468
          ira_object_conflict_iterator oci;
2469
 
2470
          FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
2471
            {
2472
              ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
2473
 
2474
              if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
2475
                continue;
2476
              conflict_nregs
2477
                = hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
2478
              if (best + nregs <= conflict_hregno
2479
                  || conflict_hregno + conflict_nregs <= best)
2480
                /* No intersection.  */
2481
                continue;
2482
              ALLOCNO_HARD_REGNO (conflict_a) = -1;
2483
              sorted_allocnos[n++] = conflict_a;
2484
              if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2485
                fprintf (ira_dump_file, "Spilling a%dr%d for a%dr%d\n",
2486
                         ALLOCNO_NUM (conflict_a), ALLOCNO_REGNO (conflict_a),
2487
                         ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2488
            }
2489
        }
2490
      /* Assign the best chosen hard register to A.  */
2491
      ALLOCNO_HARD_REGNO (a) = best;
2492
      if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2493
        fprintf (ira_dump_file, "Assigning %d to a%dr%d\n",
2494
                 best, ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
2495
    }
2496
  if (n == 0)
2497
    return;
2498
  /* We spilled some allocnos to assign their hard registers to other
2499
     allocnos.  The spilled allocnos are now in array
2500
     'sorted_allocnos'.  There is still a possibility that some of the
2501
     spilled allocnos can get hard registers.  So let us try assign
2502
     them hard registers again (just a reminder -- function
2503
     'assign_hard_reg' assigns hard registers only if it is possible
2504
     and profitable).  We process the spilled allocnos with biggest
2505
     benefit to get hard register first -- see function
2506
     'allocno_cost_compare_func'.  */
2507
  qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2508
         allocno_cost_compare_func);
2509
  for (j = 0; j < n; j++)
2510
    {
2511
      a = sorted_allocnos[j];
2512
      ALLOCNO_ASSIGNED_P (a) = false;
2513
      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2514
        {
2515
          fprintf (ira_dump_file, "      ");
2516
          ira_print_expanded_allocno (a);
2517
          fprintf (ira_dump_file, "  -- ");
2518
        }
2519
      if (assign_hard_reg (a, false))
2520
        {
2521
          if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2522
            fprintf (ira_dump_file, "assign hard reg %d\n",
2523
                     ALLOCNO_HARD_REGNO (a));
2524
        }
2525
      else
2526
        {
2527
          if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2528
            fprintf (ira_dump_file, "assign memory\n");
2529
        }
2530
    }
2531
}
2532
 
2533
/* Sort allocnos according to their priorities which are calculated
2534
   analogous to ones in file `global.c'.  */
2535
static int
2536
allocno_priority_compare_func (const void *v1p, const void *v2p)
2537
{
2538
  ira_allocno_t a1 = *(const ira_allocno_t *) v1p;
2539
  ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
2540
  int pri1, pri2;
2541
 
2542
  pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
2543
  pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
2544
  if (pri2 != pri1)
2545
    return SORTGT (pri2, pri1);
2546
 
2547
  /* If regs are equally good, sort by allocnos, so that the results of
2548
     qsort leave nothing to chance.  */
2549
  return ALLOCNO_NUM (a1) - ALLOCNO_NUM (a2);
2550
}
2551
 
2552
/* Chaitin-Briggs coloring for allocnos in COLORING_ALLOCNO_BITMAP
2553
   taking into account allocnos in CONSIDERATION_ALLOCNO_BITMAP.  */
2554
static void
2555
color_allocnos (void)
2556
{
2557
  unsigned int i, n;
2558
  bitmap_iterator bi;
2559
  ira_allocno_t a;
2560
 
2561
  setup_profitable_hard_regs ();
2562
  if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY)
2563
    {
2564
      n = 0;
2565
      EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2566
        {
2567
          a = ira_allocnos[i];
2568
          if (ALLOCNO_CLASS (a) == NO_REGS)
2569
            {
2570
              ALLOCNO_HARD_REGNO (a) = -1;
2571
              ALLOCNO_ASSIGNED_P (a) = true;
2572
              ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
2573
              ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
2574
              if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2575
                {
2576
                  fprintf (ira_dump_file, "      Spill");
2577
                  ira_print_expanded_allocno (a);
2578
                  fprintf (ira_dump_file, "\n");
2579
                }
2580
              continue;
2581
            }
2582
          sorted_allocnos[n++] = a;
2583
        }
2584
      if (n != 0)
2585
        {
2586
          setup_allocno_priorities (sorted_allocnos, n);
2587
          qsort (sorted_allocnos, n, sizeof (ira_allocno_t),
2588
                 allocno_priority_compare_func);
2589
          for (i = 0; i < n; i++)
2590
            {
2591
              a = sorted_allocnos[i];
2592
              if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2593
                {
2594
                  fprintf (ira_dump_file, "      ");
2595
                  ira_print_expanded_allocno (a);
2596
                  fprintf (ira_dump_file, "  -- ");
2597
                }
2598
              if (assign_hard_reg (a, false))
2599
                {
2600
                  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2601
                    fprintf (ira_dump_file, "assign hard reg %d\n",
2602
                             ALLOCNO_HARD_REGNO (a));
2603
                }
2604
              else
2605
                {
2606
                  if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2607
                    fprintf (ira_dump_file, "assign memory\n");
2608
                }
2609
            }
2610
        }
2611
    }
2612
  else
2613
    {
2614
      form_allocno_hard_regs_nodes_forest ();
2615
      if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
2616
        print_hard_regs_forest (ira_dump_file);
2617
      EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2618
        {
2619
          a = ira_allocnos[i];
2620
          if (ALLOCNO_CLASS (a) != NO_REGS && ! empty_profitable_hard_regs (a))
2621
            ALLOCNO_COLOR_DATA (a)->in_graph_p = true;
2622
          else
2623
            {
2624
              ALLOCNO_HARD_REGNO (a) = -1;
2625
              ALLOCNO_ASSIGNED_P (a) = true;
2626
              /* We don't need updated costs anymore.  */
2627
              ira_free_allocno_updated_costs (a);
2628
              if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
2629
                {
2630
                  fprintf (ira_dump_file, "      Spill");
2631
                  ira_print_expanded_allocno (a);
2632
                  fprintf (ira_dump_file, "\n");
2633
                }
2634
            }
2635
        }
2636
      /* Put the allocnos into the corresponding buckets.  */
2637
      colorable_allocno_bucket = NULL;
2638
      uncolorable_allocno_bucket = NULL;
2639
      EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
2640
        {
2641
          a = ira_allocnos[i];
2642
          if (ALLOCNO_COLOR_DATA (a)->in_graph_p)
2643
            put_allocno_into_bucket (a);
2644
        }
2645
      push_allocnos_to_stack ();
2646
      pop_allocnos_from_stack ();
2647
      finish_allocno_hard_regs_nodes_forest ();
2648
    }
2649
  improve_allocation ();
2650
}
2651
 
2652
 
2653
 
2654
/* Output information about the loop given by its LOOP_TREE_NODE. */
2655
static void
2656
print_loop_title (ira_loop_tree_node_t loop_tree_node)
2657
{
2658
  unsigned int j;
2659
  bitmap_iterator bi;
2660
  ira_loop_tree_node_t subloop_node, dest_loop_node;
2661
  edge e;
2662
  edge_iterator ei;
2663
 
2664
  if (loop_tree_node->parent == NULL)
2665
    fprintf (ira_dump_file,
2666
             "\n  Loop 0 (parent -1, header bb%d, depth 0)\n    bbs:",
2667
             NUM_FIXED_BLOCKS);
2668
  else
2669
    {
2670
      ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
2671
      fprintf (ira_dump_file,
2672
               "\n  Loop %d (parent %d, header bb%d, depth %d)\n    bbs:",
2673
               loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
2674
               loop_tree_node->loop->header->index,
2675
               loop_depth (loop_tree_node->loop));
2676
    }
2677
  for (subloop_node = loop_tree_node->children;
2678
       subloop_node != NULL;
2679
       subloop_node = subloop_node->next)
2680
    if (subloop_node->bb != NULL)
2681
      {
2682
        fprintf (ira_dump_file, " %d", subloop_node->bb->index);
2683
        FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
2684
          if (e->dest != EXIT_BLOCK_PTR
2685
              && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
2686
                  != loop_tree_node))
2687
            fprintf (ira_dump_file, "(->%d:l%d)",
2688
                     e->dest->index, dest_loop_node->loop_num);
2689
      }
2690
  fprintf (ira_dump_file, "\n    all:");
2691
  EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
2692
    fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
2693
  fprintf (ira_dump_file, "\n    modified regnos:");
2694
  EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->modified_regnos, 0, j, bi)
2695
    fprintf (ira_dump_file, " %d", j);
2696
  fprintf (ira_dump_file, "\n    border:");
2697
  EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->border_allocnos, 0, j, bi)
2698
    fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
2699
  fprintf (ira_dump_file, "\n    Pressure:");
2700
  for (j = 0; (int) j < ira_pressure_classes_num; j++)
2701
    {
2702
      enum reg_class pclass;
2703
 
2704
      pclass = ira_pressure_classes[j];
2705
      if (loop_tree_node->reg_pressure[pclass] == 0)
2706
        continue;
2707
      fprintf (ira_dump_file, " %s=%d", reg_class_names[pclass],
2708
               loop_tree_node->reg_pressure[pclass]);
2709
    }
2710
  fprintf (ira_dump_file, "\n");
2711
}
2712
 
2713
/* Color the allocnos inside loop (in the extreme case it can be all
2714
   of the function) given the corresponding LOOP_TREE_NODE.  The
2715
   function is called for each loop during top-down traverse of the
2716
   loop tree.  */
2717
static void
2718
color_pass (ira_loop_tree_node_t loop_tree_node)
2719
{
2720
  int regno, hard_regno, index = -1, n;
2721
  int cost, exit_freq, enter_freq;
2722
  unsigned int j;
2723
  bitmap_iterator bi;
2724
  enum machine_mode mode;
2725
  enum reg_class rclass, aclass, pclass;
2726
  ira_allocno_t a, subloop_allocno;
2727
  ira_loop_tree_node_t subloop_node;
2728
 
2729
  ira_assert (loop_tree_node->bb == NULL);
2730
  if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
2731
    print_loop_title (loop_tree_node);
2732
 
2733
  bitmap_copy (coloring_allocno_bitmap, loop_tree_node->all_allocnos);
2734
  bitmap_copy (consideration_allocno_bitmap, coloring_allocno_bitmap);
2735
  n = 0;
2736
  EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2737
    {
2738
      a = ira_allocnos[j];
2739
      n++;
2740
      if (! ALLOCNO_ASSIGNED_P (a))
2741
        continue;
2742
      bitmap_clear_bit (coloring_allocno_bitmap, ALLOCNO_NUM (a));
2743
    }
2744
  allocno_color_data
2745
    = (allocno_color_data_t) ira_allocate (sizeof (struct allocno_color_data)
2746
                                           * n);
2747
  memset (allocno_color_data, 0, sizeof (struct allocno_color_data) * n);
2748
  curr_allocno_process = 0;
2749
  n = 0;
2750
  EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2751
    {
2752
      a = ira_allocnos[j];
2753
      ALLOCNO_ADD_DATA (a) = allocno_color_data + n;
2754
      n++;
2755
    }
2756
  /* Color all mentioned allocnos including transparent ones.  */
2757
  color_allocnos ();
2758
  /* Process caps.  They are processed just once.  */
2759
  if (flag_ira_region == IRA_REGION_MIXED
2760
      || flag_ira_region == IRA_REGION_ALL)
2761
    EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
2762
      {
2763
        a = ira_allocnos[j];
2764
        if (ALLOCNO_CAP_MEMBER (a) == NULL)
2765
          continue;
2766
        /* Remove from processing in the next loop.  */
2767
        bitmap_clear_bit (consideration_allocno_bitmap, j);
2768
        rclass = ALLOCNO_CLASS (a);
2769
        pclass = ira_pressure_class_translate[rclass];
2770
        if (flag_ira_region == IRA_REGION_MIXED
2771
            && (loop_tree_node->reg_pressure[pclass]
2772
                <= ira_available_class_regs[pclass]))
2773
          {
2774
            mode = ALLOCNO_MODE (a);
2775
            hard_regno = ALLOCNO_HARD_REGNO (a);
2776
            if (hard_regno >= 0)
2777
              {
2778
                index = ira_class_hard_reg_index[rclass][hard_regno];
2779
                ira_assert (index >= 0);
2780
              }
2781
            regno = ALLOCNO_REGNO (a);
2782
            subloop_allocno = ALLOCNO_CAP_MEMBER (a);
2783
            subloop_node = ALLOCNO_LOOP_TREE_NODE (subloop_allocno);
2784
            ira_assert (!ALLOCNO_ASSIGNED_P (subloop_allocno));
2785
            ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2786
            ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2787
            if (hard_regno >= 0)
2788
              update_copy_costs (subloop_allocno, true);
2789
            /* We don't need updated costs anymore: */
2790
            ira_free_allocno_updated_costs (subloop_allocno);
2791
          }
2792
      }
2793
  /* Update costs of the corresponding allocnos (not caps) in the
2794
     subloops.  */
2795
  for (subloop_node = loop_tree_node->subloops;
2796
       subloop_node != NULL;
2797
       subloop_node = subloop_node->subloop_next)
2798
    {
2799
      ira_assert (subloop_node->bb == NULL);
2800
      EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi)
2801
        {
2802
          a = ira_allocnos[j];
2803
          ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
2804
          mode = ALLOCNO_MODE (a);
2805
          rclass = ALLOCNO_CLASS (a);
2806
          pclass = ira_pressure_class_translate[rclass];
2807
          hard_regno = ALLOCNO_HARD_REGNO (a);
2808
          /* Use hard register class here.  ??? */
2809
          if (hard_regno >= 0)
2810
            {
2811
              index = ira_class_hard_reg_index[rclass][hard_regno];
2812
              ira_assert (index >= 0);
2813
            }
2814
          regno = ALLOCNO_REGNO (a);
2815
          /* ??? conflict costs */
2816
          subloop_allocno = subloop_node->regno_allocno_map[regno];
2817
          if (subloop_allocno == NULL
2818
              || ALLOCNO_CAP (subloop_allocno) != NULL)
2819
            continue;
2820
          ira_assert (ALLOCNO_CLASS (subloop_allocno) == rclass);
2821
          ira_assert (bitmap_bit_p (subloop_node->all_allocnos,
2822
                                    ALLOCNO_NUM (subloop_allocno)));
2823
          if ((flag_ira_region == IRA_REGION_MIXED)
2824
              && (loop_tree_node->reg_pressure[pclass]
2825
                  <= ira_available_class_regs[pclass]))
2826
            {
2827
              if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
2828
                {
2829
                  ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2830
                  ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2831
                  if (hard_regno >= 0)
2832
                    update_copy_costs (subloop_allocno, true);
2833
                  /* We don't need updated costs anymore: */
2834
                  ira_free_allocno_updated_costs (subloop_allocno);
2835
                }
2836
              continue;
2837
            }
2838
          exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
2839
          enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
2840
          ira_assert (regno < ira_reg_equiv_len);
2841
          if (ira_reg_equiv_invariant_p[regno]
2842
              || ira_reg_equiv_const[regno] != NULL_RTX)
2843
            {
2844
              if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
2845
                {
2846
                  ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
2847
                  ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
2848
                  if (hard_regno >= 0)
2849
                    update_copy_costs (subloop_allocno, true);
2850
                  /* We don't need updated costs anymore: */
2851
                  ira_free_allocno_updated_costs (subloop_allocno);
2852
                }
2853
            }
2854
          else if (hard_regno < 0)
2855
            {
2856
              ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
2857
                -= ((ira_memory_move_cost[mode][rclass][1] * enter_freq)
2858
                    + (ira_memory_move_cost[mode][rclass][0] * exit_freq));
2859
            }
2860
          else
2861
            {
2862
              aclass = ALLOCNO_CLASS (subloop_allocno);
2863
              ira_init_register_move_cost_if_necessary (mode);
2864
              cost = (ira_register_move_cost[mode][rclass][rclass]
2865
                      * (exit_freq + enter_freq));
2866
              ira_allocate_and_set_or_copy_costs
2867
                (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), aclass,
2868
                 ALLOCNO_UPDATED_CLASS_COST (subloop_allocno),
2869
                 ALLOCNO_HARD_REG_COSTS (subloop_allocno));
2870
              ira_allocate_and_set_or_copy_costs
2871
                (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
2872
                 aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
2873
              ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
2874
              ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
2875
                -= cost;
2876
              if (ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
2877
                  > ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
2878
                ALLOCNO_UPDATED_CLASS_COST (subloop_allocno)
2879
                  = ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
2880
              ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
2881
                += (ira_memory_move_cost[mode][rclass][0] * enter_freq
2882
                    + ira_memory_move_cost[mode][rclass][1] * exit_freq);
2883
            }
2884
        }
2885
    }
2886
  ira_free (allocno_color_data);
2887
  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
2888
    {
2889
      a = ira_allocnos[j];
2890
      ALLOCNO_ADD_DATA (a) = NULL;
2891
    }
2892
}
2893
 
2894
/* Initialize the common data for coloring and calls functions to do
2895
   Chaitin-Briggs and regional coloring.  */
2896
static void
2897
do_coloring (void)
2898
{
2899
  coloring_allocno_bitmap = ira_allocate_bitmap ();
2900
  if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
2901
    fprintf (ira_dump_file, "\n**** Allocnos coloring:\n\n");
2902
 
2903
  ira_traverse_loop_tree (false, ira_loop_tree_root, color_pass, NULL);
2904
 
2905
  if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
2906
    ira_print_disposition (ira_dump_file);
2907
 
2908
  ira_free_bitmap (coloring_allocno_bitmap);
2909
}
2910
 
2911
 
2912
 
2913
/* Move spill/restore code, which are to be generated in ira-emit.c,
2914
   to less frequent points (if it is profitable) by reassigning some
2915
   allocnos (in loop with subloops containing in another loop) to
2916
   memory which results in longer live-range where the corresponding
2917
   pseudo-registers will be in memory.  */
2918
static void
2919
move_spill_restore (void)
2920
{
2921
  int cost, regno, hard_regno, hard_regno2, index;
2922
  bool changed_p;
2923
  int enter_freq, exit_freq;
2924
  enum machine_mode mode;
2925
  enum reg_class rclass;
2926
  ira_allocno_t a, parent_allocno, subloop_allocno;
2927
  ira_loop_tree_node_t parent, loop_node, subloop_node;
2928
  ira_allocno_iterator ai;
2929
 
2930
  for (;;)
2931
    {
2932
      changed_p = false;
2933
      if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
2934
        fprintf (ira_dump_file, "New iteration of spill/restore move\n");
2935
      FOR_EACH_ALLOCNO (a, ai)
2936
        {
2937
          regno = ALLOCNO_REGNO (a);
2938
          loop_node = ALLOCNO_LOOP_TREE_NODE (a);
2939
          if (ALLOCNO_CAP_MEMBER (a) != NULL
2940
              || ALLOCNO_CAP (a) != NULL
2941
              || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0
2942
              || loop_node->children == NULL
2943
              /* don't do the optimization because it can create
2944
                 copies and the reload pass can spill the allocno set
2945
                 by copy although the allocno will not get memory
2946
                 slot.  */
2947
              || ira_reg_equiv_invariant_p[regno]
2948
              || ira_reg_equiv_const[regno] != NULL_RTX
2949
              || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
2950
            continue;
2951
          mode = ALLOCNO_MODE (a);
2952
          rclass = ALLOCNO_CLASS (a);
2953
          index = ira_class_hard_reg_index[rclass][hard_regno];
2954
          ira_assert (index >= 0);
2955
          cost = (ALLOCNO_MEMORY_COST (a)
2956
                  - (ALLOCNO_HARD_REG_COSTS (a) == NULL
2957
                     ? ALLOCNO_CLASS_COST (a)
2958
                     : ALLOCNO_HARD_REG_COSTS (a)[index]));
2959
          ira_init_register_move_cost_if_necessary (mode);
2960
          for (subloop_node = loop_node->subloops;
2961
               subloop_node != NULL;
2962
               subloop_node = subloop_node->subloop_next)
2963
            {
2964
              ira_assert (subloop_node->bb == NULL);
2965
              subloop_allocno = subloop_node->regno_allocno_map[regno];
2966
              if (subloop_allocno == NULL)
2967
                continue;
2968
              ira_assert (rclass == ALLOCNO_CLASS (subloop_allocno));
2969
              /* We have accumulated cost.  To get the real cost of
2970
                 allocno usage in the loop we should subtract costs of
2971
                 the subloop allocnos.  */
2972
              cost -= (ALLOCNO_MEMORY_COST (subloop_allocno)
2973
                       - (ALLOCNO_HARD_REG_COSTS (subloop_allocno) == NULL
2974
                          ? ALLOCNO_CLASS_COST (subloop_allocno)
2975
                          : ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index]));
2976
              exit_freq = ira_loop_edge_freq (subloop_node, regno, true);
2977
              enter_freq = ira_loop_edge_freq (subloop_node, regno, false);
2978
              if ((hard_regno2 = ALLOCNO_HARD_REGNO (subloop_allocno)) < 0)
2979
                cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
2980
                         + ira_memory_move_cost[mode][rclass][1] * enter_freq);
2981
              else
2982
                {
2983
                  cost
2984
                    += (ira_memory_move_cost[mode][rclass][0] * exit_freq
2985
                        + ira_memory_move_cost[mode][rclass][1] * enter_freq);
2986
                  if (hard_regno2 != hard_regno)
2987
                    cost -= (ira_register_move_cost[mode][rclass][rclass]
2988
                             * (exit_freq + enter_freq));
2989
                }
2990
            }
2991
          if ((parent = loop_node->parent) != NULL
2992
              && (parent_allocno = parent->regno_allocno_map[regno]) != NULL)
2993
            {
2994
              ira_assert (rclass == ALLOCNO_CLASS (parent_allocno));
2995
              exit_freq = ira_loop_edge_freq (loop_node, regno, true);
2996
              enter_freq = ira_loop_edge_freq (loop_node, regno, false);
2997
              if ((hard_regno2 = ALLOCNO_HARD_REGNO (parent_allocno)) < 0)
2998
                cost -= (ira_memory_move_cost[mode][rclass][0] * exit_freq
2999
                         + ira_memory_move_cost[mode][rclass][1] * enter_freq);
3000
              else
3001
                {
3002
                  cost
3003
                    += (ira_memory_move_cost[mode][rclass][1] * exit_freq
3004
                        + ira_memory_move_cost[mode][rclass][0] * enter_freq);
3005
                  if (hard_regno2 != hard_regno)
3006
                    cost -= (ira_register_move_cost[mode][rclass][rclass]
3007
                             * (exit_freq + enter_freq));
3008
                }
3009
            }
3010
          if (cost < 0)
3011
            {
3012
              ALLOCNO_HARD_REGNO (a) = -1;
3013
              if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3014
                {
3015
                  fprintf
3016
                    (ira_dump_file,
3017
                     "      Moving spill/restore for a%dr%d up from loop %d",
3018
                     ALLOCNO_NUM (a), regno, loop_node->loop_num);
3019
                  fprintf (ira_dump_file, " - profit %d\n", -cost);
3020
                }
3021
              changed_p = true;
3022
            }
3023
        }
3024
      if (! changed_p)
3025
        break;
3026
    }
3027
}
3028
 
3029
 
3030
 
3031
/* Update current hard reg costs and current conflict hard reg costs
3032
   for allocno A.  It is done by processing its copies containing
3033
   other allocnos already assigned.  */
3034
static void
3035
update_curr_costs (ira_allocno_t a)
3036
{
3037
  int i, hard_regno, cost;
3038
  enum machine_mode mode;
3039
  enum reg_class aclass, rclass;
3040
  ira_allocno_t another_a;
3041
  ira_copy_t cp, next_cp;
3042
 
3043
  ira_free_allocno_updated_costs (a);
3044
  ira_assert (! ALLOCNO_ASSIGNED_P (a));
3045
  aclass = ALLOCNO_CLASS (a);
3046
  if (aclass == NO_REGS)
3047
    return;
3048
  mode = ALLOCNO_MODE (a);
3049
  ira_init_register_move_cost_if_necessary (mode);
3050
  for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3051
    {
3052
      if (cp->first == a)
3053
        {
3054
          next_cp = cp->next_first_allocno_copy;
3055
          another_a = cp->second;
3056
        }
3057
      else if (cp->second == a)
3058
        {
3059
          next_cp = cp->next_second_allocno_copy;
3060
          another_a = cp->first;
3061
        }
3062
      else
3063
        gcc_unreachable ();
3064
      if (! ira_reg_classes_intersect_p[aclass][ALLOCNO_CLASS (another_a)]
3065
          || ! ALLOCNO_ASSIGNED_P (another_a)
3066
          || (hard_regno = ALLOCNO_HARD_REGNO (another_a)) < 0)
3067
        continue;
3068
      rclass = REGNO_REG_CLASS (hard_regno);
3069
      i = ira_class_hard_reg_index[aclass][hard_regno];
3070
      if (i < 0)
3071
        continue;
3072
      cost = (cp->first == a
3073
              ? ira_register_move_cost[mode][rclass][aclass]
3074
              : ira_register_move_cost[mode][aclass][rclass]);
3075
      ira_allocate_and_set_or_copy_costs
3076
        (&ALLOCNO_UPDATED_HARD_REG_COSTS (a), aclass, ALLOCNO_CLASS_COST (a),
3077
         ALLOCNO_HARD_REG_COSTS (a));
3078
      ira_allocate_and_set_or_copy_costs
3079
        (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
3080
         aclass, 0, ALLOCNO_CONFLICT_HARD_REG_COSTS (a));
3081
      ALLOCNO_UPDATED_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3082
      ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a)[i] -= cp->freq * cost;
3083
    }
3084
}
3085
 
3086
/* Try to assign hard registers to the unassigned allocnos and
3087
   allocnos conflicting with them or conflicting with allocnos whose
3088
   regno >= START_REGNO.  The function is called after ira_flattening,
3089
   so more allocnos (including ones created in ira-emit.c) will have a
3090
   chance to get a hard register.  We use simple assignment algorithm
3091
   based on priorities.  */
3092
void
3093
ira_reassign_conflict_allocnos (int start_regno)
3094
{
3095
  int i, allocnos_to_color_num;
3096
  ira_allocno_t a;
3097
  enum reg_class aclass;
3098
  bitmap allocnos_to_color;
3099
  ira_allocno_iterator ai;
3100
 
3101
  allocnos_to_color = ira_allocate_bitmap ();
3102
  allocnos_to_color_num = 0;
3103
  FOR_EACH_ALLOCNO (a, ai)
3104
    {
3105
      int n = ALLOCNO_NUM_OBJECTS (a);
3106
 
3107
      if (! ALLOCNO_ASSIGNED_P (a)
3108
          && ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
3109
        {
3110
          if (ALLOCNO_CLASS (a) != NO_REGS)
3111
            sorted_allocnos[allocnos_to_color_num++] = a;
3112
          else
3113
            {
3114
              ALLOCNO_ASSIGNED_P (a) = true;
3115
              ALLOCNO_HARD_REGNO (a) = -1;
3116
              ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
3117
              ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
3118
            }
3119
          bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (a));
3120
        }
3121
      if (ALLOCNO_REGNO (a) < start_regno
3122
          || (aclass = ALLOCNO_CLASS (a)) == NO_REGS)
3123
        continue;
3124
      for (i = 0; i < n; i++)
3125
        {
3126
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
3127
          ira_object_t conflict_obj;
3128
          ira_object_conflict_iterator oci;
3129
 
3130
          FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
3131
            {
3132
              ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
3133
 
3134
              ira_assert (ira_reg_classes_intersect_p
3135
                          [aclass][ALLOCNO_CLASS (conflict_a)]);
3136
              if (!bitmap_set_bit (allocnos_to_color, ALLOCNO_NUM (conflict_a)))
3137
                continue;
3138
              sorted_allocnos[allocnos_to_color_num++] = conflict_a;
3139
            }
3140
        }
3141
    }
3142
  ira_free_bitmap (allocnos_to_color);
3143
  if (allocnos_to_color_num > 1)
3144
    {
3145
      setup_allocno_priorities (sorted_allocnos, allocnos_to_color_num);
3146
      qsort (sorted_allocnos, allocnos_to_color_num, sizeof (ira_allocno_t),
3147
             allocno_priority_compare_func);
3148
    }
3149
  for (i = 0; i < allocnos_to_color_num; i++)
3150
    {
3151
      a = sorted_allocnos[i];
3152
      ALLOCNO_ASSIGNED_P (a) = false;
3153
      update_curr_costs (a);
3154
    }
3155
  for (i = 0; i < allocnos_to_color_num; i++)
3156
    {
3157
      a = sorted_allocnos[i];
3158
      if (assign_hard_reg (a, true))
3159
        {
3160
          if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3161
            fprintf
3162
              (ira_dump_file,
3163
               "      Secondary allocation: assign hard reg %d to reg %d\n",
3164
               ALLOCNO_HARD_REGNO (a), ALLOCNO_REGNO (a));
3165
        }
3166
    }
3167
}
3168
 
3169
 
3170
 
3171
/* This page contains functions used to find conflicts using allocno
3172
   live ranges.  */
3173
 
3174
/* Return TRUE if live ranges of allocnos A1 and A2 intersect.  It is
3175
   used to find a conflict for new allocnos or allocnos with the
3176
   different allocno classes.  */
3177
static bool
3178
allocnos_conflict_by_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
3179
{
3180
  rtx reg1, reg2;
3181
  int i, j;
3182
  int n1 = ALLOCNO_NUM_OBJECTS (a1);
3183
  int n2 = ALLOCNO_NUM_OBJECTS (a2);
3184
 
3185
  if (a1 == a2)
3186
    return false;
3187
  reg1 = regno_reg_rtx[ALLOCNO_REGNO (a1)];
3188
  reg2 = regno_reg_rtx[ALLOCNO_REGNO (a2)];
3189
  if (reg1 != NULL && reg2 != NULL
3190
      && ORIGINAL_REGNO (reg1) == ORIGINAL_REGNO (reg2))
3191
    return false;
3192
 
3193
  for (i = 0; i < n1; i++)
3194
    {
3195
      ira_object_t c1 = ALLOCNO_OBJECT (a1, i);
3196
 
3197
      for (j = 0; j < n2; j++)
3198
        {
3199
          ira_object_t c2 = ALLOCNO_OBJECT (a2, j);
3200
 
3201
          if (ira_live_ranges_intersect_p (OBJECT_LIVE_RANGES (c1),
3202
                                           OBJECT_LIVE_RANGES (c2)))
3203
            return true;
3204
        }
3205
    }
3206
  return false;
3207
}
3208
 
3209
#ifdef ENABLE_IRA_CHECKING
3210
 
3211
/* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
3212
   intersect.  This should be used when there is only one region.
3213
   Currently this is used during reload.  */
3214
static bool
3215
conflict_by_live_ranges_p (int regno1, int regno2)
3216
{
3217
  ira_allocno_t a1, a2;
3218
 
3219
  ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
3220
              && regno2 >= FIRST_PSEUDO_REGISTER);
3221
  /* Reg info caclulated by dataflow infrastructure can be different
3222
     from one calculated by regclass.  */
3223
  if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
3224
      || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
3225
    return false;
3226
  return allocnos_conflict_by_live_ranges_p (a1, a2);
3227
}
3228
 
3229
#endif
3230
 
3231
 
3232
 
3233
/* This page contains code to coalesce memory stack slots used by
3234
   spilled allocnos.  This results in smaller stack frame, better data
3235
   locality, and in smaller code for some architectures like
3236
   x86/x86_64 where insn size depends on address displacement value.
3237
   On the other hand, it can worsen insn scheduling after the RA but
3238
   in practice it is less important than smaller stack frames.  */
3239
 
3240
/* TRUE if we coalesced some allocnos.  In other words, if we got
3241
   loops formed by members first_coalesced_allocno and
3242
   next_coalesced_allocno containing more one allocno.  */
3243
static bool allocno_coalesced_p;
3244
 
3245
/* Bitmap used to prevent a repeated allocno processing because of
3246
   coalescing.  */
3247
static bitmap processed_coalesced_allocno_bitmap;
3248
 
3249
/* See below.  */
3250
typedef struct coalesce_data *coalesce_data_t;
3251
 
3252
/* To decrease footprint of ira_allocno structure we store all data
3253
   needed only for coalescing in the following structure.  */
3254
struct coalesce_data
3255
{
3256
  /* Coalesced allocnos form a cyclic list.  One allocno given by
3257
     FIRST represents all coalesced allocnos.  The
3258
     list is chained by NEXT.  */
3259
  ira_allocno_t first;
3260
  ira_allocno_t next;
3261
  int temp;
3262
};
3263
 
3264
/* Container for storing allocno data concerning coalescing.  */
3265
static coalesce_data_t allocno_coalesce_data;
3266
 
3267
/* Macro to access the data concerning coalescing.  */
3268
#define ALLOCNO_COALESCE_DATA(a) ((coalesce_data_t) ALLOCNO_ADD_DATA (a))
3269
 
3270
/* The function is used to sort allocnos according to their execution
3271
   frequencies.  */
3272
static int
3273
copy_freq_compare_func (const void *v1p, const void *v2p)
3274
{
3275
  ira_copy_t cp1 = *(const ira_copy_t *) v1p, cp2 = *(const ira_copy_t *) v2p;
3276
  int pri1, pri2;
3277
 
3278
  pri1 = cp1->freq;
3279
  pri2 = cp2->freq;
3280
  if (pri2 - pri1)
3281
    return pri2 - pri1;
3282
 
3283
  /* If freqencies are equal, sort by copies, so that the results of
3284
     qsort leave nothing to chance.  */
3285
  return cp1->num - cp2->num;
3286
}
3287
 
3288
/* Merge two sets of coalesced allocnos given correspondingly by
3289
   allocnos A1 and A2 (more accurately merging A2 set into A1
3290
   set).  */
3291
static void
3292
merge_allocnos (ira_allocno_t a1, ira_allocno_t a2)
3293
{
3294
  ira_allocno_t a, first, last, next;
3295
 
3296
  first = ALLOCNO_COALESCE_DATA (a1)->first;
3297
  a = ALLOCNO_COALESCE_DATA (a2)->first;
3298
  if (first == a)
3299
    return;
3300
  for (last = a2, a = ALLOCNO_COALESCE_DATA (a2)->next;;
3301
       a = ALLOCNO_COALESCE_DATA (a)->next)
3302
    {
3303
      ALLOCNO_COALESCE_DATA (a)->first = first;
3304
      if (a == a2)
3305
        break;
3306
      last = a;
3307
    }
3308
  next = allocno_coalesce_data[ALLOCNO_NUM (first)].next;
3309
  allocno_coalesce_data[ALLOCNO_NUM (first)].next = a2;
3310
  allocno_coalesce_data[ALLOCNO_NUM (last)].next = next;
3311
}
3312
 
3313
/* Return TRUE if there are conflicting allocnos from two sets of
3314
   coalesced allocnos given correspondingly by allocnos A1 and A2.  We
3315
   use live ranges to find conflicts because conflicts are represented
3316
   only for allocnos of the same allocno class and during the reload
3317
   pass we coalesce allocnos for sharing stack memory slots.  */
3318
static bool
3319
coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
3320
{
3321
  ira_allocno_t a, conflict_a;
3322
 
3323
  if (allocno_coalesced_p)
3324
    {
3325
      bitmap_clear (processed_coalesced_allocno_bitmap);
3326
      for (a = ALLOCNO_COALESCE_DATA (a1)->next;;
3327
           a = ALLOCNO_COALESCE_DATA (a)->next)
3328
        {
3329
          bitmap_set_bit (processed_coalesced_allocno_bitmap, ALLOCNO_NUM (a));
3330
          if (a == a1)
3331
            break;
3332
        }
3333
    }
3334
  for (a = ALLOCNO_COALESCE_DATA (a2)->next;;
3335
       a = ALLOCNO_COALESCE_DATA (a)->next)
3336
    {
3337
      for (conflict_a = ALLOCNO_COALESCE_DATA (a1)->next;;
3338
           conflict_a = ALLOCNO_COALESCE_DATA (conflict_a)->next)
3339
        {
3340
          if (allocnos_conflict_by_live_ranges_p (a, conflict_a))
3341
            return true;
3342
          if (conflict_a == a1)
3343
            break;
3344
        }
3345
      if (a == a2)
3346
        break;
3347
    }
3348
  return false;
3349
}
3350
 
3351
/* The major function for aggressive allocno coalescing.  We coalesce
3352
   only spilled allocnos.  If some allocnos have been coalesced, we
3353
   set up flag allocno_coalesced_p.  */
3354
static void
3355
coalesce_allocnos (void)
3356
{
3357
  ira_allocno_t a;
3358
  ira_copy_t cp, next_cp, *sorted_copies;
3359
  unsigned int j;
3360
  int i, n, cp_num, regno;
3361
  bitmap_iterator bi;
3362
 
3363
  sorted_copies = (ira_copy_t *) ira_allocate (ira_copies_num
3364
                                               * sizeof (ira_copy_t));
3365
  cp_num = 0;
3366
  /* Collect copies.  */
3367
  EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, j, bi)
3368
    {
3369
      a = ira_allocnos[j];
3370
      regno = ALLOCNO_REGNO (a);
3371
      if (! ALLOCNO_ASSIGNED_P (a) || ALLOCNO_HARD_REGNO (a) >= 0
3372
          || (regno < ira_reg_equiv_len
3373
              && (ira_reg_equiv_const[regno] != NULL_RTX
3374
                  || ira_reg_equiv_invariant_p[regno])))
3375
        continue;
3376
      for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
3377
        {
3378
          if (cp->first == a)
3379
            {
3380
              next_cp = cp->next_first_allocno_copy;
3381
              regno = ALLOCNO_REGNO (cp->second);
3382
              /* For priority coloring we coalesce allocnos only with
3383
                 the same allocno class not with intersected allocno
3384
                 classes as it were possible.  It is done for
3385
                 simplicity.  */
3386
              if ((cp->insn != NULL || cp->constraint_p)
3387
                  && ALLOCNO_ASSIGNED_P (cp->second)
3388
                  && ALLOCNO_HARD_REGNO (cp->second) < 0
3389
                  && (regno >= ira_reg_equiv_len
3390
                      || (! ira_reg_equiv_invariant_p[regno]
3391
                          && ira_reg_equiv_const[regno] == NULL_RTX)))
3392
                sorted_copies[cp_num++] = cp;
3393
            }
3394
          else if (cp->second == a)
3395
            next_cp = cp->next_second_allocno_copy;
3396
          else
3397
            gcc_unreachable ();
3398
        }
3399
    }
3400
  qsort (sorted_copies, cp_num, sizeof (ira_copy_t), copy_freq_compare_func);
3401
  /* Coalesced copies, most frequently executed first.  */
3402
  for (; cp_num != 0;)
3403
    {
3404
      for (i = 0; i < cp_num; i++)
3405
        {
3406
          cp = sorted_copies[i];
3407
          if (! coalesced_allocno_conflict_p (cp->first, cp->second))
3408
            {
3409
              allocno_coalesced_p = true;
3410
              if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3411
                fprintf
3412
                  (ira_dump_file,
3413
                   "      Coalescing copy %d:a%dr%d-a%dr%d (freq=%d)\n",
3414
                   cp->num, ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
3415
                   ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second),
3416
                   cp->freq);
3417
              merge_allocnos (cp->first, cp->second);
3418
              i++;
3419
              break;
3420
            }
3421
        }
3422
      /* Collect the rest of copies.  */
3423
      for (n = 0; i < cp_num; i++)
3424
        {
3425
          cp = sorted_copies[i];
3426
          if (allocno_coalesce_data[ALLOCNO_NUM (cp->first)].first
3427
              != allocno_coalesce_data[ALLOCNO_NUM (cp->second)].first)
3428
            sorted_copies[n++] = cp;
3429
        }
3430
      cp_num = n;
3431
    }
3432
  ira_free (sorted_copies);
3433
}
3434
 
3435
/* Usage cost and order number of coalesced allocno set to which
3436
   given pseudo register belongs to.  */
3437
static int *regno_coalesced_allocno_cost;
3438
static int *regno_coalesced_allocno_num;
3439
 
3440
/* Sort pseudos according frequencies of coalesced allocno sets they
3441
   belong to (putting most frequently ones first), and according to
3442
   coalesced allocno set order numbers.  */
3443
static int
3444
coalesced_pseudo_reg_freq_compare (const void *v1p, const void *v2p)
3445
{
3446
  const int regno1 = *(const int *) v1p;
3447
  const int regno2 = *(const int *) v2p;
3448
  int diff;
3449
 
3450
  if ((diff = (regno_coalesced_allocno_cost[regno2]
3451
               - regno_coalesced_allocno_cost[regno1])) != 0)
3452
    return diff;
3453
  if ((diff = (regno_coalesced_allocno_num[regno1]
3454
               - regno_coalesced_allocno_num[regno2])) != 0)
3455
    return diff;
3456
  return regno1 - regno2;
3457
}
3458
 
3459
/* Widest width in which each pseudo reg is referred to (via subreg).
3460
   It is used for sorting pseudo registers.  */
3461
static unsigned int *regno_max_ref_width;
3462
 
3463
/* Redefine STACK_GROWS_DOWNWARD in terms of 0 or 1.  */
3464
#ifdef STACK_GROWS_DOWNWARD
3465
# undef STACK_GROWS_DOWNWARD
3466
# define STACK_GROWS_DOWNWARD 1
3467
#else
3468
# define STACK_GROWS_DOWNWARD 0
3469
#endif
3470
 
3471
/* Sort pseudos according their slot numbers (putting ones with
3472
  smaller numbers first, or last when the frame pointer is not
3473
  needed).  */
3474
static int
3475
coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
3476
{
3477
  const int regno1 = *(const int *) v1p;
3478
  const int regno2 = *(const int *) v2p;
3479
  ira_allocno_t a1 = ira_regno_allocno_map[regno1];
3480
  ira_allocno_t a2 = ira_regno_allocno_map[regno2];
3481
  int diff, slot_num1, slot_num2;
3482
  int total_size1, total_size2;
3483
 
3484
  if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
3485
    {
3486
      if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3487
        return regno1 - regno2;
3488
      return 1;
3489
    }
3490
  else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
3491
    return -1;
3492
  slot_num1 = -ALLOCNO_HARD_REGNO (a1);
3493
  slot_num2 = -ALLOCNO_HARD_REGNO (a2);
3494
  if ((diff = slot_num1 - slot_num2) != 0)
3495
    return (frame_pointer_needed
3496
            || !FRAME_GROWS_DOWNWARD == STACK_GROWS_DOWNWARD ? diff : -diff);
3497
  total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1),
3498
                     regno_max_ref_width[regno1]);
3499
  total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
3500
                     regno_max_ref_width[regno2]);
3501
  if ((diff = total_size2 - total_size1) != 0)
3502
    return diff;
3503
  return regno1 - regno2;
3504
}
3505
 
3506
/* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM
3507
   for coalesced allocno sets containing allocnos with their regnos
3508
   given in array PSEUDO_REGNOS of length N.  */
3509
static void
3510
setup_coalesced_allocno_costs_and_nums (int *pseudo_regnos, int n)
3511
{
3512
  int i, num, regno, cost;
3513
  ira_allocno_t allocno, a;
3514
 
3515
  for (num = i = 0; i < n; i++)
3516
    {
3517
      regno = pseudo_regnos[i];
3518
      allocno = ira_regno_allocno_map[regno];
3519
      if (allocno == NULL)
3520
        {
3521
          regno_coalesced_allocno_cost[regno] = 0;
3522
          regno_coalesced_allocno_num[regno] = ++num;
3523
          continue;
3524
        }
3525
      if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3526
        continue;
3527
      num++;
3528
      for (cost = 0, a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3529
           a = ALLOCNO_COALESCE_DATA (a)->next)
3530
        {
3531
          cost += ALLOCNO_FREQ (a);
3532
          if (a == allocno)
3533
            break;
3534
        }
3535
      for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3536
           a = ALLOCNO_COALESCE_DATA (a)->next)
3537
        {
3538
          regno_coalesced_allocno_num[ALLOCNO_REGNO (a)] = num;
3539
          regno_coalesced_allocno_cost[ALLOCNO_REGNO (a)] = cost;
3540
          if (a == allocno)
3541
            break;
3542
        }
3543
    }
3544
}
3545
 
3546
/* Collect spilled allocnos representing coalesced allocno sets (the
3547
   first coalesced allocno).  The collected allocnos are returned
3548
   through array SPILLED_COALESCED_ALLOCNOS.  The function returns the
3549
   number of the collected allocnos.  The allocnos are given by their
3550
   regnos in array PSEUDO_REGNOS of length N.  */
3551
static int
3552
collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n,
3553
                                    ira_allocno_t *spilled_coalesced_allocnos)
3554
{
3555
  int i, num, regno;
3556
  ira_allocno_t allocno;
3557
 
3558
  for (num = i = 0; i < n; i++)
3559
    {
3560
      regno = pseudo_regnos[i];
3561
      allocno = ira_regno_allocno_map[regno];
3562
      if (allocno == NULL || ALLOCNO_HARD_REGNO (allocno) >= 0
3563
          || ALLOCNO_COALESCE_DATA (allocno)->first != allocno)
3564
        continue;
3565
      spilled_coalesced_allocnos[num++] = allocno;
3566
    }
3567
  return num;
3568
}
3569
 
3570
/* Array of live ranges of size IRA_ALLOCNOS_NUM.  Live range for
3571
   given slot contains live ranges of coalesced allocnos assigned to
3572
   given slot.  */
3573
static live_range_t *slot_coalesced_allocnos_live_ranges;
3574
 
3575
/* Return TRUE if coalesced allocnos represented by ALLOCNO has live
3576
   ranges intersected with live ranges of coalesced allocnos assigned
3577
   to slot with number N.  */
3578
static bool
3579
slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
3580
{
3581
  ira_allocno_t a;
3582
 
3583
  for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3584
       a = ALLOCNO_COALESCE_DATA (a)->next)
3585
    {
3586
      int i;
3587
      int nr = ALLOCNO_NUM_OBJECTS (a);
3588
 
3589
      for (i = 0; i < nr; i++)
3590
        {
3591
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
3592
 
3593
          if (ira_live_ranges_intersect_p
3594
              (slot_coalesced_allocnos_live_ranges[n],
3595
               OBJECT_LIVE_RANGES (obj)))
3596
            return true;
3597
        }
3598
      if (a == allocno)
3599
        break;
3600
    }
3601
  return false;
3602
}
3603
 
3604
/* Update live ranges of slot to which coalesced allocnos represented
3605
   by ALLOCNO were assigned.  */
3606
static void
3607
setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
3608
{
3609
  int i, n;
3610
  ira_allocno_t a;
3611
  live_range_t r;
3612
 
3613
  n = ALLOCNO_COALESCE_DATA (allocno)->temp;
3614
  for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3615
       a = ALLOCNO_COALESCE_DATA (a)->next)
3616
    {
3617
      int nr = ALLOCNO_NUM_OBJECTS (a);
3618
      for (i = 0; i < nr; i++)
3619
        {
3620
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
3621
 
3622
          r = ira_copy_live_range_list (OBJECT_LIVE_RANGES (obj));
3623
          slot_coalesced_allocnos_live_ranges[n]
3624
            = ira_merge_live_ranges
3625
              (slot_coalesced_allocnos_live_ranges[n], r);
3626
        }
3627
      if (a == allocno)
3628
        break;
3629
    }
3630
}
3631
 
3632
/* We have coalesced allocnos involving in copies.  Coalesce allocnos
3633
   further in order to share the same memory stack slot.  Allocnos
3634
   representing sets of allocnos coalesced before the call are given
3635
   in array SPILLED_COALESCED_ALLOCNOS of length NUM.  Return TRUE if
3636
   some allocnos were coalesced in the function.  */
3637
static bool
3638
coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
3639
{
3640
  int i, j, n, last_coalesced_allocno_num;
3641
  ira_allocno_t allocno, a;
3642
  bool merged_p = false;
3643
  bitmap set_jump_crosses = regstat_get_setjmp_crosses ();
3644
 
3645
  slot_coalesced_allocnos_live_ranges
3646
    = (live_range_t *) ira_allocate (sizeof (live_range_t) * ira_allocnos_num);
3647
  memset (slot_coalesced_allocnos_live_ranges, 0,
3648
          sizeof (live_range_t) * ira_allocnos_num);
3649
  last_coalesced_allocno_num = 0;
3650
  /* Coalesce non-conflicting spilled allocnos preferring most
3651
     frequently used.  */
3652
  for (i = 0; i < num; i++)
3653
    {
3654
      allocno = spilled_coalesced_allocnos[i];
3655
      if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
3656
          || bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (allocno))
3657
          || (ALLOCNO_REGNO (allocno) < ira_reg_equiv_len
3658
              && (ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX
3659
                  || ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)])))
3660
        continue;
3661
      for (j = 0; j < i; j++)
3662
        {
3663
          a = spilled_coalesced_allocnos[j];
3664
          n = ALLOCNO_COALESCE_DATA (a)->temp;
3665
          if (ALLOCNO_COALESCE_DATA (a)->first == a
3666
              && ! bitmap_bit_p (set_jump_crosses, ALLOCNO_REGNO (a))
3667
              && (ALLOCNO_REGNO (a) >= ira_reg_equiv_len
3668
                  || (! ira_reg_equiv_invariant_p[ALLOCNO_REGNO (a)]
3669
                      && ira_reg_equiv_const[ALLOCNO_REGNO (a)] == NULL_RTX))
3670
              && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
3671
            break;
3672
        }
3673
      if (j >= i)
3674
        {
3675
          /* No coalescing: set up number for coalesced allocnos
3676
             represented by ALLOCNO.  */
3677
          ALLOCNO_COALESCE_DATA (allocno)->temp = last_coalesced_allocno_num++;
3678
          setup_slot_coalesced_allocno_live_ranges (allocno);
3679
        }
3680
      else
3681
        {
3682
          allocno_coalesced_p = true;
3683
          merged_p = true;
3684
          if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3685
            fprintf (ira_dump_file,
3686
                     "      Coalescing spilled allocnos a%dr%d->a%dr%d\n",
3687
                     ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
3688
                     ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
3689
          ALLOCNO_COALESCE_DATA (allocno)->temp
3690
            = ALLOCNO_COALESCE_DATA (a)->temp;
3691
          setup_slot_coalesced_allocno_live_ranges (allocno);
3692
          merge_allocnos (a, allocno);
3693
          ira_assert (ALLOCNO_COALESCE_DATA (a)->first == a);
3694
        }
3695
    }
3696
  for (i = 0; i < ira_allocnos_num; i++)
3697
    ira_finish_live_range_list (slot_coalesced_allocnos_live_ranges[i]);
3698
  ira_free (slot_coalesced_allocnos_live_ranges);
3699
  return merged_p;
3700
}
3701
 
3702
/* Sort pseudo-register numbers in array PSEUDO_REGNOS of length N for
3703
   subsequent assigning stack slots to them in the reload pass.  To do
3704
   this we coalesce spilled allocnos first to decrease the number of
3705
   memory-memory move insns.  This function is called by the
3706
   reload.  */
3707
void
3708
ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n,
3709
                               unsigned int *reg_max_ref_width)
3710
{
3711
  int max_regno = max_reg_num ();
3712
  int i, regno, num, slot_num;
3713
  ira_allocno_t allocno, a;
3714
  ira_allocno_iterator ai;
3715
  ira_allocno_t *spilled_coalesced_allocnos;
3716
 
3717
  /* Set up allocnos can be coalesced.  */
3718
  coloring_allocno_bitmap = ira_allocate_bitmap ();
3719
  for (i = 0; i < n; i++)
3720
    {
3721
      regno = pseudo_regnos[i];
3722
      allocno = ira_regno_allocno_map[regno];
3723
      if (allocno != NULL)
3724
        bitmap_set_bit (coloring_allocno_bitmap, ALLOCNO_NUM (allocno));
3725
    }
3726
  allocno_coalesced_p = false;
3727
  processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
3728
  allocno_coalesce_data
3729
    = (coalesce_data_t) ira_allocate (sizeof (struct coalesce_data)
3730
                                      * ira_allocnos_num);
3731
  /* Initialize coalesce data for allocnos.  */
3732
  FOR_EACH_ALLOCNO (a, ai)
3733
    {
3734
      ALLOCNO_ADD_DATA (a) = allocno_coalesce_data + ALLOCNO_NUM (a);
3735
      ALLOCNO_COALESCE_DATA (a)->first = a;
3736
      ALLOCNO_COALESCE_DATA (a)->next = a;
3737
    }
3738
  coalesce_allocnos ();
3739
  ira_free_bitmap (coloring_allocno_bitmap);
3740
  regno_coalesced_allocno_cost
3741
    = (int *) ira_allocate (max_regno * sizeof (int));
3742
  regno_coalesced_allocno_num
3743
    = (int *) ira_allocate (max_regno * sizeof (int));
3744
  memset (regno_coalesced_allocno_num, 0, max_regno * sizeof (int));
3745
  setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
3746
  /* Sort regnos according frequencies of the corresponding coalesced
3747
     allocno sets.  */
3748
  qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_freq_compare);
3749
  spilled_coalesced_allocnos
3750
    = (ira_allocno_t *) ira_allocate (ira_allocnos_num
3751
                                      * sizeof (ira_allocno_t));
3752
  /* Collect allocnos representing the spilled coalesced allocno
3753
     sets.  */
3754
  num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
3755
                                            spilled_coalesced_allocnos);
3756
  if (flag_ira_share_spill_slots
3757
      && coalesce_spill_slots (spilled_coalesced_allocnos, num))
3758
    {
3759
      setup_coalesced_allocno_costs_and_nums (pseudo_regnos, n);
3760
      qsort (pseudo_regnos, n, sizeof (int),
3761
             coalesced_pseudo_reg_freq_compare);
3762
      num = collect_spilled_coalesced_allocnos (pseudo_regnos, n,
3763
                                                spilled_coalesced_allocnos);
3764
    }
3765
  ira_free_bitmap (processed_coalesced_allocno_bitmap);
3766
  allocno_coalesced_p = false;
3767
  /* Assign stack slot numbers to spilled allocno sets, use smaller
3768
     numbers for most frequently used coalesced allocnos.  -1 is
3769
     reserved for dynamic search of stack slots for pseudos spilled by
3770
     the reload.  */
3771
  slot_num = 1;
3772
  for (i = 0; i < num; i++)
3773
    {
3774
      allocno = spilled_coalesced_allocnos[i];
3775
      if (ALLOCNO_COALESCE_DATA (allocno)->first != allocno
3776
          || ALLOCNO_HARD_REGNO (allocno) >= 0
3777
          || (ALLOCNO_REGNO (allocno) < ira_reg_equiv_len
3778
              && (ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX
3779
                  || ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)])))
3780
        continue;
3781
      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3782
        fprintf (ira_dump_file, "      Slot %d (freq,size):", slot_num);
3783
      slot_num++;
3784
      for (a = ALLOCNO_COALESCE_DATA (allocno)->next;;
3785
           a = ALLOCNO_COALESCE_DATA (a)->next)
3786
        {
3787
          ira_assert (ALLOCNO_HARD_REGNO (a) < 0);
3788
          ALLOCNO_HARD_REGNO (a) = -slot_num;
3789
          if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3790
            fprintf (ira_dump_file, " a%dr%d(%d,%d)",
3791
                     ALLOCNO_NUM (a), ALLOCNO_REGNO (a), ALLOCNO_FREQ (a),
3792
                     MAX (PSEUDO_REGNO_BYTES (ALLOCNO_REGNO (a)),
3793
                          reg_max_ref_width[ALLOCNO_REGNO (a)]));
3794
 
3795
          if (a == allocno)
3796
            break;
3797
        }
3798
      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3799
        fprintf (ira_dump_file, "\n");
3800
    }
3801
  ira_spilled_reg_stack_slots_num = slot_num - 1;
3802
  ira_free (spilled_coalesced_allocnos);
3803
  /* Sort regnos according the slot numbers.  */
3804
  regno_max_ref_width = reg_max_ref_width;
3805
  qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
3806
  FOR_EACH_ALLOCNO (a, ai)
3807
    ALLOCNO_ADD_DATA (a) = NULL;
3808
  ira_free (allocno_coalesce_data);
3809
  ira_free (regno_coalesced_allocno_num);
3810
  ira_free (regno_coalesced_allocno_cost);
3811
}
3812
 
3813
 
3814
 
3815
/* This page contains code used by the reload pass to improve the
3816
   final code.  */
3817
 
3818
/* The function is called from reload to mark changes in the
3819
   allocation of REGNO made by the reload.  Remember that reg_renumber
3820
   reflects the change result.  */
3821
void
3822
ira_mark_allocation_change (int regno)
3823
{
3824
  ira_allocno_t a = ira_regno_allocno_map[regno];
3825
  int old_hard_regno, hard_regno, cost;
3826
  enum reg_class aclass = ALLOCNO_CLASS (a);
3827
 
3828
  ira_assert (a != NULL);
3829
  hard_regno = reg_renumber[regno];
3830
  if ((old_hard_regno = ALLOCNO_HARD_REGNO (a)) == hard_regno)
3831
    return;
3832
  if (old_hard_regno < 0)
3833
    cost = -ALLOCNO_MEMORY_COST (a);
3834
  else
3835
    {
3836
      ira_assert (ira_class_hard_reg_index[aclass][old_hard_regno] >= 0);
3837
      cost = -(ALLOCNO_HARD_REG_COSTS (a) == NULL
3838
               ? ALLOCNO_CLASS_COST (a)
3839
               : ALLOCNO_HARD_REG_COSTS (a)
3840
                 [ira_class_hard_reg_index[aclass][old_hard_regno]]);
3841
      update_copy_costs (a, false);
3842
    }
3843
  ira_overall_cost -= cost;
3844
  ALLOCNO_HARD_REGNO (a) = hard_regno;
3845
  if (hard_regno < 0)
3846
    {
3847
      ALLOCNO_HARD_REGNO (a) = -1;
3848
      cost += ALLOCNO_MEMORY_COST (a);
3849
    }
3850
  else if (ira_class_hard_reg_index[aclass][hard_regno] >= 0)
3851
    {
3852
      cost += (ALLOCNO_HARD_REG_COSTS (a) == NULL
3853
               ? ALLOCNO_CLASS_COST (a)
3854
               : ALLOCNO_HARD_REG_COSTS (a)
3855
                 [ira_class_hard_reg_index[aclass][hard_regno]]);
3856
      update_copy_costs (a, true);
3857
    }
3858
  else
3859
    /* Reload changed class of the allocno.  */
3860
    cost = 0;
3861
  ira_overall_cost += cost;
3862
}
3863
 
3864
/* This function is called when reload deletes memory-memory move.  In
3865
   this case we marks that the allocation of the corresponding
3866
   allocnos should be not changed in future.  Otherwise we risk to get
3867
   a wrong code.  */
3868
void
3869
ira_mark_memory_move_deletion (int dst_regno, int src_regno)
3870
{
3871
  ira_allocno_t dst = ira_regno_allocno_map[dst_regno];
3872
  ira_allocno_t src = ira_regno_allocno_map[src_regno];
3873
 
3874
  ira_assert (dst != NULL && src != NULL
3875
              && ALLOCNO_HARD_REGNO (dst) < 0
3876
              && ALLOCNO_HARD_REGNO (src) < 0);
3877
  ALLOCNO_DONT_REASSIGN_P (dst) = true;
3878
  ALLOCNO_DONT_REASSIGN_P (src) = true;
3879
}
3880
 
3881
/* Try to assign a hard register (except for FORBIDDEN_REGS) to
3882
   allocno A and return TRUE in the case of success.  */
3883
static bool
3884
allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs)
3885
{
3886
  int hard_regno;
3887
  enum reg_class aclass;
3888
  int regno = ALLOCNO_REGNO (a);
3889
  HARD_REG_SET saved[2];
3890
  int i, n;
3891
 
3892
  n = ALLOCNO_NUM_OBJECTS (a);
3893
  for (i = 0; i < n; i++)
3894
    {
3895
      ira_object_t obj = ALLOCNO_OBJECT (a, i);
3896
      COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
3897
      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs);
3898
      if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
3899
        IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
3900
                          call_used_reg_set);
3901
    }
3902
  ALLOCNO_ASSIGNED_P (a) = false;
3903
  aclass = ALLOCNO_CLASS (a);
3904
  update_curr_costs (a);
3905
  assign_hard_reg (a, true);
3906
  hard_regno = ALLOCNO_HARD_REGNO (a);
3907
  reg_renumber[regno] = hard_regno;
3908
  if (hard_regno < 0)
3909
    ALLOCNO_HARD_REGNO (a) = -1;
3910
  else
3911
    {
3912
      ira_assert (ira_class_hard_reg_index[aclass][hard_regno] >= 0);
3913
      ira_overall_cost
3914
        -= (ALLOCNO_MEMORY_COST (a)
3915
            - (ALLOCNO_HARD_REG_COSTS (a) == NULL
3916
               ? ALLOCNO_CLASS_COST (a)
3917
               : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index
3918
                                            [aclass][hard_regno]]));
3919
      if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0
3920
          && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a),
3921
                                              call_used_reg_set))
3922
        {
3923
          ira_assert (flag_caller_saves);
3924
          caller_save_needed = 1;
3925
        }
3926
    }
3927
 
3928
  /* If we found a hard register, modify the RTL for the pseudo
3929
     register to show the hard register, and mark the pseudo register
3930
     live.  */
3931
  if (reg_renumber[regno] >= 0)
3932
    {
3933
      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3934
        fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
3935
      SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
3936
      mark_home_live (regno);
3937
    }
3938
  else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
3939
    fprintf (ira_dump_file, "\n");
3940
  for (i = 0; i < n; i++)
3941
    {
3942
      ira_object_t obj = ALLOCNO_OBJECT (a, i);
3943
      COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]);
3944
    }
3945
  return reg_renumber[regno] >= 0;
3946
}
3947
 
3948
/* Sort pseudos according their usage frequencies (putting most
3949
   frequently ones first).  */
3950
static int
3951
pseudo_reg_compare (const void *v1p, const void *v2p)
3952
{
3953
  int regno1 = *(const int *) v1p;
3954
  int regno2 = *(const int *) v2p;
3955
  int diff;
3956
 
3957
  if ((diff = REG_FREQ (regno2) - REG_FREQ (regno1)) != 0)
3958
    return diff;
3959
  return regno1 - regno2;
3960
}
3961
 
3962
/* Try to allocate hard registers to SPILLED_PSEUDO_REGS (there are
3963
   NUM of them) or spilled pseudos conflicting with pseudos in
3964
   SPILLED_PSEUDO_REGS.  Return TRUE and update SPILLED, if the
3965
   allocation has been changed.  The function doesn't use
3966
   BAD_SPILL_REGS and hard registers in PSEUDO_FORBIDDEN_REGS and
3967
   PSEUDO_PREVIOUS_REGS for the corresponding pseudos.  The function
3968
   is called by the reload pass at the end of each reload
3969
   iteration.  */
3970
bool
3971
ira_reassign_pseudos (int *spilled_pseudo_regs, int num,
3972
                      HARD_REG_SET bad_spill_regs,
3973
                      HARD_REG_SET *pseudo_forbidden_regs,
3974
                      HARD_REG_SET *pseudo_previous_regs,
3975
                      bitmap spilled)
3976
{
3977
  int i, n, regno;
3978
  bool changed_p;
3979
  ira_allocno_t a;
3980
  HARD_REG_SET forbidden_regs;
3981
  bitmap temp = BITMAP_ALLOC (NULL);
3982
 
3983
  /* Add pseudos which conflict with pseudos already in
3984
     SPILLED_PSEUDO_REGS to SPILLED_PSEUDO_REGS.  This is preferable
3985
     to allocating in two steps as some of the conflicts might have
3986
     a higher priority than the pseudos passed in SPILLED_PSEUDO_REGS.  */
3987
  for (i = 0; i < num; i++)
3988
    bitmap_set_bit (temp, spilled_pseudo_regs[i]);
3989
 
3990
  for (i = 0, n = num; i < n; i++)
3991
    {
3992
      int nr, j;
3993
      int regno = spilled_pseudo_regs[i];
3994
      bitmap_set_bit (temp, regno);
3995
 
3996
      a = ira_regno_allocno_map[regno];
3997
      nr = ALLOCNO_NUM_OBJECTS (a);
3998
      for (j = 0; j < nr; j++)
3999
        {
4000
          ira_object_t conflict_obj;
4001
          ira_object_t obj = ALLOCNO_OBJECT (a, j);
4002
          ira_object_conflict_iterator oci;
4003
 
4004
          FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
4005
            {
4006
              ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
4007
              if (ALLOCNO_HARD_REGNO (conflict_a) < 0
4008
                  && ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
4009
                  && bitmap_set_bit (temp, ALLOCNO_REGNO (conflict_a)))
4010
                {
4011
                  spilled_pseudo_regs[num++] = ALLOCNO_REGNO (conflict_a);
4012
                  /* ?!? This seems wrong.  */
4013
                  bitmap_set_bit (consideration_allocno_bitmap,
4014
                                  ALLOCNO_NUM (conflict_a));
4015
                }
4016
            }
4017
        }
4018
    }
4019
 
4020
  if (num > 1)
4021
    qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
4022
  changed_p = false;
4023
  /* Try to assign hard registers to pseudos from
4024
     SPILLED_PSEUDO_REGS.  */
4025
  for (i = 0; i < num; i++)
4026
    {
4027
      regno = spilled_pseudo_regs[i];
4028
      COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs);
4029
      IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]);
4030
      IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]);
4031
      gcc_assert (reg_renumber[regno] < 0);
4032
      a = ira_regno_allocno_map[regno];
4033
      ira_mark_allocation_change (regno);
4034
      ira_assert (reg_renumber[regno] < 0);
4035
      if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
4036
        fprintf (ira_dump_file,
4037
                 "      Try Assign %d(a%d), cost=%d", regno, ALLOCNO_NUM (a),
4038
                 ALLOCNO_MEMORY_COST (a)
4039
                 - ALLOCNO_CLASS_COST (a));
4040
      allocno_reload_assign (a, forbidden_regs);
4041
      if (reg_renumber[regno] >= 0)
4042
        {
4043
          CLEAR_REGNO_REG_SET (spilled, regno);
4044
          changed_p = true;
4045
        }
4046
    }
4047
  BITMAP_FREE (temp);
4048
  return changed_p;
4049
}
4050
 
4051
/* The function is called by reload and returns already allocated
4052
   stack slot (if any) for REGNO with given INHERENT_SIZE and
4053
   TOTAL_SIZE.  In the case of failure to find a slot which can be
4054
   used for REGNO, the function returns NULL.  */
4055
rtx
4056
ira_reuse_stack_slot (int regno, unsigned int inherent_size,
4057
                      unsigned int total_size)
4058
{
4059
  unsigned int i;
4060
  int slot_num, best_slot_num;
4061
  int cost, best_cost;
4062
  ira_copy_t cp, next_cp;
4063
  ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
4064
  rtx x;
4065
  bitmap_iterator bi;
4066
  struct ira_spilled_reg_stack_slot *slot = NULL;
4067
 
4068
  ira_assert (inherent_size == PSEUDO_REGNO_BYTES (regno)
4069
              && inherent_size <= total_size
4070
              && ALLOCNO_HARD_REGNO (allocno) < 0);
4071
  if (! flag_ira_share_spill_slots)
4072
    return NULL_RTX;
4073
  slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4074
  if (slot_num != -1)
4075
    {
4076
      slot = &ira_spilled_reg_stack_slots[slot_num];
4077
      x = slot->mem;
4078
    }
4079
  else
4080
    {
4081
      best_cost = best_slot_num = -1;
4082
      x = NULL_RTX;
4083
      /* It means that the pseudo was spilled in the reload pass, try
4084
         to reuse a slot.  */
4085
      for (slot_num = 0;
4086
           slot_num < ira_spilled_reg_stack_slots_num;
4087
           slot_num++)
4088
        {
4089
          slot = &ira_spilled_reg_stack_slots[slot_num];
4090
          if (slot->mem == NULL_RTX)
4091
            continue;
4092
          if (slot->width < total_size
4093
              || GET_MODE_SIZE (GET_MODE (slot->mem)) < inherent_size)
4094
            continue;
4095
 
4096
          EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4097
                                    FIRST_PSEUDO_REGISTER, i, bi)
4098
            {
4099
              another_allocno = ira_regno_allocno_map[i];
4100
              if (allocnos_conflict_by_live_ranges_p (allocno,
4101
                                                      another_allocno))
4102
                goto cont;
4103
            }
4104
          for (cost = 0, cp = ALLOCNO_COPIES (allocno);
4105
               cp != NULL;
4106
               cp = next_cp)
4107
            {
4108
              if (cp->first == allocno)
4109
                {
4110
                  next_cp = cp->next_first_allocno_copy;
4111
                  another_allocno = cp->second;
4112
                }
4113
              else if (cp->second == allocno)
4114
                {
4115
                  next_cp = cp->next_second_allocno_copy;
4116
                  another_allocno = cp->first;
4117
                }
4118
              else
4119
                gcc_unreachable ();
4120
              if (cp->insn == NULL_RTX)
4121
                continue;
4122
              if (bitmap_bit_p (&slot->spilled_regs,
4123
                                ALLOCNO_REGNO (another_allocno)))
4124
                cost += cp->freq;
4125
            }
4126
          if (cost > best_cost)
4127
            {
4128
              best_cost = cost;
4129
              best_slot_num = slot_num;
4130
            }
4131
        cont:
4132
          ;
4133
        }
4134
      if (best_cost >= 0)
4135
        {
4136
          slot_num = best_slot_num;
4137
          slot = &ira_spilled_reg_stack_slots[slot_num];
4138
          SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4139
          x = slot->mem;
4140
          ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4141
        }
4142
    }
4143
  if (x != NULL_RTX)
4144
    {
4145
      ira_assert (slot->width >= total_size);
4146
#ifdef ENABLE_IRA_CHECKING
4147
      EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4148
                                FIRST_PSEUDO_REGISTER, i, bi)
4149
        {
4150
          ira_assert (! conflict_by_live_ranges_p (regno, i));
4151
        }
4152
#endif
4153
      SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4154
      if (internal_flag_ira_verbose > 3 && ira_dump_file)
4155
        {
4156
          fprintf (ira_dump_file, "      Assigning %d(freq=%d) slot %d of",
4157
                   regno, REG_FREQ (regno), slot_num);
4158
          EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
4159
                                    FIRST_PSEUDO_REGISTER, i, bi)
4160
            {
4161
              if ((unsigned) regno != i)
4162
                fprintf (ira_dump_file, " %d", i);
4163
            }
4164
          fprintf (ira_dump_file, "\n");
4165
        }
4166
    }
4167
  return x;
4168
}
4169
 
4170
/* This is called by reload every time a new stack slot X with
4171
   TOTAL_SIZE was allocated for REGNO.  We store this info for
4172
   subsequent ira_reuse_stack_slot calls.  */
4173
void
4174
ira_mark_new_stack_slot (rtx x, int regno, unsigned int total_size)
4175
{
4176
  struct ira_spilled_reg_stack_slot *slot;
4177
  int slot_num;
4178
  ira_allocno_t allocno;
4179
 
4180
  ira_assert (PSEUDO_REGNO_BYTES (regno) <= total_size);
4181
  allocno = ira_regno_allocno_map[regno];
4182
  slot_num = -ALLOCNO_HARD_REGNO (allocno) - 2;
4183
  if (slot_num == -1)
4184
    {
4185
      slot_num = ira_spilled_reg_stack_slots_num++;
4186
      ALLOCNO_HARD_REGNO (allocno) = -slot_num - 2;
4187
    }
4188
  slot = &ira_spilled_reg_stack_slots[slot_num];
4189
  INIT_REG_SET (&slot->spilled_regs);
4190
  SET_REGNO_REG_SET (&slot->spilled_regs, regno);
4191
  slot->mem = x;
4192
  slot->width = total_size;
4193
  if (internal_flag_ira_verbose > 3 && ira_dump_file)
4194
    fprintf (ira_dump_file, "      Assigning %d(freq=%d) a new slot %d\n",
4195
             regno, REG_FREQ (regno), slot_num);
4196
}
4197
 
4198
 
4199
/* Return spill cost for pseudo-registers whose numbers are in array
4200
   REGNOS (with a negative number as an end marker) for reload with
4201
   given IN and OUT for INSN.  Return also number points (through
4202
   EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and
4203
   the register pressure is high, number of references of the
4204
   pseudo-registers (through NREFS), number of callee-clobbered
4205
   hard-registers occupied by the pseudo-registers (through
4206
   CALL_USED_COUNT), and the first hard regno occupied by the
4207
   pseudo-registers (through FIRST_HARD_REGNO).  */
4208
static int
4209
calculate_spill_cost (int *regnos, rtx in, rtx out, rtx insn,
4210
                      int *excess_pressure_live_length,
4211
                      int *nrefs, int *call_used_count, int *first_hard_regno)
4212
{
4213
  int i, cost, regno, hard_regno, j, count, saved_cost, nregs;
4214
  bool in_p, out_p;
4215
  int length;
4216
  ira_allocno_t a;
4217
 
4218
  *nrefs = 0;
4219
  for (length = count = cost = i = 0;; i++)
4220
    {
4221
      regno = regnos[i];
4222
      if (regno < 0)
4223
        break;
4224
      *nrefs += REG_N_REFS (regno);
4225
      hard_regno = reg_renumber[regno];
4226
      ira_assert (hard_regno >= 0);
4227
      a = ira_regno_allocno_map[regno];
4228
      length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
4229
      cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
4230
      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
4231
      for (j = 0; j < nregs; j++)
4232
        if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
4233
          break;
4234
      if (j == nregs)
4235
        count++;
4236
      in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno;
4237
      out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno;
4238
      if ((in_p || out_p)
4239
          && find_regno_note (insn, REG_DEAD, hard_regno) != NULL_RTX)
4240
        {
4241
          saved_cost = 0;
4242
          if (in_p)
4243
            saved_cost += ira_memory_move_cost
4244
                          [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][1];
4245
          if (out_p)
4246
            saved_cost
4247
              += ira_memory_move_cost
4248
                 [ALLOCNO_MODE (a)][ALLOCNO_CLASS (a)][0];
4249
          cost -= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)) * saved_cost;
4250
        }
4251
    }
4252
  *excess_pressure_live_length = length;
4253
  *call_used_count = count;
4254
  hard_regno = -1;
4255
  if (regnos[0] >= 0)
4256
    {
4257
      hard_regno = reg_renumber[regnos[0]];
4258
    }
4259
  *first_hard_regno = hard_regno;
4260
  return cost;
4261
}
4262
 
4263
/* Return TRUE if spilling pseudo-registers whose numbers are in array
4264
   REGNOS is better than spilling pseudo-registers with numbers in
4265
   OTHER_REGNOS for reload with given IN and OUT for INSN.  The
4266
   function used by the reload pass to make better register spilling
4267
   decisions.  */
4268
bool
4269
ira_better_spill_reload_regno_p (int *regnos, int *other_regnos,
4270
                                 rtx in, rtx out, rtx insn)
4271
{
4272
  int cost, other_cost;
4273
  int length, other_length;
4274
  int nrefs, other_nrefs;
4275
  int call_used_count, other_call_used_count;
4276
  int hard_regno, other_hard_regno;
4277
 
4278
  cost = calculate_spill_cost (regnos, in, out, insn,
4279
                               &length, &nrefs, &call_used_count, &hard_regno);
4280
  other_cost = calculate_spill_cost (other_regnos, in, out, insn,
4281
                                     &other_length, &other_nrefs,
4282
                                     &other_call_used_count,
4283
                                     &other_hard_regno);
4284
  if (nrefs == 0 && other_nrefs != 0)
4285
    return true;
4286
  if (nrefs != 0 && other_nrefs == 0)
4287
    return false;
4288
  if (cost != other_cost)
4289
    return cost < other_cost;
4290
  if (length != other_length)
4291
    return length > other_length;
4292
#ifdef REG_ALLOC_ORDER
4293
  if (hard_regno >= 0 && other_hard_regno >= 0)
4294
    return (inv_reg_alloc_order[hard_regno]
4295
            < inv_reg_alloc_order[other_hard_regno]);
4296
#else
4297
  if (call_used_count != other_call_used_count)
4298
    return call_used_count > other_call_used_count;
4299
#endif
4300
  return false;
4301
}
4302
 
4303
 
4304
 
4305
/* Allocate and initialize data necessary for assign_hard_reg.  */
4306
void
4307
ira_initiate_assign (void)
4308
{
4309
  sorted_allocnos
4310
    = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4311
                                      * ira_allocnos_num);
4312
  consideration_allocno_bitmap = ira_allocate_bitmap ();
4313
  initiate_cost_update ();
4314
  allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4315
}
4316
 
4317
/* Deallocate data used by assign_hard_reg.  */
4318
void
4319
ira_finish_assign (void)
4320
{
4321
  ira_free (sorted_allocnos);
4322
  ira_free_bitmap (consideration_allocno_bitmap);
4323
  finish_cost_update ();
4324
  ira_free (allocno_priorities);
4325
}
4326
 
4327
 
4328
 
4329
/* Entry function doing color-based register allocation.  */
4330
static void
4331
color (void)
4332
{
4333
  allocno_stack_vec = VEC_alloc (ira_allocno_t, heap, ira_allocnos_num);
4334
  memset (allocated_hardreg_p, 0, sizeof (allocated_hardreg_p));
4335
  ira_initiate_assign ();
4336
  do_coloring ();
4337
  ira_finish_assign ();
4338
  VEC_free (ira_allocno_t, heap, allocno_stack_vec);
4339
  move_spill_restore ();
4340
}
4341
 
4342
 
4343
 
4344
/* This page contains a simple register allocator without usage of
4345
   allocno conflicts.  This is used for fast allocation for -O0.  */
4346
 
4347
/* Do register allocation by not using allocno conflicts.  It uses
4348
   only allocno live ranges.  The algorithm is close to Chow's
4349
   priority coloring.  */
4350
static void
4351
fast_allocation (void)
4352
{
4353
  int i, j, k, num, class_size, hard_regno;
4354
#ifdef STACK_REGS
4355
  bool no_stack_reg_p;
4356
#endif
4357
  enum reg_class aclass;
4358
  enum machine_mode mode;
4359
  ira_allocno_t a;
4360
  ira_allocno_iterator ai;
4361
  live_range_t r;
4362
  HARD_REG_SET conflict_hard_regs, *used_hard_regs;
4363
 
4364
  sorted_allocnos = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t)
4365
                                                    * ira_allocnos_num);
4366
  num = 0;
4367
  FOR_EACH_ALLOCNO (a, ai)
4368
    sorted_allocnos[num++] = a;
4369
  allocno_priorities = (int *) ira_allocate (sizeof (int) * ira_allocnos_num);
4370
  setup_allocno_priorities (sorted_allocnos, num);
4371
  used_hard_regs = (HARD_REG_SET *) ira_allocate (sizeof (HARD_REG_SET)
4372
                                                  * ira_max_point);
4373
  for (i = 0; i < ira_max_point; i++)
4374
    CLEAR_HARD_REG_SET (used_hard_regs[i]);
4375
  qsort (sorted_allocnos, num, sizeof (ira_allocno_t),
4376
         allocno_priority_compare_func);
4377
  for (i = 0; i < num; i++)
4378
    {
4379
      int nr, l;
4380
 
4381
      a = sorted_allocnos[i];
4382
      nr = ALLOCNO_NUM_OBJECTS (a);
4383
      CLEAR_HARD_REG_SET (conflict_hard_regs);
4384
      for (l = 0; l < nr; l++)
4385
        {
4386
          ira_object_t obj = ALLOCNO_OBJECT (a, l);
4387
          IOR_HARD_REG_SET (conflict_hard_regs,
4388
                            OBJECT_CONFLICT_HARD_REGS (obj));
4389
          for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4390
            for (j = r->start; j <= r->finish; j++)
4391
              IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]);
4392
        }
4393
      aclass = ALLOCNO_CLASS (a);
4394
      ALLOCNO_ASSIGNED_P (a) = true;
4395
      ALLOCNO_HARD_REGNO (a) = -1;
4396
      if (hard_reg_set_subset_p (reg_class_contents[aclass],
4397
                                 conflict_hard_regs))
4398
        continue;
4399
      mode = ALLOCNO_MODE (a);
4400
#ifdef STACK_REGS
4401
      no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a);
4402
#endif
4403
      class_size = ira_class_hard_regs_num[aclass];
4404
      for (j = 0; j < class_size; j++)
4405
        {
4406
          hard_regno = ira_class_hard_regs[aclass][j];
4407
#ifdef STACK_REGS
4408
          if (no_stack_reg_p && FIRST_STACK_REG <= hard_regno
4409
              && hard_regno <= LAST_STACK_REG)
4410
            continue;
4411
#endif
4412
          if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs)
4413
              || (TEST_HARD_REG_BIT
4414
                  (ira_prohibited_class_mode_regs[aclass][mode], hard_regno)))
4415
            continue;
4416
          ALLOCNO_HARD_REGNO (a) = hard_regno;
4417
          for (l = 0; l < nr; l++)
4418
            {
4419
              ira_object_t obj = ALLOCNO_OBJECT (a, l);
4420
              for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
4421
                for (k = r->start; k <= r->finish; k++)
4422
                  IOR_HARD_REG_SET (used_hard_regs[k],
4423
                                    ira_reg_mode_hard_regset[hard_regno][mode]);
4424
            }
4425
          break;
4426
        }
4427
    }
4428
  ira_free (sorted_allocnos);
4429
  ira_free (used_hard_regs);
4430
  ira_free (allocno_priorities);
4431
  if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
4432
    ira_print_disposition (ira_dump_file);
4433
}
4434
 
4435
 
4436
 
4437
/* Entry function doing coloring.  */
4438
void
4439
ira_color (void)
4440
{
4441
  ira_allocno_t a;
4442
  ira_allocno_iterator ai;
4443
 
4444
  /* Setup updated costs.  */
4445
  FOR_EACH_ALLOCNO (a, ai)
4446
    {
4447
      ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
4448
      ALLOCNO_UPDATED_CLASS_COST (a) = ALLOCNO_CLASS_COST (a);
4449
    }
4450
  if (ira_conflicts_p)
4451
    color ();
4452
  else
4453
    fast_allocation ();
4454
}

powered by: WebSVN 2.1.0

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