Commit cb1ca6ac by Vladimir Makarov Committed by Vladimir Makarov

ira-int.h (ira_allocno): Add member updated_cover_class_cost.

2008-10-27  Vladimir Makarov  <vmakarov@redhat.com>

	* ira-int.h (ira_allocno): Add member updated_cover_class_cost.
	(ALLOCNO_UPDATED_COVER_CLASS_COST): New.
	(ira_fast_allocation): Remove the prototype.
	
	* ira-color.c (update_copy_costs, allocno_cost_compare_func,
	assign_hard_reg, calculate_allocno_spill_cost): Use updated costs.
	(color_pass): Modify the updated costs.
	(ira_color): Rename to color.  Make it static.
	(ira_fast_allocation): Rename to fast_allocation.  Make it static.
	(ira_color): New function.
	
	* ira-conflicts.c (process_regs_for_copy): Propagate hard reg cost
	change.

	* ira-lives.c (last_call_num, allocno_saved_at_call): New
	variables.
	(set_allocno_live, clear_allocno_live, mark_ref_live,
	mark_ref_dead): Invalidate corresponding element of
	allocno_saved_at_call.
	(process_bb_node_lives): Increment last_call_num.  Setup
	allocno_saved_at_call.  Don't increase ALLOCNO_CALL_FREQ if the
	allocno was already saved.
	(ira_create_allocno_live_ranges): Initiate last_call_num and
	allocno_saved_at_call.

	* ira-build.c (ira_create_allocno): Initiate
	ALLOCNO_UPDATED_COVER_CLASS_COST.
	(create_cap_allocno, propagate_allocno_info,
	remove_unnecessary_allocnos): Remove setting updated costs.
	(ira_flattening): Set up ALLOCNO_UPDATED_COVER_CLASS_COST.

	* ira.c (ira):  Don't call ira_fast_allocation.

	* ira-costs.c (setup_allocno_cover_class_and_costs): Don't set up
	updated costs.

From-SVN: r141385
parent c0683a82
2008-10-27 Vladimir Makarov <vmakarov@redhat.com> 2008-10-27 Vladimir Makarov <vmakarov@redhat.com>
* ira-int.h (ira_allocno): Add member updated_cover_class_cost.
(ALLOCNO_UPDATED_COVER_CLASS_COST): New.
(ira_fast_allocation): Remove the prototype.
* ira-color.c (update_copy_costs, allocno_cost_compare_func,
assign_hard_reg, calculate_allocno_spill_cost): Use updated costs.
(color_pass): Modify the updated costs.
(ira_color): Rename to color. Make it static.
(ira_fast_allocation): Rename to fast_allocation. Make it static.
(ira_color): New function.
* ira-conflicts.c (process_regs_for_copy): Propagate hard reg cost
change.
* ira-lives.c (last_call_num, allocno_saved_at_call): New
variables.
(set_allocno_live, clear_allocno_live, mark_ref_live,
mark_ref_dead): Invalidate corresponding element of
allocno_saved_at_call.
(process_bb_node_lives): Increment last_call_num. Setup
allocno_saved_at_call. Don't increase ALLOCNO_CALL_FREQ if the
allocno was already saved.
(ira_create_allocno_live_ranges): Initiate last_call_num and
allocno_saved_at_call.
* ira-build.c (ira_create_allocno): Initiate
ALLOCNO_UPDATED_COVER_CLASS_COST.
(create_cap_allocno, propagate_allocno_info,
remove_unnecessary_allocnos): Remove setting updated costs.
(ira_flattening): Set up ALLOCNO_UPDATED_COVER_CLASS_COST.
* ira.c (ira): Don't call ira_fast_allocation.
* ira-costs.c (setup_allocno_cover_class_and_costs): Don't set up
updated costs.
2008-10-27 Vladimir Makarov <vmakarov@redhat.com>
PR middle-end/37813 PR middle-end/37813
* ira-conflicts.c (process_regs_for_copy): Remove class subset * ira-conflicts.c (process_regs_for_copy): Remove class subset
check. check.
......
...@@ -469,6 +469,7 @@ ira_create_allocno (int regno, bool cap_p, ira_loop_tree_node_t loop_tree_node) ...@@ -469,6 +469,7 @@ ira_create_allocno (int regno, bool cap_p, ira_loop_tree_node_t loop_tree_node)
ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) = NULL; ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) = NULL;
ALLOCNO_LEFT_CONFLICTS_NUM (a) = -1; ALLOCNO_LEFT_CONFLICTS_NUM (a) = -1;
ALLOCNO_COVER_CLASS (a) = NO_REGS; ALLOCNO_COVER_CLASS (a) = NO_REGS;
ALLOCNO_UPDATED_COVER_CLASS_COST (a) = 0;
ALLOCNO_COVER_CLASS_COST (a) = 0; ALLOCNO_COVER_CLASS_COST (a) = 0;
ALLOCNO_MEMORY_COST (a) = 0; ALLOCNO_MEMORY_COST (a) = 0;
ALLOCNO_UPDATED_MEMORY_COST (a) = 0; ALLOCNO_UPDATED_MEMORY_COST (a) = 0;
...@@ -769,7 +770,6 @@ create_cap_allocno (ira_allocno_t a) ...@@ -769,7 +770,6 @@ create_cap_allocno (ira_allocno_t a)
ALLOCNO_CAP (a) = cap; ALLOCNO_CAP (a) = cap;
ALLOCNO_COVER_CLASS_COST (cap) = ALLOCNO_COVER_CLASS_COST (a); ALLOCNO_COVER_CLASS_COST (cap) = ALLOCNO_COVER_CLASS_COST (a);
ALLOCNO_MEMORY_COST (cap) = ALLOCNO_MEMORY_COST (a); ALLOCNO_MEMORY_COST (cap) = ALLOCNO_MEMORY_COST (a);
ALLOCNO_UPDATED_MEMORY_COST (cap) = ALLOCNO_UPDATED_MEMORY_COST (a);
ira_allocate_and_copy_costs ira_allocate_and_copy_costs
(&ALLOCNO_HARD_REG_COSTS (cap), cover_class, ALLOCNO_HARD_REG_COSTS (a)); (&ALLOCNO_HARD_REG_COSTS (cap), cover_class, ALLOCNO_HARD_REG_COSTS (a));
ira_allocate_and_copy_costs ira_allocate_and_copy_costs
...@@ -1509,8 +1509,6 @@ propagate_allocno_info (void) ...@@ -1509,8 +1509,6 @@ propagate_allocno_info (void)
ALLOCNO_COVER_CLASS_COST (parent_a) ALLOCNO_COVER_CLASS_COST (parent_a)
+= ALLOCNO_COVER_CLASS_COST (a); += ALLOCNO_COVER_CLASS_COST (a);
ALLOCNO_MEMORY_COST (parent_a) += ALLOCNO_MEMORY_COST (a); ALLOCNO_MEMORY_COST (parent_a) += ALLOCNO_MEMORY_COST (a);
ALLOCNO_UPDATED_MEMORY_COST (parent_a)
+= ALLOCNO_UPDATED_MEMORY_COST (a);
} }
} }
...@@ -1789,8 +1787,6 @@ remove_unnecessary_allocnos (void) ...@@ -1789,8 +1787,6 @@ remove_unnecessary_allocnos (void)
ALLOCNO_COVER_CLASS_COST (parent_a) ALLOCNO_COVER_CLASS_COST (parent_a)
+= ALLOCNO_COVER_CLASS_COST (a); += ALLOCNO_COVER_CLASS_COST (a);
ALLOCNO_MEMORY_COST (parent_a) += ALLOCNO_MEMORY_COST (a); ALLOCNO_MEMORY_COST (parent_a) += ALLOCNO_MEMORY_COST (a);
ALLOCNO_UPDATED_MEMORY_COST (parent_a)
+= ALLOCNO_UPDATED_MEMORY_COST (a);
finish_allocno (a); finish_allocno (a);
} }
} }
...@@ -2353,7 +2349,9 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit) ...@@ -2353,7 +2349,9 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
ALLOCNO_LOOP_TREE_NODE (a) = ira_loop_tree_root; ALLOCNO_LOOP_TREE_NODE (a) = ira_loop_tree_root;
ALLOCNO_REGNO (a) = REGNO (ALLOCNO_REG (a)); ALLOCNO_REGNO (a) = REGNO (ALLOCNO_REG (a));
ALLOCNO_CAP (a) = NULL; ALLOCNO_CAP (a) = NULL;
/* Restore updated costs for assignments from reload. */
ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a); ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
ALLOCNO_UPDATED_COVER_CLASS_COST (a) = ALLOCNO_COVER_CLASS_COST (a);
if (! ALLOCNO_ASSIGNED_P (a)) if (! ALLOCNO_ASSIGNED_P (a))
ira_free_allocno_updated_costs (a); ira_free_allocno_updated_costs (a);
ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL); ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
......
...@@ -252,7 +252,7 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p) ...@@ -252,7 +252,7 @@ update_copy_costs (ira_allocno_t allocno, bool decr_p)
ira_allocate_and_set_or_copy_costs ira_allocate_and_set_or_copy_costs
(&ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno), cover_class, (&ALLOCNO_UPDATED_HARD_REG_COSTS (another_allocno), cover_class,
ALLOCNO_COVER_CLASS_COST (another_allocno), ALLOCNO_UPDATED_COVER_CLASS_COST (another_allocno),
ALLOCNO_HARD_REG_COSTS (another_allocno)); ALLOCNO_HARD_REG_COSTS (another_allocno));
ira_allocate_and_set_or_copy_costs ira_allocate_and_set_or_copy_costs
(&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno), (&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (another_allocno),
...@@ -348,8 +348,8 @@ allocno_cost_compare_func (const void *v1p, const void *v2p) ...@@ -348,8 +348,8 @@ allocno_cost_compare_func (const void *v1p, const void *v2p)
ira_allocno_t p2 = *(const ira_allocno_t *) v2p; ira_allocno_t p2 = *(const ira_allocno_t *) v2p;
int c1, c2; int c1, c2;
c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_COVER_CLASS_COST (p1); c1 = ALLOCNO_UPDATED_MEMORY_COST (p1) - ALLOCNO_UPDATED_COVER_CLASS_COST (p1);
c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_COVER_CLASS_COST (p2); c2 = ALLOCNO_UPDATED_MEMORY_COST (p2) - ALLOCNO_UPDATED_COVER_CLASS_COST (p2);
if (c1 - c2) if (c1 - c2)
return c1 - c2; return c1 - c2;
...@@ -426,7 +426,9 @@ assign_hard_reg (ira_allocno_t allocno, bool retry_p) ...@@ -426,7 +426,9 @@ assign_hard_reg (ira_allocno_t allocno, bool retry_p)
#ifdef STACK_REGS #ifdef STACK_REGS
no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a); no_stack_reg_p = no_stack_reg_p || ALLOCNO_TOTAL_NO_STACK_REG_P (a);
#endif #endif
for (cost = ALLOCNO_COVER_CLASS_COST (a), i = 0; i < class_size; i++) for (cost = ALLOCNO_UPDATED_COVER_CLASS_COST (a), i = 0;
i < class_size;
i++)
if (a_costs != NULL) if (a_costs != NULL)
{ {
costs[i] += a_costs[i]; costs[i] += a_costs[i];
...@@ -959,7 +961,7 @@ calculate_allocno_spill_cost (ira_allocno_t a) ...@@ -959,7 +961,7 @@ calculate_allocno_spill_cost (ira_allocno_t a)
ira_loop_tree_node_t parent_node, loop_node; ira_loop_tree_node_t parent_node, loop_node;
regno = ALLOCNO_REGNO (a); regno = ALLOCNO_REGNO (a);
cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_COVER_CLASS_COST (a); cost = ALLOCNO_UPDATED_MEMORY_COST (a) - ALLOCNO_UPDATED_COVER_CLASS_COST (a);
if (ALLOCNO_CAP (a) != NULL) if (ALLOCNO_CAP (a) != NULL)
return cost; return cost;
loop_node = ALLOCNO_LOOP_TREE_NODE (a); loop_node = ALLOCNO_LOOP_TREE_NODE (a);
...@@ -1821,24 +1823,26 @@ color_pass (ira_loop_tree_node_t loop_tree_node) ...@@ -1821,24 +1823,26 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
else else
{ {
cover_class = ALLOCNO_COVER_CLASS (subloop_allocno); cover_class = ALLOCNO_COVER_CLASS (subloop_allocno);
ira_allocate_and_set_costs
(&ALLOCNO_HARD_REG_COSTS (subloop_allocno), cover_class,
ALLOCNO_COVER_CLASS_COST (subloop_allocno));
ira_allocate_and_set_costs
(&ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno),
cover_class, 0);
cost = (ira_register_move_cost[mode][rclass][rclass] cost = (ira_register_move_cost[mode][rclass][rclass]
* (exit_freq + enter_freq)); * (exit_freq + enter_freq));
ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index] -= cost; ira_allocate_and_set_or_copy_costs
ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index] (&ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno), cover_class,
ALLOCNO_UPDATED_COVER_CLASS_COST (subloop_allocno),
ALLOCNO_HARD_REG_COSTS (subloop_allocno));
ira_allocate_and_set_or_copy_costs
(&ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno),
cover_class, 0,
ALLOCNO_CONFLICT_HARD_REG_COSTS (subloop_allocno));
ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index] -= cost;
ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (subloop_allocno)[index]
-= cost; -= cost;
if (ALLOCNO_UPDATED_COVER_CLASS_COST (subloop_allocno)
> ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index])
ALLOCNO_UPDATED_COVER_CLASS_COST (subloop_allocno)
= ALLOCNO_UPDATED_HARD_REG_COSTS (subloop_allocno)[index];
ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno) ALLOCNO_UPDATED_MEMORY_COST (subloop_allocno)
+= (ira_memory_move_cost[mode][rclass][0] * enter_freq += (ira_memory_move_cost[mode][rclass][0] * enter_freq
+ ira_memory_move_cost[mode][rclass][1] * exit_freq); + ira_memory_move_cost[mode][rclass][1] * exit_freq);
if (ALLOCNO_COVER_CLASS_COST (subloop_allocno)
> ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index])
ALLOCNO_COVER_CLASS_COST (subloop_allocno)
= ALLOCNO_HARD_REG_COSTS (subloop_allocno)[index];
} }
} }
} }
...@@ -3054,8 +3058,8 @@ ira_finish_assign (void) ...@@ -3054,8 +3058,8 @@ ira_finish_assign (void)
/* Entry function doing color-based register allocation. */ /* Entry function doing color-based register allocation. */
void static void
ira_color (void) color (void)
{ {
allocno_stack_vec = VEC_alloc (ira_allocno_t, heap, ira_allocnos_num); allocno_stack_vec = VEC_alloc (ira_allocno_t, heap, ira_allocnos_num);
removed_splay_allocno_vec removed_splay_allocno_vec
...@@ -3077,8 +3081,8 @@ ira_color (void) ...@@ -3077,8 +3081,8 @@ ira_color (void)
/* Do register allocation by not using allocno conflicts. It uses /* Do register allocation by not using allocno conflicts. It uses
only allocno live ranges. The algorithm is close to Chow's only allocno live ranges. The algorithm is close to Chow's
priority coloring. */ priority coloring. */
void static void
ira_fast_allocation (void) fast_allocation (void)
{ {
int i, j, k, num, class_size, hard_regno; int i, j, k, num, class_size, hard_regno;
#ifdef STACK_REGS #ifdef STACK_REGS
...@@ -3148,3 +3152,24 @@ ira_fast_allocation (void) ...@@ -3148,3 +3152,24 @@ ira_fast_allocation (void)
if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL) if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
ira_print_disposition (ira_dump_file); ira_print_disposition (ira_dump_file);
} }
/* Entry function doing coloring. */
void
ira_color (void)
{
ira_allocno_t a;
ira_allocno_iterator ai;
/* Setup updated costs. */
FOR_EACH_ALLOCNO (a, ai)
{
ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
ALLOCNO_UPDATED_COVER_CLASS_COST (a) = ALLOCNO_COVER_CLASS_COST (a);
}
if (optimize)
color ();
else
fast_allocation ();
}
...@@ -337,6 +337,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, rtx insn, int freq) ...@@ -337,6 +337,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, rtx insn, int freq)
enum reg_class rclass, cover_class; enum reg_class rclass, cover_class;
enum machine_mode mode; enum machine_mode mode;
ira_copy_t cp; ira_copy_t cp;
ira_loop_tree_node_t parent;
gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2)); gcc_assert (REG_SUBREG_P (reg1) && REG_SUBREG_P (reg2));
only_regs_p = REG_P (reg1) && REG_P (reg2); only_regs_p = REG_P (reg1) && REG_P (reg2);
...@@ -386,6 +387,8 @@ process_regs_for_copy (rtx reg1, rtx reg2, rtx insn, int freq) ...@@ -386,6 +387,8 @@ process_regs_for_copy (rtx reg1, rtx reg2, rtx insn, int freq)
cost = ira_register_move_cost[mode][cover_class][rclass] * freq; cost = ira_register_move_cost[mode][cover_class][rclass] * freq;
else else
cost = ira_register_move_cost[mode][rclass][cover_class] * freq; cost = ira_register_move_cost[mode][rclass][cover_class] * freq;
for (;;)
{
ira_allocate_and_set_costs ira_allocate_and_set_costs
(&ALLOCNO_HARD_REG_COSTS (a), cover_class, (&ALLOCNO_HARD_REG_COSTS (a), cover_class,
ALLOCNO_COVER_CLASS_COST (a)); ALLOCNO_COVER_CLASS_COST (a));
...@@ -393,6 +396,14 @@ process_regs_for_copy (rtx reg1, rtx reg2, rtx insn, int freq) ...@@ -393,6 +396,14 @@ process_regs_for_copy (rtx reg1, rtx reg2, rtx insn, int freq)
(&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), cover_class, 0); (&ALLOCNO_CONFLICT_HARD_REG_COSTS (a), cover_class, 0);
ALLOCNO_HARD_REG_COSTS (a)[index] -= cost; ALLOCNO_HARD_REG_COSTS (a)[index] -= cost;
ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost; ALLOCNO_CONFLICT_HARD_REG_COSTS (a)[index] -= cost;
if (ALLOCNO_HARD_REG_COSTS (a)[index] < ALLOCNO_COVER_CLASS_COST (a))
ALLOCNO_COVER_CLASS_COST (a) = ALLOCNO_HARD_REG_COSTS (a)[index];
if (ALLOCNO_CAP (a) != NULL)
a = ALLOCNO_CAP (a);
else if ((parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) == NULL
|| (a = parent->regno_allocno_map[ALLOCNO_REGNO (a)]) == NULL)
break;
}
return true; return true;
} }
......
...@@ -1407,8 +1407,7 @@ setup_allocno_cover_class_and_costs (void) ...@@ -1407,8 +1407,7 @@ setup_allocno_cover_class_and_costs (void)
mode = ALLOCNO_MODE (a); mode = ALLOCNO_MODE (a);
cover_class = ira_class_translate[allocno_pref[i]]; cover_class = ira_class_translate[allocno_pref[i]];
ira_assert (allocno_pref[i] == NO_REGS || cover_class != NO_REGS); ira_assert (allocno_pref[i] == NO_REGS || cover_class != NO_REGS);
ALLOCNO_MEMORY_COST (a) = ALLOCNO_UPDATED_MEMORY_COST (a) ALLOCNO_MEMORY_COST (a) = COSTS_OF_ALLOCNO (allocno_costs, i)->mem_cost;
= COSTS_OF_ALLOCNO (allocno_costs, i)->mem_cost;
ira_set_allocno_cover_class (a, cover_class); ira_set_allocno_cover_class (a, cover_class);
if (cover_class == NO_REGS) if (cover_class == NO_REGS)
continue; continue;
......
...@@ -258,9 +258,9 @@ struct ira_allocno ...@@ -258,9 +258,9 @@ struct ira_allocno
/* Register class which should be used for allocation for given /* Register class which should be used for allocation for given
allocno. NO_REGS means that we should use memory. */ allocno. NO_REGS means that we should use memory. */
enum reg_class cover_class; enum reg_class cover_class;
/* Minimal accumulated cost of usage register of the cover class for /* Minimal accumulated and updated costs of usage register of the
the allocno. */ cover class for the allocno. */
int cover_class_cost; int cover_class_cost, updated_cover_class_cost;
/* Minimal accumulated, and updated costs of memory for the allocno. /* Minimal accumulated, and updated costs of memory for the allocno.
At the allocation start, the original and updated costs are At the allocation start, the original and updated costs are
equal. The updated cost may be changed after finishing equal. The updated cost may be changed after finishing
...@@ -451,6 +451,7 @@ struct ira_allocno ...@@ -451,6 +451,7 @@ struct ira_allocno
#define ALLOCNO_LEFT_CONFLICTS_NUM(A) ((A)->left_conflicts_num) #define ALLOCNO_LEFT_CONFLICTS_NUM(A) ((A)->left_conflicts_num)
#define ALLOCNO_COVER_CLASS(A) ((A)->cover_class) #define ALLOCNO_COVER_CLASS(A) ((A)->cover_class)
#define ALLOCNO_COVER_CLASS_COST(A) ((A)->cover_class_cost) #define ALLOCNO_COVER_CLASS_COST(A) ((A)->cover_class_cost)
#define ALLOCNO_UPDATED_COVER_CLASS_COST(A) ((A)->updated_cover_class_cost)
#define ALLOCNO_MEMORY_COST(A) ((A)->memory_cost) #define ALLOCNO_MEMORY_COST(A) ((A)->memory_cost)
#define ALLOCNO_UPDATED_MEMORY_COST(A) ((A)->updated_memory_cost) #define ALLOCNO_UPDATED_MEMORY_COST(A) ((A)->updated_memory_cost)
#define ALLOCNO_EXCESS_PRESSURE_POINTS_NUM(A) ((A)->excess_pressure_points_num) #define ALLOCNO_EXCESS_PRESSURE_POINTS_NUM(A) ((A)->excess_pressure_points_num)
...@@ -902,7 +903,6 @@ extern void ira_reassign_conflict_allocnos (int); ...@@ -902,7 +903,6 @@ extern void ira_reassign_conflict_allocnos (int);
extern void ira_initiate_assign (void); extern void ira_initiate_assign (void);
extern void ira_finish_assign (void); extern void ira_finish_assign (void);
extern void ira_color (void); extern void ira_color (void);
extern void ira_fast_allocation (void);
/* ira-emit.c */ /* ira-emit.c */
extern void ira_emit (bool); extern void ira_emit (bool);
......
...@@ -75,6 +75,11 @@ static HARD_REG_SET hard_regs_live; ...@@ -75,6 +75,11 @@ static HARD_REG_SET hard_regs_live;
/* The loop tree node corresponding to the current basic block. */ /* The loop tree node corresponding to the current basic block. */
static ira_loop_tree_node_t curr_bb_node; static ira_loop_tree_node_t curr_bb_node;
/* The number of the last processed call. */
static int last_call_num;
/* The number of last call at which given allocno was saved. */
static int *allocno_saved_at_call;
/* The function processing birth of register REGNO. It updates living /* The function processing birth of register REGNO. It updates living
hard regs and conflict hard regs for living allocnos or starts a hard regs and conflict hard regs for living allocnos or starts a
new live range for the allocno corresponding to REGNO if it is new live range for the allocno corresponding to REGNO if it is
...@@ -163,6 +168,8 @@ set_allocno_live (ira_allocno_t a) ...@@ -163,6 +168,8 @@ set_allocno_live (ira_allocno_t a)
int nregs; int nregs;
enum reg_class cover_class; enum reg_class cover_class;
/* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a))) if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
return; return;
sparseset_set_bit (allocnos_live, ALLOCNO_NUM (a)); sparseset_set_bit (allocnos_live, ALLOCNO_NUM (a));
...@@ -189,6 +196,8 @@ clear_allocno_live (ira_allocno_t a) ...@@ -189,6 +196,8 @@ clear_allocno_live (ira_allocno_t a)
unsigned int i; unsigned int i;
enum reg_class cover_class; enum reg_class cover_class;
/* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a))) if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
{ {
cover_class = ALLOCNO_COVER_CLASS (a); cover_class = ALLOCNO_COVER_CLASS (a);
...@@ -228,7 +237,11 @@ mark_reg_live (rtx reg) ...@@ -228,7 +237,11 @@ mark_reg_live (rtx reg)
if (a != NULL) if (a != NULL)
{ {
if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a))) if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
{
/* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
return; return;
}
set_allocno_live (a); set_allocno_live (a);
} }
make_regno_born (regno); make_regno_born (regno);
...@@ -293,7 +306,11 @@ mark_reg_dead (rtx reg) ...@@ -293,7 +306,11 @@ mark_reg_dead (rtx reg)
if (a != NULL) if (a != NULL)
{ {
if (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a))) if (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
{
/* Invalidate because it is referenced. */
allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
return; return;
}
clear_allocno_live (a); clear_allocno_live (a);
} }
make_regno_dead (regno); make_regno_dead (regno);
...@@ -820,6 +837,9 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) ...@@ -820,6 +837,9 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
if (freq == 0) if (freq == 0)
freq = 1; freq = 1;
/* Invalidate all allocno_saved_at_call entries. */
last_call_num++;
/* Scan the code of this basic block, noting which allocnos and /* Scan the code of this basic block, noting which allocnos and
hard regs are born or die. hard regs are born or die.
...@@ -901,12 +921,21 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) ...@@ -901,12 +921,21 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
if (call_p) if (call_p)
{ {
last_call_num++;
/* The current set of live allocnos are live across the call. */ /* The current set of live allocnos are live across the call. */
EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i) EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
{ {
ira_allocno_t a = ira_allocnos[i]; ira_allocno_t a = ira_allocnos[i];
if (allocno_saved_at_call[i] != last_call_num)
/* Here we are mimicking caller-save.c behaviour
which does not save hard register at a call if
it was saved on previous call in the same basic
block and the hard register was not mentioned
between the two calls. */
ALLOCNO_CALL_FREQ (a) += freq; ALLOCNO_CALL_FREQ (a) += freq;
/* Mark it as saved at the next call. */
allocno_saved_at_call[i] = last_call_num + 1;
ALLOCNO_CALLS_CROSSED_NUM (a)++; ALLOCNO_CALLS_CROSSED_NUM (a)++;
/* Don't allocate allocnos that cross setjmps or any /* Don't allocate allocnos that cross setjmps or any
call, if this function receives a nonlocal call, if this function receives a nonlocal
...@@ -1152,6 +1181,10 @@ ira_create_allocno_live_ranges (void) ...@@ -1152,6 +1181,10 @@ ira_create_allocno_live_ranges (void)
{ {
allocnos_live = sparseset_alloc (ira_allocnos_num); allocnos_live = sparseset_alloc (ira_allocnos_num);
curr_point = 0; curr_point = 0;
last_call_num = 0;
allocno_saved_at_call
= (int *) ira_allocate (ira_allocnos_num * sizeof (int));
memset (allocno_saved_at_call, 0, ira_allocnos_num * sizeof (int));
ira_traverse_loop_tree (true, ira_loop_tree_root, NULL, ira_traverse_loop_tree (true, ira_loop_tree_root, NULL,
process_bb_node_lives); process_bb_node_lives);
ira_max_point = curr_point; ira_max_point = curr_point;
...@@ -1159,6 +1192,7 @@ ira_create_allocno_live_ranges (void) ...@@ -1159,6 +1192,7 @@ ira_create_allocno_live_ranges (void)
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
print_live_ranges (ira_dump_file); print_live_ranges (ira_dump_file);
/* Clean up. */ /* Clean up. */
ira_free (allocno_saved_at_call);
sparseset_free (allocnos_live); sparseset_free (allocnos_live);
} }
......
...@@ -1792,10 +1792,7 @@ ira (FILE *f) ...@@ -1792,10 +1792,7 @@ ira (FILE *f)
loops_p = ira_build (optimize loops_p = ira_build (optimize
&& (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL && (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
|| flag_ira_algorithm == IRA_ALGORITHM_MIXED)); || flag_ira_algorithm == IRA_ALGORITHM_MIXED));
if (optimize)
ira_color (); ira_color ();
else
ira_fast_allocation ();
ira_max_point_before_emit = ira_max_point; ira_max_point_before_emit = ira_max_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