在all_passes链中,执行了pass_expand过程之后,GCC的中间表示就已经转换成RTL形式,此后的所有处理都是基于RTL的处理过程,即RTL_PASS。
所有的RTL处理都包含在pass_rest_of_compilation的处理过程以及子过程中,主要包含对pass_expand所生成的insn序列进行进一步的处理: 循环优化、指令调度、寄存器分配、窥孔优化
RTL的处理过程
基于RTL中间表示进行的处理过程主要包括以下的Pass:
NEXT_PASS (pass_rest_of_compilation);
{
struct opt_pass **p = &pass_rest_of_compilation.pass.sub;
NEXT_PASS (pass_init_function);
NEXT_PASS (pass_jump);
NEXT_PASS (pass_rtl_eh);
NEXT_PASS (pass_initial_value_sets);
NEXT_PASS (pass_unshare_all_rtl);
NEXT_PASS (pass_instantiate_virtual_regs);
NEXT_PASS (pass_into_cfg_layout_mode);
NEXT_PASS (pass_jump2);
NEXT_PASS (pass_lower_subreg);
NEXT_PASS (pass_df_initialize_opt);
NEXT_PASS (pass_cse);
NEXT_PASS (pass_rtl_fwprop);
NEXT_PASS (pass_gcse);
NEXT_PASS (pass_rtl_ifcvt);
/* Perform loop optimizations. It might be better to do them a bit
sooner, but we want the profile feedback to work more
efficiently. */
NEXT_PASS (pass_loop2);
{
struct opt_pass **p = &pass_loop2.pass.sub;
NEXT_PASS (pass_rtl_loop_init);
NEXT_PASS (pass_rtl_move_loop_invariants);
NEXT_PASS (pass_rtl_unswitch);
NEXT_PASS (pass_rtl_unroll_and_peel_loops);
NEXT_PASS (pass_rtl_doloop);
NEXT_PASS (pass_rtl_loop_done);
*p = NULL;
}
NEXT_PASS (pass_web);
NEXT_PASS (pass_jump_bypass);
NEXT_PASS (pass_cse2);
NEXT_PASS (pass_rtl_dse1);
NEXT_PASS (pass_rtl_fwprop_addr);
NEXT_PASS (pass_reginfo_init);
NEXT_PASS (pass_inc_dec);
NEXT_PASS (pass_initialize_regs);
NEXT_PASS (pass_outof_cfg_layout_mode);
NEXT_PASS (pass_ud_rtl_dce);
NEXT_PASS (pass_combine);
NEXT_PASS (pass_if_after_combine);
NEXT_PASS (pass_partition_blocks);
NEXT_PASS (pass_regmove);
NEXT_PASS (pass_split_all_insns);
NEXT_PASS (pass_lower_subreg2);
NEXT_PASS (pass_df_initialize_no_opt);
NEXT_PASS (pass_stack_ptr_mod);
NEXT_PASS (pass_mode_switching);
NEXT_PASS (pass_see);
NEXT_PASS (pass_match_asm_constraints);
NEXT_PASS (pass_sms);
NEXT_PASS (pass_sched);
NEXT_PASS (pass_subregs_of_mode_init);
NEXT_PASS (pass_ira);
NEXT_PASS (pass_subregs_of_mode_finish);
NEXT_PASS (pass_postreload);
{
struct opt_pass **p = &pass_postreload.pass.sub;
NEXT_PASS (pass_postreload_cse);
NEXT_PASS (pass_gcse2);
NEXT_PASS (pass_split_after_reload);
NEXT_PASS (pass_branch_target_load_optimize1);
NEXT_PASS (pass_thread_prologue_and_epilogue);
NEXT_PASS (pass_rtl_dse2);
NEXT_PASS (pass_rtl_seqabstr);
NEXT_PASS (pass_stack_adjustments);
NEXT_PASS (pass_peephole2);
NEXT_PASS (pass_if_after_reload);
NEXT_PASS (pass_regrename);
NEXT_PASS (pass_cprop_hardreg);
NEXT_PASS (pass_fast_rtl_dce);
NEXT_PASS (pass_reorder_blocks);
NEXT_PASS (pass_branch_target_load_optimize2);
NEXT_PASS (pass_leaf_regs);
NEXT_PASS (pass_split_before_sched2);
NEXT_PASS (pass_sched2);
NEXT_PASS (pass_stack_regs);
{
struct opt_pass **p = &pass_stack_regs.pass.sub;
NEXT_PASS (pass_split_before_regstack);
NEXT_PASS (pass_stack_regs_run);
}
NEXT_PASS (pass_compute_alignments);
NEXT_PASS (pass_duplicate_computed_gotos);
NEXT_PASS (pass_variable_tracking);
NEXT_PASS (pass_free_cfg);
NEXT_PASS (pass_machine_reorg);
NEXT_PASS (pass_cleanup_barriers);
NEXT_PASS (pass_delay_slots);
NEXT_PASS (pass_split_for_shorten_branches);
NEXT_PASS (pass_convert_to_eh_region_ranges);
NEXT_PASS (pass_shorten_branches);
NEXT_PASS (pass_set_nothrow_function_flags);
NEXT_PASS (pass_final);
}
NEXT_PASS (pass_df_finish);
}
NEXT_PASS (pass_clean_state);
*p = NULL;
特殊虚拟寄存器的实例化
指令调度
指令调度(Instruction Scheduling)就是对当前函数中的insn序列进行重新排序,从而更充分地利用目标机器的硬件资源,提高指令执行的效率。
指令调度主要考虑的因素包括数据相关(Data Dependency)、控制相关(Control Dependency)、结构相关(Structural Harzard)、指令延迟(Delay)或者指令代价(Cost)等,通常指令调度与目标机器中的流水线设置紧密相关。
主要因素介绍
数据相关
数据相关是指指令之间由于操作数的使用而引入的一些相关关系,这种关系决定了指令之间的执行顺序。
数据之间的关系主要包括以下几种形式:
(1)真相关
(2)反相关
(3)输出相关
真相关(True Dependence)
指令S2和S1真相关,表示指令S1在S2之前执行,并且S2需要S1的目的操作数,通常会被称为写后读(RAW,Read After Wrirte)
x = 10;
y = x + c;
S2的源操作数x是S1的目的操作数,此时称S2与S1真相关。