【编译原理笔记19】代码优化: 支配结点和回边,自然循环及其识别,删除全局公共子表达式和复制语句,代码移动,作用于归纳变量的强度削弱,归纳变量的删除
本次笔记内容:
8-10 支配结点和回边
8-11 自然循环及其识别
8-12 删除全局工工资表达式和赋值语句
8-13 代码移动
8-14 作用于归纳变量的强度削弱
8-15 归纳变量的删除
本节课幻灯片,见于我的 GitHub 仓库:第19讲 代码优化_4.pdf
文章目录
- 支配结点和回边
- 支配结点(Dominators)
- 例
- 寻找支配结点
- 计算支配结点的迭代算法
- 例
- 回边(Back Edges)
- 自然循环及其识别
- 自然循环(Natural Loops)
- 自然循环的识别
- 算法:构造一条回边的自然循环
- 删除全局公共子表达式和复制语句
- 删除全局公共子表达式
- 全局公共子表达式删除算法
- 删除复制语句
- 删除复制语句的算法
- 代码移动
- 循环不变计算检测算法
- 代码外提
- 循环不变计算语句s : x = y + z 移动的条件
- 代码移动算法
- 例
- 作用于归纳变量的强度削弱
- 归纳变量检测算法
- 作用于归纳变量的强度削弱算法
- 归纳变量的删除
- 归纳变量的删除
- 删除仅用于测试的归纳变量
支配结点和回边
支配结点(Dominators)
如果从流图的入口结点到结点 n 的每条路径
都经过结点 d ,则称结点 d 支配
(dominate)结点 n ,记为d dom n
。
每个结点都支配它自己。
例
每个结点只支配它和它的后代结点。
直接支配结点(Immediate Dominator):
- 从入口结点到达n的所有路径上,结点n的
最后一个支配结点
称为直接支配结点
寻找支配结点
支配结点的数据流方程:
计算支配结点的迭代算法
- 输入:流图G,G的结点集是
N
,边集是E,入口结点是ENTRY - 输出:对于N中的各个结点n,给出D(n),即支配n的所有结点的集合
例
回边(Back Edges)
假定流图中存在两个结点d和n满足d dom n。如果存在从结点n到d的有向边n→d,那么这条边称为回边
。
自然循环及其识别
自然循环(Natural Loops)
自然循环是一种适合于优化的循环。
从程序分析的角度来看,循环在代码中以什么形式出现
并不重要,重要的是它是否具有易于优化的性质
。
自然循环
是满足以下性质的循环:
- 有唯一的入口结点,称为
首结点
(header)。首结点支配循环中的所有结点
,否则,它就不会成为循环的唯一入口; - 循环中至少有一条
返回首结点的路径
,否则,控制就不可能从“循环”中直接回到循环头,也就无法构成循环。
之前说的“回边”,就是用于自然循环的识别。
自然循环的识别
给定一个回边n → d,该回边的自然循环
为:d,以及所有可以不经过d而到达n的结点
。d为该循环的首结点。
算法:构造一条回边的自然循环
- 输入:流图G和回边n → d
- 输出:由回边n → d的自然循环中的所有结点组成的集合
结点d在初始时刻已经在loop中,不会去考虑它的前驱。因此, 找出的都是不经过d而能到达n的结点。
自然循环的一个重要性质:
- 除非两个自然循环的首结点相同,否则,它们或者
互不相交
,或者一个完全包含
(嵌入)在另外一个里面。 - 例。
如果两个循环具有相同的首结点,那么很难说哪个是最内循环。此时把两个循环合并。
删除全局公共子表达式和复制语句
删除全局公共子表达式
可用表达式
的数据流问题可以帮助确定位于流图中p点的表达式是否为全局公共子表达式
。
全局公共子表达式删除算法
输入:带有可用表达式信息
的流图
输出:修正后的流图
方法:对于语句s:z = x op y
,如果x op y在s之前可用,那么执行如下步骤:
- ① 从s开始逆向搜索,但不穿过任何计算了x op y的块,找到所有离s最近的计算了x op y的语句
- ② 建立新的临时变量u
- ③ 把步骤①中找到的语句w = x op y用下列语句代替:
u = x op y
,w = u
- ④ 用
z = u
替代s
删除复制语句
对于复制语句
s: x=y,如果在x的所有
引用点都可以用对y的引用代替对x的引用(复制传播),那么可以删除复制语句x=y。
在x的引用点u用y代替x (复制传播)的条件:复制语句s: x=y在u点“可用”。
删除复制语句的算法
输入:流图G 、du链、各基本块B入口处的可用复制语句集合
输出:修改后的流图
方法:对于每个复制语句x=y,执行下列步骤:
- ① 根据du链找出该定值所能够到达的那些对x的引用
- ② 确定是否对于
每个
这样的引用,x=y都在IN[B]中(B是包含这个引用的基本块) ,并且B中该引用的前面没有x或者y的定值 - ③ 如果x=y满足第②步的条件,删除x=y ,且把步骤①中找到的对x的引用用y代替
代码移动
- 循环不变计算的检测
- 代码外提
循环不变计算检测算法
输入:循环L,每个三地址指令的ud链
输出: L的循环不变计算语句
方法:
- 将下面这样的语句标记为“不变”:语句的运算分量或者是
常数
,或者其所有定值点都在循环L外部
- 重复执行步骤(3),直到某次没有新的语句可标记为“不变”为止
- 将下面这样的语句标记为“不变”:先前没有被标记过,且所有运算分量或者是
常数
,或者其所有定值点都在循环L外部,或者只有一个到达定值,该定值是循环中已经被标记为“不变”的语句
代码外提
前置首结点(preheader):循环不变计算将被移至首结点之前,为此创建一个称为前置首结点
的新块
。前置首结点的唯一后继
是首结点
,并且原来从循环L外
到达L首结点
的边都改成进入前置首结点
。从循环L里面
到达首结点
的边不变。
循环不变计算语句s : x = y + z 移动的条件
(1)s所在的基本块是循环所有出口结点
(有后继结点在循环外的结点)的支配结点
(2) 循环中没有其它语句对x赋值
(3) 循环中对x的引用仅由s到达
代码移动算法
输入:循环L、ud链、支配结点信息
输出:修改后的循环
方法:
- 寻找
循环不变计算
- 对于步骤(1)中找到的每个循环不变计算,检查是否满足上面的
三个条件
- 按照循环不变计算找出的次序,把所找到的满足上述条件的循环不变计算外提到前置首结点中。如果循环不变计算有分量在循环中定值,只有将定值点外提后,该循环不变计算才可以外提
例
作用于归纳变量的强度削弱
对于一个变量x ,如果存在一个正的或负的常量c
,使得每次x被赋值时,它的值总是增加c
,则称x为归纳变量。
如果循环L中的变量i只有形如i =i+c
的定值(c是常量),则称i为循环L的基本归纳变量
。
如果j = c×i+d
,其中i是基本归纳变量
,c和d是常量,则j也是一个归纳变量,称j属于i族。
- 基本归纳变量i属于它自己的族。
每个归纳变量都关联一个三元组。如果j = c×i+d
,其中i是基本归纳变量,c和d是常量,则与j相关联的三元组是( i, c, d )
。
归纳变量检测算法
输入:带有循环不变计算
信息和到达定值
信息的循环L
输出:一组归纳变量
方法:
- 扫描L的语句,找出所有
基本归纳变量
。在此要用到循环不变计算
信息。与每个基本归纳变量i相关联的三元组是(i, 1, 0) - 寻
找L中只有一次定值
的变量k,它具有下面的形式。
k=c′×j+d′。其中c′和d′是常量,j是基本的
或非基本的
归纳变量:
- 如果j
是基本归纳变量
,那么k属于j族。k对应的三元组可以通过其定值语句确定 - 如果j
不是基本归纳变量
,假设其属于i族, k的三元组可以通过j的三元组
和k的定值语句
来计算,此时我们还要求:- 循环L中对j的唯一定值和对k的定值之间
没有对i的定值
- 循环L外没有j的定值可以到达k
- (这两个条件是为了保证对k进行赋值的时候,j当时的值一定等于c*(i当时的值)+d)
- 循环L中对j的唯一定值和对k的定值之间
作用于归纳变量的强度削弱算法
输入:带有到达定值信息
和已计算出的归纳变量族
的循环L
输出:修改后的循环
方法:对于每个基本归纳变量i,对其族中的每个归纳变量j:(i, c, d)
:
执行下列步骤
- 建立新的临时变量t。如果变量j1和j2具有相同的三元组,则只为它们建立一个新变量
- 用j=t代替对j的赋值
- 在L中紧跟定值i=i+n之后,添加t=t+c*n。将t放入i族,其三元组为(i, c, d)
- 在前置节点的末尾,添加语句t=c*i和t=t+d ,使得在循环开始的时候t=c*i+d=j
如上,将乘法运算转换为加减法运算,从而实现了强度削弱。
归纳变量的删除
对于在强度削弱算法中引入的复制语句j=t
,如果在归纳变量j的所有引用点都可以用对t的引用代替对j的引用,并且j在循环的出口处不活跃,则可以删除复制语句j=t。
归纳变量的删除
对于在强度削弱算法中引入的复制语句j=t
,如果在归纳变量j的所有引用点都可以用对t的引用代替对j的引用,并且j在循环的出口处不活跃,则可以删除复制语句j=t。
强度削弱后,有些归纳变量的作用只是用于测试
。如果可以用对其它归纳变量的测试代替对这种归纳变量的测试,那么可以删除这种归纳变量。
删除仅用于测试的归纳变量
对于仅用于测试的基本归纳变量i,取i族的某个归纳变量j(尽量使得c、d简单,即c=1或d=0的情况)。把每个对i的测试替换成为对j的测试。
- ( relop i x B )替换为( relop j c*x+d B ),其中x
不是归纳变量
,并假设c>0; - ( relop i1 i2 B ),如果能够找到三元组j1 ( i1, c, d )和j2 ( i2, c, d ),那么可以将其替换为( relop j1 j2 B ) (假设c>0 )。否则,测试的替换可能是没有价值的。
如果归纳变量i不再被引用,那么可以删除和它相关的指令。
【编译原理笔记19】代码优化: 支配结点和回边,自然循环及其识别,删除全局公共子表达式和复制语句,代码移动,作用于归纳变量的强度削弱,归纳变量的删除相关推荐
- 【编译原理笔记18】代码优化:活跃变量分析,可用表达式分析
本次笔记内容: 8-8 活跃变量分析 8-9 可用表达式分析 本节课幻灯片,见于我的 GitHub 仓库:第18讲 代码优化_3.pdf 文章目录 活跃变量分析 活跃变量 例:各基本块的出口处的活跃变 ...
- 【编译原理笔记16】代码优化:流图,常用代码优化方法, 基本块的优化
本次笔记内容: 8-1 流图 8-2 常用代码优化方法一 8-3 常用代码优化方案二 8-4 基本快的优化 本节课幻灯片,见于我的 GitHub 仓库:第16讲 代码优化_1.pdf 文章目录 流图 ...
- 了解编译原理-笔记小结
这是之前学习编译原理过程中做下的笔记. 因能力有限,在很多地方都理解不到位,特别是对于词法分析与语法分析的过程感觉特别晦涩. 分享这个笔记也是为了自己做个总结,算是一个小的提纲吧,都没怎么深入解析编译 ...
- 【编译原理】中间代码优化(三) 循环优化
文章目录 循环优化概述. 计算必经节点集. 循环查找算法. 1.查找回边. 2.查找循环. 代码外提. 强度削弱. 删除归纳变量. 循环优化概述. 什么叫做循环?循环就是程序中那些可能反复执行的代码序 ...
- 【编译原理】中间代码优化(二) 局部优化
预备知识简述. 对于一个给定的程序,我们可以把它划分为一系列的基本块.在各个基本块范围内,分别进行优化.局限于基本块范围内的优化称为基本块内的优化,或者称为局部优化. 所谓基本块,是指程序中一个顺序执 ...
- 编译原理笔记(二)之词法分析
编译原理笔记(二)之词法分析 1. 词法分析中的若干问题 1.1 基本概念 1.2 记号的属性 1.3 词法分析器的作用与工作方式 1.4 输入缓冲区 2. 模式的形式化描述 2.1 字符串与语言 2 ...
- zucc 编译原理 笔记
zucc 编译原理 笔记 lec02 lec03 lec04
- 【编译原理】中间代码优化(一) 优化技术大观
代码优化概述. 通过对程序进行等价变换,使得从变换后的程序出发,能够生成更加有效的目标代码,这种变换我们叫做优化. 优化其实可以在编译的各个阶段进行,但最主要的一类优化是在目标代码生成以前,对语法分析 ...
- 【编译原理笔记01】什么是编译,编译系统各结构作用
资源Bilibili AV17649289 编译原理 哈尔滨工业大学 陈鄞 本次笔记内容: 1-1 什么是编译 1-2 编译系统的结构 1-3 词法分析 1-4 语法分析概述 1-5 语义分析概述 1 ...
最新文章
- Auto-Machine-Learning初探
- ACM MM:一种基于情感脑电信号时-频-空特征的3D密集连接网络
- python做方差分析和卡方检验
- python用编程软件_Python编程工具pycharm的使用
- 理解 pkg-config 工具
- 洛谷 P1027 Car的旅行路线
- 冷热分离和直接使用大数据库_基于 MySQL 的热数据与冷数据分离设计与实现
- 跨平台(Android, iOS, WP, HTML5)游戏开发libGDX学习教程
- 蓝桥杯2017初赛-正则问题
- Apache-DBUtils实现CRUD操作,已封装的API实现jdbc对数据库进行操作
- electron 入坑记
- Flask make_response(*args)
- SAP License:BW/BCS(BO)难在那里--SAP中的公司和会计凭证
- linux的环境变量相关的小记
- OpenStack是吞噬金钱和人力的怪兽吗?
- 基于Matlab绘制演化博弈主体的演化轨迹
- uni-app设置屏幕亮度
- centos7.6 挂载硬盘
- 电影《检察风云》投资价值简单分析
- 为你的App瘦身,优化你的App
热门文章
- main()如果返回0,则代表程序正常退出,返回非零代表程序异常退出。
- Ubuntu14.04 搜索不到WIFI或连接不上的解决方法。
- 解决bootstrap模态框居中问题
- QT学习之解决QT中QIcon图标不显示的问题
- Mysql 时间格式默认空串 ‘0000-00-00 00:00:00‘ select抛出异常的解决方法
- 问题 : lang.NoClassDefFoundError: org/springframework/core/annotation/AnnotatedElementUtils,的解决方法
- Python3.7 Scrapy crawl 运行出错解决方法
- 写入Visual Studio的输出窗口
- css 设置表格右边有图片_我写CSS常用的方法
- win11间歇性卡顿怎么办 windows11间歇性卡顿的解决方法