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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 684 jeremybenn
/* IRA conflict builder.
2
   Copyright (C) 2006, 2007, 2008, 2009, 2010
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 "regs.h"
27
#include "rtl.h"
28
#include "tm_p.h"
29
#include "target.h"
30
#include "flags.h"
31
#include "hard-reg-set.h"
32
#include "basic-block.h"
33
#include "insn-config.h"
34
#include "recog.h"
35
#include "diagnostic-core.h"
36
#include "params.h"
37
#include "df.h"
38
#include "sparseset.h"
39
#include "ira-int.h"
40
#include "addresses.h"
41
 
42
/* This file contains code responsible for allocno conflict creation,
43
   allocno copy creation and allocno info accumulation on upper level
44
   regions.  */
45
 
46
/* ira_allocnos_num array of arrays of bits, recording whether two
47
   allocno's conflict (can't go in the same hardware register).
48
 
49
   Some arrays will be used as conflict bit vector of the
50
   corresponding allocnos see function build_object_conflicts.  */
51
static IRA_INT_TYPE **conflicts;
52
 
53
/* Macro to test a conflict of C1 and C2 in `conflicts'.  */
54
#define OBJECTS_CONFLICT_P(C1, C2)                                      \
55
  (OBJECT_MIN (C1) <= OBJECT_CONFLICT_ID (C2)                           \
56
   && OBJECT_CONFLICT_ID (C2) <= OBJECT_MAX (C1)                        \
57
   && TEST_MINMAX_SET_BIT (conflicts[OBJECT_CONFLICT_ID (C1)],          \
58
                           OBJECT_CONFLICT_ID (C2),                     \
59
                           OBJECT_MIN (C1), OBJECT_MAX (C1)))
60
 
61
 
62
/* Record a conflict between objects OBJ1 and OBJ2.  If necessary,
63
   canonicalize the conflict by recording it for lower-order subobjects
64
   of the corresponding allocnos. */
65
static void
66
record_object_conflict (ira_object_t obj1, ira_object_t obj2)
67
{
68
  ira_allocno_t a1 = OBJECT_ALLOCNO (obj1);
69
  ira_allocno_t a2 = OBJECT_ALLOCNO (obj2);
70
  int w1 = OBJECT_SUBWORD (obj1);
71
  int w2 = OBJECT_SUBWORD (obj2);
72
  int id1, id2;
73
 
74
  /* Canonicalize the conflict.  If two identically-numbered words
75
     conflict, always record this as a conflict between words 0.  That
76
     is the only information we need, and it is easier to test for if
77
     it is collected in each allocno's lowest-order object.  */
78
  if (w1 == w2 && w1 > 0)
79
    {
80
      obj1 = ALLOCNO_OBJECT (a1, 0);
81
      obj2 = ALLOCNO_OBJECT (a2, 0);
82
    }
83
  id1 = OBJECT_CONFLICT_ID (obj1);
84
  id2 = OBJECT_CONFLICT_ID (obj2);
85
 
86
  SET_MINMAX_SET_BIT (conflicts[id1], id2, OBJECT_MIN (obj1),
87
                      OBJECT_MAX (obj1));
88
  SET_MINMAX_SET_BIT (conflicts[id2], id1, OBJECT_MIN (obj2),
89
                      OBJECT_MAX (obj2));
90
}
91
 
92
/* Build allocno conflict table by processing allocno live ranges.
93
   Return true if the table was built.  The table is not built if it
94
   is too big.  */
95
static bool
96
build_conflict_bit_table (void)
97
{
98
  int i;
99
  unsigned int j;
100
  enum reg_class aclass;
101
  int object_set_words, allocated_words_num, conflict_bit_vec_words_num;
102
  live_range_t r;
103
  ira_allocno_t allocno;
104
  ira_allocno_iterator ai;
105
  sparseset objects_live;
106
  ira_object_t obj;
107
  ira_allocno_object_iterator aoi;
108
 
109
  allocated_words_num = 0;
110
  FOR_EACH_ALLOCNO (allocno, ai)
111
    FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
112
      {
113
        if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
114
          continue;
115
        conflict_bit_vec_words_num
116
          = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
117
             / IRA_INT_BITS);
118
        allocated_words_num += conflict_bit_vec_words_num;
119
        if ((unsigned HOST_WIDEST_INT) allocated_words_num * sizeof (IRA_INT_TYPE)
120
            > (unsigned HOST_WIDEST_INT) IRA_MAX_CONFLICT_TABLE_SIZE * 1024 * 1024)
121
          {
122
            if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
123
              fprintf
124
                (ira_dump_file,
125
                 "+++Conflict table will be too big(>%dMB) -- don't use it\n",
126
                 IRA_MAX_CONFLICT_TABLE_SIZE);
127
            return false;
128
          }
129
      }
130
 
131
  conflicts = (IRA_INT_TYPE **) ira_allocate (sizeof (IRA_INT_TYPE *)
132
                                              * ira_objects_num);
133
  allocated_words_num = 0;
134
  FOR_EACH_ALLOCNO (allocno, ai)
135
    FOR_EACH_ALLOCNO_OBJECT (allocno, obj, aoi)
136
      {
137
        int id = OBJECT_CONFLICT_ID (obj);
138
        if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
139
          {
140
            conflicts[id] = NULL;
141
            continue;
142
          }
143
        conflict_bit_vec_words_num
144
          = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
145
             / IRA_INT_BITS);
146
        allocated_words_num += conflict_bit_vec_words_num;
147
        conflicts[id]
148
          = (IRA_INT_TYPE *) ira_allocate (sizeof (IRA_INT_TYPE)
149
                                           * conflict_bit_vec_words_num);
150
        memset (conflicts[id], 0,
151
                sizeof (IRA_INT_TYPE) * conflict_bit_vec_words_num);
152
      }
153
 
154
  object_set_words = (ira_objects_num + IRA_INT_BITS - 1) / IRA_INT_BITS;
155
  if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
156
    fprintf
157
      (ira_dump_file,
158
       "+++Allocating %ld bytes for conflict table (uncompressed size %ld)\n",
159
       (long) allocated_words_num * sizeof (IRA_INT_TYPE),
160
       (long) object_set_words * ira_objects_num * sizeof (IRA_INT_TYPE));
161
 
162
  objects_live = sparseset_alloc (ira_objects_num);
163
  for (i = 0; i < ira_max_point; i++)
164
    {
165
      for (r = ira_start_point_ranges[i]; r != NULL; r = r->start_next)
166
        {
167
          ira_object_t obj = r->object;
168
          ira_allocno_t allocno = OBJECT_ALLOCNO (obj);
169
          int id = OBJECT_CONFLICT_ID (obj);
170
 
171
          gcc_assert (id < ira_objects_num);
172
 
173
          aclass = ALLOCNO_CLASS (allocno);
174
          sparseset_set_bit (objects_live, id);
175
          EXECUTE_IF_SET_IN_SPARSESET (objects_live, j)
176
            {
177
              ira_object_t live_obj = ira_object_id_map[j];
178
              ira_allocno_t live_a = OBJECT_ALLOCNO (live_obj);
179
              enum reg_class live_aclass = ALLOCNO_CLASS (live_a);
180
 
181
              if (ira_reg_classes_intersect_p[aclass][live_aclass]
182
                  /* Don't set up conflict for the allocno with itself.  */
183
                  && live_a != allocno)
184
                {
185
                  record_object_conflict (obj, live_obj);
186
                }
187
            }
188
        }
189
 
190
      for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
191
        sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (r->object));
192
    }
193
  sparseset_free (objects_live);
194
  return true;
195
}
196
 
197
/* Return true iff allocnos A1 and A2 cannot be allocated to the same
198
   register due to conflicts.  */
199
 
200
static bool
201
allocnos_conflict_for_copy_p (ira_allocno_t a1, ira_allocno_t a2)
202
{
203
  /* Due to the fact that we canonicalize conflicts (see
204
     record_object_conflict), we only need to test for conflicts of
205
     the lowest order words.  */
206
  ira_object_t obj1 = ALLOCNO_OBJECT (a1, 0);
207
  ira_object_t obj2 = ALLOCNO_OBJECT (a2, 0);
208
 
209
  return OBJECTS_CONFLICT_P (obj1, obj2);
210
}
211
 
212
/* Return TRUE if the operand constraint STR is commutative.  */
213
static bool
214
commutative_constraint_p (const char *str)
215
{
216
  int curr_alt, c;
217
  bool ignore_p;
218
 
219
  for (ignore_p = false, curr_alt = 0;;)
220
    {
221
      c = *str;
222
      if (c == '\0')
223
        break;
224
      str += CONSTRAINT_LEN (c, str);
225
      if (c == '#' || !recog_data.alternative_enabled_p[curr_alt])
226
        ignore_p = true;
227
      else if (c == ',')
228
        {
229
          curr_alt++;
230
          ignore_p = false;
231
        }
232
      else if (! ignore_p)
233
        {
234
          /* Usually `%' is the first constraint character but the
235
             documentation does not require this.  */
236
          if (c == '%')
237
            return true;
238
        }
239
    }
240
  return false;
241
}
242
 
243
/* Return the number of the operand which should be the same in any
244
   case as operand with number OP_NUM (or negative value if there is
245
   no such operand).  If USE_COMMUT_OP_P is TRUE, the function makes
246
   temporarily commutative operand exchange before this.  The function
247
   takes only really possible alternatives into consideration.  */
248
static int
249
get_dup_num (int op_num, bool use_commut_op_p)
250
{
251
  int curr_alt, c, original, dup;
252
  bool ignore_p, commut_op_used_p;
253
  const char *str;
254
  rtx op;
255
 
256
  if (op_num < 0 || recog_data.n_alternatives == 0)
257
    return -1;
258
  op = recog_data.operand[op_num];
259
  commut_op_used_p = true;
260
  if (use_commut_op_p)
261
    {
262
      if (commutative_constraint_p (recog_data.constraints[op_num]))
263
        op_num++;
264
      else if (op_num > 0 && commutative_constraint_p (recog_data.constraints
265
                                                       [op_num - 1]))
266
        op_num--;
267
      else
268
        commut_op_used_p = false;
269
    }
270
  str = recog_data.constraints[op_num];
271
  for (ignore_p = false, original = -1, curr_alt = 0;;)
272
    {
273
      c = *str;
274
      if (c == '\0')
275
        break;
276
      if (c == '#' || !recog_data.alternative_enabled_p[curr_alt])
277
        ignore_p = true;
278
      else if (c == ',')
279
        {
280
          curr_alt++;
281
          ignore_p = false;
282
        }
283
      else if (! ignore_p)
284
        switch (c)
285
          {
286
          case 'X':
287
            return -1;
288
 
289
          case 'm':
290
          case 'o':
291
            /* Accept a register which might be placed in memory.  */
292
            return -1;
293
            break;
294
 
295
          case 'V':
296
          case '<':
297
          case '>':
298
            break;
299
 
300
          case 'p':
301
            if (address_operand (op, VOIDmode))
302
              return -1;
303
            break;
304
 
305
          case 'g':
306
            return -1;
307
 
308
          case 'r':
309
          case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
310
          case 'h': case 'j': case 'k': case 'l':
311
          case 'q': case 't': case 'u':
312
          case 'v': case 'w': case 'x': case 'y': case 'z':
313
          case 'A': case 'B': case 'C': case 'D':
314
          case 'Q': case 'R': case 'S': case 'T': case 'U':
315
          case 'W': case 'Y': case 'Z':
316
            {
317
              enum reg_class cl;
318
 
319
              cl = (c == 'r'
320
                    ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, str));
321
              if (cl != NO_REGS)
322
                return -1;
323
#ifdef EXTRA_CONSTRAINT_STR
324
              else if (EXTRA_CONSTRAINT_STR (op, c, str))
325
                return -1;
326
#endif
327
              break;
328
            }
329
 
330
          case '0': case '1': case '2': case '3': case '4':
331
          case '5': case '6': case '7': case '8': case '9':
332
            if (original != -1 && original != c)
333
              return -1;
334
            original = c;
335
            break;
336
          }
337
      str += CONSTRAINT_LEN (c, str);
338
    }
339
  if (original == -1)
340
    return -1;
341
  dup = original - '0';
342
  if (use_commut_op_p)
343
    {
344
      if (commutative_constraint_p (recog_data.constraints[dup]))
345
        dup++;
346
      else if (dup > 0
347
               && commutative_constraint_p (recog_data.constraints[dup -1]))
348
        dup--;
349
      else if (! commut_op_used_p)
350
        return -1;
351
    }
352
  return dup;
353
}
354
 
355
/* Check that X is REG or SUBREG of REG.  */
356
#define REG_SUBREG_P(x)                                                 \
357
   (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))
358
 
359
/* Return X if X is a REG, otherwise it should be SUBREG of REG and
360
   the function returns the reg in this case.  *OFFSET will be set to
361
 
362
static rtx
363
go_through_subreg (rtx x, int *offset)
364
{
365
  rtx reg;
366
 
367
  *offset = 0;
368
  if (REG_P (x))
369
    return x;
370
  ira_assert (GET_CODE (x) == SUBREG);
371
  reg = SUBREG_REG (x);
372
  ira_assert (REG_P (reg));
373
  if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
374
    *offset = subreg_regno_offset (REGNO (reg), GET_MODE (reg),
375
                                   SUBREG_BYTE (x), GET_MODE (x));
376
  else
377
    *offset = (SUBREG_BYTE (x) / REGMODE_NATURAL_SIZE (GET_MODE (x)));
378
  return reg;
379
}
380
 
381
/* Process registers REG1 and REG2 in move INSN with execution
382
   frequency FREQ.  The function also processes the registers in a
383
   potential move insn (INSN == NULL in this case) with frequency
384
   FREQ.  The function can modify hard register costs of the
385
   corresponding allocnos or create a copy involving the corresponding
386
   allocnos.  The function does nothing if the both registers are hard
387
   registers.  When nothing is changed, the function returns
388
   FALSE.  */
389
static bool
390
process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
391
                       rtx insn, int freq)
392
{
393
  int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
394
  bool only_regs_p;
395
  ira_allocno_t a;
396
  reg_class_t rclass, aclass;
397
  enum machine_mode mode;
398
  ira_copy_t cp;
399
 
400
  gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
401
  only_regs_p = REG_P (reg1) && REG_P (reg2);
402
  reg1 = go_through_subreg (reg1, &offset1);
403
  reg2 = go_through_subreg (reg2, &offset2);
404
  /* Set up hard regno preferenced by allocno.  If allocno gets the
405
     hard regno the copy (or potential move) insn will be removed.  */
406
  if (HARD_REGISTER_P (reg1))
407
    {
408
      if (HARD_REGISTER_P (reg2))
409
        return false;
410
      allocno_preferenced_hard_regno = REGNO (reg1) + offset1 - offset2;
411
      a = ira_curr_regno_allocno_map[REGNO (reg2)];
412
    }
413
  else if (HARD_REGISTER_P (reg2))
414
    {
415
      allocno_preferenced_hard_regno = REGNO (reg2) + offset2 - offset1;
416
      a = ira_curr_regno_allocno_map[REGNO (reg1)];
417
    }
418
  else
419
    {
420
      ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
421
      ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
422
 
423
      if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2)
424
        {
425
          cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
426
                                     ira_curr_loop_tree_node);
427
          bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
428
          return true;
429
        }
430
      else
431
        return false;
432
    }
433
 
434
  if (! IN_RANGE (allocno_preferenced_hard_regno,
435
                  0, FIRST_PSEUDO_REGISTER - 1))
436
    /* Can not be tied.  */
437
    return false;
438
  rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno);
439
  mode = ALLOCNO_MODE (a);
440
  aclass = ALLOCNO_CLASS (a);
441
  if (only_regs_p && insn != NULL_RTX
442
      && reg_class_size[rclass] <= ira_reg_class_max_nregs [rclass][mode])
443
    /* It is already taken into account in ira-costs.c.  */
444
    return false;
445
  index = ira_class_hard_reg_index[aclass][allocno_preferenced_hard_regno];
446
  if (index < 0)
447
    /* Can not be tied.  It is not in the allocno class.  */
448
    return false;
449
  ira_init_register_move_cost_if_necessary (mode);
450
  if (HARD_REGISTER_P (reg1))
451
    cost = ira_register_move_cost[mode][aclass][rclass] * freq;
452
  else
453
    cost = ira_register_move_cost[mode][rclass][aclass] * freq;
454
  do
455
    {
456
      ira_allocate_and_set_costs
457
        (&ALLOCNO_HARD_REG_COSTS (a), aclass,
458
         ALLOCNO_CLASS_COST (a));
459
      ira_allocate_and_set_costs
460
        (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), aclass, 0);
461
      ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
462
      ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost;
463
      if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_CLASS_COST (a))
464
        ALLOCNO_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
465
      a = ira_parent_or_cap_allocno (a);
466
    }
467
  while (a != NULL);
468
  return true;
469
}
470
 
471
/* Process all of the output registers of the current insn which are
472
   not bound (BOUND_P) and the input register REG (its operand number
473
   OP_NUM) which dies in the insn as if there were a move insn between
474
   them with frequency FREQ.  */
475
static void
476
process_reg_shuffles (rtx reg, int op_num, int freq, bool *bound_p)
477
{
478
  int i;
479
  rtx another_reg;
480
 
481
  gcc_assert (REG_SUBREG_P (reg));
482
  for (i = 0; i < recog_data.n_operands; i++)
483
    {
484
      another_reg = recog_data.operand[i];
485
 
486
      if (!REG_SUBREG_P (another_reg) || op_num == i
487
          || recog_data.operand_type[i] != OP_OUT
488
          || bound_p[i])
489
        continue;
490
 
491
      process_regs_for_copy (reg, another_reg, false, NULL_RTX, freq);
492
    }
493
}
494
 
495
/* Process INSN and create allocno copies if necessary.  For example,
496
   it might be because INSN is a pseudo-register move or INSN is two
497
   operand insn.  */
498
static void
499
add_insn_allocno_copies (rtx insn)
500
{
501
  rtx set, operand, dup;
502
  const char *str;
503
  bool commut_p, bound_p[MAX_RECOG_OPERANDS];
504
  int i, j, n, freq;
505
 
506
  freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
507
  if (freq == 0)
508
    freq = 1;
509
  if ((set = single_set (insn)) != NULL_RTX
510
      && REG_SUBREG_P (SET_DEST (set)) && REG_SUBREG_P (SET_SRC (set))
511
      && ! side_effects_p (set)
512
      && find_reg_note (insn, REG_DEAD,
513
                        REG_P (SET_SRC (set))
514
                        ? SET_SRC (set)
515
                        : SUBREG_REG (SET_SRC (set))) != NULL_RTX)
516
    {
517
      process_regs_for_copy (SET_DEST (set), SET_SRC (set),
518
                             false, insn, freq);
519
      return;
520
    }
521
  /* Fast check of possibility of constraint or shuffle copies.  If
522
     there are no dead registers, there will be no such copies.  */
523
  if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
524
    return;
525
  extract_insn (insn);
526
  for (i = 0; i < recog_data.n_operands; i++)
527
    bound_p[i] = false;
528
  for (i = 0; i < recog_data.n_operands; i++)
529
    {
530
      operand = recog_data.operand[i];
531
      if (! REG_SUBREG_P (operand))
532
        continue;
533
      str = recog_data.constraints[i];
534
      while (*str == ' ' || *str == '\t')
535
        str++;
536
      for (j = 0, commut_p = false; j < 2; j++, commut_p = true)
537
        if ((n = get_dup_num (i, commut_p)) >= 0)
538
          {
539
            bound_p[n] = true;
540
            dup = recog_data.operand[n];
541
            if (REG_SUBREG_P (dup)
542
                && find_reg_note (insn, REG_DEAD,
543
                                  REG_P (operand)
544
                                  ? operand
545
                                  : SUBREG_REG (operand)) != NULL_RTX)
546
              process_regs_for_copy (operand, dup, true, NULL_RTX, freq);
547
          }
548
    }
549
  for (i = 0; i < recog_data.n_operands; i++)
550
    {
551
      operand = recog_data.operand[i];
552
      if (REG_SUBREG_P (operand)
553
          && find_reg_note (insn, REG_DEAD,
554
                            REG_P (operand)
555
                            ? operand : SUBREG_REG (operand)) != NULL_RTX)
556
        /* If an operand dies, prefer its hard register for the output
557
           operands by decreasing the hard register cost or creating
558
           the corresponding allocno copies.  The cost will not
559
           correspond to a real move insn cost, so make the frequency
560
           smaller.  */
561
        process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8, bound_p);
562
    }
563
}
564
 
565
/* Add copies originated from BB given by LOOP_TREE_NODE.  */
566
static void
567
add_copies (ira_loop_tree_node_t loop_tree_node)
568
{
569
  basic_block bb;
570
  rtx insn;
571
 
572
  bb = loop_tree_node->bb;
573
  if (bb == NULL)
574
    return;
575
  FOR_BB_INSNS (bb, insn)
576
    if (NONDEBUG_INSN_P (insn))
577
      add_insn_allocno_copies (insn);
578
}
579
 
580
/* Propagate copies the corresponding allocnos on upper loop tree
581
   level.  */
582
static void
583
propagate_copies (void)
584
{
585
  ira_copy_t cp;
586
  ira_copy_iterator ci;
587
  ira_allocno_t a1, a2, parent_a1, parent_a2;
588
 
589
  FOR_EACH_COPY (cp, ci)
590
    {
591
      a1 = cp->first;
592
      a2 = cp->second;
593
      if (ALLOCNO_LOOP_TREE_NODE (a1) == ira_loop_tree_root)
594
        continue;
595
      ira_assert ((ALLOCNO_LOOP_TREE_NODE (a2) != ira_loop_tree_root));
596
      parent_a1 = ira_parent_or_cap_allocno (a1);
597
      parent_a2 = ira_parent_or_cap_allocno (a2);
598
      ira_assert (parent_a1 != NULL && parent_a2 != NULL);
599
      if (! allocnos_conflict_for_copy_p (parent_a1, parent_a2))
600
        ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
601
                              cp->constraint_p, cp->insn, cp->loop_tree_node);
602
    }
603
}
604
 
605
/* Array used to collect all conflict allocnos for given allocno.  */
606
static ira_object_t *collected_conflict_objects;
607
 
608
/* Build conflict vectors or bit conflict vectors (whatever is more
609
   profitable) for object OBJ from the conflict table.  */
610
static void
611
build_object_conflicts (ira_object_t obj)
612
{
613
  int i, px, parent_num;
614
  ira_allocno_t parent_a, another_parent_a;
615
  ira_object_t parent_obj;
616
  ira_allocno_t a = OBJECT_ALLOCNO (obj);
617
  IRA_INT_TYPE *object_conflicts;
618
  minmax_set_iterator asi;
619
  int parent_min, parent_max ATTRIBUTE_UNUSED;
620
 
621
  object_conflicts = conflicts[OBJECT_CONFLICT_ID (obj)];
622
  px = 0;
623
  FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
624
                              OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
625
    {
626
      ira_object_t another_obj = ira_object_id_map[i];
627
      ira_allocno_t another_a = OBJECT_ALLOCNO (obj);
628
 
629
      ira_assert (ira_reg_classes_intersect_p
630
                  [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
631
      collected_conflict_objects[px++] = another_obj;
632
    }
633
  if (ira_conflict_vector_profitable_p (obj, px))
634
    {
635
      ira_object_t *vec;
636
      ira_allocate_conflict_vec (obj, px);
637
      vec = OBJECT_CONFLICT_VEC (obj);
638
      memcpy (vec, collected_conflict_objects, sizeof (ira_object_t) * px);
639
      vec[px] = NULL;
640
      OBJECT_NUM_CONFLICTS (obj) = px;
641
    }
642
  else
643
    {
644
      int conflict_bit_vec_words_num;
645
 
646
      OBJECT_CONFLICT_ARRAY (obj) = object_conflicts;
647
      if (OBJECT_MAX (obj) < OBJECT_MIN (obj))
648
        conflict_bit_vec_words_num = 0;
649
      else
650
        conflict_bit_vec_words_num
651
          = ((OBJECT_MAX (obj) - OBJECT_MIN (obj) + IRA_INT_BITS)
652
             / IRA_INT_BITS);
653
      OBJECT_CONFLICT_ARRAY_SIZE (obj)
654
        = conflict_bit_vec_words_num * sizeof (IRA_INT_TYPE);
655
    }
656
 
657
  parent_a = ira_parent_or_cap_allocno (a);
658
  if (parent_a == NULL)
659
    return;
660
  ira_assert (ALLOCNO_CLASS (a) == ALLOCNO_CLASS (parent_a));
661
  ira_assert (ALLOCNO_NUM_OBJECTS (a) == ALLOCNO_NUM_OBJECTS (parent_a));
662
  parent_obj = ALLOCNO_OBJECT (parent_a, OBJECT_SUBWORD (obj));
663
  parent_num = OBJECT_CONFLICT_ID (parent_obj);
664
  parent_min = OBJECT_MIN (parent_obj);
665
  parent_max = OBJECT_MAX (parent_obj);
666
  FOR_EACH_BIT_IN_MINMAX_SET (object_conflicts,
667
                              OBJECT_MIN (obj), OBJECT_MAX (obj), i, asi)
668
    {
669
      ira_object_t another_obj = ira_object_id_map[i];
670
      ira_allocno_t another_a = OBJECT_ALLOCNO (another_obj);
671
      int another_word = OBJECT_SUBWORD (another_obj);
672
 
673
      ira_assert (ira_reg_classes_intersect_p
674
                  [ALLOCNO_CLASS (a)][ALLOCNO_CLASS (another_a)]);
675
 
676
      another_parent_a = ira_parent_or_cap_allocno (another_a);
677
      if (another_parent_a == NULL)
678
        continue;
679
      ira_assert (ALLOCNO_NUM (another_parent_a) >= 0);
680
      ira_assert (ALLOCNO_CLASS (another_a)
681
                  == ALLOCNO_CLASS (another_parent_a));
682
      ira_assert (ALLOCNO_NUM_OBJECTS (another_a)
683
                  == ALLOCNO_NUM_OBJECTS (another_parent_a));
684
      SET_MINMAX_SET_BIT (conflicts[parent_num],
685
                          OBJECT_CONFLICT_ID (ALLOCNO_OBJECT (another_parent_a,
686
                                                              another_word)),
687
                          parent_min, parent_max);
688
    }
689
}
690
 
691
/* Build conflict vectors or bit conflict vectors (whatever is more
692
   profitable) of all allocnos from the conflict table.  */
693
static void
694
build_conflicts (void)
695
{
696
  int i;
697
  ira_allocno_t a, cap;
698
 
699
  collected_conflict_objects
700
    = (ira_object_t *) ira_allocate (sizeof (ira_object_t)
701
                                          * ira_objects_num);
702
  for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
703
    for (a = ira_regno_allocno_map[i];
704
         a != NULL;
705
         a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
706
      {
707
        int j, nregs = ALLOCNO_NUM_OBJECTS (a);
708
        for (j = 0; j < nregs; j++)
709
          {
710
            ira_object_t obj = ALLOCNO_OBJECT (a, j);
711
            build_object_conflicts (obj);
712
            for (cap = ALLOCNO_CAP (a); cap != NULL; cap = ALLOCNO_CAP (cap))
713
              {
714
                ira_object_t cap_obj = ALLOCNO_OBJECT (cap, j);
715
                gcc_assert (ALLOCNO_NUM_OBJECTS (cap) == ALLOCNO_NUM_OBJECTS (a));
716
                build_object_conflicts (cap_obj);
717
              }
718
          }
719
      }
720
  ira_free (collected_conflict_objects);
721
}
722
 
723
 
724
 
725
/* Print hard reg set SET with TITLE to FILE.  */
726
static void
727
print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
728
{
729
  int i, start;
730
 
731
  fputs (title, file);
732
  for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
733
    {
734
      if (TEST_HARD_REG_BIT (set, i))
735
        {
736
          if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
737
            start = i;
738
        }
739
      if (start >= 0
740
          && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
741
        {
742
          if (start == i - 1)
743
            fprintf (file, " %d", start);
744
          else if (start == i - 2)
745
            fprintf (file, " %d %d", start, start + 1);
746
          else
747
            fprintf (file, " %d-%d", start, i - 1);
748
          start = -1;
749
        }
750
    }
751
  putc ('\n', file);
752
}
753
 
754
static void
755
print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
756
{
757
  HARD_REG_SET conflicting_hard_regs;
758
  basic_block bb;
759
  int n, i;
760
 
761
  if (reg_p)
762
    fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
763
  else
764
    {
765
      fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
766
      if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
767
        fprintf (file, "b%d", bb->index);
768
      else
769
        fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
770
      putc (')', file);
771
    }
772
 
773
  fputs (" conflicts:", file);
774
  n = ALLOCNO_NUM_OBJECTS (a);
775
  for (i = 0; i < n; i++)
776
    {
777
      ira_object_t obj = ALLOCNO_OBJECT (a, i);
778
      ira_object_t conflict_obj;
779
      ira_object_conflict_iterator oci;
780
 
781
      if (OBJECT_CONFLICT_ARRAY (obj) == NULL)
782
        continue;
783
      if (n > 1)
784
        fprintf (file, "\n;;   subobject %d:", i);
785
      FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
786
        {
787
          ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj);
788
          if (reg_p)
789
            fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
790
          else
791
            {
792
              fprintf (file, " a%d(r%d", ALLOCNO_NUM (conflict_a),
793
                       ALLOCNO_REGNO (conflict_a));
794
              if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1)
795
                fprintf (file, ",w%d", OBJECT_SUBWORD (conflict_obj));
796
              if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
797
                fprintf (file, ",b%d", bb->index);
798
              else
799
                fprintf (file, ",l%d",
800
                         ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
801
              putc (')', file);
802
            }
803
        }
804
      COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
805
      AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
806
      AND_HARD_REG_SET (conflicting_hard_regs,
807
                        reg_class_contents[ALLOCNO_CLASS (a)]);
808
      print_hard_reg_set (file, "\n;;     total conflict hard regs:",
809
                          conflicting_hard_regs);
810
 
811
      COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_CONFLICT_HARD_REGS (obj));
812
      AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
813
      AND_HARD_REG_SET (conflicting_hard_regs,
814
                        reg_class_contents[ALLOCNO_CLASS (a)]);
815
      print_hard_reg_set (file, ";;     conflict hard regs:",
816
                          conflicting_hard_regs);
817
      putc ('\n', file);
818
    }
819
 
820
}
821
 
822
/* Print information about allocno or only regno (if REG_P) conflicts
823
   to FILE.  */
824
static void
825
print_conflicts (FILE *file, bool reg_p)
826
{
827
  ira_allocno_t a;
828
  ira_allocno_iterator ai;
829
 
830
  FOR_EACH_ALLOCNO (a, ai)
831
    print_allocno_conflicts (file, reg_p, a);
832
}
833
 
834
/* Print information about allocno or only regno (if REG_P) conflicts
835
   to stderr.  */
836
void
837
ira_debug_conflicts (bool reg_p)
838
{
839
  print_conflicts (stderr, reg_p);
840
}
841
 
842
 
843
 
844
/* Entry function which builds allocno conflicts and allocno copies
845
   and accumulate some allocno info on upper level regions.  */
846
void
847
ira_build_conflicts (void)
848
{
849
  enum reg_class base;
850
  ira_allocno_t a;
851
  ira_allocno_iterator ai;
852
  HARD_REG_SET temp_hard_reg_set;
853
 
854
  if (ira_conflicts_p)
855
    {
856
      ira_conflicts_p = build_conflict_bit_table ();
857
      if (ira_conflicts_p)
858
        {
859
          ira_object_t obj;
860
          ira_object_iterator oi;
861
 
862
          build_conflicts ();
863
          ira_traverse_loop_tree (true, ira_loop_tree_root, NULL, add_copies);
864
          /* We need finished conflict table for the subsequent call.  */
865
          if (flag_ira_region == IRA_REGION_ALL
866
              || flag_ira_region == IRA_REGION_MIXED)
867
            propagate_copies ();
868
 
869
          /* Now we can free memory for the conflict table (see function
870
             build_object_conflicts for details).  */
871
          FOR_EACH_OBJECT (obj, oi)
872
            {
873
              if (OBJECT_CONFLICT_ARRAY (obj) != conflicts[OBJECT_CONFLICT_ID (obj)])
874
                ira_free (conflicts[OBJECT_CONFLICT_ID (obj)]);
875
            }
876
          ira_free (conflicts);
877
        }
878
    }
879
  base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH);
880
  if (! targetm.class_likely_spilled_p (base))
881
    CLEAR_HARD_REG_SET (temp_hard_reg_set);
882
  else
883
    {
884
      COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[base]);
885
      AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs);
886
      AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set);
887
    }
888
  FOR_EACH_ALLOCNO (a, ai)
889
    {
890
      int i, n = ALLOCNO_NUM_OBJECTS (a);
891
 
892
      for (i = 0; i < n; i++)
893
        {
894
          ira_object_t obj = ALLOCNO_OBJECT (a, i);
895
          reg_attrs *attrs = REG_ATTRS (regno_reg_rtx [ALLOCNO_REGNO (a)]);
896
          tree decl;
897
 
898
          if ((! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
899
              /* For debugging purposes don't put user defined variables in
900
                 callee-clobbered registers.  */
901
              || (optimize == 0
902
                  && attrs != NULL
903
                  && (decl = attrs->decl) != NULL
904
                  && VAR_OR_FUNCTION_DECL_P (decl)
905
                  && ! DECL_ARTIFICIAL (decl)))
906
            {
907
              IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
908
                                call_used_reg_set);
909
              IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
910
                                call_used_reg_set);
911
            }
912
          else if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
913
            {
914
              IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
915
                                no_caller_save_reg_set);
916
              IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
917
                                temp_hard_reg_set);
918
              IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
919
                                no_caller_save_reg_set);
920
              IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
921
                                temp_hard_reg_set);
922
            }
923
 
924
          if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
925
            {
926
              int regno;
927
 
928
              /* Allocnos bigger than the saved part of call saved
929
                 regs must conflict with them.  */
930
              for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
931
                if (!TEST_HARD_REG_BIT (call_used_reg_set, regno)
932
                    && HARD_REGNO_CALL_PART_CLOBBERED (regno,
933
                                                       obj->allocno->mode))
934
                  {
935
                    SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
936
                    SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
937
                                      regno);
938
                  }
939
            }
940
        }
941
    }
942
  if (optimize && ira_conflicts_p
943
      && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
944
    print_conflicts (ira_dump_file, false);
945
}

powered by: WebSVN 2.1.0

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