}
/* Create and return copy with given attributes LOOP_TREE_NODE, FIRST,
- SECOND, FREQ, and INSN. */
+ SECOND, FREQ, CONSTRAINT_P, and INSN. */
ira_copy_t
-ira_create_copy (ira_allocno_t first, ira_allocno_t second, int freq, rtx insn,
+ira_create_copy (ira_allocno_t first, ira_allocno_t second, int freq,
+ bool constraint_p, rtx insn,
ira_loop_tree_node_t loop_tree_node)
{
ira_copy_t cp;
cp->first = first;
cp->second = second;
cp->freq = freq;
+ cp->constraint_p = constraint_p;
cp->insn = insn;
cp->loop_tree_node = loop_tree_node;
VEC_safe_push (ira_copy_t, heap, copy_vec, cp);
LOOP_TREE_NODE. */
ira_copy_t
ira_add_allocno_copy (ira_allocno_t first, ira_allocno_t second, int freq,
- rtx insn, ira_loop_tree_node_t loop_tree_node)
+ bool constraint_p, rtx insn,
+ ira_loop_tree_node_t loop_tree_node)
{
ira_copy_t cp;
cp->freq += freq;
return cp;
}
- cp = ira_create_copy (first, second, freq, insn, loop_tree_node);
+ cp = ira_create_copy (first, second, freq, constraint_p, insn,
+ loop_tree_node);
ira_assert (first != NULL && second != NULL);
ira_add_allocno_copy_to_list (cp);
ira_swap_allocno_copy_ends_if_necessary (cp);
static void
print_copy (FILE *f, ira_copy_t cp)
{
- fprintf (f, " cp%d:a%d(r%d)<->a%d(r%d)@%d\n", cp->num,
+ fprintf (f, " cp%d:a%d(r%d)<->a%d(r%d)@%d:%s\n", cp->num,
ALLOCNO_NUM (cp->first), ALLOCNO_REGNO (cp->first),
- ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second), cp->freq);
+ ALLOCNO_NUM (cp->second), ALLOCNO_REGNO (cp->second), cp->freq,
+ cp->insn != NULL
+ ? "move" : cp->constraint_p ? "constraint" : "shuffle");
}
/* Print info about copy CP into stderr. */
cover_class = ALLOCNO_COVER_CLASS (allocno);
if (cover_class != ALLOCNO_COVER_CLASS (another_allocno)
|| ALLOCNO_ASSIGNED_P (another_allocno)
- || ALLOCNO_MAY_BE_SPILLED_P (another_allocno))
+ || ALLOCNO_MAY_BE_SPILLED_P (ALLOCNO_FIRST_COALESCED_ALLOCNO
+ (another_allocno)))
continue;
class_size = ira_class_hard_regs_num[cover_class];
ira_allocate_and_copy_costs
}
continue;
}
- else if (! ALLOCNO_MAY_BE_SPILLED_P (conflict_allocno))
+ else if (! ALLOCNO_MAY_BE_SPILLED_P (ALLOCNO_FIRST_COALESCED_ALLOCNO
+ (conflict_allocno)))
{
ira_allocate_and_copy_costs
(&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (conflict_allocno),
for (j = 0, a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
{
+ ira_assert (! ALLOCNO_IN_GRAPH_P (a));
sorted_allocnos[j++] = a;
if (a == allocno)
break;
/* Add ALLOCNO to bucket *BUCKET_PTR. ALLOCNO should be not in a bucket
before the call. */
static void
-add_ira_allocno_to_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
+add_allocno_to_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr)
{
ira_allocno_t first_allocno;
enum reg_class cover_class;
their priority. ALLOCNO should be not in a bucket before the
call. */
static void
-add_ira_allocno_to_ordered_bucket (ira_allocno_t allocno,
- ira_allocno_t *bucket_ptr)
+add_allocno_to_ordered_bucket (ira_allocno_t allocno,
+ ira_allocno_t *bucket_ptr)
{
ira_allocno_t before, after;
enum reg_class cover_class;
conflicting allocnos from the uncolorable bucket to the colorable
one. */
static void
-push_ira_allocno_to_stack (ira_allocno_t allocno)
+push_allocno_to_stack (ira_allocno_t allocno)
{
int conflicts_num, conflict_size, size;
ira_allocno_t a, conflict_allocno;
a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
{
FOR_EACH_ALLOCNO_CONFLICT (a, conflict_allocno, aci)
- if (bitmap_bit_p (coloring_allocno_bitmap,
- ALLOCNO_NUM (conflict_allocno)))
- {
- ira_assert (cover_class == ALLOCNO_COVER_CLASS (conflict_allocno));
- if (allocno_coalesced_p)
- {
- if (bitmap_bit_p (processed_coalesced_allocno_bitmap,
- ALLOCNO_NUM (conflict_allocno)))
- continue;
- bitmap_set_bit (processed_coalesced_allocno_bitmap,
- ALLOCNO_NUM (conflict_allocno));
- }
- if (ALLOCNO_IN_GRAPH_P (conflict_allocno)
- && ! ALLOCNO_ASSIGNED_P (conflict_allocno))
- {
- conflicts_num = ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno);
- conflict_size
- = (ira_reg_class_nregs
- [cover_class][ALLOCNO_MODE (conflict_allocno)]);
- ira_assert
- (ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno) >= size);
- if (conflicts_num + conflict_size
- <= ALLOCNO_AVAILABLE_REGS_NUM (conflict_allocno))
- {
- ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno) -= size;
+ {
+ conflict_allocno = ALLOCNO_FIRST_COALESCED_ALLOCNO (conflict_allocno);
+ if (bitmap_bit_p (coloring_allocno_bitmap,
+ ALLOCNO_NUM (conflict_allocno)))
+ {
+ ira_assert (cover_class
+ == ALLOCNO_COVER_CLASS (conflict_allocno));
+ if (allocno_coalesced_p)
+ {
+ if (bitmap_bit_p (processed_coalesced_allocno_bitmap,
+ ALLOCNO_NUM (conflict_allocno)))
continue;
- }
- conflicts_num
- = ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno) - size;
- if (uncolorable_allocnos_splay_tree[cover_class] != NULL
- && !ALLOCNO_SPLAY_REMOVED_P (conflict_allocno)
- && USE_SPLAY_P (cover_class))
- {
- ira_assert
+ bitmap_set_bit (processed_coalesced_allocno_bitmap,
+ ALLOCNO_NUM (conflict_allocno));
+ }
+ if (ALLOCNO_IN_GRAPH_P (conflict_allocno)
+ && ! ALLOCNO_ASSIGNED_P (conflict_allocno))
+ {
+ conflicts_num = ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno);
+ conflict_size
+ = (ira_reg_class_nregs
+ [cover_class][ALLOCNO_MODE (conflict_allocno)]);
+ ira_assert
+ (ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno) >= size);
+ if (conflicts_num + conflict_size
+ <= ALLOCNO_AVAILABLE_REGS_NUM (conflict_allocno))
+ {
+ ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno) -= size;
+ continue;
+ }
+ conflicts_num
+ = ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno) - size;
+ if (uncolorable_allocnos_splay_tree[cover_class] != NULL
+ && !ALLOCNO_SPLAY_REMOVED_P (conflict_allocno)
+ && USE_SPLAY_P (cover_class))
+ {
+ ira_assert
(splay_tree_lookup
(uncolorable_allocnos_splay_tree[cover_class],
(splay_tree_key) conflict_allocno) != NULL);
- splay_tree_remove
- (uncolorable_allocnos_splay_tree[cover_class],
- (splay_tree_key) conflict_allocno);
- ALLOCNO_SPLAY_REMOVED_P (conflict_allocno) = true;
- VEC_safe_push (ira_allocno_t, heap,
- removed_splay_allocno_vec,
- conflict_allocno);
- }
- ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno) = conflicts_num;
- if (conflicts_num + conflict_size
- <= ALLOCNO_AVAILABLE_REGS_NUM (conflict_allocno))
- {
- delete_allocno_from_bucket (conflict_allocno,
- &uncolorable_allocno_bucket);
- add_ira_allocno_to_ordered_bucket (conflict_allocno,
- &colorable_allocno_bucket);
- }
- }
- }
+ splay_tree_remove
+ (uncolorable_allocnos_splay_tree[cover_class],
+ (splay_tree_key) conflict_allocno);
+ ALLOCNO_SPLAY_REMOVED_P (conflict_allocno) = true;
+ VEC_safe_push (ira_allocno_t, heap,
+ removed_splay_allocno_vec,
+ conflict_allocno);
+ }
+ ALLOCNO_LEFT_CONFLICTS_NUM (conflict_allocno) = conflicts_num;
+ if (conflicts_num + conflict_size
+ <= ALLOCNO_AVAILABLE_REGS_NUM (conflict_allocno))
+ {
+ delete_allocno_from_bucket
+ (conflict_allocno, &uncolorable_allocno_bucket);
+ add_allocno_to_ordered_bucket
+ (conflict_allocno, &colorable_allocno_bucket);
+ }
+ }
+ }
+ }
if (a == allocno)
break;
}
> ALLOCNO_AVAILABLE_REGS_NUM (allocno))));
if (! colorable_p)
ALLOCNO_MAY_BE_SPILLED_P (allocno) = true;
- push_ira_allocno_to_stack (allocno);
+ push_allocno_to_stack (allocno);
}
/* Put all allocnos from colorable bucket onto the coloring stack. */
/* Puts ALLOCNO chosen for potential spilling onto the coloring
stack. */
static void
-push_ira_allocno_to_spill (ira_allocno_t allocno)
+push_allocno_to_spill (ira_allocno_t allocno)
{
delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
ALLOCNO_MAY_BE_SPILLED_P (allocno) = true;
if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
fprintf (ira_dump_file, " Pushing p%d(%d) (potential spill)\n",
ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno));
- push_ira_allocno_to_stack (allocno);
+ push_allocno_to_stack (allocno);
}
/* Return the frequency of exit edges (if EXIT_P) or entry from/to the
cover_class = ALLOCNO_COVER_CLASS (allocno);
if (cover_class == NO_REGS)
{
- push_ira_allocno_to_spill (allocno);
+ push_allocno_to_spill (allocno);
continue;
}
/* Potential spilling. */
if (ALLOCNO_IN_GRAPH_P (i_allocno))
{
i++;
- if (ALLOCNO_TEMP (i_allocno) == INT_MAX)
- {
- ira_allocno_t a;
- int cost = 0;
-
- for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (i_allocno);;
- a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
- {
- cost += calculate_allocno_spill_cost (i_allocno);
- if (a == i_allocno)
- break;
- }
- /* ??? Remove cost of copies between the coalesced
- allocnos. */
- ALLOCNO_TEMP (i_allocno) = cost;
- }
+ ira_assert (ALLOCNO_TEMP (i_allocno) != INT_MAX);
i_allocno_cost = ALLOCNO_TEMP (i_allocno);
i_allocno_pri
= (i_allocno_cost
a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
{
FOR_EACH_ALLOCNO_CONFLICT (a, conflict_allocno, aci)
- if (bitmap_bit_p (consideration_allocno_bitmap,
- ALLOCNO_NUM (conflict_allocno)))
- {
- ira_assert (cover_class
- == ALLOCNO_COVER_CLASS (conflict_allocno));
- if (allocno_coalesced_p)
- {
- if (bitmap_bit_p (processed_coalesced_allocno_bitmap,
- ALLOCNO_NUM (conflict_allocno)))
- continue;
- bitmap_set_bit (processed_coalesced_allocno_bitmap,
- ALLOCNO_NUM (conflict_allocno));
- }
- if (! ALLOCNO_ASSIGNED_P (conflict_allocno))
- conflict_allocnos_size
- += (ira_reg_class_nregs
- [cover_class][ALLOCNO_MODE (conflict_allocno)]);
- else if ((hard_regno = ALLOCNO_HARD_REGNO (conflict_allocno))
- >= 0)
- {
- int last = (hard_regno
- + hard_regno_nregs
+ {
+ conflict_allocno
+ = ALLOCNO_FIRST_COALESCED_ALLOCNO (conflict_allocno);
+ if (bitmap_bit_p (consideration_allocno_bitmap,
+ ALLOCNO_NUM (conflict_allocno)))
+ {
+ ira_assert (cover_class
+ == ALLOCNO_COVER_CLASS (conflict_allocno));
+ if (allocno_coalesced_p)
+ {
+ if (bitmap_bit_p (processed_coalesced_allocno_bitmap,
+ ALLOCNO_NUM (conflict_allocno)))
+ continue;
+ bitmap_set_bit (processed_coalesced_allocno_bitmap,
+ ALLOCNO_NUM (conflict_allocno));
+ }
+ if (! ALLOCNO_ASSIGNED_P (conflict_allocno))
+ conflict_allocnos_size
+ += (ira_reg_class_nregs
+ [cover_class][ALLOCNO_MODE (conflict_allocno)]);
+ else if ((hard_regno = ALLOCNO_HARD_REGNO (conflict_allocno))
+ >= 0)
+ {
+ int last = (hard_regno
+ + hard_regno_nregs
[hard_regno][ALLOCNO_MODE (conflict_allocno)]);
-
- while (hard_regno < last)
- {
- if (! TEST_HARD_REG_BIT (temp_set, hard_regno))
- {
- conflict_allocnos_size++;
- SET_HARD_REG_BIT (temp_set, hard_regno);
- }
- hard_regno++;
- }
- }
- }
+
+ while (hard_regno < last)
+ {
+ if (! TEST_HARD_REG_BIT (temp_set, hard_regno))
+ {
+ conflict_allocnos_size++;
+ SET_HARD_REG_BIT (temp_set, hard_regno);
+ }
+ hard_regno++;
+ }
+ }
+ }
+ }
if (a == allocno)
break;
}
if (ALLOCNO_LEFT_CONFLICTS_NUM (allocno)
+ ira_reg_class_nregs[cover_class][ALLOCNO_MODE (allocno)]
<= ALLOCNO_AVAILABLE_REGS_NUM (allocno))
- add_ira_allocno_to_bucket (allocno, &colorable_allocno_bucket);
+ add_allocno_to_bucket (allocno, &colorable_allocno_bucket);
else
- add_ira_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
+ add_allocno_to_bucket (allocno, &uncolorable_allocno_bucket);
}
/* The function is used to sort allocnos according to their execution
if ((reload_p
|| (ALLOCNO_COVER_CLASS (cp->second) == cover_class
&& ALLOCNO_MODE (cp->second) == mode))
- && cp->insn != NULL
+ && (cp->insn != NULL || cp->constraint_p)
&& ((! reload_p && ! ALLOCNO_ASSIGNED_P (cp->second))
|| (reload_p
&& ALLOCNO_ASSIGNED_P (cp->second)
registers. When nothing is changed, the function returns
FALSE. */
static bool
-process_regs_for_copy (rtx reg1, rtx reg2, rtx insn, int freq)
+process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
+ rtx insn, int freq)
{
int allocno_preferenced_hard_regno, cost, index, offset1, offset2;
bool only_regs_p;
{
cp = ira_add_allocno_copy (ira_curr_regno_allocno_map[REGNO (reg1)],
ira_curr_regno_allocno_map[REGNO (reg2)],
- freq, insn, ira_curr_loop_tree_node);
+ freq, constraint_p, insn,
+ ira_curr_loop_tree_node);
bitmap_set_bit (ira_curr_loop_tree_node->local_copies, cp->num);
return true;
}
|| recog_data.operand_type[i] != OP_OUT)
continue;
- process_regs_for_copy (reg, another_reg, NULL_RTX, freq);
+ process_regs_for_copy (reg, another_reg, false, NULL_RTX, freq);
}
}
REG_P (SET_SRC (set))
? SET_SRC (set)
: SUBREG_REG (SET_SRC (set))) != NULL_RTX)
- process_regs_for_copy (SET_DEST (set), SET_SRC (set), insn, freq);
+ process_regs_for_copy (SET_DEST (set), SET_SRC (set), false, insn, freq);
else
{
extract_insn (insn);
for (j = 0, commut_p = false; j < 2; j++, commut_p = true)
if ((dup = get_dup (i, commut_p)) != NULL_RTX
&& REG_SUBREG_P (dup)
- && process_regs_for_copy (operand, dup, NULL_RTX, freq))
+ && process_regs_for_copy (operand, dup, true,
+ NULL_RTX, freq))
bound_p = true;
if (bound_p)
continue;
parent_a2 = parent->regno_allocno_map[ALLOCNO_REGNO (a2)];
ira_assert (parent_a1 != NULL && parent_a2 != NULL);
if (! CONFLICT_ALLOCNO_P (parent_a1, parent_a2))
- ira_add_allocno_copy (parent_a1, parent_a1, cp->freq,
- cp->insn, cp->loop_tree_node);
+ ira_add_allocno_copy (parent_a1, parent_a2, cp->freq,
+ cp->constraint_p, cp->insn, cp->loop_tree_node);
}
}