![](https://hackmd.io/_uploads/H1_dikA_n.png)
在gcc 可以下
```bash=
-fdump-rtl-all-all
```
得到gcc 執行rtl pass的優化結果,其中目前我的平台是 x86
那唯一看到rtl tree有真正執行 並且變化的 pass有三個
```
combine
reload
cprop_hardreg
```
這是在pass中所呈現的rtl tree
```rtl=
(insn 31 30 32 5 (set (reg:DF 89 [ _8 ])
(mem/u:DF (plus:DI (mult:DI (reg:DI 105)
(const_int 8 [0x8]))
(symbol_ref:DI ("altitudeTable") [flags 0x2] <var_decl 0x7f096528e120 altitudeTable>)) [1 altitudeTableD.3397[_7]+0 S8 A64])) "test.c":23:96 135 {*movdf_internal}
(nil))
(insn 32 31 33 5 (set (reg:SI 107)
(mem/c:SI (plus:DI (reg/f:DI 19 frame)
(const_int -4 [0xfffffffffffffffc])) [2 iD.3409+0 S4 A32])) "test.c":23:119 75 {*movsi_internal}
(nil))
(insn 33 32 34 5 (set (reg:DI 106)
(sign_extend:DI (reg:SI 107))) "test.c":23:119 147 {*extendsidi2_rex64}
(nil))
(insn 34 33 35 5 (set (reg:DF 90 [ _9 ])
(mem/u:DF (plus:DI (mult:DI (reg:DI 106)
(const_int 8 [0x8]))
(symbol_ref:DI ("altitudeTable") [flags 0x2] <var_decl 0x7f096528e120 altitudeTable>)) [1 altitudeTableD.3397[i_15]+0 S8 A64])) "test.c":23:119 135 {*movdf_internal}
(nil))
```
為了找出可以間接合成的指令,來寫一個pass
改良以前寫的修改gcc unroll pass的部分
```c
int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
{
if (!plugin_default_version_check(version, &gcc_version))
{
printf("incompatible gcc/plugin versions\n");
return 1;
}
fprintf(stderr, "%s %s %s\n", plugin_info->full_name, version->basever, version->devphase);
detect_passinfo.pass = make_pass_detect(g);
detect_passinfo.reference_pass_name = "combine";
detect_passinfo.ref_pass_instance_number = 0;
detect_passinfo.pos_op = PASS_POS_INSERT_AFTER;
inline_passinfo.pass=make_pass_detect2(g);
inline_passinfo.reference_pass_name="combine";
inline_passinfo.ref_pass_instance_number=0;
inline_passinfo.pos_op=PASS_POS_INSERT_BEFORE;
register_callback("static_analyzer", PLUGIN_PASS_MANAGER_SETUP, NULL, &detect_passinfo);
register_callback("exinline", PLUGIN_PASS_MANAGER_SETUP, NULL, &inline_passinfo);
return 0;
}
```
簡單的插入這個plugin 在 gcc 裡面,觀察pass前後rtl tree的變化,
根據function -> basic block -> rtx
```c=
fprintf(stderr, "\n===============Print ALL RTL IR BEFORE=================\n");
FOR_EACH_FUNCTION(node)
{
name = get_name(cfun->decl);
if (name != NULL)
{
fprintf(stderr, "=======Mapping node_fun:%s=========\n", name);
}
….
calculate_dominance_info(CDI_DOMINATORS);
int count = 0;
FOR_EACH_BB_FN(bb, cfun)
{
rtx_insn *insn;
FOR_BB_INSNS(bb, insn)
if (NONDEBUG_INSN_P(insn))
{
rtx body = PATTERN(insn);
int code = INSN_CODE(insn);
fprintf(stderr, "\nbb index %d,rtl inst count %d\n", bb->index, count);
debug(insn);
expanded_location xloc = insn_location(insn);
fprintf(stderr, "source code : %s:%i\n", xloc.file, xloc.line);
count++;
}
}
pop_cfun();
}
fprintf(stderr, "\n===============Print ALL RTL IR BEFORE=================\n");
```
這是處理完的數據格式
```log!
=======Mapping node_fun:main=========
bb index 2,rtl inst count 0
(insn 8 7 9 2 (set (reg:DI 5 di)
(symbol_ref/f:DI ("*.LC0") [flags 0x2] <var_decl 0x7febd94a02d0 *.LC0>)) "test.c":65:5 74 {*movdi_internal}
(nil))
source code : test.c:65
Opcode number of insn: 74
Opcode of insn: *movdi_internal
===== of insn: *cmpqi_1
bb index 2,rtl inst count 1
(insn 9 8 10 2 (set (reg:QI 0 ax)
(const_int 0 [0])) "test.c":65:5 77 {*movqi_internal}
(nil))
source code : test.c:65
Opcode number of insn: 77
Opcode of insn: *movqi_internal
===== of insn: *cmpqi_1
```
基本上已經是比較可讀的狀況,到這邊再觀察rtl的tree就可讀,如果需要找那些pattern可以根據這些訊息來建立一個table