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
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
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
25 #include "coretypes.h"
32 #include "hard-reg-set.h"
33 #include "basic-block.h"
34 #include "insn-config.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
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. */
115 mirror_conflicts (void)
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
;
125 for (i
= allocnos_num
- 1, mask
= 1; i
>= 0; i
--, mask
<<= 1)
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
;
138 word
>>= 1, q2
+= rw
)
149 /* The function returns nonzero, if the operand constraint STR is
152 commutative_constraint_p (const char *str
)
157 for (ignore_p
= FALSE
;;)
162 str
+= CONSTRAINT_LEN (c
, str
);
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. */
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
;
187 rtx op
, equiv_const
= NULL_RTX
;
189 if (op_num
< 0 || recog_data
.n_alternatives
== 0)
191 op
= recog_data
.operand
[op_num
];
192 ira_assert (REG_P (op
));
193 commut_op_used_p
= TRUE
;
196 if (commutative_constraint_p (recog_data
.constraints
[op_num
]))
198 else if (op_num
> 0 && commutative_constraint_p (recog_data
.constraints
202 commut_op_used_p
= FALSE
;
204 str
= recog_data
.constraints
[op_num
];
205 for (ignore_p
= FALSE
, original
= -1, curr_alt
= 0;;)
224 if (equiv_const
!= NULL_RTX
&& CONSTANT_P (equiv_const
))
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
)))
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
))
253 if ((equiv_const
!= NULL_RTX
254 && GET_CODE (equiv_const
) == CONST_INT
255 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (equiv_const
),
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
))))
272 if (equiv_const
!= NULL_RTX
273 && GET_CODE (equiv_const
) == CONST_DOUBLE
274 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (equiv_const
, c
, str
))
280 /* Accept a register which might be placed in memory. */
290 GO_IF_LEGITIMATE_ADDRESS (VOIDmode
, op
, win_p
);
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':
311 ? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c
, str
));
314 #ifdef EXTRA_CONSTRAINT_STR
315 else if (EXTRA_CONSTRAINT_STR (op
, c
, str
))
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
)
328 str
+= CONSTRAINT_LEN (c
, str
);
332 dup
= original
- '0';
335 if (commutative_constraint_p (recog_data
.constraints
[dup
]))
338 && commutative_constraint_p (recog_data
.constraints
[dup
-1]))
340 else if (! commut_op_used_p
)
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
351 get_dup (int op_num
, int use_commut_op_p
)
353 int n
= get_dup_num (op_num
, use_commut_op_p
);
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. */
365 add_insn_allocno_copies (rtx insn
)
367 rtx set
, operand
, dup
;
369 int commut_p
, bound_p
;
370 int i
, j
, freq
, hard_regno
, cost
, index
, hard_regs_num
;
373 enum reg_class
class, cover_class
;
374 enum machine_mode mode
;
376 freq
= REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn
));
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
)))
391 hard_regno
= REGNO (SET_DEST (set
));
392 a
= ira_curr_regno_allocno_map
[REGNO (SET_SRC (set
))];
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
])
404 if (reg_class_size
[class]
405 <= (unsigned) CLASS_MAX_NREGS (class, mode
))
406 /* It is already taken into account in ira-costs.c. */
408 index
= class_hard_reg_index
[cover_class
] [hard_regno
];
411 if (HARD_REGISTER_P (SET_DEST (set
)))
412 cost
= register_move_cost
[mode
] [cover_class
] [class] * freq
;
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
;
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
);
436 for (i
= 0; i
< recog_data
.n_operands
; i
++)
438 operand
= recog_data
.operand
[i
];
440 && find_reg_note (insn
, REG_DEAD
, operand
) != NULL_RTX
)
442 str
= recog_data
.constraints
[i
];
443 while (*str
== ' ' && *str
== '\t')
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
))
457 hard_regno
= REGNO (operand
);
458 a
= ira_curr_regno_allocno_map
[REGNO (dup
)];
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
])
471 = class_hard_reg_index
[cover_class
] [hard_regno
];
474 if (HARD_REGISTER_P (operand
))
476 = register_move_cost
[mode
] [cover_class
] [class];
479 = register_move_cost
[mode
] [class] [cover_class
];
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
),
488 ALLOCNO_HARD_REG_COSTS (a
) [index
] -= cost
;
489 ALLOCNO_CONFLICT_HARD_REG_COSTS (a
) [index
] -= cost
;
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
);
500 (ira_curr_loop_tree_node
->local_copies
, cp
->num
);
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
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
))
523 hard_regno
= REGNO (operand
);
524 a
= ira_curr_regno_allocno_map
[REGNO (dup
)];
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
])
537 = class_hard_reg_index
[cover_class
] [hard_regno
];
540 if (HARD_REGISTER_P (operand
))
542 = register_move_cost
[mode
] [cover_class
] [class];
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
),
554 ALLOCNO_HARD_REG_COSTS (a
) [index
] -= cost
;
555 ALLOCNO_CONFLICT_HARD_REG_COSTS (a
) [index
] -= cost
;
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
);
565 (ira_curr_loop_tree_node
->local_copies
, cp
->num
);
573 /* The function adds copies originated from bb given by
576 add_copies (loop_tree_node_t loop_tree_node
)
581 bb
= loop_tree_node
->bb
;
584 FOR_BB_INSNS (bb
, 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
594 propagate_allocno_info (allocno_t a
)
597 allocno_t father_a
, another_a
, another_father_a
;
598 loop_tree_node_t father
;
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
);
607 if (ALLOCNO_TOTAL_NO_STACK_REG_P (a
))
608 ALLOCNO_TOTAL_NO_STACK_REG_P (father_a
) = TRUE
;
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
)
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
;
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. */
644 propagate_info (void)
649 for (i
= max_reg_num () - 1; i
>= FIRST_PSEUDO_REGISTER
; i
--)
650 for (a
= regno_allocno_map
[i
];
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
660 allocno_live_ranges_intersect_p (allocno_t a1
, allocno_t a2
)
662 allocno_live_range_t r1
, r2
;
666 if (ALLOCNO_REG (a1
) != NULL
&& ALLOCNO_REG (a2
) != NULL
667 && (ORIGINAL_REGNO (ALLOCNO_REG (a1
))
668 == ORIGINAL_REGNO (ALLOCNO_REG (a2
))))
670 for (r1
= ALLOCNO_LIVE_RANGES (a1
), r2
= ALLOCNO_LIVE_RANGES (a2
);
671 r1
!= NULL
&& r2
!= NULL
;)
673 if (r1
->start
> r2
->finish
)
675 else if (r2
->start
> r1
->finish
)
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
687 pseudo_live_ranges_intersect_p (int regno1
, int regno2
)
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
)
698 return allocno_live_ranges_intersect_p (a1
, a2
);
701 /* Remove copies involving conflicting allocnos. */
703 remove_conflict_allocno_copies (void)
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
++)
715 for (cp
= ALLOCNO_COPIES (a
); cp
!= NULL
; cp
= next_cp
)
717 next_cp
= cp
->next_first_allocno_copy
;
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
736 build_allocno_conflict_vects (void)
738 int i
, j
, level
, px
, another_father_pn
, conflict_allocnos_num
;
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
];
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
;
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
;
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
);
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
)
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
)
808 another_father_pn
= ALLOCNO_NUM (another_father_a
);
809 if (another_father_pn
< 0)
811 ira_assert (ALLOCNO_COVER_CLASS (another_a
)
812 == ALLOCNO_COVER_CLASS (another_father_a
));
813 if (cover_class
== ALLOCNO_COVER_CLASS (another_a
))
815 (accumulated_conflicts
+ allocno_set_words
* level
,
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
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
)
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. */
841 print_hard_reg_set (FILE *file
, const char *title
, HARD_REG_SET set
)
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))
854 && (i
== FIRST_PSEUDO_REGISTER
- 1 || ! TEST_HARD_REG_BIT (set
, i
)))
857 fprintf (file
, " %d", start
);
858 else if (start
== i
- 2)
859 fprintf (file
, " %d %d", start
, start
+ 1);
861 fprintf (file
, " %d-%d", start
, i
- 1);
865 fprintf (file
, "\n");
868 /* The function outputs information about allocno or regno (if REG_P)
869 conflicts to FILE. */
871 print_conflicts (FILE *file
, int reg_p
)
875 for (i
= 0; i
< allocnos_num
; i
++)
878 allocno_t a
, conflict_a
, *allocno_vec
;
883 fprintf (file
, ";; r%d", ALLOCNO_REGNO (a
));
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
);
890 fprintf (file
, "l%d", ALLOCNO_LOOP_TREE_NODE (a
)->loop
->num
);
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
++)
899 fprintf (file
, " r%d,", ALLOCNO_REGNO (conflict_a
));
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
);
907 fprintf (file
, "l%d)",
908 ALLOCNO_LOOP_TREE_NODE (conflict_a
)->loop
->num
);
910 if (j
+ 1 == ALLOCNO_CONFLICT_ALLOCNOS_NUM (a
))
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. */
924 debug_conflicts (int reg_p
)
926 print_conflicts (stderr
, reg_p
);
931 /* Entry function which builds allocno conflicts. */
933 ira_build_conflicts (void)
938 build_conflict_bit_table ();
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
)
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
++)
950 if (ALLOCNO_CALLS_CROSSED_NUM (a
) == 0)
952 if (! flag_caller_saves
)
954 IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a
),
956 if (ALLOCNO_CALLS_CROSSED_NUM (a
) != 0)
957 IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a
),
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
);