- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Part5-机器无关伮.amp;gt;-机器无关优化.ppt
编译原理 机器无关优化 授课:胡静 编译器的结构 1.3、保持语义不变的转换 编译器可以使用多种方法改进程序,并保持语义不变 公共子表达式消除 复制传播 死代码消除 常量折叠 如右图所示,在这个块内,对 4*i和4*j进行了重复计算,虽然这些计算不是程序员显式要求的。 5. 部分冗余消除 考虑如何尽可能的减少表达式求值的次数。也就是说我们希望考虑一个流图中所有可能的执行顺序并检查x+y这样的表达式被求值的次数。 通过移动各个对x+y求值的位置,并在必要时把求值结果保存在临时变量中,可以在很多执行路径中减少对这个表达式求值的次数,并保证不增加任何路径中的求值次数。 本节所讲技术符合如下原则:只有在绝对必要时才会进行一次计算。 在流图中寻找(一个或多个)位置来对各个表达式求值需要进行四种不同的数据流分析,因此本节中讲述的方法有助于我们理解数据流分析技术在编译器中所扮演的角色 5. 部分冗余消除 程序中的冗余可以以多种形式存在。 公共子表达式——对表达式的多次求值产生同样的结果 循环不变表达式——这个表达式在循环的每次迭代中都得到相同的值。 冗余也可以是部分性的——只能在部分路径而不是全部路径中找到冗余。(不是基本块中的局部性) 前两种情况可以看作是部分冗余的特例,因此可以设计一个部分冗余消除算法来消除不同种类的冗余。 5.1 冗余的来源 全局公共子表达式 在所有到达程序点p的路径中,表达式b+c已经被求值,并且在最后一次求值之后变量b和c没有被重新定值,那么可以认为这个表达式在该点上是完全冗余的。 如果在对b+c最后一次求值之后以及基本块B4之前对b或c有一个赋值运算,那么B4中的这个表达式就不是冗余的。 5.1冗余的来源 深层公共子表达式 当我们寻找公共子表达式时,只能找到字面上相同的公共子表达式,形如下面的片段可能没有办法处理: t1=b+c; a=t1+d和 t2=b+c; e=t2+d 寻找深层公共子表达式的方法就是重复使用公共子表达式的寻找算法,进行多次扫描。 5.1冗余的来源 循环不变表达式 我们可以把循环中的所有重复执行替换为循环外的单次计算,从而优化程序 这里需要注意一个问题:不应该执行任何在未优化时不执行的指令: 如果该指令会引发一个异常,那么执行此指令可能抛出一个原程序中本来不会发生的异常。 如果循环提早退出,“优化”过的程序需要的执行时间比原程序更多。 循环不变表达式 通常为了保证while循环中的循环不变表达式可以被优化,编译器通常把语句 while c { S; } 改成如下等价语句: if c { repeat S; until not c; } 各个循环不变表达式可以直接放置在repeat-until结构之前。 循环不变表达式 在公共子表达式消除中,一个冗余的表达式计算直接被丢弃。 循环不变表达式消除则不同,它要求把循环内的一个表达式移动到循环之外。——循环不变代码移动 循环不变代码移动可能需要重复进行 部分冗余表达式 部分冗余表达式的消除不能直接将冗余计算去掉,需要在不包含冗余的路径上加入计算临时值的指令,保证在进入下一步之前,公共子表达式的值已经计算,并放置在一个临时变量中。 5.2 可能消除所有的冗余吗 除非我们能够通过创建新的基本块来改变流图,否则不可能消除所有的冗余。 我们把所有从一个具有多个后继的结点到达另一个具有多个前驱的结点的边称为关键边。 通过在关键边上引入新的基本块,总是可以找到一个基本块作为放置表达式的适当位置。 5.2 可能消除所有的冗余吗 仅靠增加基本块可能不足以消除所有的冗余计算。 消除所有的冗余表达式可能会大大增加优化后代码的大小。因此,我们只允许引入新的基本块,不允许复制控制流图的任何部分。 5.3懒惰代码移动问题 我们期望使用部分冗余消除算法进行优化而得到的程序具有如下性质: 所有不复制代码就可以消除的表达式冗余计算都被消除掉了 优化后的程序不会执行原来的程序不执行的任何计算。 表达式的计算时刻应该尽量靠后。 尽量靠后的计算一个值可以尽可能的降低该值的生命周期,即从该值被定值的时刻到它最后被使用的时刻之间的时间间隔尽可能的短。 缩短生命期也就尽可能降低了它使用寄存器的时间。我们把以尽可能延迟计算为目标的部分冗余消除优化成为懒惰代码移动。 5.3懒惰代码移动问题 对于完全冗余和部分冗余的处理: 对于部分冗余,将其改造成完全冗余,而后按照完全冗余的方法处理。 完全冗余的性质:如果B中的表达式e是完全冗余的,令S是那些使得基本块B中的e变得冗余,并且包含表示e的基本块的集合。将所有从S中的某个基本块离开的边删除,那么基本块B必然和程序的入口点分离。 所有从S中的某个基本块离开的边必然形成一个割集。 5.4 表达式的预期执行 如果从程序点p出发的所有
文档评论(0)