This is the mail archive of the
mailing list for the GCC project.
[PATCH] Don't decrease mem_cost for special MEMs, even with REG_EQUIV (PR rtl-optimization/52208)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Vladimir Makarov <vmakarov at redhat dot com>, Jeff Law <law at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 16 Feb 2012 07:56:03 +0100
- Subject: [PATCH] Don't decrease mem_cost for special MEMs, even with REG_EQUIV (PR rtl-optimization/52208)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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?
2012-02-16 Jakub Jelinek <firstname.lastname@example.org>
* 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);