2008-03-03 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / ira-conflicts.c
blob383fea93306537a526ad2077f40d394237eba6f9
1 /* IRA conflict builder.
2 Copyright (C) 2006, 2007, 2008
3 Free Software Foundation, Inc.
4 Contributed by Vladimir Makarov <vmakarov@redhat.com>.
6 This file is part of GCC.
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 2, or (at your option) any later
11 version.
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.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "regs.h"
28 #include "rtl.h"
29 #include "tm_p.h"
30 #include "target.h"
31 #include "flags.h"
32 #include "hard-reg-set.h"
33 #include "basic-block.h"
34 #include "insn-config.h"
35 #include "recog.h"
36 #include "toplev.h"
37 #include "params.h"
38 #include "df.h"
39 #include "ira-int.h"
41 /* The file contains code is analogous to one in global but the code
42 works on the allocno basis. */
44 static void build_conflict_bit_table (void);
45 static void mirror_conflicts (void);
46 static int commutative_constraint_p (const char *);
47 static int get_dup_num (int, int);
48 static rtx get_dup (int, int);
49 static void add_insn_allocno_copies (rtx);
50 static void add_copies (loop_tree_node_t);
51 static void propagate_allocno_info (allocno_t);
52 static void propagate_info (void);
53 static void remove_conflict_allocno_copies (void);
54 static void build_allocno_conflict_vects (void);
55 static void propagate_modified_regnos (loop_tree_node_t);
56 static void print_hard_reg_set (FILE *, const char *, HARD_REG_SET);
57 static void print_conflicts (FILE *, int);
59 /* Set, clear or test bit number I in `allocnos_live',
60 a bit vector indexed by allocno number. */
61 #define SET_ALLOCNO_LIVE(I) SET_ALLOCNO_SET_BIT (allocnos_live, I)
62 #define CLEAR_ALLOCNO_LIVE(I) CLEAR_ALLOCNO_SET_BIT (allocnos_live, I)
63 #define TEST_ALLOCNO_LIVE(I) TEST_ALLOCNO_SET_BIT (allocnos_live, I)
65 /* allocnos_num by allocnos_num array of bits, recording whether two
66 allocno's conflict (can't go in the same hardware register).
68 `conflicts' is symmetric after the call to mirror_conflicts. */
69 static INT_TYPE *conflicts;
71 /* Two macros to test 1 in an element of `conflicts'. */
72 #define CONFLICT_P(I, J) \
73 (conflicts[(I) * allocno_set_words + (unsigned) (J) / INT_BITS] \
74 & ((INT_TYPE) 1 << ((unsigned) (J) % INT_BITS)))
76 /* Bit mask for allocnos live at current point in the scan. */
77 static INT_TYPE *allocnos_live;
81 /* The function builds allocno conflict table by processing allocno
82 live ranges. */
83 static void
84 build_conflict_bit_table (void)
86 int i, j, pn, pn_prod;
87 allocno_live_range_t r;
89 allocno_set_words = (allocnos_num + INT_BITS - 1) / INT_BITS;
90 allocnos_live = ira_allocate (sizeof (INT_TYPE) * allocno_set_words);
91 memset (allocnos_live, 0, sizeof (INT_TYPE) * allocno_set_words);
92 conflicts = ira_allocate (sizeof (INT_TYPE)
93 * allocnos_num * allocno_set_words);
94 memset (conflicts, 0, sizeof (INT_TYPE) * allocnos_num * allocno_set_words);
95 for (i = 0; i < max_point; i++)
97 for (r = start_point_ranges [i]; r != NULL; r = r->start_next)
99 pn = ALLOCNO_NUM (r->allocno);
100 SET_ALLOCNO_LIVE (pn);
101 pn_prod = pn * allocno_set_words;
102 for (j = allocno_set_words - 1; j >= 0; j--)
103 conflicts [pn_prod + j] |= allocnos_live [j];
104 /* Don't set up conflict for the allocno with itself. */
105 CLEAR_ALLOCNO_SET_BIT (conflicts + pn_prod, pn);
108 for (r = finish_point_ranges [i]; r != NULL; r = r->finish_next)
109 CLEAR_ALLOCNO_LIVE (ALLOCNO_NUM (r->allocno));
113 /* If CONFLICT_P (i, j) is TRUE, make sure CONFLICT_P (j, i) is also TRUE. */
114 static void
115 mirror_conflicts (void)
117 int i, j;
118 unsigned INT_TYPE mask;
119 int rw = allocno_set_words;
120 int rwb = rw * INT_BITS;
121 INT_TYPE *p = conflicts;
122 INT_TYPE *q0 = conflicts;
123 INT_TYPE *q1, *q2;
125 for (i = allocnos_num - 1, mask = 1; i >= 0; i--, mask <<= 1)
127 if (! mask)
129 mask = 1;
130 q0++;
132 for (j = allocno_set_words - 1, q1 = q0; j >= 0; j--, q1 += rwb)
134 unsigned INT_TYPE word;
136 for (word = (unsigned INT_TYPE) *p++, q2 = q1;
137 word;
138 word >>= 1, q2 += rw)
140 if (word & 1)
141 *q2 |= mask;
149 /* The function returns nonzero, if the operand constraint STR is
150 commutative. */
151 static int
152 commutative_constraint_p (const char *str)
154 int ignore_p;
155 int c;
157 for (ignore_p = FALSE;;)
159 c = *str;
160 if (c == '\0')
161 break;
162 str += CONSTRAINT_LEN (c, str);
163 if (c == '#')
164 ignore_p = TRUE;
165 else if (c == ',')
166 ignore_p = FALSE;
167 else if (! ignore_p)
169 if (c == '%')
170 return TRUE;
173 return FALSE;
176 /* The function returns number of the operand which should be the same
177 in any case as operand with number OP_NUM. If USE_COMMUT_OP_P is
178 non-zero, the function makes temporarily commutative operand
179 exchange before this. The function takes only really possible
180 alternatives into consideration. */
181 static int
182 get_dup_num (int op_num, int use_commut_op_p)
184 int curr_alt, c, original, dup;
185 int ignore_p, commut_op_used_p;
186 const char *str;
187 rtx op, equiv_const = NULL_RTX;
189 if (op_num < 0 || recog_data.n_alternatives == 0)
190 return -1;
191 op = recog_data.operand [op_num];
192 ira_assert (REG_P (op));
193 commut_op_used_p = TRUE;
194 if (use_commut_op_p)
196 if (commutative_constraint_p (recog_data.constraints [op_num]))
197 op_num++;
198 else if (op_num > 0 && commutative_constraint_p (recog_data.constraints
199 [op_num - 1]))
200 op_num--;
201 else
202 commut_op_used_p = FALSE;
204 str = recog_data.constraints [op_num];
205 for (ignore_p = FALSE, original = -1, curr_alt = 0;;)
207 c = *str;
208 if (c == '\0')
209 break;
210 if (c == '#')
211 ignore_p = TRUE;
212 else if (c == ',')
214 curr_alt++;
215 ignore_p = FALSE;
217 else if (! ignore_p)
218 switch (c)
220 case 'X':
221 return -1;
223 case 'i':
224 if (equiv_const != NULL_RTX && CONSTANT_P (equiv_const))
225 return -1;
226 break;
228 case 'n':
229 if (equiv_const != NULL_RTX
230 && (GET_CODE (equiv_const) == CONST_INT
231 || (GET_CODE (equiv_const) == CONST_DOUBLE
232 && GET_MODE (equiv_const) == VOIDmode)))
233 return -1;
234 break;
236 case 's':
237 if (equiv_const != NULL_RTX
238 && CONSTANT_P (equiv_const)
239 && GET_CODE (equiv_const) != CONST_INT
240 && (GET_CODE (equiv_const) != CONST_DOUBLE
241 || GET_MODE (equiv_const) != VOIDmode))
242 return -1;
243 break;
245 case 'I':
246 case 'J':
247 case 'K':
248 case 'L':
249 case 'M':
250 case 'N':
251 case 'O':
252 case 'P':
253 if ((equiv_const != NULL_RTX
254 && GET_CODE (equiv_const) == CONST_INT
255 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (equiv_const),
256 c, str)))
257 return -1;
258 break;
260 case 'E':
261 case 'F':
262 if (equiv_const != NULL_RTX
263 && (GET_CODE (equiv_const) == CONST_DOUBLE
264 || (GET_CODE (equiv_const) == CONST_VECTOR
265 && (GET_MODE_CLASS (GET_MODE (equiv_const))
266 == MODE_VECTOR_FLOAT))))
267 return -1;
268 break;
270 case 'G':
271 case 'H':
272 if (equiv_const != NULL_RTX
273 && GET_CODE (equiv_const) == CONST_DOUBLE
274 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (equiv_const, c, str))
275 return -1;
276 break;
278 case 'm':
279 case 'o':
280 /* Accept a register which might be placed in memory. */
281 return -1;
282 break;
284 case 'V':
285 case '<':
286 case '>':
287 break;
289 case 'p':
290 GO_IF_LEGITIMATE_ADDRESS (VOIDmode, op, win_p);
291 break;
293 win_p:
294 return -1;
296 case 'g':
297 return -1;
299 case 'r':
300 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
301 case 'h': case 'j': case 'k': case 'l':
302 case 'q': case 't': case 'u':
303 case 'v': case 'w': case 'x': case 'y': case 'z':
304 case 'A': case 'B': case 'C': case 'D':
305 case 'Q': case 'R': case 'S': case 'T': case 'U':
306 case 'W': case 'Y': case 'Z':
308 enum reg_class cl;
310 cl = (c == 'r'
311 ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, str));
312 if (cl != NO_REGS)
313 return -1;
314 #ifdef EXTRA_CONSTRAINT_STR
315 else if (EXTRA_CONSTRAINT_STR (op, c, str))
316 return -1;
317 #endif
318 break;
321 case '0': case '1': case '2': case '3': case '4':
322 case '5': case '6': case '7': case '8': case '9':
323 if (original != -1 && original != c)
324 return -1;
325 original = c;
326 break;
328 str += CONSTRAINT_LEN (c, str);
330 if (original == -1)
331 return -1;
332 dup = original - '0';
333 if (use_commut_op_p)
335 if (commutative_constraint_p (recog_data.constraints [dup]))
336 dup++;
337 else if (dup > 0
338 && commutative_constraint_p (recog_data.constraints [dup -1]))
339 dup--;
340 else if (! commut_op_used_p)
341 return -1;
343 return dup;
346 /* The function returns operand which should be in any case the same
347 as operand with number OP_NUM. If USE_COMMUT_OP_P is non-zero, the
348 function makes temporarily commutative operand exchange before
349 this. */
350 static rtx
351 get_dup (int op_num, int use_commut_op_p)
353 int n = get_dup_num (op_num, use_commut_op_p);
355 if (n < 0)
356 return NULL_RTX;
357 else
358 return recog_data.operand [n];
361 /* The function processes INSN and create allocno copies if
362 necessary. For example, it might be because INSN is a
363 pseudo-register move or INSN is two operand insn. */
364 static void
365 add_insn_allocno_copies (rtx insn)
367 rtx set, operand, dup;
368 const char *str;
369 int commut_p, bound_p;
370 int i, j, freq, hard_regno, cost, index, hard_regs_num;
371 copy_t cp;
372 allocno_t a;
373 enum reg_class class, cover_class;
374 enum machine_mode mode;
376 freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
377 if (freq == 0)
378 freq = 1;
379 if ((set = single_set (insn)) != NULL_RTX
380 && REG_P (SET_DEST (set)) && REG_P (SET_SRC (set))
381 && ! side_effects_p (set)
382 && find_reg_note (insn, REG_DEAD, SET_SRC (set)) != NULL_RTX
383 && find_reg_note (insn, REG_RETVAL, NULL_RTX) == NULL_RTX)
385 if (HARD_REGISTER_P (SET_SRC (set)) || HARD_REGISTER_P (SET_DEST (set)))
387 if (HARD_REGISTER_P (SET_DEST (set)))
389 if (HARD_REGISTER_P (SET_SRC (set)))
390 return;
391 hard_regno = REGNO (SET_DEST (set));
392 a = ira_curr_regno_allocno_map [REGNO (SET_SRC (set))];
394 else
396 hard_regno = REGNO (SET_SRC (set));
397 a = ira_curr_regno_allocno_map [REGNO (SET_DEST (set))];
399 class = REGNO_REG_CLASS (hard_regno);
400 mode = ALLOCNO_MODE (a);
401 cover_class = ALLOCNO_COVER_CLASS (a);
402 if (! class_subset_p [class] [cover_class])
403 return;
404 if (reg_class_size [class]
405 <= (unsigned) CLASS_MAX_NREGS (class, mode))
406 /* It is already taken into account in ira-costs.c. */
407 return;
408 index = class_hard_reg_index [cover_class] [hard_regno];
409 if (index < 0)
410 return;
411 if (HARD_REGISTER_P (SET_DEST (set)))
412 cost = register_move_cost [mode] [cover_class] [class] * freq;
413 else
414 cost = register_move_cost [mode] [class] [cover_class] * freq;
415 hard_regs_num = class_hard_regs_num [cover_class];
416 allocate_and_set_costs
417 (&ALLOCNO_HARD_REG_COSTS (a), hard_regs_num,
418 ALLOCNO_COVER_CLASS_COST (a));
419 allocate_and_set_costs
420 (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), hard_regs_num, 0);
421 ALLOCNO_HARD_REG_COSTS (a) [index] -= cost;
422 ALLOCNO_CONFLICT_HARD_REG_COSTS (a) [index] -= cost;
424 else
426 cp = add_allocno_copy
427 (ira_curr_regno_allocno_map [REGNO (SET_DEST (set))],
428 ira_curr_regno_allocno_map [REGNO (SET_SRC (set))],
429 freq, insn, ira_curr_loop_tree_node);
430 bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
433 else
435 extract_insn (insn);
436 for (i = 0; i < recog_data.n_operands; i++)
438 operand = recog_data.operand [i];
439 if (REG_P (operand)
440 && find_reg_note (insn, REG_DEAD, operand) != NULL_RTX)
442 str = recog_data.constraints [i];
443 while (*str == ' ' && *str == '\t')
444 str++;
445 bound_p = FALSE;
446 for (j = 0, commut_p = FALSE; j < 2; j++, commut_p = TRUE)
447 if ((dup = get_dup (i, commut_p)) != NULL_RTX
448 && REG_P (dup) && GET_MODE (operand) == GET_MODE (dup))
450 if (HARD_REGISTER_NUM_P (REGNO (operand))
451 || HARD_REGISTER_NUM_P (REGNO (dup)))
453 if (HARD_REGISTER_P (operand))
455 if (HARD_REGISTER_P (dup))
456 continue;
457 hard_regno = REGNO (operand);
458 a = ira_curr_regno_allocno_map [REGNO (dup)];
460 else
462 hard_regno = REGNO (dup);
463 a = ira_curr_regno_allocno_map [REGNO (operand)];
465 class = REGNO_REG_CLASS (hard_regno);
466 mode = ALLOCNO_MODE (a);
467 cover_class = ALLOCNO_COVER_CLASS (a);
468 if (! class_subset_p [class] [cover_class])
469 continue;
470 index
471 = class_hard_reg_index [cover_class] [hard_regno];
472 if (index < 0)
473 continue;
474 if (HARD_REGISTER_P (operand))
475 cost
476 = register_move_cost [mode] [cover_class] [class];
477 else
478 cost
479 = register_move_cost [mode] [class] [cover_class];
480 cost *= freq;
481 hard_regs_num = class_hard_regs_num [cover_class];
482 allocate_and_set_costs
483 (&ALLOCNO_HARD_REG_COSTS (a), hard_regs_num,
484 ALLOCNO_COVER_CLASS_COST (a));
485 allocate_and_set_costs
486 (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a),
487 hard_regs_num, 0);
488 ALLOCNO_HARD_REG_COSTS (a) [index] -= cost;
489 ALLOCNO_CONFLICT_HARD_REG_COSTS (a) [index] -= cost;
490 bound_p = TRUE;
492 else
494 bound_p = TRUE;
495 cp = add_allocno_copy
496 (ira_curr_regno_allocno_map [REGNO (dup)],
497 ira_curr_regno_allocno_map [REGNO (operand)],
498 freq, NULL_RTX, ira_curr_loop_tree_node);
499 bitmap_set_bit
500 (ira_curr_loop_tree_node->local_copies, cp->num);
503 if (bound_p)
504 continue;
505 /* If an operand dies, prefer its hard register for the
506 output operands by decreasing the hard register cost
507 or creating the corresponding allocno copies. */
508 for (j = 0; j < recog_data.n_operands; j++)
510 dup = recog_data.operand [j];
512 if (i == j || recog_data.operand_type [j] != OP_OUT
513 || !REG_P (dup))
514 continue;
516 if (HARD_REGISTER_NUM_P (REGNO (operand))
517 || HARD_REGISTER_NUM_P (REGNO (dup)))
519 if (HARD_REGISTER_P (operand))
521 if (HARD_REGISTER_P (dup))
522 continue;
523 hard_regno = REGNO (operand);
524 a = ira_curr_regno_allocno_map [REGNO (dup)];
526 else
528 hard_regno = REGNO (dup);
529 a = ira_curr_regno_allocno_map [REGNO (operand)];
531 class = REGNO_REG_CLASS (hard_regno);
532 mode = ALLOCNO_MODE (a);
533 cover_class = ALLOCNO_COVER_CLASS (a);
534 if (! class_subset_p [class] [cover_class])
535 continue;
536 index
537 = class_hard_reg_index [cover_class] [hard_regno];
538 if (index < 0)
539 continue;
540 if (HARD_REGISTER_P (operand))
541 cost
542 = register_move_cost [mode] [cover_class] [class];
543 else
544 cost
545 = register_move_cost [mode] [class] [cover_class];
546 cost *= (freq < 8 ? 1 : freq / 8);
547 hard_regs_num = class_hard_regs_num [cover_class];
548 allocate_and_set_costs
549 (&ALLOCNO_HARD_REG_COSTS (a), hard_regs_num,
550 ALLOCNO_COVER_CLASS_COST (a));
551 allocate_and_set_costs
552 (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a),
553 hard_regs_num, 0);
554 ALLOCNO_HARD_REG_COSTS (a) [index] -= cost;
555 ALLOCNO_CONFLICT_HARD_REG_COSTS (a) [index] -= cost;
557 else
559 cp = add_allocno_copy
560 (ira_curr_regno_allocno_map [REGNO (dup)],
561 ira_curr_regno_allocno_map [REGNO (operand)],
562 (freq < 8 ? 1 : freq / 8), NULL_RTX,
563 ira_curr_loop_tree_node);
564 bitmap_set_bit
565 (ira_curr_loop_tree_node->local_copies, cp->num);
573 /* The function adds copies originated from bb given by
574 LOOP_TREE_NODE. */
575 static void
576 add_copies (loop_tree_node_t loop_tree_node)
578 basic_block bb;
579 rtx insn;
581 bb = loop_tree_node->bb;
582 if (bb == NULL)
583 return;
584 FOR_BB_INSNS (bb, insn)
585 if (INSN_P (insn))
586 add_insn_allocno_copies (insn);
589 /* The function propagates info about allocno A to the corresponding
590 allocno on upper loop tree level. So allocnos on upper levels
591 accumulate information about the corresponding allocnos in nested
592 loops. */
593 static void
594 propagate_allocno_info (allocno_t a)
596 int regno;
597 allocno_t father_a, another_a, another_father_a;
598 loop_tree_node_t father;
599 copy_t cp, next_cp;
601 regno = ALLOCNO_REGNO (a);
602 if ((father = ALLOCNO_LOOP_TREE_NODE (a)->father) != NULL
603 && (father_a = father->regno_allocno_map [regno]) != NULL)
605 ALLOCNO_CALL_FREQ (father_a) += ALLOCNO_CALL_FREQ (a);
606 #ifdef STACK_REGS
607 if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
608 ALLOCNO_TOTAL_NO_STACK_REG_P (father_a) = TRUE;
609 #endif
610 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (father_a),
611 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
612 if (ALLOCNO_CALLS_CROSSED_START (father_a) < 0
613 || (ALLOCNO_CALLS_CROSSED_START (a) >= 0
614 && (ALLOCNO_CALLS_CROSSED_START (father_a)
615 > ALLOCNO_CALLS_CROSSED_START (a))))
616 ALLOCNO_CALLS_CROSSED_START (father_a)
617 = ALLOCNO_CALLS_CROSSED_START (a);
618 ALLOCNO_CALLS_CROSSED_NUM (father_a) += ALLOCNO_CALLS_CROSSED_NUM (a);
619 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
621 if (cp->first == a)
623 next_cp = cp->next_first_allocno_copy;
624 another_a = cp->second;
626 else if (cp->second == a)
628 next_cp = cp->next_second_allocno_copy;
629 another_a = cp->first;
631 else
632 gcc_unreachable ();
633 if ((another_father_a = (father->regno_allocno_map
634 [ALLOCNO_REGNO (another_a)])) != NULL)
635 add_allocno_copy (father_a, another_father_a, cp->freq,
636 cp->insn, cp->loop_tree_node);
641 /* The function propagates info about allocnos to the corresponding
642 allocnos on upper loop tree level. */
643 static void
644 propagate_info (void)
646 int i;
647 allocno_t a;
649 for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
650 for (a = regno_allocno_map [i];
651 a != NULL;
652 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
653 propagate_allocno_info (a);
656 /* The function returns TRUE if live ranges of allocnos A1 and A2
657 intersect. It checks intersection of the corresponding live ranges
658 for this. */
660 allocno_live_ranges_intersect_p (allocno_t a1, allocno_t a2)
662 allocno_live_range_t r1, r2;
664 if (a1 == a2)
665 return FALSE;
666 if (ALLOCNO_REG (a1) != NULL && ALLOCNO_REG (a2) != NULL
667 && (ORIGINAL_REGNO (ALLOCNO_REG (a1))
668 == ORIGINAL_REGNO (ALLOCNO_REG (a2))))
669 return FALSE;
670 for (r1 = ALLOCNO_LIVE_RANGES (a1), r2 = ALLOCNO_LIVE_RANGES (a2);
671 r1 != NULL && r2 != NULL;)
673 if (r1->start > r2->finish)
674 r1 = r1->next;
675 else if (r2->start > r1->finish)
676 r2 = r2->next;
677 else
678 return TRUE;
680 return FALSE;
683 /* The function returns TRUE if live ranges of pseudo-registers REGNO1
684 and REGNO2 intersect. It should be used when there is only one
685 region. */
687 pseudo_live_ranges_intersect_p (int regno1, int regno2)
689 allocno_t a1, a2;
691 ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
692 && regno2 >= FIRST_PSEUDO_REGISTER);
693 /* Reg info caclulated by dataflow infrastructure can be different
694 from one calculated by regclass. */
695 if ((a1 = ira_loop_tree_root->regno_allocno_map [regno1]) == NULL
696 || (a2 = ira_loop_tree_root->regno_allocno_map [regno2]) == NULL)
697 return FALSE;
698 return allocno_live_ranges_intersect_p (a1, a2);
701 /* Remove copies involving conflicting allocnos. */
702 static void
703 remove_conflict_allocno_copies (void)
705 int i;
706 allocno_t a;
707 copy_t cp, next_cp;
708 varray_type conflict_allocno_copy_varray;
710 VARRAY_GENERIC_PTR_NOGC_INIT (conflict_allocno_copy_varray, get_max_uid (),
711 "copies of conflicting allocnos");
712 for (i = 0; i < allocnos_num; i++)
714 a = allocnos [i];
715 for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
716 if (cp->first == a)
717 next_cp = cp->next_first_allocno_copy;
718 else
720 next_cp = cp->next_second_allocno_copy;
721 VARRAY_PUSH_GENERIC_PTR (conflict_allocno_copy_varray, cp);
724 for (i = VARRAY_ACTIVE_SIZE (conflict_allocno_copy_varray) - 1; i >= 0; i--)
726 cp = VARRAY_GENERIC_PTR (conflict_allocno_copy_varray, i);
727 if (CONFLICT_P (ALLOCNO_NUM (cp->first), ALLOCNO_NUM (cp->second)))
728 remove_allocno_copy_from_list (cp);
730 VARRAY_FREE (conflict_allocno_copy_varray);
733 /* The function builds conflict vectors of all allocnos from the
734 conflict table. */
735 static void
736 build_allocno_conflict_vects (void)
738 int i, j, level, px, another_father_pn, conflict_allocnos_num;
739 int *level_init_p;
740 enum reg_class cover_class;
741 loop_tree_node_t father;
742 allocno_t a, father_a, another_a, another_father_a, *conflict_allocnos, *vec;
743 INT_TYPE *accumulated_conflicts, *allocno_conflicts, *propagate_conflicts;
745 conflict_allocnos = ira_allocate (sizeof (allocno_t) * allocnos_num);
746 level_init_p = ira_allocate (ira_loop_tree_height * sizeof (int));
747 memset (level_init_p, 0, ira_loop_tree_height * sizeof (int));
748 accumulated_conflicts
749 = ira_allocate (ira_loop_tree_height
750 * allocno_set_words * sizeof (INT_TYPE));
751 for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
752 for (a = regno_allocno_map [i];
753 a != NULL;
754 a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
756 cover_class = ALLOCNO_COVER_CLASS (a);
757 level = ALLOCNO_LOOP_TREE_NODE (a)->level;
758 allocno_conflicts = conflicts + ALLOCNO_NUM (a) * allocno_set_words;
759 px = 0;
760 EXECUTE_IF_SET_IN_ALLOCNO_SET (allocno_conflicts, j,
762 another_a = allocnos [j];
763 if (cover_class == ALLOCNO_COVER_CLASS (another_a))
764 conflict_allocnos [px++] = another_a;
766 conflict_allocnos_num = px;
767 if (! level_init_p [level])
768 propagate_conflicts = allocno_conflicts;
769 else
771 propagate_conflicts
772 = accumulated_conflicts + level * allocno_set_words;
773 EXECUTE_IF_SET_IN_ALLOCNO_SET (propagate_conflicts, j,
775 another_a = allocnos [j];
776 ira_assert (cover_class == ALLOCNO_COVER_CLASS (another_a));
777 if (! TEST_ALLOCNO_SET_BIT (allocno_conflicts, j))
778 conflict_allocnos [px++] = another_a;
780 for (j = 0; j < allocno_set_words; j++)
781 propagate_conflicts [j] |= allocno_conflicts [j];
783 allocate_allocno_conflicts (a, px);
784 vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
785 memcpy (vec, conflict_allocnos, sizeof (allocno_t) * px);
786 vec [px] = NULL;
787 ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = conflict_allocnos_num;
788 ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (a) = px;
789 level_init_p [level] = FALSE;
790 if ((father = ALLOCNO_LOOP_TREE_NODE (a)->father) == NULL
791 || (father_a = father->regno_allocno_map [i]) == NULL)
792 continue;
793 level--;
794 ira_assert (level == ALLOCNO_LOOP_TREE_NODE (father_a)->level
795 && cover_class == ALLOCNO_COVER_CLASS (father_a));
796 if (! level_init_p [level])
798 level_init_p [level] = TRUE;
799 memset (accumulated_conflicts + level * allocno_set_words, 0,
800 allocno_set_words * sizeof (INT_TYPE));
802 EXECUTE_IF_SET_IN_ALLOCNO_SET (propagate_conflicts, j,
804 another_a = allocnos [j];
805 if ((another_father_a = (father->regno_allocno_map
806 [ALLOCNO_REGNO (another_a)])) == NULL)
807 continue;
808 another_father_pn = ALLOCNO_NUM (another_father_a);
809 if (another_father_pn < 0)
810 continue;
811 ira_assert (ALLOCNO_COVER_CLASS (another_a)
812 == ALLOCNO_COVER_CLASS (another_father_a));
813 if (cover_class == ALLOCNO_COVER_CLASS (another_a))
814 SET_ALLOCNO_SET_BIT
815 (accumulated_conflicts + allocno_set_words * level,
816 another_father_pn);
819 ira_free (accumulated_conflicts);
820 ira_free (level_init_p);
821 ira_free (conflict_allocnos);
826 /* The function propagates information about allocnos modified inside
827 the loops. */
828 static void
829 propagate_modified_regnos (loop_tree_node_t loop_tree_node)
831 if (loop_tree_node->bb != NULL || loop_tree_node == ira_loop_tree_root)
832 return;
833 bitmap_ior_into (loop_tree_node->father->modified_regnos,
834 loop_tree_node->modified_regnos);
839 /* The function prints hard reg set SET with TITLE to FILE. */
840 static void
841 print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
843 int i, start;
845 fprintf (file, title);
846 for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
848 if (TEST_HARD_REG_BIT (set, i))
850 if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1))
851 start = i;
853 if (start >= 0
854 && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i)))
856 if (start == i - 1)
857 fprintf (file, " %d", start);
858 else if (start == i - 2)
859 fprintf (file, " %d %d", start, start + 1);
860 else
861 fprintf (file, " %d-%d", start, i - 1);
862 start = -1;
865 fprintf (file, "\n");
868 /* The function outputs information about allocno or regno (if REG_P)
869 conflicts to FILE. */
870 static void
871 print_conflicts (FILE *file, int reg_p)
873 int i;
875 for (i = 0; i < allocnos_num; i++)
877 int j;
878 allocno_t a, conflict_a, *allocno_vec;
879 basic_block bb;
881 a = allocnos [i];
882 if (reg_p)
883 fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
884 else
886 fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
887 if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
888 fprintf (file, "b%d", bb->index);
889 else
890 fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
891 fprintf (file, ")");
893 fprintf (file, " conflicts:");
894 allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
895 if (allocno_vec != NULL)
896 for (j = 0; (conflict_a = allocno_vec [j]) != NULL; j++)
898 if (reg_p)
899 fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
900 else
902 fprintf (file, " a%d(r%d,", ALLOCNO_NUM (conflict_a),
903 ALLOCNO_REGNO (conflict_a));
904 if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
905 fprintf (file, "b%d)", bb->index);
906 else
907 fprintf (file, "l%d)",
908 ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num);
910 if (j + 1 == ALLOCNO_CONFLICT_ALLOCNOS_NUM (a))
911 fprintf (file, "*");
913 print_hard_reg_set (file, "\n;; total conflict hard regs:",
914 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
915 print_hard_reg_set (file, ";; conflict hard regs:",
916 ALLOCNO_CONFLICT_HARD_REGS (a));
918 fprintf (file, "\n");
921 /* The function outputs information about allocno or regno (if REG_P)
922 conflicts to stderr. */
923 void
924 debug_conflicts (int reg_p)
926 print_conflicts (stderr, reg_p);
931 /* Entry function which builds allocno conflicts. */
932 void
933 ira_build_conflicts (void)
935 int i;
936 allocno_t a;
938 build_conflict_bit_table ();
939 mirror_conflicts ();
940 traverse_loop_tree (FALSE, ira_loop_tree_root, NULL, add_copies);
941 if (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
942 || flag_ira_algorithm == IRA_ALGORITHM_MIXED)
943 propagate_info ();
944 /* We need finished conflict table for the subsequent call. */
945 remove_conflict_allocno_copies ();
946 build_allocno_conflict_vects ();
947 for (i = 0; i < allocnos_num; i++)
949 a = allocnos [i];
950 if (ALLOCNO_CALLS_CROSSED_NUM (a) == 0)
951 continue;
952 if (! flag_caller_saves)
954 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
955 call_used_reg_set);
956 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
957 IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
958 call_used_reg_set);
960 else
962 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
963 no_caller_save_reg_set);
964 if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
965 IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
966 no_caller_save_reg_set);
969 traverse_loop_tree (FALSE, ira_loop_tree_root, NULL,
970 propagate_modified_regnos);
971 if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
972 print_conflicts (ira_dump_file, FALSE);