- 追加された行はこの色です。
- 削除された行はこの色です。
*参照元 [#oefa532f]
#backlinks
*説明 [#vcf5a90b]
-パス: [[gcc-8.3/gcc/]]
-FIXME: これは何?
--説明
**引数 [#ucd24358]
-FILE *f
--
**返り値 [#k01672a1]
-なし
**参考 [#wf0cea2d]
*実装 [#f3c8b080]
/* This is the main entry of IRA. */
static void
ira (FILE *f)
{
bool loops_p;
int ira_max_point_before_emit;
bool saved_flag_caller_saves = flag_caller_saves;
enum ira_region saved_flag_ira_region = flag_ira_region;
clear_bb_flags ();
-
--[[gcc-8.3/gcc/ira_region]]
--[[gcc-8.3/gcc/clear_bb_flags()]]
/* Determine if the current function is a leaf before running IRA
since this can impact optimizations done by the prologue and
epilogue thus changing register elimination offsets.
Other target callbacks may use crtl->is_leaf too, including
SHRINK_WRAPPING_ENABLED, so initialize as early as possible. */
crtl->is_leaf = leaf_function_p ();
-
--[[gcc-8.3/gcc/leaf_function_p()]]
/* Perform target specific PIC register initialization. */
targetm.init_pic_reg ();
ira_conflicts_p = optimize > 0;
/* If there are too many pseudos and/or basic blocks (e.g. 10K
pseudos and 10K blocks or 100K pseudos and 1K blocks), we will
use simplified and faster algorithms in LRA. */
lra_simple_p
= (ira_use_lra_p
&& max_reg_num () >= (1 << 26) / last_basic_block_for_fn (cfun));
if (lra_simple_p)
{
/* It permits to skip live range splitting in LRA. */
flag_caller_saves = false;
/* There is no sense to do regional allocation when we use
simplified LRA. */
flag_ira_region = IRA_REGION_ONE;
ira_conflicts_p = false;
}
-
--[[gcc-8.3/gcc/max_reg_num()]]
--[[gcc-8.3/gcc/last_basic_block_for_fn()]]
#ifndef IRA_NO_OBSTACK
gcc_obstack_init (&ira_obstack);
#endif
bitmap_obstack_initialize (&ira_bitmap_obstack);
-
--[[gcc-8.3/gcc/gcc_obstack_init()]]
--[[gcc-8.3/gcc/bitmap_obstack_initialize()]]
/* LRA uses its own infrastructure to handle caller save registers. */
if (flag_caller_saves && !ira_use_lra_p)
init_caller_save ();
-
--[[gcc-8.3/gcc/init_caller_save()]]
if (flag_ira_verbose < 10)
{
internal_flag_ira_verbose = flag_ira_verbose;
ira_dump_file = f;
}
else
{
internal_flag_ira_verbose = flag_ira_verbose - 10;
ira_dump_file = stderr;
}
setup_prohibited_mode_move_regs ();
decrease_live_ranges_number ();
df_note_add_problem ();
-
--[[gcc-8.3/gcc/setup_prohibited_mode_move_regs()]]
--[[gcc-8.3/gcc/decrease_live_ranges_number()]]
--[[gcc-8.3/gcc/df_note_add_problem()]]
/* DF_LIVE can't be used in the register allocator, too many other
parts of the compiler depend on using the "classic" liveness
interpretation of the DF_LR problem. See PR38711.
Remove the problem, so that we don't spend time updating it in
any of the df_analyze() calls during IRA/LRA. */
if (optimize > 1)
df_remove_problem (df_live);
gcc_checking_assert (df_live == NULL);
-
--[[gcc-8.3/gcc/df_remove_problem()]]
--[[gcc-8.3/gcc/gcc_checking_assert()]]
if (flag_checking)
df->changeable_flags |= DF_VERIFY_SCHEDULED;
df_analyze ();
-
--[[gcc-8.3/gcc/df_analyze()]]
init_reg_equiv ();
if (ira_conflicts_p)
{
calculate_dominance_info (CDI_DOMINATORS);
if (split_live_ranges_for_shrink_wrap ())
df_analyze ();
free_dominance_info (CDI_DOMINATORS);
}
-
--[[gcc-8.3/gcc/init_reg_equiv()]]
df_clear_flags (DF_NO_INSN_RESCAN);
indirect_jump_optimize ();
if (delete_trivially_dead_insns (get_insns (), max_reg_num ()))
df_analyze ();
regstat_init_n_sets_and_refs ();
regstat_compute_ri ();
-
--[[gcc-8.3/gcc/df_clear_flags()]]
--[[gcc-8.3/gcc/indirect_jump_optimize()]]
--[[gcc-8.3/gcc/delete_trivially_dead_insns()]]
--[[gcc-8.3/gcc/get_insns()]]
--[[gcc-8.3/gcc/max_reg_num()]]
--[[gcc-8.3/gcc/df_analyze()]]
--[[gcc-8.3/gcc/regstat_init_n_sets_and_refs()]]
--[[gcc-8.3/gcc/regstat_compute_ri()]]
/* If we are not optimizing, then this is the only place before
register allocation where dataflow is done. And that is needed
to generate these warnings. */
if (warn_clobbered)
generate_setjmp_warnings ();
if (resize_reg_info () && flag_ira_loop_pressure)
ira_set_pseudo_classes (true, ira_dump_file);
-
--[[gcc-8.3/gcc/generate_setjmp_warnings()]]
--[[gcc-8.3/gcc/resize_reg_info()]]
--[[gcc-8.3/gcc/ira_set_pseudo_classes()]]
init_alias_analysis ();
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
reg_equiv = XCNEWVEC (struct equivalence, max_reg_num ());
update_equiv_regs ();
-
--[[gcc-8.3/gcc/init_alias_analysis()]]
--[[gcc-8.3/gcc/loop_optimizer_init()]]
--[[gcc-8.3/gcc/XCNEWVEC()]]
--[[gcc-8.3/gcc/max_reg_num()]]
--[[gcc-8.3/gcc/update_equiv_regs()]]
/* Don't move insns if live range shrinkage or register
pressure-sensitive scheduling were done because it will not
improve allocation but likely worsen insn scheduling. */
if (optimize
&& !flag_live_range_shrinkage
&& !(flag_sched_pressure && flag_schedule_insns))
combine_and_move_insns ();
-
--[[gcc-8.3/gcc/combine_and_move_insns()]]
/* Gather additional equivalences with memory. */
if (optimize)
add_store_equivs ();
-
--[[gcc-8.3/gcc/add_store_equivs()]]
loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
end_alias_analysis ();
free (reg_equiv);
setup_reg_equiv ();
grow_reg_equivs ();
setup_reg_equiv_init ();
allocated_reg_info_size = max_reg_num ();
-
--[[gcc-8.3/gcc/loop_optimizer_finalize()]]
--[[gcc-8.3/gcc/free_dominance_info()]]
--[[gcc-8.3/gcc/end_alias_analysis()]]
--[[gcc-8.3/gcc/setup_reg_equiv()]]
--[[gcc-8.3/gcc/grow_reg_equivs()]]
--[[gcc-8.3/gcc/setup_reg_equiv_init()]]
--[[gcc-8.3/gcc/max_reg_num()]]
/* It is not worth to do such improvement when we use a simple
allocation because of -O0 usage or because the function is too
big. */
if (ira_conflicts_p)
find_moveable_pseudos ();
-
--[[gcc-8.3/gcc/find_moveable_pseudos()]]
max_regno_before_ira = max_reg_num ();
ira_setup_eliminable_regset ();
-
--[[gcc-8.3/gcc/max_reg_num()]]
--[[gcc-8.3/gcc/ira_setup_eliminable_regset()]]
ira_overall_cost = ira_reg_cost = ira_mem_cost = 0;
ira_load_cost = ira_store_cost = ira_shuffle_cost = 0;
ira_move_loops_num = ira_additional_jumps_num = 0;
ira_assert (current_loops == NULL);
if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED)
loop_optimizer_init (AVOID_CFG_MODIFICATIONS | LOOPS_HAVE_RECORDED_EXITS);
-
--[[gcc-8.3/gcc/loop_optimizer_init()]]
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
fprintf (ira_dump_file, "Building IRA IR\n");
loops_p = ira_build ();
ira_assert (ira_conflicts_p || !loops_p);
-
--[[gcc-8.3/gcc/ira_build()]]
--[[gcc-8.3/gcc/ira_assert()]]
saved_flag_ira_share_spill_slots = flag_ira_share_spill_slots;
if (too_high_register_pressure_p () || cfun->calls_setjmp)
/* It is just wasting compiler's time to pack spilled pseudos into
stack slots in this case -- prohibit it. We also do this if
there is setjmp call because a variable not modified between
setjmp and longjmp the compiler is required to preserve its
value and sharing slots does not guarantee it. */
flag_ira_share_spill_slots = FALSE;
ira_color ();
ira_max_point_before_emit = ira_max_point;
ira_initiate_emit_data ();
ira_emit (loops_p);
-
--[[gcc-8.3/gcc/too_high_register_pressure_p()]]
--[[gcc-8.3/gcc/ira_color()]]
--[[gcc-8.3/gcc/ira_initiate_emit_data()]]
--[[gcc-8.3/gcc/ira_emit()]]
max_regno = max_reg_num ();
if (ira_conflicts_p)
{
if (! loops_p)
{
if (! ira_use_lra_p)
ira_initiate_assign ();
}
-
--[[gcc-8.3/gcc/max_reg_num()]]
--[[gcc-8.3/gcc/ira\initiate_assign()]]
else
{
expand_reg_info ();
if (ira_use_lra_p)
{
ira_allocno_t a;
ira_allocno_iterator ai;
FOR_EACH_ALLOCNO (a, ai)
{
int old_regno = ALLOCNO_REGNO (a);
int new_regno = REGNO (ALLOCNO_EMIT_DATA (a)->reg);
ALLOCNO_REGNO (a) = new_regno;
if (old_regno != new_regno)
setup_reg_classes (new_regno, reg_preferred_class (old_regno),
reg_alternate_class (old_regno),
reg_allocno_class (old_regno));
}
}
-
--[[gcc-8.3/gcc/ira_allocno_t]]
--[[gcc-8.3/gcc/ira_allocno_iterator]]
--[[gcc-8.3/gcc/FOR_EACH_ALLOC_NO()]]
else
{
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
fprintf (ira_dump_file, "Flattening IR\n");
ira_flattening (max_regno_before_ira, ira_max_point_before_emit);
}
-
--[[gcc-8.3/gcc/ira_flattening()]]
/* New insns were generated: add notes and recalculate live
info. */
df_analyze ();
/* ??? Rebuild the loop tree, but why? Does the loop tree
change if new insns were generated? Can that be handled
by updating the loop tree incrementally? */
loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
loop_optimizer_init (AVOID_CFG_MODIFICATIONS
| LOOPS_HAVE_RECORDED_EXITS);
-
--[[gcc-8.3/gcc/df_analyze()]]
--[[gcc-8.3/gcc/loop_optimizer_finalize()]]
--[[gcc-8.3/gcc/free_dominance_info()]]
--[[gcc-8.3/gcc/loop_optimizer_init()]]
if (! ira_use_lra_p)
{
setup_allocno_assignment_flags ();
ira_initiate_assign ();
ira_reassign_conflict_allocnos (max_regno);
}
}
}
-
--[[gcc-8.3/gcc/setup_allocno_assignment_flags()]]
--[[gcc-8.3/gcc/ira_initiate_assign()]]
--[[gcc-8.3/gcc/ira_reassign_conflict_allocnos()]]
ira_finish_emit_data ();
setup_reg_renumber ();
calculate_allocation_cost ();
-
--[[gcc-8.3/gcc/ira_finish_emit_data()]]
--[[gcc-8.3/gcc/setup_reg_renumber()]]
--[[gcc-8.3/gcc/calculate_allocation_cost()]]
#ifdef ENABLE_IRA_CHECKING
if (ira_conflicts_p && ! ira_use_lra_p)
/* Opposite to reload pass, LRA does not use any conflict info
from IRA. We don't rebuild conflict info for LRA (through
ira_flattening call) and can not use the check here. We could
rebuild this info for LRA in the check mode but there is a risk
that code generated with the check and without it will be a bit
different. Calling ira_flattening in any mode would be a
wasting CPU time. So do not check the allocation for LRA. */
check_allocation ();
#endif
-
--[[gcc-8.3/gcc/check_allocation()]]
if (max_regno != max_regno_before_ira)
{
regstat_free_n_sets_and_refs ();
regstat_free_ri ();
regstat_init_n_sets_and_refs ();
regstat_compute_ri ();
}
-
--[[gcc-8.3/gcc/regstat_free_n_sets_and_refs()]]
--[[gcc-8.3/gcc/regstat_free_ri()]]
--[[gcc-8.3/gcc/regstat_compute_ri()]]
overall_cost_before = ira_overall_cost;
if (! ira_conflicts_p)
grow_reg_equivs ();
else
{
fix_reg_equiv_init ();
#ifdef ENABLE_IRA_CHECKING
print_redundant_copies ();
#endif
if (! ira_use_lra_p)
{
ira_spilled_reg_stack_slots_num = 0;
ira_spilled_reg_stack_slots
= ((struct ira_spilled_reg_stack_slot *)
ira_allocate (max_regno
* sizeof (struct ira_spilled_reg_stack_slot)));
memset (ira_spilled_reg_stack_slots, 0,
max_regno * sizeof (struct ira_spilled_reg_stack_slot));
}
}
allocate_initial_values ();
-
--[[gcc-8.3/gcc/grow_reg_equivs()]]
--[[gcc-8.3/gcc/fix_reg_equiv_init()]]
--[[gcc-8.3/gcc/print_redundant_copies()]]
--[[gcc-8.3/gcc/ira_spilled_reg_stack_slot]]
--[[gcc-8.3/gcc/ira_allocate()]]
--[[gcc-8.3/gcc/allocate_initial_values()]]
/* See comment for find_moveable_pseudos call. */
if (ira_conflicts_p)
move_unallocated_pseudos ();
-
--[[gcc-8.3/gcc/move_unallocated_pseudos()]]
/* Restore original values. */
if (lra_simple_p)
{
flag_caller_saves = saved_flag_caller_saves;
flag_ira_region = saved_flag_ira_region;
}
}
*コメント [#g739a617]