*参照元 [#qb4d62d3] #backlinks *説明 [#m55cd702] -パス: [[gcc-8.3/gcc/lra.c]] -FIXME: これは何? --説明 **引数 [#pb6c7c67] -FILE *f -- **返り値 [#wfb24545] -なし -- **参考 [#e02d686b] *実装 [#jed3dd42] /* 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); - --[[gcc-8.3/gcc/timevar_push()]] /* 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 (); - --[[gcc-8.3/gcc/emit_note()]] --[[gcc-8.3/gcc/COPY_HARD_REG_SET()]] --[[gcc-8.3/gcc/init_reg_info()]] --[[gcc-8.3/gcc/expand_reg_info()]] --[[gcc-8.3/gcc/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 (); - --[[gcc-8.3/gcc/check_rtl()]] --[[gcc-8.3/gcc/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 (); - --[[gcc-8.3/gcc/max_reg_num()]] --[[gcc-8.3/gcc/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); - --[[gcc-8.3/gcc/has_nonexceptional_receiver()]] --[[gcc-8.3/gcc/LOCAL_REGNO()]] --[[gcc-8.3/gcc/df_set_regs_ever_live()]] /* 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); - --[[gcc-8.3/gcc/df_set_flags()]] --[[gcc-8.3/gcc/sbitmap_alloc()]] --[[gcc-8.3/gcc/get_max_uid()]] --[[gcc-8.3/gcc/bitmap_clear()]] --[[gcc-8.3/gcc/lra_live_ranges_init()]] --[[gcc-8.3/gcc/lra_constraints_init()]] --[[gcc-8.3/gcc/push_insns()]] --[[gcc-8.3/gcc/get_last_insn()]] /* 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 (); - --[[gcc-8.3/gcc/bitmap_initialize()]] --[[gcc-8.3/gcc/maybe_ne()]] --[[gcc-8.3/gcc/get_frame_size()]] --[[gcc-8.3/gcc/assign_stack_local()]] --[[gcc-8.3/gcc/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); - --[[gcc-8.3/gcc/lra_constraints()]] --[[gcc-8.3/gcc/lra_eliminate()]] /* 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; } - --[[gcc-8.3/gcc/bitmap_empty_p()]] /* 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 (); - --[[gcc-8.3/gcc/lra_clear_live_ranges()]] --[[gcc-8.3/gcc/lra_create_live_ranges()]] --[[gcc-8.3/gcc/lra_inheritance()]] 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); - --[[gcc-8.3/gcc/lra_create_live_ranges()]] --[[gcc-8.3/gcc/lra_assign()]] --[[gcc-8.3/gcc/lra_undo_inheritance()]] --[[gcc-8.3/gcc/lra_coalesce()]] --[[gcc-8.3/gcc/lra_split_hard_reg_for()]] } /* 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; } - --[[gcc-8.3/gcc/bitmap_clear()]] /* 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()] --[[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 (); - --[[gcc-8.3/gcc/lra_remat()]] --[[gcc-8.3/gcc/lra_need_for_spills_p()]] --[[gcc-8.3/gcc/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; } - --[[gcc-8.3/gcc/lra_eliminate()]] --[[gcc-8.3/gcc/max_reg_num()]] 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 (); - --[[gcc-8.3/gcc/resotre_scratches()]] --[[gcc-8.3/gcc/lra_eliminate()]] --[[gcc-8.3/gcc/lra_final_code_change()]] --[[gcc-8.3/gcc/lra_clear_live_ranges()]] --[[gcc-8.3/gcc/lra_live_ranges_finish()]] --[[gcc-8.3/gcc/lra_constraints_finish()]] --[[gcc-8.3/gcc/finish_reg_info()]] --[[gcc-8.3/gcc/sbitmap_free()]] --[[gcc-8.3/gcc/finish_insn_recog_data()]] --[[gcc-8.3/gcc/regstat_free_n_sets_and_refs()]] --[[gcc-8.3/gcc/regstat_free_ri()]] --[[gcc-8.3/gcc/update_inc_notes()]] /* 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 (); - --[[gcc-8.3/gcc/auto_sbitmap]] --[[gcc-8.3/gcc/last_basic_block_for_fn()]] --[[gcc-8.3/gcc/bitmap_ones()]] --[[gcc-8.3/gcc/find_many_sub_basic_blocks()]] --[[gcc-8.3/gcc/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); } - --[[gcc-8.3/gcc/unshare_all_rtl_again()]] --[[gcc-8.3/gcc/get_insns()]] --[[gcc-8.3/gcc/check_rtl()]] --[[gcc-8.3/gcc/timevar_pop()]] *コメント [#aa0bf522]