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> 2013-05-24 Dehao Chen <dehao@google.com>
* gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c: New Testcase. * 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)) if (GET_MODE (mem_pseudo) != GET_MODE (val))
{ {
val = gen_rtx_SUBREG (GET_MODE (mem_pseudo), lra_assert (GET_MODE_SIZE (GET_MODE (mem_pseudo))
GET_CODE (val) == SUBREG ? SUBREG_REG (val) : val, >= GET_MODE_SIZE (GET_MODE (val)));
0); if (! MEM_P (val))
LRA_SUBREG_P (val) = 1; {
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 return (to_p
? gen_move_insn (mem_pseudo, val) ? 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); dreg = SUBREG_REG (dest);
if (GET_CODE (src) == SUBREG) if (GET_CODE (src) == SUBREG)
sreg = SUBREG_REG (src); 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; return false;
sclass = dclass = NO_REGS; sclass = dclass = NO_REGS;
if (REG_P (dreg)) 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) if (sclass == ALL_REGS)
/* See comments above. */ /* See comments above. */
return false; return false;
if (sclass == NO_REGS && dclass == NO_REGS)
return false;
#ifdef SECONDARY_MEMORY_NEEDED #ifdef SECONDARY_MEMORY_NEEDED
if (dclass != NO_REGS && sclass != NO_REGS if (SECONDARY_MEMORY_NEEDED (sclass, dclass, GET_MODE (src))
&& 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; *sec_mem_p = true;
return false; return false;
} }
#endif #endif
if (! REG_P (dreg) || ! REG_P (sreg))
return false;
sri.prev_sri = NULL; sri.prev_sri = NULL;
sri.icode = CODE_FOR_nothing; sri.icode = CODE_FOR_nothing;
sri.extra_cost = 0; sri.extra_cost = 0;
@ -3006,16 +3024,22 @@ curr_insn_transform (void)
/* If the target says specifically to use another mode for /* If the target says specifically to use another mode for
secondary memory moves we can not reuse the original secondary memory moves we can not reuse the original
insn. */ insn. */
after = emit_spill_move (false, new_reg, dest); after = emit_spill_move (false, new_reg, dest);
lra_process_new_insns (curr_insn, NULL_RTX, after, lra_process_new_insns (curr_insn, NULL_RTX, after,
"Inserting the sec. move"); "Inserting the sec. move");
before = emit_spill_move (true, new_reg, src); /* We may have non null BEFORE here (e.g. after address
lra_process_new_insns (curr_insn, before, NULL_RTX, "Changing on"); processing. */
lra_set_insn_deleted (curr_insn); 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) 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); after = emit_spill_move (false, new_reg, dest);
lra_process_new_insns (curr_insn, NULL_RTX, after, lra_process_new_insns (curr_insn, NULL_RTX, after,
"Inserting the sec. move"); "Inserting the sec. move");
@ -3023,7 +3047,12 @@ curr_insn_transform (void)
else else
{ {
*curr_id->operand_loc[1] = new_reg; *curr_id->operand_loc[1] = new_reg;
/* See comments above. */
push_to_sequence (before);
before = emit_spill_move (true, new_reg, src); 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, lra_process_new_insns (curr_insn, before, NULL_RTX,
"Inserting the sec. move"); "Inserting the sec. move");
} }
@ -3823,7 +3852,9 @@ struct usage_insns
{ {
/* If the value is equal to CURR_USAGE_INSNS_CHECK, then the member /* 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 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; int check;
/* Value of global reloads_num at the last insn in INSNS. */ /* Value of global reloads_num at the last insn in INSNS. */
int reloads_num; int reloads_num;
@ -4796,14 +4827,15 @@ inherit_in_ebb (rtx head, rtx tail)
&& (dst_regno < FIRST_PSEUDO_REGISTER && (dst_regno < FIRST_PSEUDO_REGISTER
|| reg_renumber[dst_regno] >= 0))) || reg_renumber[dst_regno] >= 0)))
{ {
/* Invalidate. */ /* Invalidate and mark definitions. */
if (dst_regno >= FIRST_PSEUDO_REGISTER) if (dst_regno >= FIRST_PSEUDO_REGISTER)
usage_insns[dst_regno].check = 0; usage_insns[dst_regno].check = -(int) INSN_UID (curr_insn);
else else
{ {
nregs = hard_regno_nregs[dst_regno][reg->biggest_mode]; nregs = hard_regno_nregs[dst_regno][reg->biggest_mode];
for (i = 0; i < nregs; i++) 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 = usage_insns[src_regno].insns) != NULL_RTX
&& NONDEBUG_INSN_P (curr_insn)) && NONDEBUG_INSN_P (curr_insn))
add_to_inherit (src_regno, next_usage_insns); add_to_inherit (src_regno, next_usage_insns);
else else if (usage_insns[src_regno].check
/* Add usages. */ != -(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); add_next_usage_insn (src_regno, curr_insn, reloads_num);
} }
else if (src_regno < FIRST_PSEUDO_REGISTER else if (src_regno < FIRST_PSEUDO_REGISTER