On 02/16/2012 01:56 AM, Jakub Jelinek wrote:
Hi!
As mentioned in the PR, if SET_SRC MEM (with REG_EQUIV note) isn't a MEM
that can be used in general operations, but requires some specialized
instruction to load it, decreasing its mem_cost results sometimes in
worse code, the MEM is loaded with a specialized insn, then stored into
a stack slot because e.g. a negative memory cost has been chosen as
cheapest, then loaded back from the stack slot.
This patch gives up if the MEM isn't general_operand.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok. Thanks, Jakub.
2012-02-16 Jakub Jelinek<ja...@redhat.com>
PR rtl-optimization/52208
* ira-costs.c (scan_one_insn): Don't decrease mem_cost
for MEMs with REG_EQUIV, if the MEM isn't general_operand.
--- gcc/ira-costs.c.jj 2012-02-15 07:34:54.000000000 +0100
+++ gcc/ira-costs.c 2012-02-15 20:57:49.239393641 +0100
@@ -1306,14 +1306,21 @@ scan_one_insn (rtx insn)
Similarly if we're loading other constants from memory (constant
pool, TOC references, small data areas, etc) and this is the only
- assignment to the destination pseudo. */
+ assignment to the destination pseudo.
+
+ Don't do this if SET_SRC (set) isn't a general operand, if it is
+ a memory requiring special instructions to load it, decreasing
+ mem_cost might result in it being loaded using the specialized
+ instruction into a register, then stored into stack and loaded
+ again from the stack. See PR52208. */
if (set != 0&& REG_P (SET_DEST (set))&& MEM_P (SET_SRC (set))
&& (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != NULL_RTX
&& ((MEM_P (XEXP (note, 0)))
|| (CONSTANT_P (XEXP (note, 0))
&& targetm.legitimate_constant_p (GET_MODE (SET_DEST (set)),
XEXP (note, 0))
- && REG_N_SETS (REGNO (SET_DEST (set))) == 1)))
+ && REG_N_SETS (REGNO (SET_DEST (set))) == 1))
+&& general_operand (SET_SRC (set), GET_MODE (SET_SRC (set))))
{
enum reg_class cl = GENERAL_REGS;
rtx reg = SET_DEST (set);
Jakub