From: Denis Chertykov <denisc@overta.ru>
To: Michael Matz <matz@suse.de>
Cc: gcc-patches@gcc.gnu.org, denisc@overta.ru
Subject: [new-regalloc] is_death/subregs patch
Date: Mon, 29 Jul 2002 12:03:00 -0000 [thread overview]
Message-ID: <auto-000003239536@overta.ru> (raw)
2002-07-29 Denis Chertykov <denisc@overta.ru>
* ra-rewrite.c (set_web_live, reset_web_live, is_partly_dead): New
functions.
(is_partly_live): Walk only on one subweb or all subwebs of super web.
(emit_loads): Use set_web_live, reset_web_live.
(detect_deaths_in_bb): Likewise.
(reloads_to_loads): Use is_partly_dead instead of is_death ....
Use set_web_live, reset_web_live.
(rewrite_program2): Likewise.
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 29 Jul 2002 18:24:02 -0000
*************** static void detect_web_parts_to_rebuild
*** 69,74 ****
--- 69,77 ----
static void delete_useless_defs PARAMS ((void));
static void detect_non_changed_webs PARAMS ((void));
static void reset_changed_flag PARAMS ((void));
+ static void set_web_live PARAMS ((sbitmap, struct web *));
+ static void reset_web_live PARAMS ((sbitmap, struct web *));
+ static int is_partly_dead PARAMS ((sbitmap, struct web *));
/* For tracking some statistics, we count the number (and cost)
of deleted move insns. */
*************** is_partly_live_1 (live, web)
*** 809,816 ****
}
/* 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
--- 812,819 ----
}
/* 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
*************** emit_loads (ri, nl_first_reload, last_bl
*** 918,923 ****
--- 921,927 ----
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
*** 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;
--- 945,951 ----
}
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 ();
--- 960,980 ----
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
*** 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)
--- 1023,1029 ----
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 ****
--- 1051,1104 ----
}
}
+ /* Test LIVE for partial WEB live. */
+ static 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. */
+ static 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. */
+ static 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;
--- 1140,1156 ----
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;
--- 1159,1174 ----
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);
}
}
}
--- 1178,1184 ----
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
--- 1203,1208 ----
*************** 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);
--- 1213,1221 ----
&& 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);
}
--- 1320,1326 ----
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);
}
});
--- 1369,1375 ----
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--;
--- 1433,1439 ----
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--;
--- 1462,1467 ----
*************** 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));
--- 1487,1496 ----
{
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)
--- 1536,1542 ----
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)
reply other threads:[~2002-07-29 18:36 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=auto-000003239536@overta.ru \
--to=denisc@overta.ru \
--cc=gcc-patches@gcc.gnu.org \
--cc=matz@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).