Peephole 优化实做介绍

 C Complier 在嵌入上使用的时候,尽量都是CodeSize 最小,那么在这样的前提下,如何将code size 最小,这是一个编译器优化中比较常见的问题,但是同时如何保证程序的效率,这两者之中难免出现冲突,存在这样的矛盾问题,首先你要了解目前你自己的C complier 编译出来的程序是要运行效率高,还是Codesize最小,这两者似乎没有办法协调。
     当然这篇文章主要在code size 优化上,而且接着前一篇继续说明peephole内部的算法如何。
1.首先使用Visual parser 将自己ASM code,进行解析,或者自己写解析器,收集每一行指令的信息,将其放入一个表中,表中的每一行都是一条ASM 指令的信息(Instrution table)。
2.合并基本块(Basic block)
   因为c complier产生的ASM code 中间经常要产生一些没有实际作用的label, 其实这些label是Debugger 等其他组件使用的,但不会影响程序的执行流程。因此我们要将这些没有实际作用的label,剔除掉,因为peephole 所聚焦的是一个basic block.
    Basic Block : 是指在局部范围内,程序的片断只有一个入口和一个出口,这样的代码片断就构成一个基本块。
     首先程序中有很多的label, 这些label 之间可能是basic block, 也可能不是,当是一个basic block 的时候,还要看能不能和周围的basic block 构成一个更大basic block.
  
     basic block 的划分:block 开始:程序的入口,跳转指令后的地址,call 指令的地址。
                                  block 结束:程序结束,Call 指令,Jmp 指令(包含直接跳转和间接跳转)

3. 在使用特定的算法对表中每一行进行处理,将处理的结果放到另一个表中(Erase table),这个表中可能记录了你当前要进行的删除或者更改的指令,表中的每一个数据项要包含什么信息,就要根据CComplier产生的ASM来确定了。
4. 根据Erase table 产生出最终的指令代码。

例如:



那么如何将这些PUSH 和Pop 指令删除掉, 当然使用什么算法因个人自己而定,这里我使用的是状态机,如下图:

图中红色的部分就是可以删除的PUSH POP 指令,因此使用上面的规则,那么刚才的代码就可以变成如下的样子:

这篇文章就这样了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章