This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[rfc] Make regrename call recog
- From: Andreas Krebbel <krebbel1 at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 25 Aug 2005 15:42:17 +0200
- Subject: [rfc] Make regrename call recog
Hi,
working on a S/390 patch optimizing load/store multiple I've
noticed that regrename replaces registers without calling
recog afterwards. So it happened that a single register out
of a PARALLEL block of SETs gets renamed. Because the
load_multiple patterns only accept SETs with consecutive
registers this insn is invalid after regrename.
The attached patch turns "do_replace" in "try_replace" using
validate_change to replace the register along the def-use chain.
Is this the way to go?
Bye,
-Andreas-
Index: gcc/regrename.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regrename.c,v
retrieving revision 1.102
diff -p -c -r1.102 regrename.c
*** gcc/regrename.c 5 Jul 2005 16:20:13 -0000 1.102
--- gcc/regrename.c 25 Aug 2005 12:16:55 -0000
*************** static const char * const scan_actions_n
*** 73,79 ****
static struct obstack rename_obstack;
! static void do_replace (struct du_chain *, int);
static void scan_rtx_reg (rtx, rtx *, enum reg_class,
enum scan_actions, enum op_type, int);
static void scan_rtx_address (rtx, rtx *, enum reg_class,
--- 73,79 ----
static struct obstack rename_obstack;
! static int try_replace (struct du_chain *, int);
static void scan_rtx_reg (rtx, rtx *, enum reg_class,
enum scan_actions, enum op_type, int);
static void scan_rtx_address (rtx, rtx *, enum reg_class,
*************** regrename_optimize (void)
*** 339,350 ****
continue;
}
! do_replace (this, best_new_reg);
! tick[best_new_reg] = ++this_tick;
! regs_ever_live[best_new_reg] = 1;
!
! if (dump_file)
! fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
}
obstack_free (&rename_obstack, first_obj);
--- 339,352 ----
continue;
}
! if (try_replace (this, best_new_reg))
! {
! tick[best_new_reg] = ++this_tick;
! regs_ever_live[best_new_reg] = 1;
!
! if (dump_file)
! fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
! }
}
obstack_free (&rename_obstack, first_obj);
*************** regrename_optimize (void)
*** 360,379 ****
PROP_DEATH_NOTES);
}
! static void
! do_replace (struct du_chain *chain, int reg)
{
while (chain)
{
unsigned int regno = ORIGINAL_REGNO (*chain->loc);
struct reg_attrs * attr = REG_ATTRS (*chain->loc);
!
! *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
if (regno >= FIRST_PSEUDO_REGISTER)
! ORIGINAL_REGNO (*chain->loc) = regno;
! REG_ATTRS (*chain->loc) = attr;
chain = chain->next_use;
}
}
--- 362,386 ----
PROP_DEATH_NOTES);
}
! static int
! try_replace (struct du_chain *chain, int reg)
{
while (chain)
{
unsigned int regno = ORIGINAL_REGNO (*chain->loc);
struct reg_attrs * attr = REG_ATTRS (*chain->loc);
! rtx new_reg = gen_raw_REG (GET_MODE (*chain->loc), reg);
!
if (regno >= FIRST_PSEUDO_REGISTER)
! ORIGINAL_REGNO (new_reg) = regno;
! REG_ATTRS (new_reg) = attr;
!
! validate_change (chain->insn, chain->loc, new_reg, 1);
!
chain = chain->next_use;
}
+
+ return apply_change_group ();
}