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