Commit 285f3cf0 by J"orn Rennecke Committed by Joern Rennecke

caller-save.c (insert_one_insn): Returns struct insn_chain *.

	* caller-save.c (insert_one_insn): Returns struct insn_chain *.
	Handle live_throughout / dead_or_set instead of live_before /
	live_after.
	(save_call_clobbered_regs): Get register livenessinformation from
	chain->live_throughout.
	(add_stored_regs): New function.
	(insert_restore, insert_save): Add restored / saved registers to
	dead_or_set.
	* global.c (reg_dies): New parameter chain.
	(reg_becomes_live): Third parameter is regs_set now.
	Changed all callers.
	(reg_dies): New parameter chain.  Changed all callers.
	(build_insn_chain): Set live_throughout instead of
	live_before / live_after.
	* reload.h (struct insn_chain): Replace members live_before /
	live_after with live_throughout / dead_or_set.
	* reload1.c (new_insn_chain): Handle live_throughout / dead_or_set
	instead of live_before / live_after.
	(maybe_fix_stack_asms, find_reload_regs, finish_spills): Likewise.
	(order_regs_for_reload, find_reg, finish_spills): Likewise.
	(choose_reload_regs_init): Likewise.
	* stupid.c (current_chain, find_clobbered_regs): Delete.
	(stupid_life_analysis): Set chain->live_throughout chain->dead_or_set
	instead of chain->live_before / chain->live_after.
	(mark_hard_ref): New function.
	(stupid_mark_refs): Call mark_hard_ref. Clear chain->live_throughout.

From-SVN: r30957
parent 4940cd60
Wed Dec 15 14:55:24 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* caller-save.c (insert_one_insn): Returns struct insn_chain *.
Handle live_throughout / dead_or_set instead of live_before /
live_after.
(save_call_clobbered_regs): Get register livenessinformation from
chain->live_throughout.
(add_stored_regs): New function.
(insert_restore, insert_save): Add restored / saved registers to
dead_or_set.
* global.c (reg_dies): New parameter chain.
(reg_becomes_live): Third parameter is regs_set now.
Changed all callers.
(reg_dies): New parameter chain. Changed all callers.
(build_insn_chain): Set live_throughout instead of
live_before / live_after.
* reload.h (struct insn_chain): Replace members live_before /
live_after with live_throughout / dead_or_set.
* reload1.c (new_insn_chain): Handle live_throughout / dead_or_set
instead of live_before / live_after.
(maybe_fix_stack_asms, find_reload_regs, finish_spills): Likewise.
(order_regs_for_reload, find_reg, finish_spills): Likewise.
(choose_reload_regs_init): Likewise.
* stupid.c (current_chain, find_clobbered_regs): Delete.
(stupid_life_analysis): Set chain->live_throughout chain->dead_or_set
instead of chain->live_before / chain->live_after.
(mark_hard_ref): New function.
(stupid_mark_refs): Call mark_hard_ref. Clear chain->live_throughout.
1999-12-15 David S. Miller <davem@redhat.com> 1999-12-15 David S. Miller <davem@redhat.com>
* rtlanal.c (reg_overlap_mentioned_p): Handle CONCAT. * rtlanal.c (reg_overlap_mentioned_p): Handle CONCAT.
......
...@@ -303,7 +303,8 @@ static void mark_reg_live_nc PROTO((int, enum machine_mode)); ...@@ -303,7 +303,8 @@ static void mark_reg_live_nc PROTO((int, enum machine_mode));
static void set_preference PROTO((rtx, rtx)); static void set_preference PROTO((rtx, rtx));
static void dump_conflicts PROTO((FILE *)); static void dump_conflicts PROTO((FILE *));
static void reg_becomes_live PROTO((rtx, rtx, void *)); static void reg_becomes_live PROTO((rtx, rtx, void *));
static void reg_dies PROTO((int, enum machine_mode)); static void reg_dies PROTO((int, enum machine_mode,
struct insn_chain *));
static void build_insn_chain PROTO((rtx)); static void build_insn_chain PROTO((rtx));
/* Perform allocation of pseudo-registers not allocated by local_alloc. /* Perform allocation of pseudo-registers not allocated by local_alloc.
...@@ -1693,13 +1694,13 @@ mark_elimination (from, to) ...@@ -1693,13 +1694,13 @@ mark_elimination (from, to)
current life information. */ current life information. */
static regset live_relevant_regs; static regset live_relevant_regs;
/* Record in live_relevant_regs that register REG became live. This /* Record in live_relevant_regs and REGS_SET that register REG became live.
is called via note_stores. */ This is called via note_stores. */
static void static void
reg_becomes_live (reg, setter, data) reg_becomes_live (reg, setter, regs_set)
rtx reg; rtx reg;
rtx setter ATTRIBUTE_UNUSED; rtx setter ATTRIBUTE_UNUSED;
void *data ATTRIBUTE_UNUSED; void *regs_set;
{ {
int regno; int regno;
...@@ -1714,26 +1715,44 @@ reg_becomes_live (reg, setter, data) ...@@ -1714,26 +1715,44 @@ reg_becomes_live (reg, setter, data)
{ {
int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg)); int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));
while (nregs-- > 0) while (nregs-- > 0)
SET_REGNO_REG_SET (live_relevant_regs, regno++); {
SET_REGNO_REG_SET (live_relevant_regs, regno);
if (! fixed_regs[regno])
SET_REGNO_REG_SET ((regset) regs_set, regno);
regno++;
}
} }
else if (reg_renumber[regno] >= 0) else if (reg_renumber[regno] >= 0)
SET_REGNO_REG_SET (live_relevant_regs, regno); {
SET_REGNO_REG_SET (live_relevant_regs, regno);
SET_REGNO_REG_SET ((regset) regs_set, regno);
}
} }
/* Record in live_relevant_regs that register REGNO died. */ /* Record in live_relevant_regs that register REGNO died. */
static void static void
reg_dies (regno, mode) reg_dies (regno, mode, chain)
int regno; int regno;
enum machine_mode mode; enum machine_mode mode;
struct insn_chain *chain;
{ {
if (regno < FIRST_PSEUDO_REGISTER) if (regno < FIRST_PSEUDO_REGISTER)
{ {
int nregs = HARD_REGNO_NREGS (regno, mode); int nregs = HARD_REGNO_NREGS (regno, mode);
while (nregs-- > 0) while (nregs-- > 0)
CLEAR_REGNO_REG_SET (live_relevant_regs, regno++); {
CLEAR_REGNO_REG_SET (live_relevant_regs, regno);
if (! fixed_regs[regno])
SET_REGNO_REG_SET (chain->dead_or_set, regno);
regno++;
}
} }
else else
CLEAR_REGNO_REG_SET (live_relevant_regs, regno); {
CLEAR_REGNO_REG_SET (live_relevant_regs, regno);
if (reg_renumber[regno] >= 0)
SET_REGNO_REG_SET (chain->dead_or_set, regno);
}
} }
/* Walk the insns of the current function and build reload_insn_chain, /* Walk the insns of the current function and build reload_insn_chain,
...@@ -1778,8 +1797,6 @@ build_insn_chain (first) ...@@ -1778,8 +1797,6 @@ build_insn_chain (first)
c->insn = first; c->insn = first;
c->block = b; c->block = b;
COPY_REG_SET (c->live_before, live_relevant_regs);
if (GET_RTX_CLASS (GET_CODE (first)) == 'i') if (GET_RTX_CLASS (GET_CODE (first)) == 'i')
{ {
rtx link; rtx link;
...@@ -1789,16 +1806,18 @@ build_insn_chain (first) ...@@ -1789,16 +1806,18 @@ build_insn_chain (first)
for (link = REG_NOTES (first); link; link = XEXP (link, 1)) for (link = REG_NOTES (first); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD if (REG_NOTE_KIND (link) == REG_DEAD
&& GET_CODE (XEXP (link, 0)) == REG) && GET_CODE (XEXP (link, 0)) == REG)
reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0))); reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)),
c);
COPY_REG_SET (c->live_throughout, live_relevant_regs);
/* Mark everything born in this instruction as live. */ /* Mark everything born in this instruction as live. */
note_stores (PATTERN (first), reg_becomes_live, NULL); note_stores (PATTERN (first), reg_becomes_live,
c->dead_or_set);
} }
else
/* Remember which registers are live at the end of the insn, before COPY_REG_SET (c->live_throughout, live_relevant_regs);
killing those with REG_UNUSED notes. */
COPY_REG_SET (c->live_after, live_relevant_regs);
if (GET_RTX_CLASS (GET_CODE (first)) == 'i') if (GET_RTX_CLASS (GET_CODE (first)) == 'i')
{ {
...@@ -1809,7 +1828,8 @@ build_insn_chain (first) ...@@ -1809,7 +1828,8 @@ build_insn_chain (first)
for (link = REG_NOTES (first); link; link = XEXP (link, 1)) for (link = REG_NOTES (first); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_UNUSED if (REG_NOTE_KIND (link) == REG_UNUSED
&& GET_CODE (XEXP (link, 0)) == REG) && GET_CODE (XEXP (link, 0)) == REG)
reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0))); reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)),
c);
} }
} }
......
...@@ -224,12 +224,9 @@ struct insn_chain ...@@ -224,12 +224,9 @@ struct insn_chain
/* The rtx of the insn. */ /* The rtx of the insn. */
rtx insn; rtx insn;
/* Register life information: record all live hard registers, and all /* Register life information: record all live hard registers, and all
live pseudos that have a hard register. live pseudos that have a hard register. */
This information is recorded for the point immediately before the insn regset live_throughout;
(in live_before), and for the point within the insn at which all regset dead_or_set;
outputs have just been written to (in live_after). */
regset live_before;
regset live_after;
/* Copies of the global variables computed by find_reloads. */ /* Copies of the global variables computed by find_reloads. */
struct reload *rld; struct reload *rld;
......
...@@ -514,8 +514,8 @@ new_insn_chain () ...@@ -514,8 +514,8 @@ new_insn_chain ()
{ {
c = (struct insn_chain *) c = (struct insn_chain *)
obstack_alloc (&reload_obstack, sizeof (struct insn_chain)); obstack_alloc (&reload_obstack, sizeof (struct insn_chain));
c->live_before = OBSTACK_ALLOC_REG_SET (&reload_obstack); c->live_throughout = OBSTACK_ALLOC_REG_SET (&reload_obstack);
c->live_after = OBSTACK_ALLOC_REG_SET (&reload_obstack); c->dead_or_set = OBSTACK_ALLOC_REG_SET (&reload_obstack);
} }
else else
{ {
...@@ -1295,8 +1295,8 @@ maybe_fix_stack_asms () ...@@ -1295,8 +1295,8 @@ maybe_fix_stack_asms ()
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (allowed, i)) if (TEST_HARD_REG_BIT (allowed, i))
{ {
CLEAR_REGNO_REG_SET (chain->live_before, i); CLEAR_REGNO_REG_SET (chain->live_throughout, i);
CLEAR_REGNO_REG_SET (chain->live_after, i); CLEAR_REGNO_REG_SET (chain->dead_or_set, i);
} }
} }
...@@ -1516,8 +1516,8 @@ order_regs_for_reload (chain) ...@@ -1516,8 +1516,8 @@ order_regs_for_reload (chain)
/* Test the various reasons why we can't use a register for /* Test the various reasons why we can't use a register for
spilling in this insn. */ spilling in this insn. */
if (fixed_regs[i] if (fixed_regs[i]
|| REGNO_REG_SET_P (chain->live_before, i) || REGNO_REG_SET_P (chain->live_throughout, i)
|| REGNO_REG_SET_P (chain->live_after, i)) || REGNO_REG_SET_P (chain->dead_or_set, i))
SET_HARD_REG_BIT (bad_spill_regs, i); SET_HARD_REG_BIT (bad_spill_regs, i);
} }
/* Now find out which pseudos are allocated to it, and update /* Now find out which pseudos are allocated to it, and update
...@@ -1525,12 +1525,12 @@ order_regs_for_reload (chain) ...@@ -1525,12 +1525,12 @@ order_regs_for_reload (chain)
CLEAR_REG_SET (&pseudos_counted); CLEAR_REG_SET (&pseudos_counted);
EXECUTE_IF_SET_IN_REG_SET EXECUTE_IF_SET_IN_REG_SET
(chain->live_before, FIRST_PSEUDO_REGISTER, j, (chain->live_throughout, FIRST_PSEUDO_REGISTER, j,
{ {
count_pseudo (j); count_pseudo (j);
}); });
EXECUTE_IF_SET_IN_REG_SET EXECUTE_IF_SET_IN_REG_SET
(chain->live_after, FIRST_PSEUDO_REGISTER, j, (chain->dead_or_set, FIRST_PSEUDO_REGISTER, j,
{ {
count_pseudo (j); count_pseudo (j);
}); });
...@@ -1645,12 +1645,12 @@ find_reg (chain, order, dumpfile) ...@@ -1645,12 +1645,12 @@ find_reg (chain, order, dumpfile)
rl->regno = best_reg; rl->regno = best_reg;
EXECUTE_IF_SET_IN_REG_SET EXECUTE_IF_SET_IN_REG_SET
(chain->live_before, FIRST_PSEUDO_REGISTER, j, (chain->live_throughout, FIRST_PSEUDO_REGISTER, j,
{ {
count_spilled_pseudo (best_reg, rl->nregs, j); count_spilled_pseudo (best_reg, rl->nregs, j);
}); });
EXECUTE_IF_SET_IN_REG_SET EXECUTE_IF_SET_IN_REG_SET
(chain->live_after, FIRST_PSEUDO_REGISTER, j, (chain->dead_or_set, FIRST_PSEUDO_REGISTER, j,
{ {
count_spilled_pseudo (best_reg, rl->nregs, j); count_spilled_pseudo (best_reg, rl->nregs, j);
}); });
...@@ -3489,13 +3489,13 @@ finish_spills (global, dumpfile) ...@@ -3489,13 +3489,13 @@ finish_spills (global, dumpfile)
for (chain = insns_need_reload; chain; chain = chain->next_need_reload) for (chain = insns_need_reload; chain; chain = chain->next_need_reload)
{ {
EXECUTE_IF_SET_IN_REG_SET EXECUTE_IF_SET_IN_REG_SET
(chain->live_before, FIRST_PSEUDO_REGISTER, i, (chain->live_throughout, FIRST_PSEUDO_REGISTER, i,
{ {
ior_hard_reg_set (pseudo_forbidden_regs + i, ior_hard_reg_set (pseudo_forbidden_regs + i,
&chain->used_spill_regs); &chain->used_spill_regs);
}); });
EXECUTE_IF_SET_IN_REG_SET EXECUTE_IF_SET_IN_REG_SET
(chain->live_after, FIRST_PSEUDO_REGISTER, i, (chain->dead_or_set, FIRST_PSEUDO_REGISTER, i,
{ {
ior_hard_reg_set (pseudo_forbidden_regs + i, ior_hard_reg_set (pseudo_forbidden_regs + i,
&chain->used_spill_regs); &chain->used_spill_regs);
...@@ -3528,22 +3528,22 @@ finish_spills (global, dumpfile) ...@@ -3528,22 +3528,22 @@ finish_spills (global, dumpfile)
HARD_REG_SET used_by_pseudos; HARD_REG_SET used_by_pseudos;
HARD_REG_SET used_by_pseudos2; HARD_REG_SET used_by_pseudos2;
AND_COMPL_REG_SET (chain->live_before, &spilled_pseudos); AND_COMPL_REG_SET (chain->live_throughout, &spilled_pseudos);
AND_COMPL_REG_SET (chain->live_after, &spilled_pseudos); AND_COMPL_REG_SET (chain->dead_or_set, &spilled_pseudos);
/* Mark any unallocated hard regs as available for spills. That /* Mark any unallocated hard regs as available for spills. That
makes inheritance work somewhat better. */ makes inheritance work somewhat better. */
if (chain->need_reload) if (chain->need_reload)
{ {
REG_SET_TO_HARD_REG_SET (used_by_pseudos, chain->live_before); REG_SET_TO_HARD_REG_SET (used_by_pseudos, chain->live_throughout);
REG_SET_TO_HARD_REG_SET (used_by_pseudos2, chain->live_after); REG_SET_TO_HARD_REG_SET (used_by_pseudos2, chain->dead_or_set);
IOR_HARD_REG_SET (used_by_pseudos, used_by_pseudos2); IOR_HARD_REG_SET (used_by_pseudos, used_by_pseudos2);
/* Save the old value for the sanity test below. */ /* Save the old value for the sanity test below. */
COPY_HARD_REG_SET (used_by_pseudos2, chain->used_spill_regs); COPY_HARD_REG_SET (used_by_pseudos2, chain->used_spill_regs);
compute_use_by_pseudos (&used_by_pseudos, chain->live_before); compute_use_by_pseudos (&used_by_pseudos, chain->live_throughout);
compute_use_by_pseudos (&used_by_pseudos, chain->live_after); compute_use_by_pseudos (&used_by_pseudos, chain->dead_or_set);
COMPL_HARD_REG_SET (chain->used_spill_regs, used_by_pseudos); COMPL_HARD_REG_SET (chain->used_spill_regs, used_by_pseudos);
AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs); AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs);
...@@ -5033,12 +5033,12 @@ choose_reload_regs_init (chain, save_reload_reg_rtx) ...@@ -5033,12 +5033,12 @@ choose_reload_regs_init (chain, save_reload_reg_rtx)
CLEAR_HARD_REG_SET (reg_used_in_insn); CLEAR_HARD_REG_SET (reg_used_in_insn);
{ {
HARD_REG_SET tmp; HARD_REG_SET tmp;
REG_SET_TO_HARD_REG_SET (tmp, chain->live_before); REG_SET_TO_HARD_REG_SET (tmp, chain->live_throughout);
IOR_HARD_REG_SET (reg_used_in_insn, tmp); IOR_HARD_REG_SET (reg_used_in_insn, tmp);
REG_SET_TO_HARD_REG_SET (tmp, chain->live_after); REG_SET_TO_HARD_REG_SET (tmp, chain->dead_or_set);
IOR_HARD_REG_SET (reg_used_in_insn, tmp); IOR_HARD_REG_SET (reg_used_in_insn, tmp);
compute_use_by_pseudos (&reg_used_in_insn, chain->live_before); compute_use_by_pseudos (&reg_used_in_insn, chain->live_throughout);
compute_use_by_pseudos (&reg_used_in_insn, chain->live_after); compute_use_by_pseudos (&reg_used_in_insn, chain->dead_or_set);
} }
for (i = 0; i < reload_n_operands; i++) for (i = 0; i < reload_n_operands; i++)
{ {
......
...@@ -129,12 +129,13 @@ static int stupid_find_reg PROTO((int, enum reg_class, enum machine_mode, ...@@ -129,12 +129,13 @@ static int stupid_find_reg PROTO((int, enum reg_class, enum machine_mode,
int, int, int)); int, int, int));
static void stupid_mark_refs PROTO((rtx, struct insn_chain *)); static void stupid_mark_refs PROTO((rtx, struct insn_chain *));
static void find_clobbered_regs PROTO((rtx, rtx, void *)); static void find_clobbered_regs PROTO((rtx, rtx, void *));
static void mark_hard_ref PROTO((rtx, int, struct insn_chain *));
/* For communication between stupid_life_analysis and find_clobbered_regs. */ /* For communication between stupid_life_analysis and find_clobbered_regs. */
static struct insn_chain *current_chain; static struct insn_chain *current_chain;
/* This function, called via note_stores, marks any hard registers that are /* This function, called via note_stores, marks any hard registers that are
clobbered in an insn as being live in the live_after and live_before fields clobbered in an insn as being live in the live_throughout field
of the appropriate insn_chain structure. */ of the appropriate insn_chain structure. */
static void static void
...@@ -161,8 +162,7 @@ find_clobbered_regs (reg, setter, data) ...@@ -161,8 +162,7 @@ find_clobbered_regs (reg, setter, data)
nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg)); nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));
while (nregs-- > 0) while (nregs-- > 0)
{ {
SET_REGNO_REG_SET (current_chain->live_after, regno); SET_REGNO_REG_SET (current_chain->live_throughout, regno++);
SET_REGNO_REG_SET (current_chain->live_before, regno++);
} }
} }
...@@ -285,7 +285,7 @@ stupid_life_analysis (f, nregs, file) ...@@ -285,7 +285,7 @@ stupid_life_analysis (f, nregs, file)
chain->insn = insn; chain->insn = insn;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (regs_live[i]) if (regs_live[i])
SET_REGNO_REG_SET (chain->live_before, i); SET_REGNO_REG_SET (chain->live_throughout, i);
} }
/* Update which hard regs are currently live /* Update which hard regs are currently live
...@@ -336,10 +336,6 @@ stupid_life_analysis (f, nregs, file) ...@@ -336,10 +336,6 @@ stupid_life_analysis (f, nregs, file)
if (GET_CODE (insn) != NOTE && GET_CODE (insn) != BARRIER) if (GET_CODE (insn) != NOTE && GET_CODE (insn) != BARRIER)
{ {
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (regs_live[i])
SET_REGNO_REG_SET (chain->live_after, i);
/* The regs_live array doesn't say anything about hard registers /* The regs_live array doesn't say anything about hard registers
clobbered by this insn. So we need an extra pass over the clobbered by this insn. So we need an extra pass over the
pattern. */ pattern. */
...@@ -407,21 +403,14 @@ stupid_life_analysis (f, nregs, file) ...@@ -407,21 +403,14 @@ stupid_life_analysis (f, nregs, file)
continue; continue;
chain = reg_where_dead_chain[i]; chain = reg_where_dead_chain[i];
if (reg_where_dead[i] > INSN_SUID (chain->insn)) SET_REGNO_REG_SET (chain->dead_or_set, i);
SET_REGNO_REG_SET (chain->live_after, i);
while (INSN_SUID (chain->insn) > reg_where_born_exact[i]) while ((chain = chain->prev)
{ && INSN_SUID (chain->insn) > reg_where_born_exact[i])
SET_REGNO_REG_SET (chain->live_before, i); SET_REGNO_REG_SET (chain->live_throughout, i);
chain = chain->prev;
if (!chain)
break;
SET_REGNO_REG_SET (chain->live_after, i);
}
if (INSN_SUID (chain->insn) == reg_where_born_exact[i] if (chain)
&& reg_where_born_clobber[i]) SET_REGNO_REG_SET (chain->dead_or_set, i);
SET_REGNO_REG_SET (chain->live_before, i);
} }
if (file) if (file)
...@@ -568,6 +557,32 @@ stupid_find_reg (call_preserved, class, mode, ...@@ -568,6 +557,32 @@ stupid_find_reg (call_preserved, class, mode,
return -1; return -1;
} }
/* Note that REG is being set or referenced, and add the appropriate
REG_DEAD / REG_UNUSED note(s). For sets, LIVE_BEFORE_P will be 0,
while for references, LIVE_BEFORE_P will be 1.
INSN is the instruction that the reg notes have to be added to. */
static void
mark_hard_ref (reg, live_before_p, chain)
rtx reg;
int live_before_p;
struct insn_chain *chain;
{
/* Hard reg: mark it live for continuing scan of previous insns. */
int regno = REGNO (reg);
char *live = regs_live;
register int j;
int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));
for (j = nregs - 1; j >= 0; j--)
{
if (! fixed_regs[regno+j]
&& (! live_before_p || ! live[regno+j]))
SET_REGNO_REG_SET (chain->dead_or_set, regno+j);
regs_ever_live[regno+j] = 1;
live[regno+j] = live_before_p;
}
}
/* Walk X, noting all assignments and references to registers /* Walk X, noting all assignments and references to registers
and recording what they imply about life spans. and recording what they imply about life spans.
INSN is the current insn, supplied so we can find its suid. */ INSN is the current insn, supplied so we can find its suid. */
...@@ -597,11 +612,13 @@ stupid_mark_refs (x, chain) ...@@ -597,11 +612,13 @@ stupid_mark_refs (x, chain)
>= FIRST_PSEUDO_REGISTER)))) >= FIRST_PSEUDO_REGISTER))))
{ {
/* Register is being assigned. */ /* Register is being assigned. */
rtx reg = SET_DEST (x);
/* If setting a SUBREG, we treat the entire reg as being set. */ /* If setting a SUBREG, we treat the entire reg as being set. */
if (GET_CODE (SET_DEST (x)) == SUBREG) if (GET_CODE (SET_DEST (x)) == SUBREG)
regno = REGNO (SUBREG_REG (SET_DEST (x))); reg = SUBREG_REG (reg);
else
regno = REGNO (SET_DEST (x)); regno = REGNO (reg);
/* For hard regs, update the where-live info. */ /* For hard regs, update the where-live info. */
if (regno < FIRST_PSEUDO_REGISTER) if (regno < FIRST_PSEUDO_REGISTER)
...@@ -609,15 +626,16 @@ stupid_mark_refs (x, chain) ...@@ -609,15 +626,16 @@ stupid_mark_refs (x, chain)
register int j register int j
= HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (x))); = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (x)));
mark_hard_ref (reg, 0, chain);
while (--j >= 0) while (--j >= 0)
{ {
regs_ever_live[regno+j] = 1;
regs_live[regno+j] = 0;
/* The following line is for unused outputs; /* The following line is for unused outputs;
they do get stored even though never used again. */ they do get stored even though never used again. */
MARK_LIVE_AFTER (insn, regno+j); MARK_LIVE_AFTER (insn, regno+j);
CLEAR_REGNO_REG_SET (chain->live_throughout, regno + j);
/* When a hard reg is clobbered, mark it in use /* When a hard reg is clobbered, mark it in use
just before this insn, so it is live all through. */ just before this insn, so it is live all through. */
if (code == CLOBBER && INSN_SUID (insn) > 0) if (code == CLOBBER && INSN_SUID (insn) > 0)
...@@ -706,15 +724,8 @@ stupid_mark_refs (x, chain) ...@@ -706,15 +724,8 @@ stupid_mark_refs (x, chain)
{ {
regno = REGNO (x); regno = REGNO (x);
if (regno < FIRST_PSEUDO_REGISTER) if (regno < FIRST_PSEUDO_REGISTER)
{ /* Hard reg: mark it live for continuing scan of previous insns. */
/* Hard reg: mark it live for continuing scan of previous insns. */ mark_hard_ref (x, 1, chain);
register int j = HARD_REGNO_NREGS (regno, GET_MODE (x));
while (--j >= 0)
{
regs_ever_live[regno+j] = 1;
regs_live[regno+j] = 1;
}
}
else else
{ {
/* Pseudo reg: record first use, last use and number of uses. */ /* Pseudo reg: record first use, last use and number of uses. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment