caller-save.c (restore_referenced_regs): Lose mode argument.
* caller-save.c (restore_referenced_regs): Lose mode argument. (insert_save): Lose mode argument. (insert_restore): Lose mode argument. (insert_one_insn): Lose mode argument. (save_call_clobbered_regs): Lose mode argument. (setup_save_areas): Take no argument and return void. All callers changed. Don't verify validity of memory addresses. * reload.h (setup_save_ares): Adjust prototype. (save_call_clobbered_regs): Likewise. * reload1.c (delete_caller_save_insns): New function. (caller_save_spill_class): Delete variable. (caller_save_group_size): Delete variable. (reload): Call setup_save_areas and save_call_clobbered_regs in the main loop, before calling calculate_needs_all_insns. Don't call save_call_clobbered_regs after the loop. Call delete_caller_save_insns at the end of an iteration if something changed. Delete code to manage caller_save_spill_class. Emit the final note before setting reload_first_uid. Simplify test that determines whether reload_as_needed gets run. (calculate_needs): Delete code to manage caller_save_spill_class. From-SVN: r22876
This commit is contained in:
parent
a4c3ddd83a
commit
437a710df0
4 changed files with 122 additions and 195 deletions
|
@ -1,3 +1,28 @@
|
|||
Wed Oct 7 01:08:43 1998 Bernd Schmidt <crux@Pool.Informatik.RWTH-Aachen.DE>
|
||||
|
||||
* caller-save.c (restore_referenced_regs): Lose mode argument.
|
||||
(insert_save): Lose mode argument.
|
||||
(insert_restore): Lose mode argument.
|
||||
(insert_one_insn): Lose mode argument.
|
||||
(save_call_clobbered_regs): Lose mode argument.
|
||||
(setup_save_areas): Take no argument and return void. All callers
|
||||
changed.
|
||||
Don't verify validity of memory addresses.
|
||||
* reload.h (setup_save_ares): Adjust prototype.
|
||||
(save_call_clobbered_regs): Likewise.
|
||||
* reload1.c (delete_caller_save_insns): New function.
|
||||
(caller_save_spill_class): Delete variable.
|
||||
(caller_save_group_size): Delete variable.
|
||||
(reload): Call setup_save_areas and save_call_clobbered_regs
|
||||
in the main loop, before calling calculate_needs_all_insns.
|
||||
Don't call save_call_clobbered_regs after the loop.
|
||||
Call delete_caller_save_insns at the end of an iteration if
|
||||
something changed.
|
||||
Delete code to manage caller_save_spill_class.
|
||||
Emit the final note before setting reload_first_uid.
|
||||
Simplify test that determines whether reload_as_needed gets run.
|
||||
(calculate_needs): Delete code to manage caller_save_spill_class.
|
||||
|
||||
Tue Oct 6 15:42:27 1998 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* collect2.c (main): Initialize ld_file_name.
|
||||
|
|
|
@ -82,14 +82,11 @@ int n_regs_saved;
|
|||
|
||||
static void set_reg_live PROTO((rtx, rtx));
|
||||
static void clear_reg_live PROTO((rtx));
|
||||
static void restore_referenced_regs PROTO((rtx, rtx, enum machine_mode,
|
||||
int));
|
||||
static int insert_restore PROTO((rtx, int, int,
|
||||
enum machine_mode, int, int));
|
||||
static int insert_save PROTO((rtx, int, int,
|
||||
enum machine_mode, int));
|
||||
static void restore_referenced_regs PROTO((rtx, rtx, int));
|
||||
static int insert_restore PROTO((rtx, int, int, int, int));
|
||||
static int insert_save PROTO((rtx, int, int, int));
|
||||
static void insert_one_insn PROTO((rtx, int, enum rtx_code,
|
||||
enum machine_mode, rtx, int));
|
||||
rtx, int));
|
||||
|
||||
/* Initialize for caller-save.
|
||||
|
||||
|
@ -234,13 +231,6 @@ init_save_areas ()
|
|||
overestimate slightly (especially if some of these registers are later
|
||||
used as spill registers), but it should not be significant.
|
||||
|
||||
Then perform register elimination in the addresses of the save area
|
||||
locations; return 1 if all eliminated addresses are strictly valid.
|
||||
We assume that our caller has set up the elimination table to the
|
||||
worst (largest) possible offsets.
|
||||
|
||||
Set *PCHANGED to 1 if we had to allocate some memory for the save area.
|
||||
|
||||
Future work:
|
||||
|
||||
In the fallback case we should iterate backwards across all possible
|
||||
|
@ -253,14 +243,11 @@ init_save_areas ()
|
|||
machine independent since they might be saving non-consecutive
|
||||
registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */
|
||||
|
||||
int
|
||||
setup_save_areas (pchanged)
|
||||
int *pchanged;
|
||||
void
|
||||
setup_save_areas ()
|
||||
{
|
||||
int i, j, k;
|
||||
HARD_REG_SET hard_regs_used;
|
||||
int ok = 1;
|
||||
|
||||
|
||||
/* Allocate space in the save area for the largest multi-register
|
||||
pseudos first, then work backwards to single register
|
||||
|
@ -334,28 +321,16 @@ setup_save_areas (pchanged)
|
|||
regno_save_mem[i+k][1]
|
||||
= adj_offsettable_operand (temp, k * UNITS_PER_WORD);
|
||||
}
|
||||
*pchanged = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
|
||||
if (regno_save_mem[i][j] != 0)
|
||||
ok &= strict_memory_address_p (GET_MODE (regno_save_mem[i][j]),
|
||||
XEXP (eliminate_regs (regno_save_mem[i][j], 0, NULL_RTX), 0));
|
||||
|
||||
return ok;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the places where hard regs are live across calls and save them.
|
||||
|
||||
INSN_MODE is the mode to assign to any insns that we add. This is used
|
||||
by reload to determine whether or not reloads or register eliminations
|
||||
need be done on these insns. */
|
||||
/* Find the places where hard regs are live across calls and save them. */
|
||||
|
||||
void
|
||||
save_call_clobbered_regs (insn_mode)
|
||||
enum machine_mode insn_mode;
|
||||
save_call_clobbered_regs ()
|
||||
{
|
||||
rtx insn;
|
||||
int b;
|
||||
|
@ -403,7 +378,7 @@ save_call_clobbered_regs (insn_mode)
|
|||
any of them. We must restore them before the insn if so. */
|
||||
|
||||
if (n_regs_saved)
|
||||
restore_referenced_regs (PATTERN (insn), insn, insn_mode, b);
|
||||
restore_referenced_regs (PATTERN (insn), insn, b);
|
||||
|
||||
/* NB: the normal procedure is to first enliven any
|
||||
registers set by insn, then deaden any registers that
|
||||
|
@ -453,7 +428,7 @@ save_call_clobbered_regs (insn_mode)
|
|||
/* It must not be set by this instruction. */
|
||||
&& ! TEST_HARD_REG_BIT (this_call_sets, regno)
|
||||
&& ! TEST_HARD_REG_BIT (hard_regs_saved, regno))
|
||||
regno += insert_save (insn, 1, regno, insn_mode, b);
|
||||
regno += insert_save (insn, 1, regno, b);
|
||||
|
||||
/* Put the information for this CALL_INSN on top of what
|
||||
we already had. */
|
||||
|
@ -493,7 +468,7 @@ save_call_clobbered_regs (insn_mode)
|
|||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
||||
if (TEST_HARD_REG_BIT (hard_regs_need_restore, regno))
|
||||
regno += insert_restore (insn, GET_CODE (insn) == JUMP_INSN,
|
||||
regno, insn_mode,
|
||||
regno,
|
||||
MOVE_MAX / UNITS_PER_WORD, b);
|
||||
}
|
||||
}
|
||||
|
@ -557,14 +532,13 @@ clear_reg_live (reg)
|
|||
}
|
||||
|
||||
/* If any register currently residing in the save area is referenced in X,
|
||||
which is part of INSN, emit code to restore the register in front of INSN.
|
||||
INSN_MODE is the mode to assign to any insns that we add. */
|
||||
which is part of INSN, emit code to restore the register in front of
|
||||
INSN. */
|
||||
|
||||
static void
|
||||
restore_referenced_regs (x, insn, insn_mode, block)
|
||||
restore_referenced_regs (x, insn, block)
|
||||
rtx x;
|
||||
rtx insn;
|
||||
enum machine_mode insn_mode;
|
||||
int block;
|
||||
{
|
||||
enum rtx_code code = GET_CODE (x);
|
||||
|
@ -584,11 +558,11 @@ restore_referenced_regs (x, insn, insn_mode, block)
|
|||
if (regno >= FIRST_PSEUDO_REGISTER
|
||||
&& reg_equiv_mem[regno] != 0)
|
||||
restore_referenced_regs (XEXP (reg_equiv_mem[regno], 0),
|
||||
insn, insn_mode, block);
|
||||
insn, block);
|
||||
else if (regno >= FIRST_PSEUDO_REGISTER
|
||||
&& reg_equiv_address[regno] != 0)
|
||||
restore_referenced_regs (reg_equiv_address[regno],
|
||||
insn, insn_mode, block);
|
||||
insn, block);
|
||||
|
||||
/* Otherwise if this is a hard register, restore any piece of it that
|
||||
is currently saved. */
|
||||
|
@ -603,7 +577,7 @@ restore_referenced_regs (x, insn, insn_mode, block)
|
|||
|
||||
for (i = regno; i < endregno; i++)
|
||||
if (TEST_HARD_REG_BIT (hard_regs_need_restore, i))
|
||||
i += insert_restore (insn, 1, i, insn_mode, saveregs, block);
|
||||
i += insert_restore (insn, 1, i, saveregs, block);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -613,18 +587,17 @@ restore_referenced_regs (x, insn, insn_mode, block)
|
|||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||
{
|
||||
if (fmt[i] == 'e')
|
||||
restore_referenced_regs (XEXP (x, i), insn, insn_mode, block);
|
||||
restore_referenced_regs (XEXP (x, i), insn, block);
|
||||
else if (fmt[i] == 'E')
|
||||
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
|
||||
restore_referenced_regs (XVECEXP (x, i, j), insn, insn_mode, block);
|
||||
restore_referenced_regs (XVECEXP (x, i, j), insn, block);
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert a sequence of insns to restore REGNO. Place these insns in front
|
||||
of or after INSN (determined by BEFORE_P). INSN_MODE is the mode
|
||||
to assign to these insns. MAXRESTORE is the maximum number of registers
|
||||
which should be restored during this call. It should never be less than
|
||||
1 since we only work with entire registers.
|
||||
of or after INSN (determined by BEFORE_P). MAXRESTORE is the maximum
|
||||
number of registers which should be restored during this call. It should
|
||||
never be less than 1 since we only work with entire registers.
|
||||
|
||||
Note that we have verified in init_caller_save that we can do this
|
||||
with a simple SET, so use it. Set INSN_CODE to what we save there
|
||||
|
@ -635,11 +608,10 @@ restore_referenced_regs (x, insn, insn_mode, block)
|
|||
Return the extra number of registers saved. */
|
||||
|
||||
static int
|
||||
insert_restore (insn, before_p, regno, insn_mode, maxrestore, block)
|
||||
insert_restore (insn, before_p, regno, maxrestore, block)
|
||||
rtx insn;
|
||||
int before_p;
|
||||
int regno;
|
||||
enum machine_mode insn_mode;
|
||||
int maxrestore;
|
||||
int block;
|
||||
{
|
||||
|
@ -697,7 +669,7 @@ insert_restore (insn, before_p, regno, insn_mode, maxrestore, block)
|
|||
break;
|
||||
}
|
||||
|
||||
insert_one_insn (insn, before_p, code, insn_mode, pat, block);
|
||||
insert_one_insn (insn, before_p, code, pat, block);
|
||||
|
||||
/* Tell our callers how many extra registers we saved/restored */
|
||||
return numregs - 1;
|
||||
|
@ -705,11 +677,10 @@ insert_restore (insn, before_p, regno, insn_mode, maxrestore, block)
|
|||
|
||||
/* Like insert_restore, but emit code to save REGNO. */
|
||||
static int
|
||||
insert_save (insn, before_p, regno, insn_mode, block)
|
||||
insert_save (insn, before_p, regno, block)
|
||||
rtx insn;
|
||||
int before_p;
|
||||
int regno;
|
||||
enum machine_mode insn_mode;
|
||||
int block;
|
||||
{
|
||||
rtx pat = NULL_RTX;
|
||||
|
@ -767,20 +738,18 @@ insert_save (insn, before_p, regno, insn_mode, block)
|
|||
break;
|
||||
}
|
||||
|
||||
insert_one_insn (insn, before_p, code, insn_mode, pat, block);
|
||||
insert_one_insn (insn, before_p, code, pat, block);
|
||||
|
||||
/* Tell our callers how many extra registers we saved/restored */
|
||||
return numregs - 1;
|
||||
}
|
||||
|
||||
/* Emit one insn, set the code and mode, and update basic block
|
||||
boundaries. */
|
||||
/* Emit one insn, set the code, and update basic block boundaries. */
|
||||
static void
|
||||
insert_one_insn (insn, before_p, code, mode, pat, block)
|
||||
insert_one_insn (insn, before_p, code, pat, block)
|
||||
rtx insn;
|
||||
int before_p;
|
||||
enum rtx_code code;
|
||||
enum machine_mode mode;
|
||||
rtx pat;
|
||||
int block;
|
||||
{
|
||||
|
@ -811,7 +780,6 @@ insert_one_insn (insn, before_p, code, mode, pat, block)
|
|||
if (insert_point == basic_block_end[block])
|
||||
basic_block_end[block] = new;
|
||||
}
|
||||
|
||||
PUT_MODE (new, mode);
|
||||
|
||||
INSN_CODE (new) = code;
|
||||
}
|
||||
|
|
|
@ -327,7 +327,7 @@ extern void init_caller_save PROTO((void));
|
|||
extern void init_save_areas PROTO((void));
|
||||
|
||||
/* Allocate save areas for any hard registers that might need saving. */
|
||||
extern int setup_save_areas PROTO((int *));
|
||||
extern void setup_save_areas PROTO((void));
|
||||
|
||||
/* Find the places where hard regs are live across calls and save them. */
|
||||
extern void save_call_clobbered_regs PROTO((enum machine_mode));
|
||||
extern void save_call_clobbered_regs PROTO((void));
|
||||
|
|
196
gcc/reload1.c
196
gcc/reload1.c
|
@ -371,6 +371,7 @@ static void count_possible_groups PROTO((int *, enum machine_mode *,
|
|||
static int modes_equiv_for_class_p PROTO((enum machine_mode,
|
||||
enum machine_mode,
|
||||
enum reg_class));
|
||||
static void delete_caller_save_insns PROTO((rtx));
|
||||
static void spill_failure PROTO((rtx));
|
||||
static int new_spill_reg PROTO((int, int, int *, int *, int,
|
||||
FILE *));
|
||||
|
@ -566,10 +567,6 @@ static int something_needs_reloads;
|
|||
/* Set during calculate_needs if an insn needs register elimination. */
|
||||
static int something_needs_elimination;
|
||||
|
||||
/* Indicate whether caller saves need a spill register. */
|
||||
static enum reg_class caller_save_spill_class = NO_REGS;
|
||||
static int caller_save_group_size = 1;
|
||||
|
||||
/* For each class, number of reload regs needed in that class.
|
||||
This is the maximum over all insns of the needs in that class
|
||||
of the individual insn. */
|
||||
|
@ -644,12 +641,13 @@ reload (first, global, dumpfile)
|
|||
|
||||
reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
|
||||
|
||||
/* Make sure that the last insn in the chain
|
||||
is not something that needs reloading. */
|
||||
emit_note (NULL_PTR, NOTE_INSN_DELETED);
|
||||
|
||||
/* Enable find_equiv_reg to distinguish insns made by reload. */
|
||||
reload_first_uid = get_max_uid ();
|
||||
|
||||
caller_save_spill_class = NO_REGS;
|
||||
caller_save_group_size = 1;
|
||||
|
||||
for (i = 0; i < N_REG_CLASSES; i++)
|
||||
basic_block_needs[i] = 0;
|
||||
|
||||
|
@ -687,10 +685,6 @@ reload (first, global, dumpfile)
|
|||
regs_ever_live[i] = 1;
|
||||
}
|
||||
|
||||
/* Make sure that the last insn in the chain
|
||||
is not something that needs reloading. */
|
||||
emit_note (NULL_PTR, NOTE_INSN_DELETED);
|
||||
|
||||
/* Find all the pseudo registers that didn't get hard regs
|
||||
but do have known equivalent constants or memory slots.
|
||||
These include parameters (known equivalent to parameter slots)
|
||||
|
@ -986,18 +980,26 @@ reload (first, global, dumpfile)
|
|||
}
|
||||
}
|
||||
|
||||
/* Insert code to save and restore call-clobbered hard regs
|
||||
around calls. Tell if what mode to use so that we will process
|
||||
those insns in reload_as_needed if we have to. */
|
||||
|
||||
if (caller_save_needed)
|
||||
setup_save_areas ();
|
||||
|
||||
if (starting_frame_size != get_frame_size ())
|
||||
something_changed = 1;
|
||||
|
||||
/* If we allocated another pseudo to the stack, redo elimination
|
||||
bookkeeping. */
|
||||
if (something_changed)
|
||||
continue;
|
||||
|
||||
/* If caller-saves needs a group, initialize the group to include
|
||||
the size and mode required for caller-saves. */
|
||||
|
||||
if (caller_save_group_size > 1)
|
||||
if (caller_save_needed)
|
||||
{
|
||||
group_mode[(int) caller_save_spill_class] = Pmode;
|
||||
group_size[(int) caller_save_spill_class] = caller_save_group_size;
|
||||
save_call_clobbered_regs ();
|
||||
/* That might have allocated new insn_chain structures. */
|
||||
reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
|
||||
}
|
||||
|
||||
something_changed |= calculate_needs_all_insns (first, global);
|
||||
|
@ -1010,32 +1012,6 @@ reload (first, global, dumpfile)
|
|||
if (dumpfile)
|
||||
dump_needs (dumpfile);
|
||||
|
||||
/* If we have caller-saves, set up the save areas and see if caller-save
|
||||
will need a spill register. */
|
||||
|
||||
if (caller_save_needed)
|
||||
{
|
||||
/* Set the offsets for setup_save_areas. */
|
||||
for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS];
|
||||
ep++)
|
||||
ep->previous_offset = ep->max_offset;
|
||||
|
||||
if ( ! setup_save_areas (&something_changed)
|
||||
&& caller_save_spill_class == NO_REGS)
|
||||
{
|
||||
/* The class we will need depends on whether the machine
|
||||
supports the sum of two registers for an address; see
|
||||
find_address_reloads for details. */
|
||||
|
||||
caller_save_spill_class
|
||||
= (double_reg_address_ok ? reload_address_index_reg_class
|
||||
: reload_address_base_reg_class);
|
||||
caller_save_group_size
|
||||
= CLASS_MAX_NREGS (caller_save_spill_class, Pmode);
|
||||
something_changed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HARD_REG_SET to_spill;
|
||||
CLEAR_HARD_REG_SET (to_spill);
|
||||
|
@ -1098,6 +1074,9 @@ reload (first, global, dumpfile)
|
|||
something_changed |= find_reload_regs (global, dumpfile);
|
||||
if (failure)
|
||||
goto failed;
|
||||
|
||||
if (something_changed)
|
||||
delete_caller_save_insns (first);
|
||||
}
|
||||
|
||||
/* If global-alloc was run, notify it of any register eliminations we have
|
||||
|
@ -1107,15 +1086,6 @@ reload (first, global, dumpfile)
|
|||
if (ep->can_eliminate)
|
||||
mark_elimination (ep->from, ep->to);
|
||||
|
||||
/* Insert code to save and restore call-clobbered hard regs
|
||||
around calls. Tell if what mode to use so that we will process
|
||||
those insns in reload_as_needed if we have to. */
|
||||
|
||||
if (caller_save_needed)
|
||||
save_call_clobbered_regs (num_eliminable ? QImode
|
||||
: caller_save_spill_class != NO_REGS ? HImode
|
||||
: VOIDmode);
|
||||
|
||||
/* If a pseudo has no hard reg, delete the insns that made the equivalence.
|
||||
If that insn didn't set the register (i.e., it copied the register to
|
||||
memory), just delete that insn instead of the equivalencing insn plus
|
||||
|
@ -1141,9 +1111,7 @@ reload (first, global, dumpfile)
|
|||
by generating move instructions to move the must-be-register
|
||||
values into or out of the reload registers. */
|
||||
|
||||
if (something_needs_reloads || something_needs_elimination
|
||||
|| (caller_save_needed && num_eliminable)
|
||||
|| caller_save_spill_class != NO_REGS)
|
||||
if (something_needs_reloads || something_needs_elimination)
|
||||
reload_as_needed (first, global);
|
||||
|
||||
/* If we were able to eliminate the frame pointer, show that it is no
|
||||
|
@ -1384,13 +1352,7 @@ calculate_needs_all_insns (first, global)
|
|||
something_needs_elimination = 1;
|
||||
}
|
||||
|
||||
/* If this insn has no reloads, we need not do anything except
|
||||
in the case of a CALL_INSN when we have caller-saves and
|
||||
caller-save needs reloads. */
|
||||
|
||||
if (n_reloads != 0
|
||||
|| (GET_CODE (insn) == CALL_INSN
|
||||
&& caller_save_spill_class != NO_REGS))
|
||||
if (n_reloads != 0)
|
||||
something_changed |= calculate_needs (this_block, insn,
|
||||
avoid_return_reg, global);
|
||||
}
|
||||
|
@ -1650,75 +1612,6 @@ calculate_needs (this_block, insn, avoid_return_reg, global)
|
|||
insn_needs.other_addr.groups[i]);
|
||||
}
|
||||
|
||||
/* If this is a CALL_INSN and caller-saves will need
|
||||
a spill register, act as if the spill register is
|
||||
needed for this insn. However, the spill register
|
||||
can be used by any reload of this insn, so we only
|
||||
need do something if no need for that class has
|
||||
been recorded.
|
||||
|
||||
The assumption that every CALL_INSN will trigger a
|
||||
caller-save is highly conservative, however, the number
|
||||
of cases where caller-saves will need a spill register but
|
||||
a block containing a CALL_INSN won't need a spill register
|
||||
of that class should be quite rare.
|
||||
|
||||
If a group is needed, the size and mode of the group will
|
||||
have been set up at the beginning of this loop. */
|
||||
|
||||
if (GET_CODE (insn) == CALL_INSN
|
||||
&& caller_save_spill_class != NO_REGS)
|
||||
{
|
||||
int j;
|
||||
/* See if this register would conflict with any reload that
|
||||
needs a group or any reload that needs a nongroup. */
|
||||
int nongroup_need = 0;
|
||||
int *caller_save_needs;
|
||||
|
||||
for (j = 0; j < n_reloads; j++)
|
||||
if (reg_classes_intersect_p (caller_save_spill_class,
|
||||
reload_reg_class[j])
|
||||
&& ((CLASS_MAX_NREGS
|
||||
(reload_reg_class[j],
|
||||
(GET_MODE_SIZE (reload_outmode[j])
|
||||
> GET_MODE_SIZE (reload_inmode[j]))
|
||||
? reload_outmode[j] : reload_inmode[j])
|
||||
> 1)
|
||||
|| reload_nongroup[j]))
|
||||
{
|
||||
nongroup_need = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
caller_save_needs
|
||||
= (caller_save_group_size > 1
|
||||
? insn_needs.other.groups
|
||||
: insn_needs.other.regs[nongroup_need]);
|
||||
|
||||
if (caller_save_needs[(int) caller_save_spill_class] == 0)
|
||||
{
|
||||
register enum reg_class *p
|
||||
= reg_class_superclasses[(int) caller_save_spill_class];
|
||||
|
||||
caller_save_needs[(int) caller_save_spill_class]++;
|
||||
|
||||
while (*p != LIM_REG_CLASSES)
|
||||
caller_save_needs[(int) *p++] += 1;
|
||||
}
|
||||
|
||||
/* Show that this basic block will need a register of
|
||||
this class. */
|
||||
|
||||
if (global
|
||||
&& ! (basic_block_needs[(int) caller_save_spill_class]
|
||||
[this_block]))
|
||||
{
|
||||
basic_block_needs[(int) caller_save_spill_class]
|
||||
[this_block] = 1;
|
||||
something_changed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this insn stores the value of a function call,
|
||||
and that value is in a register that has been spilled,
|
||||
and if the insn needs a reload in a class
|
||||
|
@ -2166,6 +2059,47 @@ dump_needs (dumpfile)
|
|||
}
|
||||
}
|
||||
|
||||
/* Delete all insns that were inserted by emit_caller_save_insns during
|
||||
this iteration. */
|
||||
static void
|
||||
delete_caller_save_insns (first)
|
||||
rtx first;
|
||||
{
|
||||
rtx insn = first;
|
||||
int b = -1;
|
||||
|
||||
while (insn != 0)
|
||||
{
|
||||
if (b + 1 != n_basic_blocks
|
||||
&& basic_block_head[b + 1] == insn)
|
||||
b++;
|
||||
|
||||
while (insn != 0 && INSN_UID (insn) >= reload_first_uid)
|
||||
{
|
||||
rtx next = NEXT_INSN (insn);
|
||||
rtx prev = PREV_INSN (insn);
|
||||
|
||||
if (insn == basic_block_head[b])
|
||||
basic_block_head[b] = next;
|
||||
if (insn == basic_block_end[b])
|
||||
basic_block_end[b] = prev;
|
||||
|
||||
if (next != 0)
|
||||
PREV_INSN (next) = prev;
|
||||
if (prev != 0)
|
||||
NEXT_INSN (prev) = next;
|
||||
|
||||
insn = next;
|
||||
|
||||
if (b + 1 != n_basic_blocks
|
||||
&& basic_block_head[b + 1] == insn)
|
||||
b++;
|
||||
}
|
||||
if (insn != 0)
|
||||
insn = NEXT_INSN (insn);
|
||||
}
|
||||
}
|
||||
|
||||
/* Nonzero if, after spilling reg REGNO for non-groups,
|
||||
it will still be possible to find a group if we still need one. */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue