This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] postreload.c: Teach move2add how to handle single_set.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 27 Feb 2004 12:10:26 -0500 (EST)
- Subject: [patch] postreload.c: Teach move2add how to handle single_set.
Hi,
Attached is a patch to teach move2add how to handle single_set as a
part of merge from my MODE_CC version of h8300 port. (Note that
move2add only handle naked SETS.)
The meat of the change is to use single_set (insn) instead of
PATTERN (insn), which you can find in the second hunk of the patch.
If some transformation (to either PLUS or STRICT_LOW_PART) is
prepared, we try to install the change to the location of the original
set. For example, if the original insn has a pattern like
(parallel [(set (reg X) (const_int Y))
(clobber (reg Z))])
the new pattern would look like
(parallel [(set (reg X) (plus (reg X) (const_int Y')))
(clobber (reg Z))])
or
(parallel [(set (strict_low_part (reg X)) (const_int Y''))
(clobber (reg Z))])
Since this patch accepts single sets, we now need to keep track of
side effects outside of single sets, such as clobbers of hard
registers. With this patch, reload_cse_move2add() delegates all the
book keeping work of reg_luid and its friends to move2add_note_store.
(See removal of two "continue" statements.)
Among the book keeping work, STRICT_LOW_PART is the only thing that
reload_cse_move2add handles but move2add_note_store does not, so I
added this feature to move2add_note_store.
The rest of the patch replaces "pat" with "set" for clarity.
Tested on i686-pc-linux-gnu. OK to apply?
Kazu Hirata
2004-02-26 Kazu Hirata <kazu@cs.umass.edu>
* postreload.c (reload_cse_move2add): Support single sets.
Delegate all the book keeping work to move2add_note_store.
(move2add_note_store): Handle STRICT_LOW_PART.
Index: postreload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/postreload.c,v
retrieving revision 2.14
diff -c -r2.14 postreload.c
*** postreload.c 26 Feb 2004 23:19:27 -0000 2.14
--- postreload.c 27 Feb 2004 03:59:05 -0000
***************
*** 1190,1196 ****
move2add_luid = 2;
for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
{
! rtx pat, note;
if (GET_CODE (insn) == CODE_LABEL)
{
--- 1190,1196 ----
move2add_luid = 2;
for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
{
! rtx set, note;
if (GET_CODE (insn) == CODE_LABEL)
{
***************
*** 1203,1217 ****
}
if (! INSN_P (insn))
continue;
- pat = PATTERN (insn);
/* For simplicity, we only perform this optimization on
! straightforward SETs. */
! if (GET_CODE (pat) == SET
! && GET_CODE (SET_DEST (pat)) == REG)
{
! rtx reg = SET_DEST (pat);
int regno = REGNO (reg);
! rtx src = SET_SRC (pat);
/* Check if we have valid information on the contents of this
register in the mode of REG. */
--- 1203,1216 ----
}
if (! INSN_P (insn))
continue;
/* For simplicity, we only perform this optimization on
! single sets. */
! set = single_set (insn);
! if (set && GET_CODE (SET_DEST (set)) == REG)
{
! rtx reg = SET_DEST (set);
int regno = REGNO (reg);
! rtx src = SET_SRC (set);
/* Check if we have valid information on the contents of this
register in the mode of REG. */
***************
*** 1250,1262 ****
(reg)), would be discarded. Maybe we should
try a truncMN pattern? */
if (INTVAL (src) == reg_offset [regno])
! validate_change (insn, &SET_SRC (pat), reg, 0);
}
else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
&& have_add2_insn (reg, new_src))
{
rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
! validate_change (insn, &SET_SRC (pat), tem, 0);
}
else
{
--- 1249,1261 ----
(reg)), would be discarded. Maybe we should
try a truncMN pattern? */
if (INTVAL (src) == reg_offset [regno])
! validate_change (insn, &SET_SRC (set), reg, 0);
}
else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
&& have_add2_insn (reg, new_src))
{
rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
! validate_change (insn, &SET_SRC (set), tem, 0);
}
else
{
***************
*** 1281,1296 ****
gen_rtx_STRICT_LOW_PART (VOIDmode,
narrow_reg),
narrow_src);
! if (validate_change (insn, &PATTERN (insn),
! new_set, 0))
break;
}
}
}
- reg_set_luid[regno] = move2add_luid;
- reg_mode[regno] = GET_MODE (reg);
- reg_offset[regno] = INTVAL (src);
- continue;
}
/* Try to transform (set (REGX) (REGY))
--- 1280,1290 ----
gen_rtx_STRICT_LOW_PART (VOIDmode,
narrow_reg),
narrow_src);
! if (validate_replace_rtx (set, new_set, insn))
break;
}
}
}
}
/* Try to transform (set (REGX) (REGY))
***************
*** 1348,1360 ****
newpat, 0);
}
if (success)
! delete_insn (insn);
! insn = next;
! reg_mode[regno] = GET_MODE (reg);
! reg_offset[regno] =
! trunc_int_for_mode (added_offset + base_offset,
! GET_MODE (reg));
! continue;
}
}
}
--- 1342,1351 ----
newpat, 0);
}
if (success)
! {
! delete_insn (insn);
! insn = next;
! }
}
}
}
***************
*** 1445,1450 ****
--- 1436,1457 ----
regno += REGNO (dst);
+ if (SCALAR_INT_MODE_P (mode)
+ && hard_regno_nregs[regno][mode] == 1 && GET_CODE (set) == SET
+ && GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
+ {
+ rtx src = SET_SRC (set);
+
+ if (reg_set_luid[regno] > move2add_last_label_luid
+ && MODES_OK_FOR_MOVE2ADD (GET_MODE (dst), reg_mode[regno])
+ && GET_CODE (src) == CONST_INT && reg_base_reg[regno] < 0)
+ {
+ reg_set_luid[regno] = move2add_luid;
+ reg_offset[regno] &= ~GET_MODE_MASK (mode);
+ reg_offset[regno] |= INTVAL (src) & GET_MODE_MASK (mode);
+ return;
+ }
+ }
if (SCALAR_INT_MODE_P (mode)
&& hard_regno_nregs[regno][mode] == 1 && GET_CODE (set) == SET
&& GET_CODE (SET_DEST (set)) != ZERO_EXTRACT