Commit 3c55880a by Bernd Schmidt Committed by Bernd Schmidt

ira-build.c (merge_hard_reg_conflicts): New function.

	* ira-build.c (merge_hard_reg_conflicts): New function.
	(create_cap_allocno, copy_info_to_removed_store_destinations,
	propagate_some_info_from_allocno, propagate_allocno_info): Use it.
	(move_allocno_live_ranges, copy_allocno_live_ranges): New functions.
	(remove_unnecessary_allocnos, remove_low_level_allocnos)
	copy_nifo_to_removed_store_destination): Use them.
	* ira-lives.c (make_hard_regno_born): New function, split out of
	make_regno_born.
	(make_allocno_born): Likewise.
	(make_hard_regno_dead): New function, split out of make_regno_dead.
	(make_allocno_dead): Likewise.
	(inc_register_pressure): New function, split out of set_allocno_live.
	(dec_register_pressure): New function, split out of clear_allocno_live.
	(mark_pseudo_regno_live): New function, split out of mark_reg_live.
	(mark_hard_reg_live): Likewise.  Use inc_register_pressure.
	(mark_pseudo_regno_dead): New function, split out of mark_reg_dead.
	(mark_hard_reg_dead): Likewise.  Use dec_register_pressure.
	(make_pseudo_conflict): Use mark_pseudo_regno_dead and
	mark_pseudo_regno_live.
	(process_bb_node_lives): Use mark_pseudo_regno_live,
	make_hard_regno_born and make_allocno_dead.
	(make_regno_born, make_regno_dead, mark_reg_live, mark_reg_dead,
	set_allocno_live, clear_allocno_live): Delete functions.

From-SVN: r161346
parent dd2e0807
...@@ -2,6 +2,30 @@ ...@@ -2,6 +2,30 @@
* ira.c (allocno_pool, copy_pool, allocno_live_range_pool): Delete. * ira.c (allocno_pool, copy_pool, allocno_live_range_pool): Delete.
* ira-build.c (merge_hard_reg_conflicts): New function.
(create_cap_allocno, copy_info_to_removed_store_destinations,
propagate_some_info_from_allocno, propagate_allocno_info): Use it.
(move_allocno_live_ranges, copy_allocno_live_ranges): New functions.
(remove_unnecessary_allocnos, remove_low_level_allocnos)
copy_nifo_to_removed_store_destination): Use them.
* ira-lives.c (make_hard_regno_born): New function, split out of
make_regno_born.
(make_allocno_born): Likewise.
(make_hard_regno_dead): New function, split out of make_regno_dead.
(make_allocno_dead): Likewise.
(inc_register_pressure): New function, split out of set_allocno_live.
(dec_register_pressure): New function, split out of clear_allocno_live.
(mark_pseudo_regno_live): New function, split out of mark_reg_live.
(mark_hard_reg_live): Likewise. Use inc_register_pressure.
(mark_pseudo_regno_dead): New function, split out of mark_reg_dead.
(mark_hard_reg_dead): Likewise. Use dec_register_pressure.
(make_pseudo_conflict): Use mark_pseudo_regno_dead and
mark_pseudo_regno_live.
(process_bb_node_lives): Use mark_pseudo_regno_live,
make_hard_regno_born and make_allocno_dead.
(make_regno_born, make_regno_dead, mark_reg_live, mark_reg_dead,
set_allocno_live, clear_allocno_live): Delete functions.
2010-06-24 Richard Earnshaw <rearnsha@arm.com> 2010-06-24 Richard Earnshaw <rearnsha@arm.com>
* thumb2.md (thumb2_tlobits_cbranch): Delete. * thumb2.md (thumb2_tlobits_cbranch): Delete.
......
...@@ -504,6 +504,25 @@ ira_set_allocno_cover_class (ira_allocno_t a, enum reg_class cover_class) ...@@ -504,6 +504,25 @@ ira_set_allocno_cover_class (ira_allocno_t a, enum reg_class cover_class)
reg_class_contents[cover_class]); reg_class_contents[cover_class]);
} }
/* Merge hard register conflicts from allocno FROM into allocno TO. If
TOTAL_ONLY is true, we ignore ALLOCNO_CONFLICT_HARD_REGS. */
static void
merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to,
bool total_only)
{
if (!total_only)
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (to),
ALLOCNO_CONFLICT_HARD_REGS (from));
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (to),
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (from));
#ifdef STACK_REGS
if (!total_only && ALLOCNO_NO_STACK_REG_P (from))
ALLOCNO_NO_STACK_REG_P (to) = true;
if (ALLOCNO_TOTAL_NO_STACK_REG_P (from))
ALLOCNO_TOTAL_NO_STACK_REG_P (to) = true;
#endif
}
/* Return TRUE if the conflict vector with NUM elements is more /* Return TRUE if the conflict vector with NUM elements is more
profitable than conflict bit vector for A. */ profitable than conflict bit vector for A. */
bool bool
...@@ -781,15 +800,8 @@ create_cap_allocno (ira_allocno_t a) ...@@ -781,15 +800,8 @@ create_cap_allocno (ira_allocno_t a)
ALLOCNO_NREFS (cap) = ALLOCNO_NREFS (a); ALLOCNO_NREFS (cap) = ALLOCNO_NREFS (a);
ALLOCNO_FREQ (cap) = ALLOCNO_FREQ (a); ALLOCNO_FREQ (cap) = ALLOCNO_FREQ (a);
ALLOCNO_CALL_FREQ (cap) = ALLOCNO_CALL_FREQ (a); ALLOCNO_CALL_FREQ (cap) = ALLOCNO_CALL_FREQ (a);
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (cap), merge_hard_reg_conflicts (a, cap, false);
ALLOCNO_CONFLICT_HARD_REGS (a));
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (cap),
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
ALLOCNO_CALLS_CROSSED_NUM (cap) = ALLOCNO_CALLS_CROSSED_NUM (a); ALLOCNO_CALLS_CROSSED_NUM (cap) = ALLOCNO_CALLS_CROSSED_NUM (a);
#ifdef STACK_REGS
ALLOCNO_NO_STACK_REG_P (cap) = ALLOCNO_NO_STACK_REG_P (a);
ALLOCNO_TOTAL_NO_STACK_REG_P (cap) = ALLOCNO_TOTAL_NO_STACK_REG_P (a);
#endif
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
{ {
fprintf (ira_dump_file, " Creating cap "); fprintf (ira_dump_file, " Creating cap ");
...@@ -1603,12 +1615,7 @@ propagate_allocno_info (void) ...@@ -1603,12 +1615,7 @@ propagate_allocno_info (void)
ALLOCNO_NREFS (parent_a) += ALLOCNO_NREFS (a); ALLOCNO_NREFS (parent_a) += ALLOCNO_NREFS (a);
ALLOCNO_FREQ (parent_a) += ALLOCNO_FREQ (a); ALLOCNO_FREQ (parent_a) += ALLOCNO_FREQ (a);
ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a); ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a);
#ifdef STACK_REGS merge_hard_reg_conflicts (a, parent_a, true);
if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true;
#endif
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a),
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
ALLOCNO_CALLS_CROSSED_NUM (parent_a) ALLOCNO_CALLS_CROSSED_NUM (parent_a)
+= ALLOCNO_CALLS_CROSSED_NUM (a); += ALLOCNO_CALLS_CROSSED_NUM (a);
ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a) ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
...@@ -1657,6 +1664,46 @@ change_allocno_in_range_list (allocno_live_range_t r, ira_allocno_t a) ...@@ -1657,6 +1664,46 @@ change_allocno_in_range_list (allocno_live_range_t r, ira_allocno_t a)
r->allocno = a; r->allocno = a;
} }
/* Move all live ranges associated with allocno FROM to allocno TO. */
static void
move_allocno_live_ranges (ira_allocno_t from, ira_allocno_t to)
{
allocno_live_range_t lr = ALLOCNO_LIVE_RANGES (from);
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
{
fprintf (ira_dump_file,
" Moving ranges of a%dr%d to a%dr%d: ",
ALLOCNO_NUM (from), ALLOCNO_REGNO (from),
ALLOCNO_NUM (to), ALLOCNO_REGNO (to));
ira_print_live_range_list (ira_dump_file, lr);
}
change_allocno_in_range_list (lr, to);
ALLOCNO_LIVE_RANGES (to)
= ira_merge_allocno_live_ranges (lr, ALLOCNO_LIVE_RANGES (to));
ALLOCNO_LIVE_RANGES (from) = NULL;
}
/* Copy all live ranges associated with allocno FROM to allocno TO. */
static void
copy_allocno_live_ranges (ira_allocno_t from, ira_allocno_t to)
{
allocno_live_range_t lr = ALLOCNO_LIVE_RANGES (from);
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
{
fprintf (ira_dump_file,
" Copying ranges of a%dr%d to a%dr%d: ",
ALLOCNO_NUM (from), ALLOCNO_REGNO (from),
ALLOCNO_NUM (to), ALLOCNO_REGNO (to));
ira_print_live_range_list (ira_dump_file, lr);
}
lr = ira_copy_allocno_live_range_list (lr);
change_allocno_in_range_list (lr, to);
ALLOCNO_LIVE_RANGES (to)
= ira_merge_allocno_live_ranges (lr, ALLOCNO_LIVE_RANGES (to));
}
/* Return TRUE if NODE represents a loop with low register /* Return TRUE if NODE represents a loop with low register
pressure. */ pressure. */
static bool static bool
...@@ -1890,26 +1937,15 @@ propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a) ...@@ -1890,26 +1937,15 @@ propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a)
{ {
enum reg_class cover_class; enum reg_class cover_class;
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), merge_hard_reg_conflicts (from_a, a, false);
ALLOCNO_CONFLICT_HARD_REGS (from_a));
#ifdef STACK_REGS
if (ALLOCNO_NO_STACK_REG_P (from_a))
ALLOCNO_NO_STACK_REG_P (a) = true;
#endif
ALLOCNO_NREFS (a) += ALLOCNO_NREFS (from_a); ALLOCNO_NREFS (a) += ALLOCNO_NREFS (from_a);
ALLOCNO_FREQ (a) += ALLOCNO_FREQ (from_a); ALLOCNO_FREQ (a) += ALLOCNO_FREQ (from_a);
ALLOCNO_CALL_FREQ (a) += ALLOCNO_CALL_FREQ (from_a); ALLOCNO_CALL_FREQ (a) += ALLOCNO_CALL_FREQ (from_a);
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (from_a));
ALLOCNO_CALLS_CROSSED_NUM (a) += ALLOCNO_CALLS_CROSSED_NUM (from_a); ALLOCNO_CALLS_CROSSED_NUM (a) += ALLOCNO_CALLS_CROSSED_NUM (from_a);
ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
+= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a); += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a);
if (! ALLOCNO_BAD_SPILL_P (from_a)) if (! ALLOCNO_BAD_SPILL_P (from_a))
ALLOCNO_BAD_SPILL_P (a) = false; ALLOCNO_BAD_SPILL_P (a) = false;
#ifdef STACK_REGS
if (ALLOCNO_TOTAL_NO_STACK_REG_P (from_a))
ALLOCNO_TOTAL_NO_STACK_REG_P (a) = true;
#endif
cover_class = ALLOCNO_COVER_CLASS (from_a); cover_class = ALLOCNO_COVER_CLASS (from_a);
ira_assert (cover_class == ALLOCNO_COVER_CLASS (a)); ira_assert (cover_class == ALLOCNO_COVER_CLASS (a));
ira_allocate_and_accumulate_costs (&ALLOCNO_HARD_REG_COSTS (a), cover_class, ira_allocate_and_accumulate_costs (&ALLOCNO_HARD_REG_COSTS (a), cover_class,
...@@ -1930,7 +1966,6 @@ remove_unnecessary_allocnos (void) ...@@ -1930,7 +1966,6 @@ remove_unnecessary_allocnos (void)
bool merged_p, rebuild_p; bool merged_p, rebuild_p;
ira_allocno_t a, prev_a, next_a, parent_a; ira_allocno_t a, prev_a, next_a, parent_a;
ira_loop_tree_node_t a_node, parent; ira_loop_tree_node_t a_node, parent;
allocno_live_range_t r;
merged_p = false; merged_p = false;
regno_allocnos = NULL; regno_allocnos = NULL;
...@@ -1971,13 +2006,8 @@ remove_unnecessary_allocnos (void) ...@@ -1971,13 +2006,8 @@ remove_unnecessary_allocnos (void)
ira_regno_allocno_map[regno] = next_a; ira_regno_allocno_map[regno] = next_a;
else else
ALLOCNO_NEXT_REGNO_ALLOCNO (prev_a) = next_a; ALLOCNO_NEXT_REGNO_ALLOCNO (prev_a) = next_a;
r = ALLOCNO_LIVE_RANGES (a); move_allocno_live_ranges (a, parent_a);
change_allocno_in_range_list (r, parent_a);
ALLOCNO_LIVE_RANGES (parent_a)
= ira_merge_allocno_live_ranges
(r, ALLOCNO_LIVE_RANGES (parent_a));
merged_p = true; merged_p = true;
ALLOCNO_LIVE_RANGES (a) = NULL;
propagate_some_info_from_allocno (parent_a, a); propagate_some_info_from_allocno (parent_a, a);
/* Remove it from the corresponding regno allocno /* Remove it from the corresponding regno allocno
map to avoid info propagation of subsequent map to avoid info propagation of subsequent
...@@ -2011,7 +2041,6 @@ remove_low_level_allocnos (void) ...@@ -2011,7 +2041,6 @@ remove_low_level_allocnos (void)
bool merged_p, propagate_p; bool merged_p, propagate_p;
ira_allocno_t a, top_a; ira_allocno_t a, top_a;
ira_loop_tree_node_t a_node, parent; ira_loop_tree_node_t a_node, parent;
allocno_live_range_t r;
ira_allocno_iterator ai; ira_allocno_iterator ai;
merged_p = false; merged_p = false;
...@@ -2030,12 +2059,8 @@ remove_low_level_allocnos (void) ...@@ -2030,12 +2059,8 @@ remove_low_level_allocnos (void)
propagate_p = a_node->parent->regno_allocno_map[regno] == NULL; propagate_p = a_node->parent->regno_allocno_map[regno] == NULL;
/* Remove the allocno and update info of allocno in the upper /* Remove the allocno and update info of allocno in the upper
region. */ region. */
r = ALLOCNO_LIVE_RANGES (a); move_allocno_live_ranges (a, top_a);
change_allocno_in_range_list (r, top_a);
ALLOCNO_LIVE_RANGES (top_a)
= ira_merge_allocno_live_ranges (r, ALLOCNO_LIVE_RANGES (top_a));
merged_p = true; merged_p = true;
ALLOCNO_LIVE_RANGES (a) = NULL;
if (propagate_p) if (propagate_p)
propagate_some_info_from_allocno (top_a, a); propagate_some_info_from_allocno (top_a, a);
} }
...@@ -2402,7 +2427,6 @@ copy_info_to_removed_store_destinations (int regno) ...@@ -2402,7 +2427,6 @@ copy_info_to_removed_store_destinations (int regno)
ira_allocno_t a; ira_allocno_t a;
ira_allocno_t parent_a = NULL; ira_allocno_t parent_a = NULL;
ira_loop_tree_node_t parent; ira_loop_tree_node_t parent;
allocno_live_range_t r;
bool merged_p; bool merged_p;
merged_p = false; merged_p = false;
...@@ -2425,26 +2449,8 @@ copy_info_to_removed_store_destinations (int regno) ...@@ -2425,26 +2449,8 @@ copy_info_to_removed_store_destinations (int regno)
break; break;
if (parent == NULL || parent_a == NULL) if (parent == NULL || parent_a == NULL)
continue; continue;
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL) copy_allocno_live_ranges (a, parent_a);
{ merge_hard_reg_conflicts (a, parent_a, true);
fprintf
(ira_dump_file,
" Coping ranges of a%dr%d to a%dr%d: ",
ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)),
ALLOCNO_NUM (parent_a), REGNO (ALLOCNO_REG (parent_a)));
ira_print_live_range_list (ira_dump_file,
ALLOCNO_LIVE_RANGES (a));
}
r = ira_copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a));
change_allocno_in_range_list (r, parent_a);
ALLOCNO_LIVE_RANGES (parent_a)
= ira_merge_allocno_live_ranges (r, ALLOCNO_LIVE_RANGES (parent_a));
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a),
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
#ifdef STACK_REGS
if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true;
#endif
ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a); ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a);
ALLOCNO_CALLS_CROSSED_NUM (parent_a) ALLOCNO_CALLS_CROSSED_NUM (parent_a)
+= ALLOCNO_CALLS_CROSSED_NUM (a); += ALLOCNO_CALLS_CROSSED_NUM (a);
...@@ -2522,28 +2528,9 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit) ...@@ -2522,28 +2528,9 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
mem_dest_p = true; mem_dest_p = true;
if (REGNO (ALLOCNO_REG (a)) == REGNO (ALLOCNO_REG (parent_a))) if (REGNO (ALLOCNO_REG (a)) == REGNO (ALLOCNO_REG (parent_a)))
{ {
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a), merge_hard_reg_conflicts (a, parent_a, true);
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a)); move_allocno_live_ranges (a, parent_a);
#ifdef STACK_REGS
if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true;
#endif
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
{
fprintf (ira_dump_file,
" Moving ranges of a%dr%d to a%dr%d: ",
ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)),
ALLOCNO_NUM (parent_a),
REGNO (ALLOCNO_REG (parent_a)));
ira_print_live_range_list (ira_dump_file,
ALLOCNO_LIVE_RANGES (a));
}
change_allocno_in_range_list (ALLOCNO_LIVE_RANGES (a), parent_a);
ALLOCNO_LIVE_RANGES (parent_a)
= ira_merge_allocno_live_ranges
(ALLOCNO_LIVE_RANGES (a), ALLOCNO_LIVE_RANGES (parent_a));
merged_p = true; merged_p = true;
ALLOCNO_LIVE_RANGES (a) = NULL;
ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a) ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a)
= (ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a) = (ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a)
|| ALLOCNO_MEM_OPTIMIZED_DEST_P (a)); || ALLOCNO_MEM_OPTIMIZED_DEST_P (a));
......
...@@ -81,19 +81,13 @@ static int last_call_num; ...@@ -81,19 +81,13 @@ static int last_call_num;
/* The number of last call at which given allocno was saved. */ /* The number of last call at which given allocno was saved. */
static int *allocno_saved_at_call; static int *allocno_saved_at_call;
/* The function processing birth of register REGNO. It updates living /* Record the birth of hard register REGNO, updating hard_regs_live
hard regs and conflict hard regs for living allocnos or starts a and hard reg conflict information for living allocno. */
new live range for the allocno corresponding to REGNO if it is
necessary. */
static void static void
make_regno_born (int regno) make_hard_regno_born (int regno)
{ {
unsigned int i; unsigned int i;
ira_allocno_t a;
allocno_live_range_t p;
if (regno < FIRST_PSEUDO_REGISTER)
{
SET_HARD_REG_BIT (hard_regs_live, regno); SET_HARD_REG_BIT (hard_regs_live, regno);
EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i) EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
{ {
...@@ -102,12 +96,29 @@ make_regno_born (int regno) ...@@ -102,12 +96,29 @@ make_regno_born (int regno)
SET_HARD_REG_BIT (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (ira_allocnos[i]), SET_HARD_REG_BIT (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (ira_allocnos[i]),
regno); regno);
} }
return; }
}
a = ira_curr_regno_allocno_map[regno]; /* Process the death of hard register REGNO. This updates
if (a == NULL) hard_regs_live. */
return; static void
if ((p = ALLOCNO_LIVE_RANGES (a)) == NULL make_hard_regno_dead (int regno)
{
CLEAR_HARD_REG_BIT (hard_regs_live, regno);
}
/* Record the birth of allocno A, starting a new live range for
it if necessary, and updating hard reg conflict information. We also
record it in allocnos_live. */
static void
make_allocno_born (ira_allocno_t a)
{
allocno_live_range_t p = ALLOCNO_LIVE_RANGES (a);
sparseset_set_bit (allocnos_live, ALLOCNO_NUM (a));
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), hard_regs_live);
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), hard_regs_live);
if (p == NULL
|| (p->finish != curr_point && p->finish + 1 != curr_point)) || (p->finish != curr_point && p->finish + 1 != curr_point))
ALLOCNO_LIVE_RANGES (a) ALLOCNO_LIVE_RANGES (a)
= ira_create_allocno_live_range (a, curr_point, -1, = ira_create_allocno_live_range (a, curr_point, -1,
...@@ -137,56 +148,39 @@ update_allocno_pressure_excess_length (ira_allocno_t a) ...@@ -137,56 +148,39 @@ update_allocno_pressure_excess_length (ira_allocno_t a)
} }
} }
/* Process the death of register REGNO. This updates hard_regs_live /* Process the death of allocno A. This finishes the current live
or finishes the current live range for the allocno corresponding to range for it. */
REGNO. */
static void static void
make_regno_dead (int regno) make_allocno_dead (ira_allocno_t a)
{ {
ira_allocno_t a;
allocno_live_range_t p; allocno_live_range_t p;
if (regno < FIRST_PSEUDO_REGISTER)
{
CLEAR_HARD_REG_BIT (hard_regs_live, regno);
return;
}
a = ira_curr_regno_allocno_map[regno];
if (a == NULL)
return;
p = ALLOCNO_LIVE_RANGES (a); p = ALLOCNO_LIVE_RANGES (a);
ira_assert (p != NULL); ira_assert (p != NULL);
p->finish = curr_point; p->finish = curr_point;
update_allocno_pressure_excess_length (a); update_allocno_pressure_excess_length (a);
sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (a));
} }
/* The current register pressures for each cover class for the current /* The current register pressures for each cover class for the current
basic block. */ basic block. */
static int curr_reg_pressure[N_REG_CLASSES]; static int curr_reg_pressure[N_REG_CLASSES];
/* Mark allocno A as currently living and update current register /* Record that register pressure for COVER_CLASS increased by N
pressure, maximal register pressure for the current BB, start point registers. Update the current register pressure, maximal register
of the register pressure excess, and conflicting hard registers of pressure for the current BB and the start point of the register
A. */ pressure excess. */
static void static void
set_allocno_live (ira_allocno_t a) inc_register_pressure (enum reg_class cover_class, int n)
{ {
int i; int i;
enum reg_class cover_class, cl; enum reg_class cl;
/* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
return;
sparseset_set_bit (allocnos_live, ALLOCNO_NUM (a));
IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), hard_regs_live);
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), hard_regs_live);
cover_class = ALLOCNO_COVER_CLASS (a);
for (i = 0; for (i = 0;
(cl = ira_reg_class_super_classes[cover_class][i]) != LIM_REG_CLASSES; (cl = ira_reg_class_super_classes[cover_class][i]) != LIM_REG_CLASSES;
i++) i++)
{ {
curr_reg_pressure[cl] += ira_reg_class_nregs[cl][ALLOCNO_MODE (a)]; curr_reg_pressure[cl] += n;
if (high_pressure_start_point[cl] < 0 if (high_pressure_start_point[cl] < 0
&& (curr_reg_pressure[cl] > ira_available_class_regs[cl])) && (curr_reg_pressure[cl] > ira_available_class_regs[cl]))
high_pressure_start_point[cl] = curr_point; high_pressure_start_point[cl] = curr_point;
...@@ -195,29 +189,24 @@ set_allocno_live (ira_allocno_t a) ...@@ -195,29 +189,24 @@ set_allocno_live (ira_allocno_t a)
} }
} }
/* Mark allocno A as currently not living and update current register /* Record that register pressure for COVER_CLASS has decreased by
pressure, start point of the register pressure excess, and register NREGS registers; update current register pressure, start point of
pressure excess length for living allocnos. */ the register pressure excess, and register pressure excess length
for living allocnos. */
static void static void
clear_allocno_live (ira_allocno_t a) dec_register_pressure (enum reg_class cover_class, int nregs)
{ {
int i; int i;
unsigned int j; unsigned int j;
enum reg_class cover_class, cl; enum reg_class cl;
bool set_p; bool set_p = false;
/* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
{
cover_class = ALLOCNO_COVER_CLASS (a);
set_p = false;
for (i = 0; for (i = 0;
(cl = ira_reg_class_super_classes[cover_class][i]) (cl = ira_reg_class_super_classes[cover_class][i]) != LIM_REG_CLASSES;
!= LIM_REG_CLASSES;
i++) i++)
{ {
curr_reg_pressure[cl] -= ira_reg_class_nregs[cl][ALLOCNO_MODE (a)]; curr_reg_pressure[cl] -= nregs;
ira_assert (curr_reg_pressure[cl] >= 0); ira_assert (curr_reg_pressure[cl] >= 0);
if (high_pressure_start_point[cl] >= 0 if (high_pressure_start_point[cl] >= 0
&& curr_reg_pressure[cl] <= ira_available_class_regs[cl]) && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
...@@ -234,71 +223,53 @@ clear_allocno_live (ira_allocno_t a) ...@@ -234,71 +223,53 @@ clear_allocno_live (ira_allocno_t a)
if (high_pressure_start_point[cl] >= 0 if (high_pressure_start_point[cl] >= 0
&& curr_reg_pressure[cl] <= ira_available_class_regs[cl]) && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
high_pressure_start_point[cl] = -1; high_pressure_start_point[cl] = -1;
} }
}
sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (a));
} }
/* Mark the register REG as live. Store a 1 in hard_regs_live or /* Mark the pseudo register REGNO as live. Update all information about
allocnos_live for this register or the corresponding allocno, live ranges and register pressure. */
record how many consecutive hardware registers it actually
needs. */
static void static void
mark_reg_live (rtx reg) mark_pseudo_regno_live (int regno)
{ {
int i, regno;
gcc_assert (REG_P (reg));
regno = REGNO (reg);
if (regno >= FIRST_PSEUDO_REGISTER)
{
ira_allocno_t a = ira_curr_regno_allocno_map[regno]; ira_allocno_t a = ira_curr_regno_allocno_map[regno];
enum reg_class cl;
int nregs;
if (a == NULL)
return;
if (a != NULL)
{
if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
{
/* Invalidate because it is referenced. */ /* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0; allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
return; return;
}
set_allocno_live (a); cl = ALLOCNO_COVER_CLASS (a);
} nregs = ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
make_regno_born (regno); inc_register_pressure (cl, nregs);
} make_allocno_born (a);
else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)) }
/* Mark the hard register REG as live. Store a 1 in hard_regs_live
for this register, record how many consecutive hardware registers
it actually needs. */
static void
mark_hard_reg_live (rtx reg)
{
int regno = REGNO (reg);
if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
{ {
int last = regno + hard_regno_nregs[regno][GET_MODE (reg)]; int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
enum reg_class cover_class, cl;
while (regno < last) while (regno < last)
{ {
if (! TEST_HARD_REG_BIT (hard_regs_live, regno) if (! TEST_HARD_REG_BIT (hard_regs_live, regno)
&& ! TEST_HARD_REG_BIT (eliminable_regset, regno)) && ! TEST_HARD_REG_BIT (eliminable_regset, regno))
{ {
cover_class = ira_hard_regno_cover_class[regno]; enum reg_class cover_class = ira_hard_regno_cover_class[regno];
for (i = 0; inc_register_pressure (cover_class, 1);
(cl = ira_reg_class_super_classes[cover_class][i]) make_hard_regno_born (regno);
!= LIM_REG_CLASSES;
i++)
{
curr_reg_pressure[cl]++;
if (high_pressure_start_point[cl] < 0
&& (curr_reg_pressure[cl]
> ira_available_class_regs[cl]))
high_pressure_start_point[cl] = curr_point;
}
make_regno_born (regno);
for (i = 0;
(cl = ira_reg_class_super_classes[cover_class][i])
!= LIM_REG_CLASSES;
i++)
{
if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
}
} }
regno++; regno++;
} }
...@@ -314,74 +285,55 @@ mark_ref_live (df_ref ref) ...@@ -314,74 +285,55 @@ mark_ref_live (df_ref ref)
reg = DF_REF_REG (ref); reg = DF_REF_REG (ref);
if (GET_CODE (reg) == SUBREG) if (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg); reg = SUBREG_REG (reg);
mark_reg_live (reg); if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
mark_pseudo_regno_live (REGNO (reg));
else
mark_hard_reg_live (reg);
} }
/* Mark the register REG as dead. Store a 0 in hard_regs_live or /* Mark the pseudo register REGNO as dead. Update all information about
allocnos_live for the register. */ live ranges and register pressure. */
static void static void
mark_reg_dead (rtx reg) mark_pseudo_regno_dead (int regno)
{ {
int regno;
gcc_assert (REG_P (reg));
regno = REGNO (reg);
if (regno >= FIRST_PSEUDO_REGISTER)
{
ira_allocno_t a = ira_curr_regno_allocno_map[regno]; ira_allocno_t a = ira_curr_regno_allocno_map[regno];
enum reg_class cl;
int nregs;
if (a == NULL)
return;
if (a != NULL)
{
if (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
{
/* Invalidate because it is referenced. */ /* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0; allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
if (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
return; return;
}
clear_allocno_live (a); cl = ALLOCNO_COVER_CLASS (a);
} nregs = ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
make_regno_dead (regno); dec_register_pressure (cl, nregs);
}
else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)) make_allocno_dead (a);
}
/* Mark the hard register REG as dead. Store a 0 in hard_regs_live
for the register. */
static void
mark_hard_reg_dead (rtx reg)
{
int regno = REGNO (reg);
if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
{ {
int i;
unsigned int j;
int last = regno + hard_regno_nregs[regno][GET_MODE (reg)]; int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
enum reg_class cover_class, cl;
bool set_p;
while (regno < last) while (regno < last)
{ {
if (TEST_HARD_REG_BIT (hard_regs_live, regno)) if (TEST_HARD_REG_BIT (hard_regs_live, regno))
{ {
set_p = false; enum reg_class cover_class = ira_hard_regno_cover_class[regno];
cover_class = ira_hard_regno_cover_class[regno]; dec_register_pressure (cover_class, 1);
for (i = 0; make_hard_regno_dead (regno);
(cl = ira_reg_class_super_classes[cover_class][i])
!= LIM_REG_CLASSES;
i++)
{
curr_reg_pressure[cl]--;
if (high_pressure_start_point[cl] >= 0
&& curr_reg_pressure[cl] <= ira_available_class_regs[cl])
set_p = true;
ira_assert (curr_reg_pressure[cl] >= 0);
}
if (set_p)
{
EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
update_allocno_pressure_excess_length (ira_allocnos[j]);
for (i = 0;
(cl = ira_reg_class_super_classes[cover_class][i])
!= LIM_REG_CLASSES;
i++)
if (high_pressure_start_point[cl] >= 0
&& (curr_reg_pressure[cl]
<= ira_available_class_regs[cl]))
high_pressure_start_point[cl] = -1;
}
make_regno_dead (regno);
} }
regno++; regno++;
} }
...@@ -402,7 +354,10 @@ mark_ref_dead (df_ref def) ...@@ -402,7 +354,10 @@ mark_ref_dead (df_ref def)
reg = DF_REF_REG (def); reg = DF_REF_REG (def);
if (GET_CODE (reg) == SUBREG) if (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg); reg = SUBREG_REG (reg);
mark_reg_dead (reg); if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
mark_pseudo_regno_dead (REGNO (reg));
else
mark_hard_reg_dead (reg);
} }
/* Make pseudo REG conflicting with pseudo DREG, if the 1st pseudo /* Make pseudo REG conflicting with pseudo DREG, if the 1st pseudo
...@@ -427,10 +382,10 @@ make_pseudo_conflict (rtx reg, enum reg_class cl, rtx dreg, bool advance_p) ...@@ -427,10 +382,10 @@ make_pseudo_conflict (rtx reg, enum reg_class cl, rtx dreg, bool advance_p)
if (advance_p) if (advance_p)
curr_point++; curr_point++;
mark_reg_live (reg); mark_pseudo_regno_live (REGNO (reg));
mark_reg_live (dreg); mark_pseudo_regno_live (REGNO (dreg));
mark_reg_dead (reg); mark_pseudo_regno_dead (REGNO (reg));
mark_reg_dead (dreg); mark_pseudo_regno_dead (REGNO (dreg));
return false; return false;
} }
...@@ -961,15 +916,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) ...@@ -961,15 +916,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
} }
} }
EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi) EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
{ mark_pseudo_regno_live (j);
ira_allocno_t a = ira_curr_regno_allocno_map[j];
if (a == NULL)
continue;
ira_assert (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)));
set_allocno_live (a);
make_regno_born (j);
}
freq = REG_FREQ_FROM_BB (bb); freq = REG_FREQ_FROM_BB (bb);
if (freq == 0) if (freq == 0)
...@@ -1137,7 +1084,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) ...@@ -1137,7 +1084,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
unsigned int regno = EH_RETURN_DATA_REGNO (j); unsigned int regno = EH_RETURN_DATA_REGNO (j);
if (regno == INVALID_REGNUM) if (regno == INVALID_REGNUM)
break; break;
make_regno_born (regno); make_hard_regno_born (regno);
} }
#endif #endif
...@@ -1155,7 +1102,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) ...@@ -1155,7 +1102,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
ALLOCNO_TOTAL_NO_STACK_REG_P (ira_allocnos[px]) = true; ALLOCNO_TOTAL_NO_STACK_REG_P (ira_allocnos[px]) = true;
} }
for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++) for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++)
make_regno_born (px); make_hard_regno_born (px);
#endif #endif
/* No need to record conflicts for call clobbered regs if we /* No need to record conflicts for call clobbered regs if we
have nonlocal labels around, as we don't ever try to have nonlocal labels around, as we don't ever try to
...@@ -1163,13 +1110,11 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) ...@@ -1163,13 +1110,11 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb)) if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb))
for (px = 0; px < FIRST_PSEUDO_REGISTER; px++) for (px = 0; px < FIRST_PSEUDO_REGISTER; px++)
if (call_used_regs[px]) if (call_used_regs[px])
make_regno_born (px); make_hard_regno_born (px);
} }
EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i) EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
{ make_allocno_dead (ira_allocnos[i]);
make_regno_dead (ALLOCNO_REGNO (ira_allocnos[i]));
}
curr_point++; curr_point++;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment