参照元†
返り値†
/* Major LRA entry function. F is a file should be used to dump LRA
debug info. */
void
lra (FILE *f)
{
int i;
bool live_p, inserted_p;
lra_dump_file = f;
timevar_push (TV_LRA);
/* Make sure that the last insn is a note. Some subsequent passes
need it. */
emit_note (NOTE_INSN_DELETED);
COPY_HARD_REG_SET (lra_no_alloc_regs, ira_no_alloc_regs);
init_reg_info ();
expand_reg_info ();
init_insn_recog_data ();
/* Some quick check on RTL generated by previous passes. */
if (flag_checking)
check_rtl (false);
lra_in_progress = 1;
lra_live_range_iter = lra_coalesce_iter = lra_constraint_iter = 0;
lra_assignment_iter = lra_assignment_iter_after_spill = 0;
lra_inheritance_iter = lra_undo_inheritance_iter = 0;
lra_rematerialization_iter = 0;
setup_reg_spill_flag ();
/* Function remove_scratches can creates new pseudos for clobbers --
so set up lra_constraint_new_regno_start before its call to
permit changing reg classes for pseudos created by this
simplification. */
lra_constraint_new_regno_start = lra_new_regno_start = max_reg_num ();
lra_bad_spill_regno_start = INT_MAX;
remove_scratches ();
/* A function that has a non-local label that can reach the exit
block via non-exceptional paths must save all call-saved
registers. */
if (cfun->has_nonlocal_label && has_nonexceptional_receiver ())
crtl->saves_all_registers = 1;
if (crtl->saves_all_registers)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
df_set_regs_ever_live (i, true);
/* We don't DF from now and avoid its using because it is to
expensive when a lot of RTL changes are made. */
df_set_flags (DF_NO_INSN_RESCAN);
lra_constraint_insn_stack.create (get_max_uid ());
lra_constraint_insn_stack_bitmap = sbitmap_alloc (get_max_uid ());
bitmap_clear (lra_constraint_insn_stack_bitmap);
lra_live_ranges_init ();
lra_constraints_init ();
lra_curr_reload_num = 0;
push_insns (get_last_insn (), NULL);
/* It is needed for the 1st coalescing. */
bitmap_initialize (&lra_inheritance_pseudos, ®_obstack);
bitmap_initialize (&lra_split_regs, ®_obstack);
bitmap_initialize (&lra_optional_reload_pseudos, ®_obstack);
bitmap_initialize (&lra_subreg_reload_pseudos, ®_obstack);
live_p = false;
if (maybe_ne (get_frame_size (), 0) && crtl->stack_alignment_needed)
/* If we have a stack frame, we must align it now. The stack size
may be a part of the offset computation for register
elimination. */
assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed);
lra_init_equiv ();
for (;;)
{
for (;;)
{
bool reloads_p = lra_constraints (lra_constraint_iter == 0);
/* Constraint transformations may result in that eliminable
hard regs become uneliminable and pseudos which use them
should be spilled. It is better to do it before pseudo
assignments.
For example, rs6000 can make
RS6000_PIC_OFFSET_TABLE_REGNUM uneliminable if we started
to use a constant pool. */
lra_eliminate (false, false);
/* We should try to assign hard registers to scratches even
if there were no RTL transformations in lra_constraints.
Also we should check IRA assignments on the first
iteration as they can be wrong because of early clobbers
operands which are ignored in IRA. */
if (! reloads_p && lra_constraint_iter > 1)
{
/* Stack is not empty here only when there are changes
during the elimination sub-pass. */
if (bitmap_empty_p (lra_constraint_insn_stack_bitmap))
break;
else
/* If there are no reloads but changing due
elimination, restart the constraint sub-pass
first. */
continue;
}
/* Do inheritance only for regular algorithms. */
if (! lra_simple_p)
{
if (flag_ipa_ra)
{
if (live_p)
lra_clear_live_ranges ();
/* As a side-effect of lra_create_live_ranges, we calculate
actual_call_used_reg_set, which is needed during
lra_inheritance. */
lra_create_live_ranges (true, true);
live_p = true;
}
lra_inheritance ();
}
if (live_p)
lra_clear_live_ranges ();
bool fails_p;
do
{
/* We need live ranges for lra_assign -- so build them.
But don't remove dead insns or change global live
info as we can undo inheritance transformations after
inheritance pseudo assigning. */
lra_create_live_ranges (true, false);
live_p = true;
/* If we don't spill non-reload and non-inheritance
pseudos, there is no sense to run memory-memory move
coalescing. If inheritance pseudos were spilled, the
memory-memory moves involving them will be removed by
pass undoing inheritance. */
if (lra_simple_p)
lra_assign (fails_p);
else
{
bool spill_p = !lra_assign (fails_p);
if (lra_undo_inheritance ())
live_p = false;
if (spill_p && ! fails_p)
{
if (! live_p)
{
lra_create_live_ranges (true, true);
live_p = true;
}
if (lra_coalesce ())
live_p = false;
}
if (! live_p)
lra_clear_live_ranges ();
}
if (fails_p)
{
/* It is a very rare case. It is the last hope to
split a hard regno live range for a reload
pseudo. */
if (live_p)
lra_clear_live_ranges ();
live_p = false;
if (! lra_split_hard_reg_for ())
break;
}
}
while (fails_p);
}
/* Don't clear optional reloads bitmap until all constraints are
satisfied as we need to differ them from regular reloads. */
bitmap_clear (&lra_optional_reload_pseudos);
bitmap_clear (&lra_subreg_reload_pseudos);
bitmap_clear (&lra_inheritance_pseudos);
bitmap_clear (&lra_split_regs);
if (! live_p)
{
/* We need full live info for spilling pseudos into
registers instead of memory. */
lra_create_live_ranges (lra_reg_spill_p, true);
live_p = true;
}
/* We should check necessity for spilling here as the above live
range pass can remove spilled pseudos. */
if (! lra_need_for_spills_p ())
break;
- [[gcc-8.3/gcc/]lra_need_for_spills_p()]
/* Now we know what pseudos should be spilled. Try to
rematerialize them first. */
if (lra_remat ())
{
/* We need full live info -- see the comment above. */
lra_create_live_ranges (lra_reg_spill_p, true);
live_p = true;
if (! lra_need_for_spills_p ())
break;
}
lra_spill ();
/* Assignment of stack slots changes elimination offsets for
some eliminations. So update the offsets here. */
lra_eliminate (false, false);
lra_constraint_new_regno_start = max_reg_num ();
if (lra_bad_spill_regno_start == INT_MAX
&& lra_inheritance_iter > LRA_MAX_INHERITANCE_PASSES
&& lra_rematerialization_iter > LRA_MAX_REMATERIALIZATION_PASSES)
/* After switching off inheritance and rematerialization
passes, avoid spilling reload pseudos will be created to
prevent LRA cycling in some complicated cases. */
lra_bad_spill_regno_start = lra_constraint_new_regno_start;
lra_assignment_iter_after_spill = 0;
}
restore_scratches ();
lra_eliminate (true, false);
lra_final_code_change ();
lra_in_progress = 0;
if (live_p)
lra_clear_live_ranges ();
lra_live_ranges_finish ();
lra_constraints_finish ();
finish_reg_info ();
sbitmap_free (lra_constraint_insn_stack_bitmap);
lra_constraint_insn_stack.release ();
finish_insn_recog_data ();
regstat_free_n_sets_and_refs ();
regstat_free_ri ();
reload_completed = 1;
update_inc_notes ();
inserted_p = fixup_abnormal_edges ();
/* We've possibly turned single trapping insn into multiple ones. */
if (cfun->can_throw_non_call_exceptions)
{
auto_sbitmap blocks (last_basic_block_for_fn (cfun));
bitmap_ones (blocks);
find_many_sub_basic_blocks (blocks);
}
if (inserted_p)
commit_edge_insertions ();
/* Replacing pseudos with their memory equivalents might have
created shared rtx. Subsequent passes would get confused
by this, so unshare everything here. */
unshare_all_rtl_again (get_insns ());
if (flag_checking)
check_rtl (true);
timevar_pop (TV_LRA);
}
コメント†