lra-constraints.c (emit_spill_move): Use smaller mode for mem-mem moves.

2013-05-24  Vladimir Makarov  <vmakarov@redhat.com>

        * lra-constraints.c (emit_spill_move): Use smaller mode for
	mem-mem moves.
        (check_and_process_move): Consider mem-reg moves for secondary
	too.
        (curr_insn_transform): Don't lose insns emitted before for
	secondary memory moves.
	(inherit_in_ebb): Mark defined reg.  Add usage only if it is not a
	reg set up in the current insn.

From-SVN: r199298
This commit is contained in:
Vladimir Makarov 2013-05-24 15:30:47 +00:00 committed by Vladimir Makarov
parent a8db59905a
commit 1ccd4874c9
2 changed files with 67 additions and 22 deletions

View file

@ -1,3 +1,14 @@
2013-05-24 Vladimir Makarov <vmakarov@redhat.com>
* lra-constraints.c (emit_spill_move): Use smaller mode for
mem-mem moves.
(check_and_process_move): Consider mem-reg moves for secondary
too.
(curr_insn_transform): Don't lose insns emitted before for
secondary memory moves.
(inherit_in_ebb): Mark defined reg. Add usage only if it is not a
reg set up in the current insn.
2013-05-24 Dehao Chen <dehao@google.com>
* gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c: New Testcase.

View file

@ -859,10 +859,20 @@ emit_spill_move (bool to_p, rtx mem_pseudo, rtx val)
{
if (GET_MODE (mem_pseudo) != GET_MODE (val))
{
val = gen_rtx_SUBREG (GET_MODE (mem_pseudo),
GET_CODE (val) == SUBREG ? SUBREG_REG (val) : val,
0);
LRA_SUBREG_P (val) = 1;
lra_assert (GET_MODE_SIZE (GET_MODE (mem_pseudo))
>= GET_MODE_SIZE (GET_MODE (val)));
if (! MEM_P (val))
{
val = gen_rtx_SUBREG (GET_MODE (mem_pseudo),
GET_CODE (val) == SUBREG ? SUBREG_REG (val) : val,
0);
LRA_SUBREG_P (val) = 1;
}
else
{
mem_pseudo = gen_lowpart_SUBREG (GET_MODE (val), mem_pseudo);
LRA_SUBREG_P (mem_pseudo) = 1;
}
}
return (to_p
? gen_move_insn (mem_pseudo, val)
@ -890,7 +900,7 @@ check_and_process_move (bool *change_p, bool *sec_mem_p ATTRIBUTE_UNUSED)
dreg = SUBREG_REG (dest);
if (GET_CODE (src) == SUBREG)
sreg = SUBREG_REG (src);
if (! REG_P (dreg) || ! REG_P (sreg))
if (! (REG_P (dreg) || MEM_P (dreg)) || ! (REG_P (sreg) || MEM_P (sreg)))
return false;
sclass = dclass = NO_REGS;
if (REG_P (dreg))
@ -911,14 +921,22 @@ check_and_process_move (bool *change_p, bool *sec_mem_p ATTRIBUTE_UNUSED)
if (sclass == ALL_REGS)
/* See comments above. */
return false;
if (sclass == NO_REGS && dclass == NO_REGS)
return false;
#ifdef SECONDARY_MEMORY_NEEDED
if (dclass != NO_REGS && sclass != NO_REGS
&& SECONDARY_MEMORY_NEEDED (sclass, dclass, GET_MODE (src)))
if (SECONDARY_MEMORY_NEEDED (sclass, dclass, GET_MODE (src))
#ifdef SECONDARY_MEMORY_NEEDED_MODE
&& ((sclass != NO_REGS && dclass != NO_REGS)
|| GET_MODE (src) != SECONDARY_MEMORY_NEEDED_MODE (GET_MODE (src)))
#endif
)
{
*sec_mem_p = true;
return false;
}
#endif
if (! REG_P (dreg) || ! REG_P (sreg))
return false;
sri.prev_sri = NULL;
sri.icode = CODE_FOR_nothing;
sri.extra_cost = 0;
@ -3006,16 +3024,22 @@ curr_insn_transform (void)
/* If the target says specifically to use another mode for
secondary memory moves we can not reuse the original
insn. */
after = emit_spill_move (false, new_reg, dest);
lra_process_new_insns (curr_insn, NULL_RTX, after,
"Inserting the sec. move");
before = emit_spill_move (true, new_reg, src);
lra_process_new_insns (curr_insn, before, NULL_RTX, "Changing on");
lra_set_insn_deleted (curr_insn);
}
after = emit_spill_move (false, new_reg, dest);
lra_process_new_insns (curr_insn, NULL_RTX, after,
"Inserting the sec. move");
/* We may have non null BEFORE here (e.g. after address
processing. */
push_to_sequence (before);
before = emit_spill_move (true, new_reg, src);
emit_insn (before);
before = get_insns ();
end_sequence ();
lra_process_new_insns (curr_insn, before, NULL_RTX, "Changing on");
lra_set_insn_deleted (curr_insn);
}
else if (dest == rld)
{
*curr_id->operand_loc[0] = new_reg;
{
*curr_id->operand_loc[0] = new_reg;
after = emit_spill_move (false, new_reg, dest);
lra_process_new_insns (curr_insn, NULL_RTX, after,
"Inserting the sec. move");
@ -3023,7 +3047,12 @@ curr_insn_transform (void)
else
{
*curr_id->operand_loc[1] = new_reg;
/* See comments above. */
push_to_sequence (before);
before = emit_spill_move (true, new_reg, src);
emit_insn (before);
before = get_insns ();
end_sequence ();
lra_process_new_insns (curr_insn, before, NULL_RTX,
"Inserting the sec. move");
}
@ -3823,7 +3852,9 @@ struct usage_insns
{
/* If the value is equal to CURR_USAGE_INSNS_CHECK, then the member
value INSNS is valid. The insns is chain of optional debug insns
and a finishing non-debug insn using the corresponding reg. */
and a finishing non-debug insn using the corresponding reg. The
value is also used to mark the registers which are set up in the
current insn. The negated insn uid is used for this. */
int check;
/* Value of global reloads_num at the last insn in INSNS. */
int reloads_num;
@ -4796,14 +4827,15 @@ inherit_in_ebb (rtx head, rtx tail)
&& (dst_regno < FIRST_PSEUDO_REGISTER
|| reg_renumber[dst_regno] >= 0)))
{
/* Invalidate. */
/* Invalidate and mark definitions. */
if (dst_regno >= FIRST_PSEUDO_REGISTER)
usage_insns[dst_regno].check = 0;
usage_insns[dst_regno].check = -(int) INSN_UID (curr_insn);
else
{
nregs = hard_regno_nregs[dst_regno][reg->biggest_mode];
for (i = 0; i < nregs; i++)
usage_insns[dst_regno + i].check = 0;
usage_insns[dst_regno + i].check
= -(int) INSN_UID (curr_insn);
}
}
}
@ -4864,8 +4896,10 @@ inherit_in_ebb (rtx head, rtx tail)
= usage_insns[src_regno].insns) != NULL_RTX
&& NONDEBUG_INSN_P (curr_insn))
add_to_inherit (src_regno, next_usage_insns);
else
/* Add usages. */
else if (usage_insns[src_regno].check
!= -(int) INSN_UID (curr_insn))
/* Add usages but only if the reg is not set up
in the same insn. */
add_next_usage_insn (src_regno, curr_insn, reloads_num);
}
else if (src_regno < FIRST_PSEUDO_REGISTER