[new-regalloc] web_class bugfix
Denis Chertykov
denisc@overta.ru
Fri Apr 19 08:32:00 GMT 2002
Hi Michael.
In addition to the following patch I have a patch against ra.c which
realise the following things:
1. Substitute regclass() to web_class();
2. Substitute reg_preferred_class() to web_preferred_class();
3. Use strict register classes (don't use something like reg_alternate_class);
4. Use DF2RA to support earlyclobber ('&') constraints - add conflicts
between any earlyclobbered operands and all uses of his insn.
With these changes I have only about 250-300 reloads (real reloads which
produced by reload pass) while `make restage2'. It's about 1.5 - 2
reloads for one compiled file.
Produced reloads are:
1. My stupid version of web_class can't split web if it can't have one
register class. (Few mails ago we have discussed this problem.);
2. Current new-allocator can't eliminate `argp' register (i386 port);
3. Problem with the '=&1' constraint from `fix_truncdi_nomemory'.
What do you think about these ?
Can I commit changes described above ?
(I have bootstrapped C,C++. But, usage of DF2RA seems ugly, but
results seems interesting.)
Also I have changed the following fragment because allocator can't
find webs for spilling.
/* CALL_INSNs are not really deaths, but still more registers
are free after a call, than before.
XXX Note, that sometimes reload barfs when we emit insns between
a call and the insn which copies the return register into a
pseudo. */
if (GET_CODE (insn) == CALL_INSN)
ri.need_load = 1;
else if (INSN_P (insn))
for (n = 0; n < info.num_uses; n++)
{
struct web *web = use2web[DF_REF_ID (info.uses[n])];
struct web *supweb = find_web_for_subweb (web);
int is_death;
if (supweb->type == PRECOLORED
&& TEST_HARD_REG_BIT (never_use_colors, supweb->color))
continue;
is_death = !TEST_BIT (ri.live, supweb->id);
is_death &= !TEST_BIT (ri.live, web->id);
if (is_death || supweb->type == SPILLED)
---------------------- added ^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
ri.need_load = 1;
bitmap_set_bit (new_deaths, INSN_UID (insn));
break;
}
}
Thu Apr 18 22:36:48 2002 Denis Chertykov <denisc@overta.ru>
* pre-reload.h (DF2RA): Remaining parameter added.
* pre-reload.c (df_link2ra_link): New function. Build array
for translation df refs to ra_refs.
(build_df2ra): Use df_link2ra_link.
* ra.c (web_class): Changed use of DF2RA.
Index: pre-reload.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Attic/pre-reload.h,v
retrieving revision 1.1.2.3
diff -c -3 -p -r1.1.2.3 pre-reload.h
*** pre-reload.h 11 Apr 2002 20:31:31 -0000 1.1.2.3
--- pre-reload.h 18 Apr 2002 19:32:30 -0000
*************** struct df2ra
*** 219,224 ****
ra_ref **use2use;
};
extern struct df2ra df2ra;
! #define DF2RA(DF_REF) (*(DF_REF_REG_DEF_P (DF_REF) \
! ? &df2ra.def2def[DF_REF_ID (DF_REF)] \
! : &df2ra.use2use[DF_REF_ID (DF_REF)]))
--- 219,224 ----
ra_ref **use2use;
};
extern struct df2ra df2ra;
! #define DF2RA(DF2RA, DF_REF) (*(DF_REF_REG_DEF_P (DF_REF) \
! ? &(DF2RA).def2def[DF_REF_ID (DF_REF)] \
! : &(DF2RA).use2use[DF_REF_ID (DF_REF)]))
Index: pre-reload.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Attic/pre-reload.c,v
retrieving revision 1.1.2.5
diff -c -3 -p -r1.1.2.5 pre-reload.c
*** pre-reload.c 11 Apr 2002 20:31:31 -0000 1.1.2.5
--- pre-reload.c 18 Apr 2002 19:32:49 -0000
*************** build_ra_refs_for_insn (ra_info, def_ref
*** 3739,3744 ****
--- 3739,3816 ----
return ra_refs;
}
+
+ /* Build array for translation all df refs from dlink to ra_refs from
+ ra_link.
+ Return zero if error. */
+
+ static int
+ df_link2ra_link (df2ra, insn, dlink, rlink)
+ struct df2ra df2ra;
+ rtx insn;
+ struct df_link *dlink;
+ struct ra_link *rlink;
+ {
+ unsigned int regno;
+ int bad = 0;
+
+ if (!link)
+ return 0;
+
+ for (; dlink; dlink = dlink->next)
+ /* This condition shows which df ref's can't be reached by
+ ra_ref's. */
+ if (dlink->ref
+ && GET_MODE_CLASS (GET_MODE (DF_REF_REG (dlink->ref))) != MODE_CC
+ && GET_CODE (PATTERN (insn)) != ASM_INPUT
+ && GET_CODE (insn) != CALL_INSN
+ && (DF_REF_REGNO (dlink->ref) < FIRST_PSEUDO_REGISTER
+ ? !fixed_regs[DF_REF_REGNO (dlink->ref)]
+ : 1))
+ {
+ struct ra_link *link;
+ struct ref *dref = dlink->ref;
+ int founded = 0;
+ regno = DF_REF_REGNO (dlink->ref);
+
+ if (regno < FIRST_PSEUDO_REGISTER)
+ for (link = rlink; link; link = link->next)
+ {
+ ra_ref *ref = link->ref;
+ unsigned int ref_regno = RA_REF_REGNO (ref);
+
+ if (ref_regno < FIRST_PSEUDO_REGISTER)
+ {
+ int i;
+ int nregs = HARD_REGNO_NREGS (ref_regno,
+ GET_MODE (ref->reg));
+
+ for (i = 0; i < nregs; ++i)
+ if (regno == ref_regno + i)
+ {
+ founded = 1;
+ DF2RA (df2ra, dref) = ref;
+ break;
+ }
+ }
+ }
+ else
+ for (link = rlink;link; link = link->next)
+ {
+ ra_ref *ref = link->ref;
+ if (regno == REGNO (ref->reg))
+ {
+ founded = 1;
+ DF2RA (df2ra, dref) = ref;
+ break;
+ }
+ }
+ if (!founded)
+ bad = 1;
+ }
+ return bad;
+ }
+
struct df2ra
build_df2ra (df, ra_info)
struct df *df;
*************** build_df2ra (df, ra_info)
*** 3746,3752 ****
{
struct df2ra df2ra;
rtx insn;
- unsigned int regno;
df2ra.def2def = xcalloc (df->def_id, sizeof (ra_ref *));
df2ra.use2use = xcalloc (df->use_id, sizeof (ra_ref *));
--- 3818,3823 ----
*************** build_df2ra (df, ra_info)
*** 3755,3829 ****
for translation df ref to ra_ref. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
- int n;
int bad = 0;
- struct df_link *dlink = DF_INSN_DEFS (df, insn);
-
- for (n = 0; dlink; dlink = dlink->next)
- /* This condition shows which df ref's can't be reached by
- ra_ref's. */
- if (dlink->ref
- && GET_MODE_CLASS (GET_MODE (DF_REF_REG (dlink->ref))) != MODE_CC
- && GET_CODE (PATTERN (insn)) != ASM_INPUT
- && GET_CODE (insn) != CALL_INSN
- && (DF_REF_REGNO (dlink->ref) < FIRST_PSEUDO_REGISTER
- ? !fixed_regs[DF_REF_REGNO (dlink->ref)]
- : 1))
- {
- struct ref *dref = dlink->ref;
- int founded = 0;
- regno = DF_REF_REGNO (dlink->ref);
! if (RA_INSN_REFS (ra_info, insn))
! {
! struct ra_link *link;
!
! if (regno < FIRST_PSEUDO_REGISTER)
! for (link = RA_INSN_DEFS (ra_info, insn);
! link && !founded;
! link = link->next)
! {
! ra_ref *ref = link->ref;
! unsigned int ref_regno = RA_REF_REGNO (ref);
!
! if (ref_regno < FIRST_PSEUDO_REGISTER)
! {
! int i;
! int nregs = HARD_REGNO_NREGS (ref_regno,
! GET_MODE (ref->reg));
!
! for (i = 0; i < nregs; ++i)
! if (regno == ref_regno + i)
! {
! founded = 1;
! DF2RA (dref) = ref;
! break;
! }
! }
! }
! else
! for (link = RA_INSN_DEFS (ra_info, insn);
! link && !founded;
! link = link->next)
! {
! ra_ref *ref = link->ref;
! if (regno == REGNO (ref->reg))
! {
! founded = 1;
! DF2RA (dref) = ref;
! break;
! }
! }
! }
! if (!founded)
! {
! bad = 1;
! }
! }
! /* FIXME denisc@overta.ru Spilling must be here.
if (bad)
{
! fprintf (stderr, "NONEQUAL: %d\n", regno);
debug_df_insn (insn);
debug_ra_insn_refs (ra_info, insn);
}
--- 3826,3844 ----
for translation df ref to ra_ref. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
int bad = 0;
! if (RA_INSN_REFS (ra_info, insn))
! {
! bad = df_link2ra_link (df2ra, insn, DF_INSN_DEFS (df, insn),
! RA_INSN_DEFS (ra_info, insn));
! bad |= df_link2ra_link (df2ra, insn, DF_INSN_USES (df, insn),
! RA_INSN_USES (ra_info, insn));
! }
! /* FIXME denisc@overta.ru
if (bad)
{
! fprintf (stderr, "NONEQUAL: ");
debug_df_insn (insn);
debug_ra_insn_refs (ra_info, insn);
}
Index: ra.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Attic/ra.c,v
retrieving revision 1.1.2.52
diff -c -3 -p -r1.1.2.52 ra.c
*** ra.c 10 Apr 2002 16:44:39 -0000 1.1.2.52
--- ra.c 18 Apr 2002 19:33:33 -0000
*************** dump_web_conflicts (web)
*** 9643,9649 ****
}
void debug_hard_reg_set PARAMS ((HARD_REG_SET));
! /* Output SET to stderr. */
void
debug_hard_reg_set (set)
HARD_REG_SET set;
--- 9643,9649 ----
}
void debug_hard_reg_set PARAMS ((HARD_REG_SET));
! /* Output HARD_REG_SET to stderr. */
void
debug_hard_reg_set (set)
HARD_REG_SET set;
*************** web_class ()
*** 9705,9711 ****
for (i = 0; i < web->num_defs; ++i)
{
dref = web->defs[i];
! rref = DF2RA (dref);
if (rref)
++class[rref->class];
}
--- 9705,9711 ----
for (i = 0; i < web->num_defs; ++i)
{
dref = web->defs[i];
! rref = DF2RA (df2ra, dref);
if (rref)
++class[rref->class];
}
*************** web_class ()
*** 9713,9719 ****
for (i = 0; i < web->num_uses; ++i)
{
dref = web->uses[i];
! rref = DF2RA (dref);
if (rref)
++class[rref->class];
}
--- 9713,9719 ----
for (i = 0; i < web->num_uses; ++i)
{
dref = web->uses[i];
! rref = DF2RA (df2ra, dref);
if (rref)
++class[rref->class];
}
*************** web_class ()
*** 9730,9741 ****
}
else if (!reg_class_subset_p (best, i))
best = NO_REGS;
! /* fprintf (stderr, "%s: %d ", reg_class_names[i], class[i]); */
}
! /* fprintf (stderr, " BEST: %s\n", reg_class_names[best]); */
if (best == NO_REGS)
{
! fprintf (stderr, "Web: %d NO_REGS\n", web->id);
best = GENERAL_REGS;
}
reg_class_of_web[n] = best;
--- 9730,9741 ----
}
else if (!reg_class_subset_p (best, i))
best = NO_REGS;
! /* fprintf (stderr, "%s: %d ", reg_class_names[i], class[i]); */
}
! /* fprintf (stderr, " BEST: %s\n", reg_class_names[best]); */
if (best == NO_REGS)
{
! fprintf (stderr, "Web: %d (%d) NO_REGS\n", web->id, web->regno);
best = GENERAL_REGS;
}
reg_class_of_web[n] = best;
More information about the Gcc-patches
mailing list