相比条件跳转优化而言,连续跳转优化的实现稍复杂。不过,读者只要理解了先前的各种连续跳转情况及其优化策略,相信掌握其源代码实现是比较容易的。当然,Neo Pascal也只处理了前三种连续跳转的情况,并没有考虑第四种情况。下面,就来详细看看其源代码实现。
程序7-17 IRSimplify.cpp
第5行:LabelMap主要用于存储标号与其实际位置的映射。例如,Ll在标号信息表中的序号是6,而LABEL Ll语句在IR列表中的实际位置是8,那么,就用<6,8>来描述标号与其实际位置的映射关系。
第6行:bHasVisit主要用于标识一次连续跳转优化过程中所有已被访问的标号,以免一个标号被两次访问。这主要是为了防止在优化过程中处理环状跳转结构时出现死循环。设置bHasVisit集合就可以保证一个标号不会被第二次访问。
第7~12行:遍历IR序列,设置标号的映射关系。
第13行:遍历IR序列。
第15行:开始一次新的连续跳转优化之前,先清空bHasVisit集合。
第16行:获取当前IR。
第19行:获取处理方案。(www.daowen.com)
第23、24行:根据IR的跳转类型,获取标号的序号。在JMP跳转IR中,标号存储于m_Opl中。而在JNT、JT跳转IR中,标号存储于m_Rslt中。
第25行:检索连续跳转的终点标号。
第27行:根据LabelMap的映射,获取当前跳转IR的目的标号的位置。
第28~38行:从目的标号IR开始,逐一向后检索第一条非标号IR。在此过程中,将所有访问过的标号记录到bHasVisit集合中。如果检索直至IR列表表尾,则退出while循环。
第39、40行:如果检索到表尾或第一条非标号IR不是JMP,那么,本次连续跳转优化不必继续进行了,直接用新获取的标号替换原IR中的标号即可。
第42~47行:直接使用顺序检索过程中最后访问的标号替代原IR中的标号即可。
第50行:如果检索到的语句是JMP,那么,按该JMP语句的目的标号继续进行优化。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。