*参照元 [#oefa532f] #backlinks *説明 [#vcf5a90b] -パス: [[gcc-8.3/gcc/]] -パス: [[gcc-8.3/gcc/ira.c]] -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]