一种很局部的优化方式,编译器仅仅在一个基本块或者多个基本块中,针对已经生成的代码,结合CPU自己指令的特点,
过一些认为可能带来性能提升的转换规则,或者通过整体的分析,通过指令转换,提升代码性能。
这个窥孔,你可以认为是一个滑动窗口,编译器在实施窥孔优化时,就仅仅分析这个窗口内的指令。
每次转换之后,可能还会暴露相邻窗口之间的某些优化机会,所以可以多次调用窥孔优化,尽可能提升性能
1) 优化对象既可以是中间代码级,也可以是目标代码级。
2)每次处理的只是一组相邻指令,相当于将一 组相邻指令暴露在一个优化窗口中(正如“窥孔”的含义)。
3)对优化对象进行线性扫描。
4)优化后产生的结果可能 会给后面的代码提供进一步优化的机会。
5)窥孔优化程序通常很小,只需很少的内存,执行速度很快。
比如冗余的load和store指令以及死代码(不会执行的代码)
中间代码生成阶段,很可能经常产生一些跳转到跳转指令,跳转到分支跳转、分支跳转到跳转之类的指令,都可以在窥孔优化中想办法解决掉,当然你也可以在中间代码中优化它们。
一些分支被删除后,可能还存在一些不会被到达的标号(label),也可以顺便删除之,这样就会提升基本块的大小,增加优化机会。
即利用代价较小的指令或操作替代代价较大的指令或操作,从而提升性能。
比如x=x+0, x=x*1之类的操作就能直接避免,x=x*2,x=x/2之类的操作可以使用左移或右移实现。
x^2之类的指数运算可以削弱为x*x的乘法运算,浮点数除以常数的运算可以转换为浮点数乘以常数的倒数。
CPU都会提供一些特殊指令完成特殊操作,比如DSP芯片中可能有复杂的数字信号处理指令,龙芯中有乘加指令以及一些向量扩展指令。
还有一些CPU可能提供自增、自减、取绝对值指令。这些都能在窥孔优化中生成。提升程序的运行性能
有些代码可能用于不会被执行到,这样在窥孔优化阶段,如果发现这样的代码,就可以直接删除。
典型的方式是优化双跳转,即第一条跳转指令的目的地址还是一条跳转指令时,可以删除后一条跳转指令,并修改第一条跳转指令的目标地址。
另外,对于不可能进入的分支也可以使用这种方式删除。