Commit 9d86e84e by Vladimir Makarov Committed by Vladimir Makarov

re PR rtl-optimization/66782 (Unable to run 64-bit wine after MS->SYSV register changes)

2015-07-09  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/66782
	* lra-int.h (struct lra_insn_recog_data): Add comment about
	clobbered hard regs for arg_hard_regs.
	* lra.c (lra_set_insn_recog_data): Add clobbered hard regs.
	* lra-lives.c (process_bb_lives): Process clobbered hard regs.
	Add condition for processing used hard regs.
	* lra-constraints.c (update_ebb_live_info, inherit_in_ebb):
	Process clobbered hard regs.

From-SVN: r225618
parent c551c21d
2015-07-09 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/66782
* lra-int.h (struct lra_insn_recog_data): Add comment about
clobbered hard regs for arg_hard_regs.
* lra.c (lra_set_insn_recog_data): Add clobbered hard regs.
* lra-lives.c (process_bb_lives): Process clobbered hard regs.
Add condition for processing used hard regs.
* lra-constraints.c (update_ebb_live_info, inherit_in_ebb):
Process clobbered hard regs.
2015-07-09 Michael Matz <matz@suse.de> 2015-07-09 Michael Matz <matz@suse.de>
* genmatch.c (fprintf_indent): New function. * genmatch.c (fprintf_indent): New function.
......
...@@ -5149,6 +5149,11 @@ update_ebb_live_info (rtx_insn *head, rtx_insn *tail) ...@@ -5149,6 +5149,11 @@ update_ebb_live_info (rtx_insn *head, rtx_insn *tail)
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
if (reg->type == OP_OUT && ! reg->subreg_p) if (reg->type == OP_OUT && ! reg->subreg_p)
bitmap_clear_bit (&live_regs, reg->regno); bitmap_clear_bit (&live_regs, reg->regno);
if (curr_id->arg_hard_regs != NULL)
/* Make clobbered argument hard registers die. */
for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++)
if (regno >= FIRST_PSEUDO_REGISTER)
bitmap_clear_bit (&live_regs, regno - FIRST_PSEUDO_REGISTER);
/* Mark each used value as live. */ /* Mark each used value as live. */
for (reg = curr_id->regs; reg != NULL; reg = reg->next) for (reg = curr_id->regs; reg != NULL; reg = reg->next)
if (reg->type != OP_OUT if (reg->type != OP_OUT
...@@ -5159,9 +5164,10 @@ update_ebb_live_info (rtx_insn *head, rtx_insn *tail) ...@@ -5159,9 +5164,10 @@ update_ebb_live_info (rtx_insn *head, rtx_insn *tail)
&& bitmap_bit_p (&check_only_regs, reg->regno)) && bitmap_bit_p (&check_only_regs, reg->regno))
bitmap_set_bit (&live_regs, reg->regno); bitmap_set_bit (&live_regs, reg->regno);
if (curr_id->arg_hard_regs != NULL) if (curr_id->arg_hard_regs != NULL)
/* Make argument hard registers live. */ /* Make used argument hard registers live. */
for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++)
if (bitmap_bit_p (&check_only_regs, regno)) if (regno < FIRST_PSEUDO_REGISTER
&& bitmap_bit_p (&check_only_regs, regno))
bitmap_set_bit (&live_regs, regno); bitmap_set_bit (&live_regs, regno);
/* It is quite important to remove dead move insns because it /* It is quite important to remove dead move insns because it
means removing dead store. We don't need to process them for means removing dead store. We don't need to process them for
...@@ -5471,6 +5477,12 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) ...@@ -5471,6 +5477,12 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
} }
} }
} }
/* Process clobbered call regs. */
if (curr_id->arg_hard_regs != NULL)
for (i = 0; (dst_regno = curr_id->arg_hard_regs[i]) >= 0; i++)
if (dst_regno >= FIRST_PSEUDO_REGISTER)
usage_insns[dst_regno - FIRST_PSEUDO_REGISTER].check
= -(int) INSN_UID (curr_insn);
if (! JUMP_P (curr_insn)) if (! JUMP_P (curr_insn))
for (i = 0; i < to_inherit_num; i++) for (i = 0; i < to_inherit_num; i++)
if (inherit_reload_reg (true, to_inherit[i].regno, if (inherit_reload_reg (true, to_inherit[i].regno,
...@@ -5578,7 +5590,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) ...@@ -5578,7 +5590,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
add_next_usage_insn (src_regno, use_insn, reloads_num); add_next_usage_insn (src_regno, use_insn, reloads_num);
} }
} }
/* Process call args. */ /* Process used call regs. */
if (curr_id->arg_hard_regs != NULL) if (curr_id->arg_hard_regs != NULL)
for (i = 0; (src_regno = curr_id->arg_hard_regs[i]) >= 0; i++) for (i = 0; (src_regno = curr_id->arg_hard_regs[i]) >= 0; i++)
if (src_regno < FIRST_PSEUDO_REGISTER) if (src_regno < FIRST_PSEUDO_REGISTER)
......
...@@ -267,9 +267,11 @@ struct lra_insn_recog_data ...@@ -267,9 +267,11 @@ struct lra_insn_recog_data
duplication numbers: */ duplication numbers: */
rtx **operand_loc; /* The operand locations, NULL if no operands. */ rtx **operand_loc; /* The operand locations, NULL if no operands. */
rtx **dup_loc; /* The dup locations, NULL if no dups. */ rtx **dup_loc; /* The dup locations, NULL if no dups. */
/* Number of hard registers implicitly used in given call insn. The /* Number of hard registers implicitly used/clobbered in given call
value can be NULL or points to array of the hard register numbers insn. The value can be NULL or points to array of the hard
ending with a negative value. */ register numbers ending with a negative value. To differ
clobbered and used hard regs, clobbered hard regs are incremented
by FIRST_PSEUDO_REGISTER. */
int *arg_hard_regs; int *arg_hard_regs;
/* Cached value of get_preferred_alternatives. */ /* Cached value of get_preferred_alternatives. */
alternative_mask preferred_alternatives; alternative_mask preferred_alternatives;
......
...@@ -814,6 +814,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) ...@@ -814,6 +814,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
if (reg->type != OP_IN) if (reg->type != OP_IN)
make_hard_regno_born (reg->regno, false); make_hard_regno_born (reg->regno, false);
if (curr_id->arg_hard_regs != NULL)
for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++)
if (regno >= FIRST_PSEUDO_REGISTER)
/* It is a clobber. */
make_hard_regno_born (regno - FIRST_PSEUDO_REGISTER, false);
sparseset_copy (unused_set, start_living); sparseset_copy (unused_set, start_living);
sparseset_clear (start_dying); sparseset_clear (start_dying);
...@@ -829,6 +835,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) ...@@ -829,6 +835,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p) if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p)
make_hard_regno_dead (reg->regno); make_hard_regno_dead (reg->regno);
if (curr_id->arg_hard_regs != NULL)
for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++)
if (regno >= FIRST_PSEUDO_REGISTER)
/* It is a clobber. */
make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER);
if (call_p) if (call_p)
{ {
if (flag_ipa_ra) if (flag_ipa_ra)
...@@ -877,7 +889,8 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) ...@@ -877,7 +889,8 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
/* Make argument hard registers live. Don't create conflict /* Make argument hard registers live. Don't create conflict
of used REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ of used REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */
for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++)
make_hard_regno_born (regno, true); if (regno < FIRST_PSEUDO_REGISTER)
make_hard_regno_born (regno, true);
sparseset_and_compl (dead_set, start_living, start_dying); sparseset_and_compl (dead_set, start_living, start_dying);
......
...@@ -1055,6 +1055,7 @@ lra_set_insn_recog_data (rtx_insn *insn) ...@@ -1055,6 +1055,7 @@ lra_set_insn_recog_data (rtx_insn *insn)
data->arg_hard_regs = NULL; data->arg_hard_regs = NULL;
if (CALL_P (insn)) if (CALL_P (insn))
{ {
bool use_p;
rtx link; rtx link;
int n_hard_regs, regno, arg_hard_regs[FIRST_PSEUDO_REGISTER]; int n_hard_regs, regno, arg_hard_regs[FIRST_PSEUDO_REGISTER];
...@@ -1065,14 +1066,16 @@ lra_set_insn_recog_data (rtx_insn *insn) ...@@ -1065,14 +1066,16 @@ lra_set_insn_recog_data (rtx_insn *insn)
for (link = CALL_INSN_FUNCTION_USAGE (insn); for (link = CALL_INSN_FUNCTION_USAGE (insn);
link != NULL_RTX; link != NULL_RTX;
link = XEXP (link, 1)) link = XEXP (link, 1))
if (GET_CODE (XEXP (link, 0)) == USE if (((use_p = GET_CODE (XEXP (link, 0)) == USE)
|| GET_CODE (XEXP (link, 0)) == CLOBBER)
&& REG_P (XEXP (XEXP (link, 0), 0))) && REG_P (XEXP (XEXP (link, 0), 0)))
{ {
regno = REGNO (XEXP (XEXP (link, 0), 0)); regno = REGNO (XEXP (XEXP (link, 0), 0));
lra_assert (regno < FIRST_PSEUDO_REGISTER); lra_assert (regno < FIRST_PSEUDO_REGISTER);
/* It is an argument register. */ /* It is an argument register. */
for (i = REG_NREGS (XEXP (XEXP (link, 0), 0)) - 1; i >= 0; i--) for (i = REG_NREGS (XEXP (XEXP (link, 0), 0)) - 1; i >= 0; i--)
arg_hard_regs[n_hard_regs++] = regno + i; arg_hard_regs[n_hard_regs++]
= regno + i + (use_p ? 0 : FIRST_PSEUDO_REGISTER);
} }
if (n_hard_regs != 0) if (n_hard_regs != 0)
{ {
......
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