[new-regalloc]: pre-reload and new allocator
Denis Chertykov
denisc@overta.ru
Thu Aug 1 13:20:00 GMT 2002
Patch for integration pre-reload and allocator.
This is a committed patch.
This patch mustn't influence on allocator without
-fnew-ra-pre-reload and -fnew-ra-spanned-deaths-pass.
2002-08-02 Denis Chertykov <denisc@overta.ru>
* pre-reload.c (scan_addr_func): Bugfix. Argument ra_info removed.
(collect_insn_info): this_alternative_address_operand,
goal_alternative_address_operand, new arrays for handling
constraint 'p'.
(pre_reload_collect): Debug a pre-reload process to rtl_dump_file.
* ra.h (max_normal_pseudo, orig_max_uid): Removed.
(emitted_by_spill, ra_modified_insns, spill_slot_regs): New bitmaps.
(is_partly_dead, set_web_live, reset_web_live, reg_class,
web_class): Prototypes declared.
(SPILL_SLOT_P): New macro.
* ra-build.c (copy_insn_p): Use SPILL_SLOT_P instead of
comparision with max_normal_pseudo.
(detect_spill_temps): Use detect_spanned_deaths if special flag.
Use bitmap emitted_by_spill instead of orig_max_uid.
(detect_remat_webs): Use bitmap emitted_by_spill instead of
orig_max_uid.
(select_regclass): Use web_class if flag_ra_pre_reload.
(handle_asm_insn): Use web_preferred_class if flag_ra_pre_reload.
(detect_spanned_deaths): New function. Calculate spanned deaths
and spanned defs of webs.
* ra.c (max_normal_pseudo, orig_max_uid): Removed.
(emitted_by_spill, ra_modified_insns, spill_slot_regs): New
bitmaps.
(init_ra): Definition of orig_max_uid removed.
Initialization of insns_with_deaths and death_insns_max_uid moved
to reg_alloc.
(reg_alloc): Use pre_reload if flag_ra_pre_reload.
(web_class): New variable "debug" for better controlling of debug
output.
* ra-colorize.c (build_worklists): Use SPILL_SLOT_P instead of
max_normal_pseudo.
(combine): Likewise.
(check_colors): Likewise.
(extended_coalesce_2): Likewise.
(colorize_one_web): Likewise. Handle flag_ra_pre_reload.
* ra-debug.c (dump_igraph): Use SPILL_SLOT_P instead of
max_normal_pseudo.
(dump_web_insns): Renamed to debug_web_insns. All debugging output
will be printed to stderr.
(dump_web_conflicts): Likewise.
* ra-rewrite.c: Set bit in ra_modified_insns for all insns handled by
by df_insn_modify.
Set bit in emitted_by_spill for all emitted insns.
(allocate_spill_web): Set bit in spill_slot_regs for new spill
slot register.
(is_partly_live): Test web->parent_web.
(emit_loads): Emit loads only for subwebs if super web isn't
marked for load.
(is_partly_dead, set_web_live, reset_web_live): New functions.
Web liveness must be accessed only throught these functions and
throught is_partly_live.
(detect_deaths_in_bb): Access web liveness only throught
is_partly_dead, set_web_live, reset_web_live and is_partly_live.
(reloads_to_loads): Likewise.
(rewrite_program2): Likewise.
* toplev.c (flag_ra_pre_reload): New flag -fnew-ra-pre-reload.
(flag_ra_spanned_deaths_from_scratch): New flag
-fnew-ra-spanned-deaths-pass.
Index: pre-reload.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Attic/pre-reload.c,v
retrieving revision 1.1.2.10
diff -c -3 -p -r1.1.2.10 pre-reload.c
*** pre-reload.c 18 Jul 2002 20:26:01 -0000 1.1.2.10
--- pre-reload.c 1 Aug 2002 20:14:13 -0000
*************** struct scan_addr_state
*** 1913,1921 ****
char *constraints;
int modified; /* Flag for auto modified addresses */
enum reg_class class; /* Register class */
};
! static int scan_addr_func PARAMS ((struct ra_info *, rtx *,
struct scan_addr_state *));
static ra_ref * scan_addr_create_ref PARAMS ((struct ra_info *, rtx *,
struct scan_addr_state *,
--- 1913,1922 ----
char *constraints;
int modified; /* Flag for auto modified addresses */
enum reg_class class; /* Register class */
+ struct ra_info *ra_info;
};
! static int scan_addr_func PARAMS ((rtx *,
struct scan_addr_state *));
static ra_ref * scan_addr_create_ref PARAMS ((struct ra_info *, rtx *,
struct scan_addr_state *,
*************** static ra_ref * scan_addr_create_ref PAR
*** 1925,1932 ****
FIXME: Must be substituted by define_address. */
static int
! scan_addr_func (ra_info, loc, scan_state)
! struct ra_info *ra_info;
rtx *loc;
struct scan_addr_state *scan_state;
{
--- 1926,1932 ----
FIXME: Must be substituted by define_address. */
static int
! scan_addr_func (loc, scan_state)
rtx *loc;
struct scan_addr_state *scan_state;
{
*************** scan_addr_func (ra_info, loc, scan_state
*** 1939,1945 ****
t = RA_REF_ADDRESS | RA_REF_READ;
if (scan_state->regs_per_addr == 1)
t |= RA_REF_WRITE;
! ref = scan_addr_create_ref (ra_info, loc, scan_state, t);
scan_state->class = INDEX_REG_CLASS;
}
break;
--- 1939,1945 ----
t = RA_REF_ADDRESS | RA_REF_READ;
if (scan_state->regs_per_addr == 1)
t |= RA_REF_WRITE;
! ref = scan_addr_create_ref (scan_state->ra_info, loc, scan_state, t);
scan_state->class = INDEX_REG_CLASS;
}
break;
*************** scan_addr_func (ra_info, loc, scan_state
*** 1957,1963 ****
if (REG_P (x1) && ! REG_P (x0))
{
! scan_addr_func (ra_info, &XEXP (*loc, 1), scan_state);
for_each_rtx (&XEXP (*loc, 0), (rtx_function) scan_addr_func,
scan_state);
return -1;
--- 1957,1963 ----
if (REG_P (x1) && ! REG_P (x0))
{
! scan_addr_func (&XEXP (*loc, 1), scan_state);
for_each_rtx (&XEXP (*loc, 0), (rtx_function) scan_addr_func,
scan_state);
return -1;
*************** scan_addr_func (ra_info, loc, scan_state
*** 1978,1984 ****
if (REG_P (*loc0))
{
ra_ref *ref;
! ref = scan_addr_create_ref (ra_info, loc0, scan_state,
RA_REF_ADDRESS | RA_REF_RDWR);
ref->class = BASE_REG_CLASS;
return -1;
--- 1978,1984 ----
if (REG_P (*loc0))
{
ra_ref *ref;
! ref = scan_addr_create_ref (scan_state->ra_info, loc0, scan_state,
RA_REF_ADDRESS | RA_REF_RDWR);
ref->class = BASE_REG_CLASS;
return -1;
*************** scan_addr_func (ra_info, loc, scan_state
*** 1994,2003 ****
if (GET_CODE (*loc0) == SUBREG)
loc0 = &SUBREG_REG (*loc0);
! if (REG_P (XEXP (*loc0, 0)))
{
ra_ref *ref;
! ref = scan_addr_create_ref (ra_info, &XEXP (*loc0, 0), scan_state,
RA_REF_ADDRESS | RA_REF_WRITE);
scan_state->class = BASE_REG_CLASS;
for_each_rtx (&XEXP (*loc, 1), (rtx_function) scan_addr_func,
--- 1994,2004 ----
if (GET_CODE (*loc0) == SUBREG)
loc0 = &SUBREG_REG (*loc0);
! if (REG_P (*loc0))
{
ra_ref *ref;
! ref = scan_addr_create_ref (scan_state->ra_info,
! loc0, scan_state,
RA_REF_ADDRESS | RA_REF_WRITE);
scan_state->class = BASE_REG_CLASS;
for_each_rtx (&XEXP (*loc, 1), (rtx_function) scan_addr_func,
*************** collect_insn_info (ra_info, insn, def_re
*** 2095,2100 ****
--- 2096,2102 ----
rtx this_alternative_reg[MAX_RECOG_OPERANDS];
rtx *this_alternative_reg_loc[MAX_RECOG_OPERANDS];
char *this_alternative_constraints[MAX_RECOG_OPERANDS];
+ int this_alternative_address_operand[MAX_RECOG_OPERANDS];
int this_alternative_number;
int swapped;
int goal_alternative[MAX_RECOG_OPERANDS];
*************** collect_insn_info (ra_info, insn, def_re
*** 2109,2114 ****
--- 2111,2117 ----
rtx goal_alternative_reg[MAX_RECOG_OPERANDS];
rtx *goal_alternative_reg_loc[MAX_RECOG_OPERANDS];
char *goal_alternative_constraints[MAX_RECOG_OPERANDS];
+ int goal_alternative_address_operand[MAX_RECOG_OPERANDS];
int goal_alternative_swapped;
int best;
int commutative;
*************** collect_insn_info (ra_info, insn, def_re
*** 2470,2475 ****
--- 2473,2479 ----
this_alternative_reg[i] = NULL_RTX;
this_alternative_reg_loc[i] = NULL;
this_alternative_constraints[i] = p;
+ this_alternative_address_operand[i] = 0;
/* An empty constraint or empty alternative
allows anything which matched the pattern. */
*************** collect_insn_info (ra_info, insn, def_re
*** 2595,2600 ****
--- 2599,2605 ----
/* All necessary reloads for an address_operand
were handled in find_reloads_address. */
this_alternative[i] = (int) BASE_REG_CLASS;
+ this_alternative_address_operand[i] = 1;
win = 1;
break;
*************** collect_insn_info (ra_info, insn, def_re
*** 2970,2977 ****
= this_alternative_earlyclobber[i];
goal_alternative_reg[i] = this_alternative_reg[i];
goal_alternative_reg_loc[i] = this_alternative_reg_loc[i];
! goal_alternative_constraints[i] =
! this_alternative_constraints[i];
}
goal_alternative_swapped = swapped;
best = losers;
--- 2975,2984 ----
= this_alternative_earlyclobber[i];
goal_alternative_reg[i] = this_alternative_reg[i];
goal_alternative_reg_loc[i] = this_alternative_reg_loc[i];
! goal_alternative_constraints[i]
! = this_alternative_constraints[i];
! goal_alternative_address_operand[i]
! = this_alternative_address_operand[i];
}
goal_alternative_swapped = swapped;
best = losers;
*************** collect_insn_info (ra_info, insn, def_re
*** 3318,3324 ****
{
opno2ref[i] = 0;
! if (GET_CODE (recog_data.operand[i]) == MEM)
{
/* FIXME: Now we can only record registers inside address. */
struct scan_addr_state scan_state;
--- 3325,3332 ----
{
opno2ref[i] = 0;
! if (GET_CODE (recog_data.operand[i]) == MEM
! || goal_alternative_address_operand[i])
{
/* FIXME: Now we can only record registers inside address. */
struct scan_addr_state scan_state;
*************** collect_insn_info (ra_info, insn, def_re
*** 3331,3336 ****
--- 3339,3345 ----
scan_state.constraints = goal_alternative_constraints[i];
scan_state.modified = 0;
scan_state.class = BASE_REG_CLASS;
+ scan_state.ra_info = ra_info;
for_each_rtx (recog_data.operand_loc[i],
(rtx_function) scan_addr_func, &scan_state);
def_refs = scan_state.defs;
*************** build_df2ra (df, ra_info)
*** 3817,3824 ****
struct df2ra df2ra;
rtx insn;
! df2ra.def2def = xcalloc (df->def_id, sizeof (ra_ref *));
! df2ra.use2use = xcalloc (df->use_id, sizeof (ra_ref *));
/* Check ra_info by comparing it with the df info and build array
for translation df ref to ra_ref. */
--- 3826,3833 ----
struct df2ra df2ra;
rtx insn;
! df2ra.def2def = xcalloc (df->def_id + 1, sizeof (ra_ref *));
! df2ra.use2use = xcalloc (df->use_id + 1, sizeof (ra_ref *));
/* Check ra_info by comparing it with the df info and build array
for translation df ref to ra_ref. */
*************** build_df2ra (df, ra_info)
*** 3833,3846 ****
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);
}
- */
}
return df2ra;
}
--- 3842,3854 ----
bad |= df_link2ra_link (df2ra, insn, DF_INSN_USES (df, insn),
RA_INSN_USES (ra_info, insn));
}
! /* FIXME denisc@overta.ru */
! if (bad & 0)
{
fprintf (stderr, "NONEQUAL: ");
debug_df_insn (insn);
debug_ra_insn_refs (ra_info, insn);
}
}
return df2ra;
}
*************** pre_reload_collect (ra_info, modified)
*** 3923,3928 ****
--- 3931,3937 ----
rtx prev;
rtx next;
rtx orig_insn;
+ rtx deb_insn;
if (modified && !bitmap_bit_p (modified, INSN_UID (insn)))
continue;
*************** pre_reload_collect (ra_info, modified)
*** 3959,3966 ****
--- 3968,3996 ----
if (n_reloads)
{
rtx before = PREV_INSN (insn);
+ rtx after = NEXT_INSN (insn);
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "Reload for insn:\n");
+ print_rtl_single (rtl_dump_file, insn);
+ fprintf (rtl_dump_file, "\n");
+ }
+
emit_pre_reload_insns (insn);
subst_pre_reloads (insn);
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "Reload results:\n");
+ for (deb_insn = NEXT_INSN (before); deb_insn != after;
+ deb_insn = NEXT_INSN (deb_insn))
+ {
+ print_rtl_single (rtl_dump_file, deb_insn);
+ fprintf (rtl_dump_file, "\n");
+ }
+ }
+
insn = NEXT_INSN (before);
continue;
}
Index: ra-build.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ra-build.c,v
retrieving revision 1.1.2.4
diff -c -3 -p -r1.1.2.4 ra-build.c
*** ra-build.c 24 Jul 2002 23:21:02 -0000 1.1.2.4
--- ra-build.c 1 Aug 2002 20:14:58 -0000
*************** static void init_bb_info PARAMS ((void))
*** 117,122 ****
--- 117,123 ----
static void free_bb_info PARAMS ((void));
static void build_web_parts_and_conflicts PARAMS ((struct df *));
static void select_regclass PARAMS ((void));
+ static void detect_spanned_deaths PARAMS ((unsigned int *spanned_deaths));
/* A sbitmap of DF_REF_IDs of uses, which are live over an abnormal
*************** copy_insn_p (insn, source, target)
*** 275,282 ****
/* Copies between hardregs are useless for us, as not coalesable anyway. */
if ((s_regno < FIRST_PSEUDO_REGISTER
&& d_regno < FIRST_PSEUDO_REGISTER)
! || s_regno >= max_normal_pseudo
! || d_regno >= max_normal_pseudo)
return 0;
if (source)
--- 276,283 ----
/* Copies between hardregs are useless for us, as not coalesable anyway. */
if ((s_regno < FIRST_PSEUDO_REGISTER
&& d_regno < FIRST_PSEUDO_REGISTER)
! || SPILL_SLOT_P (s_regno)
! || SPILL_SLOT_P (d_regno))
return 0;
if (source)
*************** detect_spill_temps ()
*** 2275,2281 ****
--- 2276,2289 ----
{
struct dlist *d;
bitmap already = BITMAP_XMALLOC ();
+ unsigned int *spanned_deaths_from_scratch;
+ if (flag_ra_spanned_deaths_from_scratch)
+ {
+ spanned_deaths_from_scratch
+ = (unsigned *)xcalloc (sizeof (int), num_webs);
+ detect_spanned_deaths (spanned_deaths_from_scratch);
+ }
/* Detect webs used for spill temporaries. */
for (d = WEBS(INITIAL); d; d = d->next)
{
*************** detect_spill_temps ()
*** 2312,2321 ****
unsigned int i;
int spill_involved = 0;
for (i = 0; i < web->num_uses && !spill_involved; i++)
! if (DF_REF_INSN_UID (web->uses[i]) >= orig_max_uid)
spill_involved = 1;
for (i = 0; i < web->num_defs && !spill_involved; i++)
! if (DF_REF_INSN_UID (web->defs[i]) >= orig_max_uid)
spill_involved = 1;
if (spill_involved/* && ra_pass > 2*/)
--- 2320,2331 ----
unsigned int i;
int spill_involved = 0;
for (i = 0; i < web->num_uses && !spill_involved; i++)
! if (bitmap_bit_p (emitted_by_spill,
! DF_REF_INSN_UID (web->uses[i])))
spill_involved = 1;
for (i = 0; i < web->num_defs && !spill_involved; i++)
! if (bitmap_bit_p (emitted_by_spill,
! DF_REF_INSN_UID (web->defs[i])))
spill_involved = 1;
if (spill_involved/* && ra_pass > 2*/)
*************** detect_spill_temps ()
*** 2334,2355 ****
dead web), so reduce the number of spanned deaths by those
insns. Note that sometimes such deaths are _not_ counted,
so negative values can result. */
! bitmap_zero (already);
! for (i = 0; i < web->num_defs; i++)
{
! rtx insn = web->defs[i]->insn;
! if (TEST_BIT (insns_with_deaths, INSN_UID (insn))
! && !bitmap_bit_p (already, INSN_UID (insn)))
{
! unsigned int j;
! bitmap_set_bit (already, INSN_UID (insn));
! /* Only decrement it once for each insn. */
! for (j = 0; j < web->num_uses; j++)
! if (web->uses[j]->insn == insn)
! {
! num_deaths--;
! break;
! }
}
}
/* But mark them specially if they could possibly be spilled,
--- 2344,2370 ----
dead web), so reduce the number of spanned deaths by those
insns. Note that sometimes such deaths are _not_ counted,
so negative values can result. */
! if (flag_ra_spanned_deaths_from_scratch)
! num_deaths = spanned_deaths_from_scratch[web->id];
! else
{
! bitmap_zero (already);
! for (i = 0; i < web->num_defs; i++)
{
! rtx insn = web->defs[i]->insn;
! if (TEST_BIT (insns_with_deaths, INSN_UID (insn))
! && !bitmap_bit_p (already, INSN_UID (insn)))
! {
! unsigned int j;
! bitmap_set_bit (already, INSN_UID (insn));
! /* Only decrement it once for each insn. */
! for (j = 0; j < web->num_uses; j++)
! if (web->uses[j]->insn == insn)
! {
! num_deaths--;
! break;
! }
! }
}
}
/* But mark them specially if they could possibly be spilled,
*************** detect_spill_temps ()
*** 2363,2374 ****
change making the graph not easier to color. Make this also
a short web. Don't do this if it crosses calls, as these are
also points of reloads. */
! else if (web->span_deaths == 0 && !web->crosses_call)
web->spill_temp = 3;
}
web->orig_spill_temp = web->spill_temp;
}
BITMAP_XFREE (already);
}
/* Returns nonzero if the rtx MEM refers somehow to a stack location. */
--- 2378,2394 ----
change making the graph not easier to color. Make this also
a short web. Don't do this if it crosses calls, as these are
also points of reloads. */
! else if ((flag_ra_spanned_deaths_from_scratch
! ? spanned_deaths_from_scratch[web->id] == 0
! : web->span_deaths == 0)
! && !web->crosses_call)
web->spill_temp = 3;
}
web->orig_spill_temp = web->spill_temp;
}
BITMAP_XFREE (already);
+ if (flag_ra_spanned_deaths_from_scratch)
+ free (spanned_deaths_from_scratch);
}
/* Returns nonzero if the rtx MEM refers somehow to a stack location. */
*************** detect_remat_webs ()
*** 2520,2526 ****
unchanging flag set, but nevertheless they are stable across
the livetime in question. */
|| (GET_CODE (src) == MEM
! && INSN_UID (insn) >= orig_max_uid
&& memref_is_stack_slot (src)))
/* And we must be able to construct an insn without
side-effects to actually load that value into a reg. */
--- 2540,2546 ----
unchanging flag set, but nevertheless they are stable across
the livetime in question. */
|| (GET_CODE (src) == MEM
! && bitmap_bit_p (emitted_by_spill, INSN_UID (insn))
&& memref_is_stack_slot (src)))
/* And we must be able to construct an insn without
side-effects to actually load that value into a reg. */
*************** static void
*** 2627,2637 ****
select_regclass ()
{
struct dlist *d;
for (d = WEBS(INITIAL); d; d = d->next)
{
int i;
- struct web *w;
struct web *web = DLIST_WEB (d);
do
{
--- 2647,2659 ----
select_regclass ()
{
struct dlist *d;
+
+ if (flag_ra_pre_reload)
+ web_class ();
for (d = WEBS(INITIAL); d; d = d->next)
{
int i;
struct web *web = DLIST_WEB (d);
do
{
*************** select_regclass ()
*** 2639,2674 ****
if (web->regno < FIRST_PSEUDO_REGISTER)
continue;
!
! if ((web->spill_temp == 1 || web->spill_temp == 2)
! && ! web->changed
! && web->type == INITIAL)
{
! if (web->regno >= max_normal_pseudo)
{
COPY_HARD_REG_SET (web->usable_regs,
! reg_class_contents
! [reg_preferred_class (web->regno)]);
IOR_HARD_REG_SET (web->usable_regs,
reg_class_contents
[reg_alternate_class (web->regno)]);
}
- else
- COPY_HARD_REG_SET (web->usable_regs,
- reg_class_contents[(int) ALL_REGS]);
}
- else
- {
- web->regclass = reg_preferred_class (web->regno);
- if (web->regclass == NO_REGS)
- abort ();
- COPY_HARD_REG_SET (web->usable_regs,
- reg_class_contents[web->regclass]);
- IOR_HARD_REG_SET (web->usable_regs,
- reg_class_contents
- [reg_alternate_class (web->regno)]);
- }
-
/* add_hardregs is wrong in multi-length classes, e.g.
using a DFmode pseudo on x86 can result in class FLOAT_INT_REGS,
where, if it finally is allocated to GENERAL_REGS it needs two,
--- 2661,2703 ----
if (web->regno < FIRST_PSEUDO_REGISTER)
continue;
!
! if (flag_ra_pre_reload)
! {
! web->regclass = web_preferred_class (web);
! COPY_HARD_REG_SET (web->usable_regs,
! reg_class_contents [web->regclass]);
! }
! else
{
! if ((web->spill_temp == 1 || web->spill_temp == 2)
! && ! web->changed)
! {
! if (SPILL_SLOT_P (web->regno))
! {
! COPY_HARD_REG_SET (web->usable_regs,
! reg_class_contents
! [reg_preferred_class (web->regno)]);
! IOR_HARD_REG_SET (web->usable_regs,
! reg_class_contents
! [reg_alternate_class (web->regno)]);
! }
! else
! COPY_HARD_REG_SET (web->usable_regs,
! reg_class_contents[(int) ALL_REGS]);
! }
! else
{
+ web->regclass = reg_preferred_class (web->regno);
+ if (web->regclass == NO_REGS)
+ abort ();
COPY_HARD_REG_SET (web->usable_regs,
! reg_class_contents[web->regclass]);
IOR_HARD_REG_SET (web->usable_regs,
reg_class_contents
[reg_alternate_class (web->regno)]);
}
}
/* add_hardregs is wrong in multi-length classes, e.g.
using a DFmode pseudo on x86 can result in class FLOAT_INT_REGS,
where, if it finally is allocated to GENERAL_REGS it needs two,
*************** select_regclass ()
*** 2684,2690 ****
if ((web->spill_temp == 1 || web->spill_temp == 2)
&& ! web->changed
! && web->type == INITIAL)
{
/* Now look for a class, which is subset of our constraints, to
setup add_hardregs, and regclass for debug output. */
--- 2713,2719 ----
if ((web->spill_temp == 1 || web->spill_temp == 2)
&& ! web->changed
! && ! flag_ra_pre_reload)
{
/* Now look for a class, which is subset of our constraints, to
setup add_hardregs, and regclass for debug output. */
*************** handle_asm_insn (df, insn)
*** 2976,2985 ****
}
else
{
! COPY_HARD_REG_SET (conflict, usable_regs
! [reg_preferred_class (web->regno)]);
! IOR_HARD_REG_SET (conflict, usable_regs
! [reg_alternate_class (web->regno)]);
AND_COMPL_HARD_REG_SET (conflict, allowed);
/* We can't yet establish these conflicts. Reload must go first
(or better said, we must implement some functionality of reload).
--- 3005,3020 ----
}
else
{
! if (flag_ra_pre_reload)
! COPY_HARD_REG_SET (conflict,
! usable_regs [web_preferred_class (web)]);
! else
! {
! COPY_HARD_REG_SET (conflict, usable_regs
! [reg_preferred_class (web->regno)]);
! IOR_HARD_REG_SET (conflict, usable_regs
! [reg_alternate_class (web->regno)]);
! }
AND_COMPL_HARD_REG_SET (conflict, allowed);
/* We can't yet establish these conflicts. Reload must go first
(or better said, we must implement some functionality of reload).
*************** ra_build_free_all (df)
*** 3251,3256 ****
--- 3286,3507 ----
free (def2web);
use2web = NULL;
def2web = NULL;
+ }
+
+ static void
+ detect_spanned_deaths (spanned_deaths)
+ unsigned int *spanned_deaths;
+ {
+ rtx insn, head_prev;
+ unsigned int j;
+ basic_block bb;
+ unsigned int i;
+ bitmap already ATTRIBUTE_UNUSED;
+ int debug = 0;
+ sbitmap live = sbitmap_alloc (num_webs);
+ sbitmap rmw_web = sbitmap_alloc (num_webs);
+ sbitmap defs_per_insn = sbitmap_alloc (num_webs);
+
+ if (debug)
+ {
+ already = BITMAP_XMALLOC ();
+ fprintf (stderr, ":::: Detect_spanned_deaths :::\n");
+ }
+
+ FOR_ALL_BB (bb)
+ {
+ if (!bb->end)
+ continue;
+
+ insn = bb->end;
+ if (!INSN_P (insn))
+ insn = prev_real_insn (insn);
+
+ /* Empty block? */
+ if (!insn || BLOCK_FOR_INSN (insn) != bb)
+ continue;
+
+ head_prev = PREV_INSN (bb->head);
+ sbitmap_zero (live);
+
+ if(debug)
+ {
+ fprintf (stderr, "live_at_end[%d]", bb->index);
+ bitmap_clear (already);
+ }
+
+ EXECUTE_IF_SET_IN_BITMAP
+ (live_at_end[bb->index], 0, j,
+ {
+ struct web *web = use2web[j];
+ struct web *aweb = alias (find_web_for_subweb (web));
+ set_web_live (live, aweb);
+ if (debug)
+ if (! bitmap_bit_p (already, aweb->id))
+ {
+ fprintf (stderr, " %d", aweb->id);
+ bitmap_set_bit (already, aweb->id);
+ }
+ });
+
+ if (debug)
+ fprintf (stderr, "\n");
+
+ for (; insn != head_prev; insn = PREV_INSN (insn))
+ {
+ struct ra_insn_info info;
+ unsigned int n;
+
+ if (!INSN_P (insn))
+ continue;
+
+ sbitmap_zero (rmw_web);
+
+ info = insn_df[INSN_UID (insn)];
+
+ if (debug > 1)
+ {
+ fprintf (stderr, "insn %d defs %d uses %d\n", INSN_UID (insn),
+ info.num_defs, info.num_uses);
+ }
+
+ for (n = 0; n < info.num_defs; n++)
+ {
+ struct web *web;
+ struct web *sweb;
+ unsigned int n2;
+ struct ref *ref = info.defs[n];
+ struct web *subweb = def2web[DF_REF_ID (ref)];
+ int is_non_def = 0;
+
+ web = find_web_for_subweb (subweb);
+ /* Detect rmw webs. */
+ for (n2 = 0; n2 < info.num_uses; n2++)
+ {
+ struct web *web2 = use2web[DF_REF_ID (info.uses[n2])];
+ if (web == find_web_for_subweb (web2))
+ {
+ SET_BIT (rmw_web, web->id);
+ SET_BIT (rmw_web, web2->id);
+ is_non_def = 1;
+ }
+ }
+ if (is_non_def)
+ {
+ if (debug > 1)
+ fprintf (stderr, " web %d RMW\n", web->id);
+ continue;
+ }
+
+ reset_web_live (live, web);
+
+ SET_BIT (defs_per_insn, web->id);
+ if (!web->parent_web)
+ for (sweb = web->subreg_next; sweb;
+ sweb = sweb->subreg_next)
+ SET_BIT (defs_per_insn, sweb->id);
+
+ if (debug > 1)
+ {
+ struct web *sweb;
+ fprintf (stderr, " web %d dead\n", subweb->id);
+ if (!web->parent_web)
+ for (sweb = web->subreg_next; sweb;
+ sweb = sweb->subreg_next)
+ fprintf (stderr, " sweb %d dead\n", sweb->id);
+ }
+ }
+ #if 1
+ EXECUTE_IF_SET_IN_SBITMAP
+ (defs_per_insn, 0, n,
+ {
+ RESET_BIT (defs_per_insn, n);
+ EXECUTE_IF_SET_IN_SBITMAP
+ (live, 0, i,
+ {
+ if (! bitmap_bit_p (emitted_by_spill, INSN_UID (insn)))
+ {
+ struct web *supweb;
+ supweb = find_web_for_subweb (id2web[i]);
+ spanned_deaths[i]++;
+ if (supweb && i != supweb->id)
+ spanned_deaths[supweb->id]++;
+
+ if (debug)
+ {
+ if (i != supweb->id)
+ fprintf (stderr, " %d.%d", supweb->id, i);
+ else
+ fprintf (stderr, " %d", i);
+ }
+ }
+ });
+ });
+ if (debug)
+ fprintf (stderr, "\n");
+ #endif
+ for (n = 0; n < info.num_uses; n++)
+ {
+ struct web *web = use2web[DF_REF_ID (info.uses[n])];
+ if (is_partly_dead (live, web))
+ {
+ if (debug)
+ fprintf (stderr, " Death web %d in insn: %d ++",
+ web->id, INSN_UID(insn));
+
+ EXECUTE_IF_SET_IN_SBITMAP
+ (live, 0, i,
+ {
+ if (! bitmap_bit_p (emitted_by_spill, INSN_UID (insn))
+ && ! TEST_BIT (rmw_web, i))
+ {
+ struct web *supweb;
+ supweb = find_web_for_subweb (id2web[i]);
+ spanned_deaths[i]++;
+ if (supweb && i != supweb->id)
+ spanned_deaths[supweb->id]++;
+
+ if (debug)
+ {
+ if (i != supweb->id)
+ fprintf (stderr, " %d.%d", supweb->id, i);
+ else
+ fprintf (stderr, " %d", i);
+ }
+ }
+ });
+ if (debug)
+ fprintf (stderr, "\n");
+ }
+ }
+
+ for (n = 0; n < info.num_uses; n++)
+ {
+ struct web *web = use2web[DF_REF_ID (info.uses[n])];
+ if (web->regno >= FIRST_PSEUDO_REGISTER)
+ set_web_live (live, web);
+ }
+ }
+ }
+
+ if (debug)
+ {
+ for (j = 0; j < num_webs - num_subwebs; ++j)
+ {
+ struct web *web = id2web[j];
+ if (web->type != PRECOLORED)
+ fprintf (stderr, "Web: %d (%d) spanned from web: %d %s %d\n",
+ j, web->regno,
+ web->span_deaths,
+ web->span_deaths == spanned_deaths[web->id] ? "==" : "!=",
+ spanned_deaths[web->id]);
+ }
+ BITMAP_XFREE (already);
+ ra_print_rtl_with_bb (stderr,get_insns());
+ }
+ sbitmap_free (live);
+ sbitmap_free (rmw_web);
+ sbitmap_free (defs_per_insn);
}
#include "gt-ra-build.h"
Index: ra.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ra.c,v
retrieving revision 1.1.2.61
diff -c -3 -p -r1.1.2.61 ra.c
*** ra.c 16 Jul 2002 19:52:44 -0000 1.1.2.61
--- ra.c 1 Aug 2002 20:15:09 -0000
*************** short *ra_reg_renumber;
*** 132,138 ****
struct df *df;
bitmap *live_at_end;
int ra_pass;
- unsigned int max_normal_pseudo;
int an_unusable_color;
/* The different lists on which a web can be (based on the type). */
--- 132,137 ----
*************** int last_max_uid;
*** 145,165 ****
sbitmap last_check_uses;
unsigned int remember_conflicts;
- int orig_max_uid;
-
HARD_REG_SET never_use_colors;
HARD_REG_SET usable_regs[N_REG_CLASSES];
unsigned int num_free_regs[N_REG_CLASSES];
HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
unsigned char byte2bitcount[256];
! #if 0
extern struct df2ra build_df2ra PARAMS ((struct df*, struct ra_info*));
static struct ra_info *ra_info;
- #endif
struct df2ra df2ra;
- static enum reg_class web_preferred_class PARAMS ((struct web *));
- void web_class PARAMS ((void));
unsigned int debug_new_regalloc = -1;
int flag_ra_dump_only_costs = 0;
--- 144,169 ----
sbitmap last_check_uses;
unsigned int remember_conflicts;
HARD_REG_SET never_use_colors;
HARD_REG_SET usable_regs[N_REG_CLASSES];
unsigned int num_free_regs[N_REG_CLASSES];
HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
unsigned char byte2bitcount[256];
! /* Used to detect spill instructions inserted by me. */
! bitmap emitted_by_spill;
!
! /* Tracking pseudos generated for spill slots by rewrite. */
! bitmap spill_slot_regs;
!
! /* Tracking insns modified/deleted/emitted by allocator in current pass. */
! bitmap ra_modified_insns;
!
! static enum reg_class *reg_class_of_web;
!
extern struct df2ra build_df2ra PARAMS ((struct df*, struct ra_info*));
static struct ra_info *ra_info;
struct df2ra df2ra;
unsigned int debug_new_regalloc = -1;
int flag_ra_dump_only_costs = 0;
*************** init_ra ()
*** 574,585 ****
if (an_unusable_color == FIRST_PSEUDO_REGISTER)
abort ();
- orig_max_uid = get_max_uid ();
compute_bb_for_insn ();
ra_reg_renumber = NULL;
! insns_with_deaths = sbitmap_alloc (orig_max_uid);
! death_insns_max_uid = orig_max_uid;
! sbitmap_ones (insns_with_deaths);
gcc_obstack_init (&ra_obstack);
}
--- 578,588 ----
if (an_unusable_color == FIRST_PSEUDO_REGISTER)
abort ();
compute_bb_for_insn ();
ra_reg_renumber = NULL;
! insns_with_deaths = NULL;
! emitted_by_spill = BITMAP_XMALLOC ();
! spill_slot_regs = BITMAP_XMALLOC ();
gcc_obstack_init (&ra_obstack);
}
*************** reg_alloc ()
*** 737,743 ****
int changed;
FILE *ra_dump_file = rtl_dump_file;
rtx last = get_last_insn ();
!
if (! INSN_P (last))
last = prev_real_insn (last);
/* If this is an empty function we shouldn't do all the following,
--- 740,749 ----
int changed;
FILE *ra_dump_file = rtl_dump_file;
rtx last = get_last_insn ();
! /*
! flag_ra_pre_reload = 0;
! flag_ra_spanned_deaths_from_scratch = 0;
! */
if (! INSN_P (last))
last = prev_real_insn (last);
/* If this is an empty function we shouldn't do all the following,
*************** reg_alloc ()
*** 787,808 ****
explicitely requested. */
if ((debug_new_regalloc & DUMP_REGCLASS) == 0)
rtl_dump_file = NULL;
! regclass (get_insns (), max_reg_num (), rtl_dump_file);
! rtl_dump_file = ra_dump_file;
!
! /* ra_info = ra_info_init (max_reg_num ());
! pre_reload (ra_info);
! {
! allocate_reg_info (max_reg_num (), FALSE, FALSE);
! compute_bb_for_insn ();
! delete_trivially_dead_insns (get_insns (), max_reg_num ());
! reg_scan_update (get_insns (), BLOCK_END (n_basic_blocks - 1),
! max_regno);
! max_regno = max_reg_num ();
regclass (get_insns (), max_reg_num (), rtl_dump_file);
! }
! ra_info_free (ra_info);
! free (ra_info);*/
/* XXX the REG_EQUIV notes currently are screwed up, when pseudos are
coalesced, which have such notes. In that case, the whole combined
--- 793,801 ----
explicitely requested. */
if ((debug_new_regalloc & DUMP_REGCLASS) == 0)
rtl_dump_file = NULL;
! if (!flag_ra_pre_reload)
regclass (get_insns (), max_reg_num (), rtl_dump_file);
! rtl_dump_file = ra_dump_file;
/* XXX the REG_EQUIV notes currently are screwed up, when pseudos are
coalesced, which have such notes. In that case, the whole combined
*************** reg_alloc ()
*** 819,825 ****
/* And some global variables. */
ra_pass = 0;
no_new_pseudos = 0;
- max_normal_pseudo = (unsigned) max_reg_num ();
ra_rewrite_init ();
last_def_id = 0;
last_use_id = 0;
--- 812,817 ----
*************** reg_alloc ()
*** 850,856 ****
/* Allocate the global df structure. */
df = df_init ();
!
/* This is the main loop, calling one_pass as long as there are still
some spilled webs. */
do
--- 842,854 ----
/* Allocate the global df structure. */
df = df_init ();
! ra_modified_insns = NULL;
! if (flag_ra_pre_reload)
! {
! ra_info = ra_info_init (max_reg_num ());
! reg_class_of_web = NULL;
! }
!
/* This is the main loop, calling one_pass as long as there are still
some spilled webs. */
do
*************** reg_alloc ()
*** 859,882 ****
if (ra_pass++ > 40)
internal_error ("Didn't find a coloring.\n");
! /* FIXME denisc@overta.ru
! Example of usage ra_info ... routines */
! #if 0
! ra_info = ra_info_init (max_reg_num ());
! pre_reload (ra_info);
! {
! allocate_reg_info (max_reg_num (), FALSE, FALSE);
! compute_bb_for_insn ();
! delete_trivially_dead_insns (get_insns (), max_reg_num ());
! reg_scan_update (get_insns (), BLOCK_END (n_basic_blocks - 1),
! max_regno);
! max_regno = max_reg_num ();
! regclass (get_insns (), max_reg_num (), rtl_dump_file);
! orig_max_uid = get_max_uid ();
! death_insns_max_uid = orig_max_uid;
! }
! #endif
/* First collect all the register refs and put them into
chains per insn, and per regno. In later passes only update
--- 857,884 ----
if (ra_pass++ > 40)
internal_error ("Didn't find a coloring.\n");
! if (flag_ra_pre_reload)
! pre_reload (ra_info, ra_modified_insns);
! if (!ra_modified_insns)
! ra_modified_insns = BITMAP_XMALLOC ();
! else
! bitmap_clear (ra_modified_insns);
!
! if (!insns_with_deaths)
! {
! death_insns_max_uid = get_max_uid ();
! insns_with_deaths = sbitmap_alloc (death_insns_max_uid);
! sbitmap_ones (insns_with_deaths);
! }
!
! if (flag_ra_pre_reload)
! {
! allocate_reg_info (max_reg_num (), FALSE, FALSE);
! compute_bb_for_insn ();
! reg_scan_update (get_insns (), NULL, max_regno);
! max_regno = max_reg_num ();
! }
/* First collect all the register refs and put them into
chains per insn, and per regno. In later passes only update
*************** reg_alloc ()
*** 884,894 ****
df_analyse (df, (ra_pass == 1) ? 0 : (bitmap) -1,
DF_HARD_REGS | DF_RD_CHAIN | DF_RU_CHAIN);
! /* FIXME denisc@overta.ru
! Example of usage ra_info ... routines */
! #if 0
! df2ra = build_df2ra (df, ra_info);
! #endif
if ((debug_new_regalloc & DUMP_DF) != 0)
{
rtx insn;
--- 886,894 ----
df_analyse (df, (ra_pass == 1) ? 0 : (bitmap) -1,
DF_HARD_REGS | DF_RD_CHAIN | DF_RU_CHAIN);
! if (flag_ra_pre_reload)
! df2ra = build_df2ra (df, ra_info);
!
if ((debug_new_regalloc & DUMP_DF) != 0)
{
rtx insn;
*************** reg_alloc ()
*** 914,927 ****
if (rtl_dump_file)
print_rtl_with_bb (rtl_dump_file, get_insns ());
verify_flow_info ();*/
! /* FIXME denisc@overta.ru
! Example of usage ra_info ... routines */
! #if 0
! ra_info_free (ra_info);
! free (df2ra.def2def);
! free (df2ra.use2use);
! free (ra_info);
! #endif
/* If that produced no changes, the graph was colorizable. */
if (!changed)
--- 914,925 ----
if (rtl_dump_file)
print_rtl_with_bb (rtl_dump_file, get_insns ());
verify_flow_info ();*/
!
! if (flag_ra_pre_reload)
! {
! free (df2ra.def2def);
! free (df2ra.use2use);
! }
/* If that produced no changes, the graph was colorizable. */
if (!changed)
*************** reg_alloc ()
*** 956,962 ****
reg_scan_update (get_insns (), NULL, max_regno);
max_regno = max_reg_num ();
/* And they need usefull classes too. */
! regclass (get_insns (), max_reg_num (), rtl_dump_file);
rtl_dump_file = ra_dump_file;
/* Remember the number of defs and uses, so we can distinguish
--- 954,961 ----
reg_scan_update (get_insns (), NULL, max_regno);
max_regno = max_reg_num ();
/* And they need usefull classes too. */
! if (!flag_ra_pre_reload)
! regclass (get_insns (), max_reg_num (), rtl_dump_file);
rtl_dump_file = ra_dump_file;
/* Remember the number of defs and uses, so we can distinguish
*************** reg_alloc ()
*** 979,984 ****
--- 978,989 ----
}
while (changed);
+ if (ra_modified_insns)
+ BITMAP_XFREE (ra_modified_insns);
+
+ if (flag_ra_pre_reload)
+ ra_info_free (ra_info);
+
/* We are done with allocation, free all memory and output some
debug info. */
free_all_mem (df);
*************** reg_alloc ()
*** 1062,1073 ****
allocate_initial_values (reg_equiv_memory_loc);
/* And one last regclass pass just before reload. */
regclass (get_insns (), max_reg_num (), rtl_dump_file);
}
! static enum reg_class *reg_class_of_web;
!
! static enum reg_class
web_preferred_class (web)
struct web *web;
{
--- 1067,1081 ----
allocate_initial_values (reg_equiv_memory_loc);
/* And one last regclass pass just before reload. */
regclass (get_insns (), max_reg_num (), rtl_dump_file);
+ if (flag_ra_pre_reload)
+ if (reg_class_of_web)
+ free (reg_class_of_web);
+ BITMAP_XFREE (emitted_by_spill);
+ BITMAP_XFREE (spill_slot_regs);
}
! enum reg_class
web_preferred_class (web)
struct web *web;
{
*************** web_preferred_class (web)
*** 1080,1085 ****
--- 1088,1094 ----
return reg_class_of_web[find_web_for_subweb(web)->id];
}
+
void
web_class ()
{
*************** web_class ()
*** 1089,1101 ****
ra_ref *rref;
struct ref* dref;
enum reg_class best;
if (reg_class_of_web)
free (reg_class_of_web);
reg_class_of_web = xmalloc (sizeof (enum reg_class) * (num_webs
- num_subwebs));
! for (n = 0; n < num_webs - num_subwebs; ++n)
{
struct web *web = id2web[n];
int founded = 0;
--- 1098,1112 ----
ra_ref *rref;
struct ref* dref;
enum reg_class best;
+ int debug = 0;
+ static const char *const reg_class_names[] = REG_CLASS_NAMES;
if (reg_class_of_web)
free (reg_class_of_web);
reg_class_of_web = xmalloc (sizeof (enum reg_class) * (num_webs
- num_subwebs));
! for (n = 0; n < (num_webs - num_subwebs); ++n)
{
struct web *web = id2web[n];
int founded = 0;
*************** web_class ()
*** 1123,1130 ****
if (rref)
++class[rref->class];
}
!
! /* fprintf (stderr, "Web: %d ", web->id); */
best = ALL_REGS;
for (i = 0; i < LIM_REG_CLASSES; ++i)
if (class[i])
--- 1134,1141 ----
if (rref)
++class[rref->class];
}
! if (debug)
! fprintf (stderr, "Web: %d ", web->id);
best = ALL_REGS;
for (i = 0; i < LIM_REG_CLASSES; ++i)
if (class[i])
*************** web_class ()
*** 1136,1153 ****
}
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;
}
}
-
/*
vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
*/
--- 1147,1166 ----
}
else if (!reg_class_subset_p (best, i))
best = NO_REGS;
! if (debug)
! fprintf (stderr, "%s: %d ", reg_class_names[i], class[i]);
}
! if (debug)
! fprintf (stderr, " BEST: %s\n", reg_class_names[best]);
if (best == NO_REGS)
{
! if (debug)
! fprintf (stderr, "Web: %d (%d) NO_REGS\n", web->id, web->regno);
best = GENERAL_REGS;
}
reg_class_of_web[n] = best;
}
}
/*
vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
*/
Index: ra-colorize.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ra-colorize.c,v
retrieving revision 1.1.2.3
diff -c -3 -p -r1.1.2.3 ra-colorize.c
*** ra-colorize.c 16 Jul 2002 19:52:44 -0000 1.1.2.3
--- ra-colorize.c 1 Aug 2002 20:15:37 -0000
*************** build_worklists (df)
*** 349,355 ****
max_num = num_webs - num_subwebs;
order2web = (struct web **) xmalloc (max_num * sizeof (order2web[0]));
for (i = 0, num = 0; i < max_num; i++)
! if (id2web[i]->regno >= max_normal_pseudo)
order2web[num++] = id2web[i];
if (num)
{
--- 349,355 ----
max_num = num_webs - num_subwebs;
order2web = (struct web **) xmalloc (max_num * sizeof (order2web[0]));
for (i = 0, num = 0; i < max_num; i++)
! if (SPILL_SLOT_P (id2web[i]->regno))
order2web[num++] = id2web[i];
if (num)
{
*************** combine (u, v)
*** 725,731 ****
struct conflict_link *wl;
if (u == v || v->type == COALESCED)
abort ();
! if ((u->regno >= max_normal_pseudo) != (v->regno >= max_normal_pseudo))
abort ();
remove_web_from_list (v);
put_web (v, COALESCED);
--- 725,731 ----
struct conflict_link *wl;
if (u == v || v->type == COALESCED)
abort ();
! if (SPILL_SLOT_P (u->regno) != SPILL_SLOT_P (v->regno))
abort ();
remove_web_from_list (v);
put_web (v, COALESCED);
*************** colorize_one_web (web, hard)
*** 1287,1293 ****
HARD_REG_SET fat_colors;
HARD_REG_SET bias;
! if (web->regno >= max_normal_pseudo)
hard = 0;
/* First we want to know the colors at which we can't begin. */
--- 1287,1293 ----
HARD_REG_SET fat_colors;
HARD_REG_SET bias;
! if (SPILL_SLOT_P (web->regno))
hard = 0;
/* First we want to know the colors at which we can't begin. */
*************** colorize_one_web (web, hard)
*** 1352,1366 ****
alternate non-cc hardregs, and only _then_ also in preferred cc
hardregs (and alternate ones). Currently we don't track the number
of calls crossed for webs. We should. */
! if (web->use_my_regs)
{
! COPY_HARD_REG_SET (colors, web->usable_regs);
! AND_HARD_REG_SET (colors,
! usable_regs[reg_preferred_class (web->regno)]);
}
- else
- COPY_HARD_REG_SET (colors,
- usable_regs[reg_preferred_class (web->regno)]);
#ifdef CLASS_CANNOT_CHANGE_MODE
if (web->mode_changed)
AND_COMPL_HARD_REG_SET (colors, reg_class_contents[
--- 1352,1371 ----
alternate non-cc hardregs, and only _then_ also in preferred cc
hardregs (and alternate ones). Currently we don't track the number
of calls crossed for webs. We should. */
! if (flag_ra_pre_reload)
! COPY_HARD_REG_SET (colors, web->usable_regs);
! else
{
! if (web->use_my_regs)
! {
! COPY_HARD_REG_SET (colors, web->usable_regs);
! AND_HARD_REG_SET (colors,
! usable_regs[reg_preferred_class (web->regno)]);
! }
! else
! COPY_HARD_REG_SET (colors,
! usable_regs[reg_preferred_class (web->regno)]);
}
#ifdef CLASS_CANNOT_CHANGE_MODE
if (web->mode_changed)
AND_COMPL_HARD_REG_SET (colors, reg_class_contents[
*************** colorize_one_web (web, hard)
*** 1388,1394 ****
c = get_biased_reg (dont_begin, bias, web->prefer_colors,
colors, PSEUDO_REGNO_MODE (web->regno));
! if (/*!web->use_my_regs &&*/ c < 0)
{
if (web->use_my_regs)
IOR_HARD_REG_SET (colors, web->usable_regs);
--- 1393,1399 ----
c = get_biased_reg (dont_begin, bias, web->prefer_colors,
colors, PSEUDO_REGNO_MODE (web->regno));
! if (/*!web->use_my_regs &&*/ c < 0 && !flag_ra_pre_reload)
{
if (web->use_my_regs)
IOR_HARD_REG_SET (colors, web->usable_regs);
*************** colorize_one_web (web, hard)
*** 1633,1639 ****
}
}
}
! if (web->regno >= max_normal_pseudo && web->type == SPILLED)
{
web->color = an_unusable_color;
remove_list (web->dlink, &WEBS(SPILLED));
--- 1638,1644 ----
}
}
}
! if (SPILL_SLOT_P (web->regno) && web->type == SPILLED)
{
web->color = an_unusable_color;
remove_list (web->dlink, &WEBS(SPILLED));
*************** check_colors ()
*** 2008,2014 ****
struct web *aweb = alias (web);
struct conflict_link *wl;
int nregs, c;
! if (aweb->type == SPILLED || web->regno >= max_normal_pseudo)
continue;
else if (aweb->type == COLORED)
nregs = HARD_REGNO_NREGS (aweb->color, GET_MODE (web->orig_x));
--- 2013,2019 ----
struct web *aweb = alias (web);
struct conflict_link *wl;
int nregs, c;
! if (aweb->type == SPILLED || SPILL_SLOT_P (web->regno))
continue;
else if (aweb->type == COLORED)
nregs = HARD_REGNO_NREGS (aweb->color, GET_MODE (web->orig_x));
*************** check_colors ()
*** 2028,2034 ****
wl = (web->have_orig_conflicts ? web->orig_conflict_list
: web->conflict_list);
for (; wl; wl = wl->next)
! if (wl->t->regno >= max_normal_pseudo)
continue;
else if (!wl->sub)
{
--- 2033,2039 ----
wl = (web->have_orig_conflicts ? web->orig_conflict_list
: web->conflict_list);
for (; wl; wl = wl->next)
! if (SPILL_SLOT_P (wl->t->regno))
continue;
else if (!wl->sub)
{
*************** extended_coalesce_2 ()
*** 2728,2734 ****
{
struct web *dest = def2web[DF_REF_ID (info.defs[n])];
dest = alias (find_web_for_subweb (dest));
! if (dest->type != PRECOLORED && dest->regno < max_normal_pseudo)
{
unsigned int n2;
for (n2 = 0; n2 < info.num_uses; n2++)
--- 2733,2739 ----
{
struct web *dest = def2web[DF_REF_ID (info.defs[n])];
dest = alias (find_web_for_subweb (dest));
! if (dest->type != PRECOLORED && !SPILL_SLOT_P (dest->regno))
{
unsigned int n2;
for (n2 = 0; n2 < info.num_uses; n2++)
*************** extended_coalesce_2 ()
*** 2737,2743 ****
source = alias (find_web_for_subweb (source));
if (source->type != PRECOLORED
&& source != dest
! && source->regno < max_normal_pseudo
/* Coalesced webs end up using the same REG rtx in
emit_colors(). So we can only coalesce something
of equal modes. */
--- 2742,2748 ----
source = alias (find_web_for_subweb (source));
if (source->type != PRECOLORED
&& source != dest
! && !SPILL_SLOT_P (source->regno)
/* Coalesced webs end up using the same REG rtx in
emit_colors(). So we can only coalesce something
of equal modes. */
cvs server: I know nothing about ra.c-orig
Index: ra-debug.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ra-debug.c,v
retrieving revision 1.1.2.3
diff -c -3 -p -r1.1.2.3 ra-debug.c
*** ra-debug.c 16 Jul 2002 19:52:44 -0000 1.1.2.3
--- ra-debug.c 1 Aug 2002 20:17:03 -0000
*************** dump_igraph (df)
*** 730,736 ****
ra_debug_msg (DUMP_WEBS, " dead");
if (web->crosses_call)
ra_debug_msg (DUMP_WEBS, " xcall");
! if (web->regno >= max_normal_pseudo)
ra_debug_msg (DUMP_WEBS, " stack");
ra_debug_msg (DUMP_WEBS, "\n");
}
--- 730,736 ----
ra_debug_msg (DUMP_WEBS, " dead");
if (web->crosses_call)
ra_debug_msg (DUMP_WEBS, " xcall");
! if (SPILL_SLOT_P (web->regno))
ra_debug_msg (DUMP_WEBS, " stack");
ra_debug_msg (DUMP_WEBS, "\n");
}
*************** web_conflicts_p (web1, web2)
*** 1020,1059 ****
/* Dump all uids of insns in which WEB is mentioned. */
void
! dump_web_insns (web)
struct web *web;
{
unsigned int i;
! ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n",
! web->id, web->regno, web->add_hardregs,
! reg_class_names[web->regclass],
! web->num_freedom, web->num_conflicts);
! ra_debug_msg (DUMP_EVER, " def insns:");
for (i = 0; i < web->num_defs; ++i)
{
! ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->defs[i]->insn));
}
! ra_debug_msg (DUMP_EVER, "\n use insns:");
for (i = 0; i < web->num_uses; ++i)
{
! ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->uses[i]->insn));
}
! ra_debug_msg (DUMP_EVER, "\n");
}
/* Dump conflicts for web WEB. */
void
! dump_web_conflicts (web)
struct web *web;
{
int num = 0;
unsigned int def2;
! ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n",
web->id, web->regno, web->add_hardregs,
reg_class_names[web->regclass],
web->num_freedom, web->num_conflicts);
--- 1020,1059 ----
/* Dump all uids of insns in which WEB is mentioned. */
void
! debug_web_insns (web)
struct web *web;
{
unsigned int i;
! fprintf (stderr, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n",
! web->id, web->regno, web->add_hardregs,
! reg_class_names[web->regclass],
! web->num_freedom, web->num_conflicts);
! fprintf (stderr, " def insns:");
for (i = 0; i < web->num_defs; ++i)
{
! fprintf (stderr, " %d ", INSN_UID (web->defs[i]->insn));
}
! fprintf (stderr, "\n use insns:");
for (i = 0; i < web->num_uses; ++i)
{
! fprintf (stderr, " %d ", INSN_UID (web->uses[i]->insn));
}
! fprintf (stderr, "\n");
}
/* Dump conflicts for web WEB. */
void
! debug_web_conflicts (web)
struct web *web;
{
int num = 0;
unsigned int def2;
! fprintf (stderr, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n",
web->id, web->regno, web->add_hardregs,
reg_class_names[web->regclass],
web->num_freedom, web->num_conflicts);
*************** dump_web_conflicts (web)
*** 1062,1098 ****
if (TEST_BIT (igraph, igraph_index (web->id, def2)) && web->id != def2)
{
if ((num % 9) == 5)
! ra_debug_msg (DUMP_EVER, "\n ");
num++;
! ra_debug_msg (DUMP_EVER, " %d(%d)", def2, id2web[def2]->regno);
if (id2web[def2]->add_hardregs)
! ra_debug_msg (DUMP_EVER, "+%d", id2web[def2]->add_hardregs);
if (web_conflicts_p (web, id2web[def2]))
! ra_debug_msg (DUMP_EVER, "/x");
if (id2web[def2]->type == SELECT)
! ra_debug_msg (DUMP_EVER, "/s");
if (id2web[def2]->type == COALESCED)
! ra_debug_msg (DUMP_EVER,"/c/%d", alias (id2web[def2])->id);
}
! ra_debug_msg (DUMP_EVER, "\n");
{
struct conflict_link *wl;
num = 0;
! ra_debug_msg (DUMP_EVER, "By conflicts: ");
for (wl = web->conflict_list; wl; wl = wl->next)
{
struct web* w = wl->t;
if ((num % 9) == 8)
! ra_debug_msg (DUMP_EVER, "\n ");
num++;
! ra_debug_msg (DUMP_EVER, "%d(%d)%s ", w->id, w->regno,
web_conflicts_p (web, w) ? "+" : "");
}
! ra_debug_msg (DUMP_EVER, "\n");
}
}
--- 1062,1098 ----
if (TEST_BIT (igraph, igraph_index (web->id, def2)) && web->id != def2)
{
if ((num % 9) == 5)
! fprintf (stderr, "\n ");
num++;
! fprintf (stderr, " %d(%d)", def2, id2web[def2]->regno);
if (id2web[def2]->add_hardregs)
! fprintf (stderr, "+%d", id2web[def2]->add_hardregs);
if (web_conflicts_p (web, id2web[def2]))
! fprintf (stderr, "/x");
if (id2web[def2]->type == SELECT)
! fprintf (stderr, "/s");
if (id2web[def2]->type == COALESCED)
! fprintf (stderr,"/c/%d", alias (id2web[def2])->id);
}
! fprintf (stderr, "\n");
{
struct conflict_link *wl;
num = 0;
! fprintf (stderr, "By conflicts: ");
for (wl = web->conflict_list; wl; wl = wl->next)
{
struct web* w = wl->t;
if ((num % 9) == 8)
! fprintf (stderr, "\n ");
num++;
! fprintf (stderr, "%d(%d)%s ", w->id, w->regno,
web_conflicts_p (web, w) ? "+" : "");
}
! fprintf (stderr, "\n");
}
}
Index: ra.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ra.h,v
retrieving revision 1.1.2.3
diff -c -3 -p -r1.1.2.3 ra.h
*** ra.h 16 Jul 2002 19:52:45 -0000 1.1.2.3
--- ra.h 1 Aug 2002 20:17:12 -0000
*************** extern bitmap *live_at_end;
*** 434,445 ****
And this is how often we already ran that for the current function. */
extern int ra_pass;
- /* The maximum pseudo regno, just before register allocation starts.
- While regalloc runs all pseudos with a larger number represent
- potentially stack slots or hardregs. I call them stackwebs or
- stackpseudos. */
- extern unsigned int max_normal_pseudo;
-
/* One of the fixed colors. It must be < FIRST_PSEUDO_REGISTER, because
we sometimes want to check the color against a HARD_REG_SET. It must
be >= 0, because negative values mean "no color".
--- 434,439 ----
*************** extern sbitmap last_check_uses;
*** 479,487 ****
I-graph. I.e. new conflicts due to coalescing trigger that copying. */
extern unsigned int remember_conflicts;
! /* The maximum UID right before calling regalloc().
! Used to detect any instructions inserted by the allocator. */
! extern int orig_max_uid;
/* A HARD_REG_SET of those color, which can't be used for coalescing.
Includes e.g. fixed_regs. */
--- 473,486 ----
I-graph. I.e. new conflicts due to coalescing trigger that copying. */
extern unsigned int remember_conflicts;
! /* Used to detect spill instructions inserted by me. */
! extern bitmap emitted_by_spill;
!
! /* Insns which must be rescanned by pre_reload. */
! extern bitmap ra_modified_insns;
!
! /* This pseudos represents stack slots allocated by ra-rewrite. */
! extern bitmap spill_slot_regs;
/* A HARD_REG_SET of those color, which can't be used for coalescing.
Includes e.g. fixed_regs. */
*************** extern int flag_ra_spill_every_use;
*** 562,567 ****
--- 561,573 ----
/* Nonzero to output all notes in the debug dumps. */
extern int flag_ra_dump_notes;
+ /* If nonzero, use pre-reload and web-class in new register allocator. */
+ extern int flag_ra_pre_reload;
+
+ /* If nonzero, use separate passs for calculation web deaths in new
+ register allocator. */
+ extern int flag_ra_spanned_deaths_from_scratch;
+
extern inline void * ra_alloc PARAMS ((size_t));
extern inline void * ra_calloc PARAMS ((size_t));
extern int hard_regs_count PARAMS ((HARD_REG_SET));
*************** extern void emit_colors PARAMS ((struct
*** 622,624 ****
--- 628,637 ----
extern void delete_moves PARAMS ((void));
extern void setup_renumber PARAMS ((int));
extern void remove_suspicious_death_notes PARAMS ((void));
+ extern int is_partly_dead PARAMS ((sbitmap, struct web *));
+ extern void set_web_live PARAMS ((sbitmap, struct web *));
+ extern void reset_web_live PARAMS ((sbitmap, struct web *));
+ extern enum reg_class web_preferred_class PARAMS ((struct web *));
+ extern void web_class PARAMS ((void));
+
+ #define SPILL_SLOT_P(REGNO) bitmap_bit_p (spill_slot_regs, (REGNO))
Index: ra-rewrite.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ra-rewrite.c,v
retrieving revision 1.1.2.3
diff -c -3 -p -r1.1.2.3 ra-rewrite.c
*** ra-rewrite.c 16 Jul 2002 19:52:44 -0000 1.1.2.3
--- ra-rewrite.c 1 Aug 2002 20:17:37 -0000
*************** spill_coalescing (coalesce, spilled)
*** 106,111 ****
--- 106,112 ----
PUT_CODE (m->insn, NOTE);
NOTE_LINE_NUMBER (m->insn) = NOTE_INSN_DELETED;
df_insn_modify (df, BLOCK_FOR_INSN (m->insn), m->insn);
+ bitmap_set_bit (ra_modified_insns, INSN_UID (m->insn));
m->target_web->target_of_spilled_move = 1;
if (s == t)
*************** allocate_spill_web (web)
*** 326,331 ****
--- 327,333 ----
set_mem_alias_set (slot, new_alias_set ());*/
slot = gen_reg_rtx (PSEUDO_REGNO_MODE (regno));
web->stack_slot = slot;
+ bitmap_set_bit (spill_slot_regs, REGNO (slot));
}
/* This chooses a color for all SPILLED webs for interference region
*************** rewrite_program (new_deaths)
*** 467,472 ****
--- 469,476 ----
{
set_block_for_insn (insn, bb);
df_insn_modify (df, bb, insn);
+ bitmap_set_bit (ra_modified_insns, INSN_UID (insn));
+ bitmap_set_bit (emitted_by_spill, INSN_UID (insn));
}
emitted_spill_loads++;
*************** rewrite_program (new_deaths)
*** 530,543 ****
emit_insn_after (insns, insn);
if (bb->end == insn)
bb->end = PREV_INSN (following);
! for (insn = insns; insn != following; insn = NEXT_INSN (insn))
{
set_block_for_insn (insn, bb);
df_insn_modify (df, bb, insn);
}
}
else
! df_insn_modify (df, bb, insn);
emitted_spill_stores++;
spill_store_cost += bb->frequency + 1;
/* XXX we should set new_deaths for all inserted stores
--- 534,553 ----
emit_insn_after (insns, insn);
if (bb->end == insn)
bb->end = PREV_INSN (following);
! for (insn = insns; insn != following;
! insn = NEXT_INSN (insn))
{
set_block_for_insn (insn, bb);
df_insn_modify (df, bb, insn);
+ bitmap_set_bit (ra_modified_insns, INSN_UID (insn));
+ bitmap_set_bit (emitted_by_spill, INSN_UID (insn));
}
}
else
! {
! df_insn_modify (df, bb, insn);
! bitmap_set_bit (ra_modified_insns, INSN_UID (insn));
! }
emitted_spill_stores++;
spill_store_cost += bb->frequency + 1;
/* XXX we should set new_deaths for all inserted stores
*************** insert_stores (new_deaths)
*** 733,745 ****
{
set_block_for_insn (ni, bb);
df_insn_modify (df, bb, ni);
}
}
else
! df_insn_modify (df, bb, insn);
emitted_spill_stores++;
spill_store_cost += bb->frequency + 1;
! bitmap_set_bit (new_deaths, INSN_UID (PREV_INSN (following)));
}
else
{
--- 743,761 ----
{
set_block_for_insn (ni, bb);
df_insn_modify (df, bb, ni);
+ bitmap_set_bit (ra_modified_insns, INSN_UID (ni));
+ bitmap_set_bit (emitted_by_spill, INSN_UID (ni));
}
}
else
! {
! df_insn_modify (df, bb, insn);
! bitmap_set_bit (ra_modified_insns, INSN_UID (insn));
! }
emitted_spill_stores++;
spill_store_cost += bb->frequency + 1;
! bitmap_set_bit (new_deaths,
! INSN_UID (PREV_INSN (following)));
}
else
{
*************** is_partly_live_1 (live, web)
*** 809,817 ****
}
/* Fast version in case WEB has no subwebs. */
! #define is_partly_live(live, web) ((!web->subreg_next) \
! ? TEST_BIT (live, web->id) \
! : is_partly_live_1 (live, web))
/* Change the set of currently IN_USE colors according to
WEB's color. Either add those colors to the hardreg set (if ADD
--- 825,833 ----
}
/* Fast version in case WEB has no subwebs. */
! #define is_partly_live(live, web) ((!web->subreg_next || web->parent_web) \
! ? TEST_BIT (live, web->id) \
! : is_partly_live_1 (live, web)) \
/* Change the set of currently IN_USE colors according to
WEB's color. Either add those colors to the hardreg set (if ADD
*************** emit_loads (ri, nl_first_reload, last_bl
*** 918,923 ****
--- 934,940 ----
struct web *supweb;
struct web *aweb;
rtx ni, slot, reg;
+ enum machine_mode innermode;
rtx before = NULL_RTX, after = NULL_RTX;
basic_block bb;
/* When spilltemps were spilled for the last insns, their
*************** emit_loads (ri, nl_first_reload, last_bl
*** 926,932 ****
if (!web)
continue;
supweb = find_web_for_subweb (web);
! if (supweb->regno >= max_normal_pseudo)
abort ();
/* Check for web being a spilltemp, if we only want to
load spilltemps. Also remember, that we emitted that
--- 943,949 ----
if (!web)
continue;
supweb = find_web_for_subweb (web);
! if (SPILL_SLOT_P (supweb->regno))
abort ();
/* Check for web being a spilltemp, if we only want to
load spilltemps. Also remember, that we emitted that
*************** emit_loads (ri, nl_first_reload, last_bl
*** 941,947 ****
}
web->in_load = 0;
/* The adding of reloads doesn't depend on liveness. */
! if (j < nl_first_reload && !TEST_BIT (ri->live, web->id))
continue;
aweb = alias (supweb);
aweb->changed = 1;
--- 958,964 ----
}
web->in_load = 0;
/* The adding of reloads doesn't depend on liveness. */
! if (j < nl_first_reload && !is_partly_live (ri->live, web))
continue;
aweb = alias (supweb);
aweb->changed = 1;
*************** emit_loads (ri, nl_first_reload, last_bl
*** 956,982 ****
if (aweb != supweb)
abort ();
slot = copy_rtx (supweb->pattern);
! reg = copy_rtx (supweb->orig_x);
! /* Sanity check. orig_x should be a REG rtx, which should be
! shared over all RTL, so copy_rtx should have no effect. */
! if (reg != supweb->orig_x)
! abort ();
}
else
{
allocate_spill_web (aweb);
slot = aweb->stack_slot;
!
! /* If we don't copy the RTL there might be some SUBREG
! rtx shared in the next iteration although being in
! different webs, which leads to wrong code. */
! reg = copy_rtx (web->orig_x);
! if (GET_CODE (reg) == SUBREG)
! /*slot = adjust_address (slot, GET_MODE (reg), SUBREG_BYTE
! (reg));*/
! slot = simplify_gen_subreg (GET_MODE (reg), slot, GET_MODE (slot),
! SUBREG_BYTE (reg));
}
ra_emit_move_insn (reg, slot);
ni = get_insns ();
end_sequence ();
--- 973,993 ----
if (aweb != supweb)
abort ();
slot = copy_rtx (supweb->pattern);
! innermode = GET_MODE (supweb->orig_x);
}
else
{
allocate_spill_web (aweb);
slot = aweb->stack_slot;
! innermode = GET_MODE (slot);
}
+ /* If we don't copy the RTL there might be some SUBREG
+ rtx shared in the next iteration although being in
+ different webs, which leads to wrong code. */
+ reg = copy_rtx (web->orig_x);
+ if (GET_CODE (reg) == SUBREG)
+ slot = simplify_gen_subreg (GET_MODE (reg), slot, innermode,
+ SUBREG_BYTE (reg));
ra_emit_move_insn (reg, slot);
ni = get_insns ();
end_sequence ();
*************** emit_loads (ri, nl_first_reload, last_bl
*** 1000,1005 ****
--- 1011,1018 ----
{
set_block_for_insn (ni, bb);
df_insn_modify (df, bb, ni);
+ bitmap_set_bit (ra_modified_insns, INSN_UID (ni));
+ bitmap_set_bit (emitted_by_spill, INSN_UID (ni));
}
}
else
*************** emit_loads (ri, nl_first_reload, last_bl
*** 1013,1018 ****
--- 1026,1033 ----
{
set_block_for_insn (ni, bb);
df_insn_modify (df, bb, ni);
+ bitmap_set_bit (ra_modified_insns, INSN_UID (ni));
+ bitmap_set_bit (emitted_by_spill, INSN_UID (ni));
}
}
if (supweb->pattern)
*************** emit_loads (ri, nl_first_reload, last_bl
*** 1025,1031 ****
emitted_spill_loads++;
spill_load_cost += bb->frequency + 1;
}
! RESET_BIT (ri->live, web->id);
/* In the special case documented above only emit the reloads and
one load. */
if (ri->need_load == 2 && j < nl_first_reload)
--- 1040,1046 ----
emitted_spill_loads++;
spill_load_cost += bb->frequency + 1;
}
! reset_web_live (ri->live, web);
/* In the special case documented above only emit the reloads and
one load. */
if (ri->need_load == 2 && j < nl_first_reload)
*************** detect_bbs_for_rewrite (changed_bbs)
*** 1053,1058 ****
--- 1068,1121 ----
}
}
+ /* Test LIVE for partial WEB live. */
+ int
+ is_partly_dead (live, web)
+ sbitmap live;
+ struct web *web;
+ {
+ struct web *sweb;
+
+ if (web->subreg_next && !web->parent_web)
+ {
+ for (sweb = web->subreg_next; sweb; sweb = sweb->subreg_next)
+ if (!TEST_BIT (live, sweb->id))
+ return 1;
+ return 0;
+ }
+ return !TEST_BIT (live, web->id);
+ }
+
+ /* Set live bit in LIVE for WEB or all his subwebs. */
+ void
+ set_web_live (live, web)
+ sbitmap live;
+ struct web *web;
+ {
+ struct web *sweb;
+
+ if (web->subreg_next && !web->parent_web)
+ for (sweb = web->subreg_next; sweb; sweb = sweb->subreg_next)
+ SET_BIT (live, sweb->id);
+ else
+ SET_BIT (live, web->id);
+ }
+
+ /* Reset live bit in LIVE for WEB or all his subwebs. */
+ void
+ reset_web_live (live, web)
+ sbitmap live;
+ struct web *web;
+ {
+ struct web *sweb;
+
+ if (web->subreg_next && !web->parent_web)
+ for (sweb = web->subreg_next; sweb; sweb = sweb->subreg_next)
+ RESET_BIT (live, sweb->id);
+ else
+ RESET_BIT (live, web->id);
+ }
+
/* Fast version of rewrite_program2() for one basic block, where
no spill code is necessary. We detect here only insns with deaths. */
static void
*************** detect_deaths_in_bb (bb, live, new_death
*** 1094,1111 ****
info = insn_df[INSN_UID (insn)];
for (n = 0; n < info.num_defs; n++)
{
struct ref *ref = info.defs[n];
struct web *web = def2web[DF_REF_ID (ref)];
! rtx reg = DF_REF_REG (ref);
int is_non_def = 0;
- unsigned int n2;
- web = find_web_for_subweb (web);
/* Detect rmw webs. */
for (n2 = 0; n2 < info.num_uses; n2++)
{
struct web *web2 = use2web[DF_REF_ID (info.uses[n2])];
! if (web == find_web_for_subweb (web2))
{
is_non_def = 1;
break;
--- 1157,1173 ----
info = insn_df[INSN_UID (insn)];
for (n = 0; n < info.num_defs; n++)
{
+ unsigned int n2;
struct ref *ref = info.defs[n];
struct web *web = def2web[DF_REF_ID (ref)];
! struct web *supweb = find_web_for_subweb (web);
int is_non_def = 0;
/* Detect rmw webs. */
for (n2 = 0; n2 < info.num_uses; n2++)
{
struct web *web2 = use2web[DF_REF_ID (info.uses[n2])];
! if (supweb == find_web_for_subweb (web2))
{
is_non_def = 1;
break;
*************** detect_deaths_in_bb (bb, live, new_death
*** 1114,1145 ****
if (is_non_def)
continue;
! if (!is_partly_live (live, web))
bitmap_set_bit (useless_defs, DF_REF_ID (ref));
! if (GET_CODE (reg) == SUBREG)
! {
! struct web *sweb;
! sweb = find_subweb (web, reg);
! RESET_BIT (live, sweb->id);
! }
! else
! {
! struct web *sweb;
! RESET_BIT (live, web->id);
! for (sweb = web->subreg_next; sweb;
! sweb = sweb->subreg_next)
! RESET_BIT (live, sweb->id);
! }
}
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 = !TEST_BIT (live, supweb->id);
! is_death &= !TEST_BIT (live, web->id);
! if (is_death)
{
bitmap_set_bit (new_deaths, INSN_UID (insn));
break;
--- 1176,1191 ----
if (is_non_def)
continue;
! if (!is_partly_live (live, supweb))
bitmap_set_bit (useless_defs, DF_REF_ID (ref));
! reset_web_live (live, web);
}
for (n = 0; n < info.num_uses; n++)
{
struct web *web = use2web[DF_REF_ID (info.uses[n])];
! if (is_partly_dead (live, web))
{
bitmap_set_bit (new_deaths, INSN_UID (insn));
break;
*************** detect_deaths_in_bb (bb, live, new_death
*** 1149,1155 ****
for (n = 0; n < info.num_uses; n++)
{
struct web *web = use2web[DF_REF_ID (info.uses[n])];
! SET_BIT (live, web->id);
}
}
}
--- 1195,1201 ----
for (n = 0; n < info.num_uses; n++)
{
struct web *web = use2web[DF_REF_ID (info.uses[n])];
! set_web_live (live, web);
}
}
}
*************** reloads_to_loads (ri, refs, num_refs, re
*** 1174,1180 ****
{
struct web *web = ref2web[DF_REF_ID (refs[n])];
struct web *supweb = find_web_for_subweb (web);
- int is_death;
int j;
/* Only emit reloads when entering their interference
region. A use of a spilled web never opens an
--- 1220,1225 ----
*************** reloads_to_loads (ri, refs, num_refs, re
*** 1185,1195 ****
&& TEST_HARD_REG_BIT (never_use_colors, supweb->color))
continue;
/* Note, that if web (and supweb) are DEFs, we already cleared
! the corresponding bits in live. I.e. is_death becomes true, which
! is what we want. */
! is_death = !TEST_BIT (ri->live, supweb->id);
! is_death &= !TEST_BIT (ri->live, web->id);
! if (is_death)
{
int old_num_r = num_reloads;
bitmap_clear (ri->scratch);
--- 1230,1238 ----
&& TEST_HARD_REG_BIT (never_use_colors, supweb->color))
continue;
/* Note, that if web (and supweb) are DEFs, we already cleared
! the corresponding bits in live. I.e. is_partly_dead becomes true,
! which is what we want. */
! if (is_partly_dead (ri->live, web))
{
int old_num_r = num_reloads;
bitmap_clear (ri->scratch);
*************** rewrite_program2 (new_deaths)
*** 1294,1300 ****
Remember to not add to colors_in_use in that case. */
if (aweb->type != SPILLED /*|| aweb->color >= 0*/)
{
! SET_BIT (ri.live, web->id);
if (aweb->type != SPILLED)
update_spill_colors (&(ri.colors_in_use), web, 1);
}
--- 1337,1343 ----
Remember to not add to colors_in_use in that case. */
if (aweb->type != SPILLED /*|| aweb->color >= 0*/)
{
! set_web_live (ri.live, web);
if (aweb->type != SPILLED)
update_spill_colors (&(ri.colors_in_use), web, 1);
}
*************** rewrite_program2 (new_deaths)
*** 1343,1349 ****
struct web *aweb = alias (find_web_for_subweb (web));
if (aweb->type != SPILLED)
{
! SET_BIT (ri.live, web->id);
update_spill_colors (&(ri.colors_in_use), web, 1);
}
});
--- 1386,1392 ----
struct web *aweb = alias (find_web_for_subweb (web));
if (aweb->type != SPILLED)
{
! set_web_live (ri.live, web);
update_spill_colors (&(ri.colors_in_use), web, 1);
}
});
*************** rewrite_program2 (new_deaths)
*** 1407,1413 ****
if (!is_partly_live (ri.live, supweb))
bitmap_set_bit (useless_defs, DF_REF_ID (ref));
! RESET_BIT (ri.live, web->id);
if (bitmap_bit_p (ri.need_reload, web->id))
{
ri.num_reloads--;
--- 1450,1456 ----
if (!is_partly_live (ri.live, supweb))
bitmap_set_bit (useless_defs, DF_REF_ID (ref));
! reset_web_live (ri.live, web);
if (bitmap_bit_p (ri.need_reload, web->id))
{
ri.num_reloads--;
*************** rewrite_program2 (new_deaths)
*** 1436,1442 ****
for (sweb = supweb->subreg_next; sweb;
sweb = sweb->subreg_next)
{
- RESET_BIT (ri.live, sweb->id);
if (bitmap_bit_p (ri.need_reload, sweb->id))
{
ri.num_reloads--;
--- 1479,1484 ----
*************** rewrite_program2 (new_deaths)
*** 1462,1474 ****
{
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)
{
ri.need_load = 1;
bitmap_set_bit (new_deaths, INSN_UID (insn));
--- 1504,1513 ----
{
struct web *web = use2web[DF_REF_ID (info.uses[n])];
struct web *supweb = find_web_for_subweb (web);
if (supweb->type == PRECOLORED
&& TEST_HARD_REG_BIT (never_use_colors, supweb->color))
continue;
! if (is_partly_dead (ri.live, web))
{
ri.need_load = 1;
bitmap_set_bit (new_deaths, INSN_UID (insn));
*************** rewrite_program2 (new_deaths)
*** 1514,1520 ****
struct web *web = use2web[DF_REF_ID (info.uses[n])];
struct web *supweb = find_web_for_subweb (web);
struct web *aweb = alias (supweb);
! SET_BIT (ri.live, web->id);
if (aweb->type != SPILLED)
continue;
if (supweb->spill_temp)
--- 1553,1559 ----
struct web *web = use2web[DF_REF_ID (info.uses[n])];
struct web *supweb = find_web_for_subweb (web);
struct web *aweb = alias (supweb);
! set_web_live (ri.live, web);
if (aweb->type != SPILLED)
continue;
if (supweb->spill_temp)
*************** delete_useless_defs ()
*** 1783,1788 ****
--- 1822,1828 ----
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
df_insn_modify (df, BLOCK_FOR_INSN (insn), insn);
+ bitmap_set_bit (ra_modified_insns, INSN_UID (insn));
}
});
}
*************** emit_colors (df)
*** 1893,1899 ****
if (web->reg_rtx || web->regno < FIRST_PSEUDO_REGISTER)
abort ();
! if (web->regno >= max_normal_pseudo)
{
rtx place;
if (web->color == an_unusable_color)
--- 1933,1939 ----
if (web->reg_rtx || web->regno < FIRST_PSEUDO_REGISTER)
abort ();
! if (SPILL_SLOT_P (web->regno))
{
rtx place;
if (web->color == an_unusable_color)
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.418.2.15
diff -c -3 -p -r1.418.2.15 toplev.c
*** toplev.c 16 Jul 2002 19:52:43 -0000 1.418.2.15
--- toplev.c 1 Aug 2002 20:18:18 -0000
*************** int flag_renumber_insns = 1;
*** 869,874 ****
--- 869,879 ----
/* If nonzero, use the graph coloring register allocator. */
int flag_new_regalloc = 1;
+ /* If nonzero, use pre-reload and web-class in new register allocator. */
+ int flag_ra_pre_reload = 0;
+ /* If nonzero, use separate passs for calculation web deaths in new
+ register allocator. */
+ int flag_ra_spanned_deaths_from_scratch = 0;
/* Nonzero if we perform superblock formation. */
*************** static const lang_independent_options f_
*** 1180,1185 ****
--- 1185,1194 ----
N_("Trap for signed overflow in addition / subtraction / multiplication") },
{ "new-ra", &flag_new_regalloc, 1,
N_("Use graph coloring register allocation.") },
+ { "new-ra-pre-reload", &flag_ra_pre_reload, 1,
+ N_("Use pre-reload in graph coloring register allocation.") },
+ { "new-ra-spanned-deaths-pass", &flag_ra_spanned_deaths_from_scratch, 1,
+ N_("Use special pass for detect web deaths in graph coloring register allocation.") },
};
/* Table of language-specific options. */
More information about the Gcc-patches
mailing list