This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFA: patch adding priority coloring for m32c and other ports
- From: Vladimir Makarov <vmakarov at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jeff Law <law at redhat dot com>, Kenneth Zadeck <zadeck at naturalbridge dot com>
- Date: Thu, 04 Dec 2008 12:37:22 -0500
- Subject: Re: RFA: patch adding priority coloring for m32c and other ports
- References: <493096F8.3000408@redhat.com>
Jeff, DJ pointed me some gcc crashes of m32c port with the priority
coloring patch on newlib and libstdc++. I fixed them. Here the two
additional patches to review (I decided to sent them instead of full
updated patch for clarity).
The 1st patch fixes a typo missing allocno_conflict_hard_regs update to
prohibit usage of callee-saved likely spilled base registers for
allocnos crossing calls. As I wrote m32c has 2 registers of class
A_REGS which are used for addressing. If a code for save/restore of
such register is generated, reload pass dies because we need one A_REG
for addressing in save/restore code for saving A_REG register, and one
A_REG register can be used explicitly in a call.
The 2nd patch adds a new register class R02A_REGS (in many cases both
R02_REGS and A_REGS is more profitable than memory) which permits to
assign wider classes for allocnos in IRA and prevent some reload crashes
(insufficient R02_REGS). The patch also fixing a latent reload bug in
reload inheritance optimization. The compiler crashes in
smallest_mode_for_size because can not find PARTIAL_INT_MODE of size 8
bytes (that is because DImode was used earlier for the pseudo and we are
reloading (subreg:PSI (reg:DI x) 4)). I have some doubts about the
original code but I used the simplest fix on this stage. And finally
the patch fixes a reload crash because jump insn code was set up to -1
by CFG (commit_edge_insertion call) and reload can not set it up again
because some insn pattern guard. So I used the simplest fix which is
to reset the code at the end of ira-emit.c if it is negative.
--- ira-conflicts.c0 2008-11-20 12:49:44.000000000 -0500
+++ ira-conflicts.c 2008-12-01 15:54:34.000000000 -0500
@@ -788,8 +788,12 @@ ira_build_conflicts (void)
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
temp_hard_reg_set);
if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
- IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
- no_caller_save_reg_set);
+ {
+ IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
+ no_caller_save_reg_set);
+ IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
+ temp_hard_reg_set);
+ }
}
}
if (optimize && internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
Index: ira-emit.c
===================================================================
--- ira-emit.c (revision 142413)
+++ ira-emit.c (working copy)
@@ -1025,6 +1025,7 @@ void
ira_emit (bool loops_p)
{
basic_block bb;
+ rtx insn;
edge_iterator ei;
edge e;
ira_allocno_t a;
@@ -1085,6 +1086,14 @@ ira_emit (bool loops_p)
ira_free (allocno_last_set_check);
ira_free (allocno_last_set);
commit_edge_insertions ();
+ /* Fix insn codes. It is necessary to do it before reload because
+ reload assumes initial insn codes defined. The insn codes can be
+ invalidated by CFG infrastructure for example in jump
+ redirection. */
+ FOR_EACH_BB (bb)
+ FOR_BB_INSNS_REVERSE (bb, insn)
+ if (INSN_P (insn))
+ recog_memoized (insn);
ira_free (at_bb_end);
ira_free (at_bb_start);
}
Index: config/m32c/m32c.h
===================================================================
--- config/m32c/m32c.h (revision 142413)
+++ config/m32c/m32c.h (working copy)
@@ -270,6 +270,7 @@ machine_function;
{ 0x000001f0 }, /* PS - a0 a1 sb fp sp */\
{ 0x0000000f }, /* SI - r0r2 r1r3 a0a1 */\
{ 0x0000003f }, /* HI - r0 r1 r2 r3 a0 a1 */\
+ { 0x00000033 }, /* R02A - r0r2 a0 a1 */ \
{ 0x0000003f }, /* RA - r0..r3 a0 a1 */\
{ 0x0000007f }, /* GENERAL */\
{ 0x00000400 }, /* FLG */\
@@ -308,6 +309,7 @@ enum reg_class
PS_REGS,
SI_REGS,
HI_REGS,
+ R02A_REGS,
RA_REGS,
GENERAL_REGS,
FLG_REGS,
@@ -348,6 +350,7 @@ enum reg_class
"PS_REGS", \
"SI_REGS", \
"HI_REGS", \
+"R02A_REGS", \
"RA_REGS", \
"GENERAL_REGS", \
"FLG_REGS", \
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c (revision 142413)
+++ gcc/reload1.c (working copy)
@@ -6084,9 +6084,10 @@ choose_reload_regs (struct insn_chain *c
need_mode = mode;
else
need_mode
- = smallest_mode_for_size (GET_MODE_BITSIZE (mode)
- + byte * BITS_PER_UNIT,
- GET_MODE_CLASS (mode));
+ = smallest_mode_for_size
+ (GET_MODE_BITSIZE (mode) + byte * BITS_PER_UNIT,
+ GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
+ ? MODE_INT : GET_MODE_CLASS (mode));
if ((GET_MODE_SIZE (GET_MODE (last_reg))
>= GET_MODE_SIZE (need_mode))