-fuse-caller-save - Support in lra

2014-05-28  Tom de Vries  <tom@codesourcery.com>

	* lra-int.h (struct lra_reg): Add field actual_call_used_reg_set.
	* lra.c (initialize_lra_reg_info_element): Add init of
	actual_call_used_reg_set field.
	(lra): Call lra_create_live_ranges before lra_inheritance for
	-fuse-caller-save.
	* lra-assigns.c (lra_assign): Allow call_used_regs to cross calls for
	-fuse-caller-save.
	* lra-constraints.c (need_for_call_save_p): Use actual_call_used_reg_set
	instead of call_used_reg_set for -fuse-caller-save.
	* lra-lives.c (process_bb_lives): Calculate actual_call_used_reg_set.

From-SVN: r211010
This commit is contained in:
Tom de Vries 2014-05-28 09:43:52 +00:00 committed by Tom de Vries
parent dbe7d9e3ff
commit b8c6a45ab7
6 changed files with 57 additions and 5 deletions

View File

@ -1,3 +1,16 @@
2014-05-28 Tom de Vries <tom@codesourcery.com>
* lra-int.h (struct lra_reg): Add field actual_call_used_reg_set.
* lra.c (initialize_lra_reg_info_element): Add init of
actual_call_used_reg_set field.
(lra): Call lra_create_live_ranges before lra_inheritance for
-fuse-caller-save.
* lra-assigns.c (lra_assign): Allow call_used_regs to cross calls for
-fuse-caller-save.
* lra-constraints.c (need_for_call_save_p): Use actual_call_used_reg_set
instead of call_used_reg_set for -fuse-caller-save.
* lra-lives.c (process_bb_lives): Calculate actual_call_used_reg_set.
2014-05-28 Radovan Obradovic <robradovic@mips.com>
Tom de Vries <tom@codesourcery.com>

View File

@ -1447,6 +1447,7 @@ lra_assign (void)
bitmap_head insns_to_process;
bool no_spills_p;
int max_regno = max_reg_num ();
unsigned int call_used_reg_crosses_call = 0;
timevar_push (TV_LRA_ASSIGN);
init_lives ();
@ -1459,14 +1460,22 @@ lra_assign (void)
bitmap_initialize (&all_spilled_pseudos, &reg_obstack);
create_live_range_start_chains ();
setup_live_pseudos_and_spill_after_risky_transforms (&all_spilled_pseudos);
#ifdef ENABLE_CHECKING
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0
&& lra_reg_info[i].call_p
&& overlaps_hard_reg_set_p (call_used_reg_set,
PSEUDO_REGNO_MODE (i), reg_renumber[i]))
gcc_unreachable ();
#endif
{
if (!flag_use_caller_save)
gcc_unreachable ();
call_used_reg_crosses_call++;
}
if (lra_dump_file
&& call_used_reg_crosses_call > 0)
fprintf (lra_dump_file,
"Found %u pseudo(s) with a call used reg crossing a call.\n"
"Allowing due to -fuse-caller-save\n",
call_used_reg_crosses_call);
/* Setup insns to process on the next constraint pass. */
bitmap_initialize (&changed_pseudo_bitmap, &reg_obstack);
init_live_reload_and_inheritance_pseudos ();

View File

@ -4605,7 +4605,10 @@ need_for_call_save_p (int regno)
lra_assert (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0);
return (usage_insns[regno].calls_num < calls_num
&& (overlaps_hard_reg_set_p
(call_used_reg_set,
((flag_use_caller_save &&
! hard_reg_set_empty_p (lra_reg_info[regno].actual_call_used_reg_set))
? lra_reg_info[regno].actual_call_used_reg_set
: call_used_reg_set,
PSEUDO_REGNO_MODE (regno), reg_renumber[regno])
|| HARD_REGNO_CALL_PART_CLOBBERED (reg_renumber[regno],
PSEUDO_REGNO_MODE (regno))));

View File

@ -77,6 +77,10 @@ struct lra_reg
/* The following fields are defined only for pseudos. */
/* Hard registers with which the pseudo conflicts. */
HARD_REG_SET conflict_hard_regs;
/* Call used registers with which the pseudo conflicts, taking into account
the registers used by functions called from calls which cross the
pseudo. */
HARD_REG_SET actual_call_used_reg_set;
/* We assign hard registers to reload pseudos which can occur in few
places. So two hard register preferences are enough for them.
The following fields define the preferred hard registers. If

View File

@ -624,6 +624,17 @@ process_bb_lives (basic_block bb, int &curr_point)
if (call_p)
{
if (flag_use_caller_save)
{
HARD_REG_SET this_call_used_reg_set;
get_call_reg_set_usage (curr_insn, &this_call_used_reg_set,
call_used_reg_set);
EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j)
IOR_HARD_REG_SET (lra_reg_info[j].actual_call_used_reg_set,
this_call_used_reg_set);
}
sparseset_ior (pseudos_live_through_calls,
pseudos_live_through_calls, pseudos_live);
if (cfun->has_nonlocal_label

View File

@ -1427,6 +1427,7 @@ initialize_lra_reg_info_element (int i)
lra_reg_info[i].no_stack_p = false;
#endif
CLEAR_HARD_REG_SET (lra_reg_info[i].conflict_hard_regs);
CLEAR_HARD_REG_SET (lra_reg_info[i].actual_call_used_reg_set);
lra_reg_info[i].preferred_hard_regno1 = -1;
lra_reg_info[i].preferred_hard_regno2 = -1;
lra_reg_info[i].preferred_hard_regno_profit1 = 0;
@ -2344,7 +2345,18 @@ lra (FILE *f)
lra_eliminate (false, false);
/* Do inheritance only for regular algorithms. */
if (! lra_simple_p)
lra_inheritance ();
{
if (flag_use_caller_save)
{
if (live_p)
lra_clear_live_ranges ();
/* As a side-effect of lra_create_live_ranges, we calculate
actual_call_used_reg_set, which is needed during
lra_inheritance. */
lra_create_live_ranges (true);
}
lra_inheritance ();
}
if (live_p)
lra_clear_live_ranges ();
/* We need live ranges for lra_assign -- so build them. */