diff options
author | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-10-27 16:39:26 +0000 |
---|---|---|
committer | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-10-27 16:39:26 +0000 |
commit | df07a54c3de6c774315ca98463160df1dac5ce60 (patch) | |
tree | 2e5a85daedf6bfc58bc769f2372dc729b240724f /gcc/ira-lives.c | |
parent | 1e204c7444fe8a80a1183349ccf75766c144d626 (diff) | |
download | gcc-df07a54c3de6c774315ca98463160df1dac5ce60.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141385 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ira-lives.c')
-rw-r--r-- | gcc/ira-lives.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index c908ab71338..5573ce86a5e 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -75,6 +75,11 @@ static HARD_REG_SET hard_regs_live; /* The loop tree node corresponding to the current basic block. */ 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 hard regs and conflict hard regs for living allocnos or starts a new live range for the allocno corresponding to REGNO if it is @@ -163,6 +168,8 @@ set_allocno_live (ira_allocno_t a) int nregs; 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))) return; sparseset_set_bit (allocnos_live, ALLOCNO_NUM (a)); @@ -189,6 +196,8 @@ clear_allocno_live (ira_allocno_t a) unsigned int i; 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))) { cover_class = ALLOCNO_COVER_CLASS (a); @@ -228,7 +237,11 @@ mark_reg_live (rtx reg) if (a != NULL) { if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a))) - return; + { + /* Invalidate because it is referenced. */ + allocno_saved_at_call[ALLOCNO_NUM (a)] = 0; + return; + } set_allocno_live (a); } make_regno_born (regno); @@ -293,7 +306,11 @@ mark_reg_dead (rtx reg) if (a != NULL) { if (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a))) - return; + { + /* Invalidate because it is referenced. */ + allocno_saved_at_call[ALLOCNO_NUM (a)] = 0; + return; + } clear_allocno_live (a); } make_regno_dead (regno); @@ -820,6 +837,9 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) if (freq == 0) freq = 1; + /* Invalidate all allocno_saved_at_call entries. */ + last_call_num++; + /* Scan the code of this basic block, noting which allocnos and hard regs are born or die. @@ -901,12 +921,21 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) if (call_p) { + last_call_num++; /* The current set of live allocnos are live across the call. */ EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i) { ira_allocno_t a = ira_allocnos[i]; - ALLOCNO_CALL_FREQ (a) += freq; + 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; + /* Mark it as saved at the next call. */ + allocno_saved_at_call[i] = last_call_num + 1; ALLOCNO_CALLS_CROSSED_NUM (a)++; /* Don't allocate allocnos that cross setjmps or any call, if this function receives a nonlocal @@ -1152,6 +1181,10 @@ ira_create_allocno_live_ranges (void) { allocnos_live = sparseset_alloc (ira_allocnos_num); 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, process_bb_node_lives); ira_max_point = curr_point; @@ -1159,6 +1192,7 @@ ira_create_allocno_live_ranges (void) if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) print_live_ranges (ira_dump_file); /* Clean up. */ + ira_free (allocno_saved_at_call); sparseset_free (allocnos_live); } |