编译原理 中间代码表示

编译原理 中间代码表示_第1张图片

编译原理 中间代码表示_第2张图片

控制流图在程序分析,程序优化中有重要的作用

编译原理 中间代码表示_第3张图片

编译原理 中间代码表示_第4张图片

将抽象层次逐渐降低,有的优化只能在特定的中间表示上才行。

编译原理 中间代码表示_第5张图片

编译原理 中间代码表示_第6张图片

三地址码:

编译原理 中间代码表示_第7张图片

编译原理 中间代码表示_第8张图片

不绑定特定的指令集,是抽象的类型

每个三地址码只完成一条指令,没有复合的情况出现。

编译原理 中间代码表示_第9张图片

编译原理 中间代码表示_第10张图片

编译原理 中间代码表示_第11张图片

编译原理 中间代码表示_第12张图片

如何生成三地址码?

编译原理 中间代码表示_第13张图片

 

 

F*代表0个或者多个F,正则文法,X是函数,可以有多个参数

S 函数体:内部可以再调用函数

编译原理 中间代码表示_第14张图片

编译原理 中间代码表示_第15张图片

 

编译原理 中间代码表示_第16张图片

编译原理 中间代码表示_第17张图片

x1中存放E的值。

编译原理 中间代码表示_第18张图片

编译原理 中间代码表示_第19张图片

编译原理 中间代码表示_第20张图片

控制流图

编译原理 中间代码表示_第21张图片

编译原理 中间代码表示_第22张图片

 编译原理 中间代码表示_第23张图片

有多少个语句可以跳转到L2,实际上转化为了有向图中,L2的入度。

编译原理 中间代码表示_第24张图片 

编译原理 中间代码表示_第25张图片

 B就是block 基本块 名字,语句以及jump 跳转

 

F 函数 一个函数由多个基本块构成 入口块,出口块

编译原理 中间代码表示_第26张图片

控制流图包括了三地址码中的信息,并且增加了block,更加精细。

编译原理 中间代码表示_第27张图片

list 表明语句的链表

jump 地址跳转

编译原理 中间代码表示_第28张图片

three address code-> control flow graph

线性扫描算法 

scan_stm 对三地址码的所有语句进行扫描

编译原理 中间代码表示_第29张图片

遇到跳转语句,则当前块跳转到j,并生成新的block,否则归并到block中。时间复杂度为O(n)

编译原理 中间代码表示_第30张图片

拓扑序只对有向无环图有意义,近似拓扑序对图的要求没有那么高。

编译原理 中间代码表示_第31张图片

L3死块 从入口块,走不到L3,即从L0出发,遍历不可达。 

深度优先遍历所有的节点,并标记,未被标记的则为死块。

编译原理 中间代码表示_第32张图片

死块删除一般做在早期,方便后续处理。

数据流分析:

编译原理 中间代码表示_第33张图片

编译原理 中间代码表示_第34张图片

静态保守

编译原理 中间代码表示_第35张图片

到达定义分析

编译原理 中间代码表示_第36张图片

如x=y+y+1,那么虽然永远走不到L1,但是编译器是不知道的。

编译原理 中间代码表示_第37张图片

编译原理 中间代码表示_第38张图片

到达定义分析

定义和使用:

编译原理 中间代码表示_第39张图片

编译原理 中间代码表示_第40张图片 

即判断哪些对变量值进行的更改能够传递到当前语句

编译原理 中间代码表示_第41张图片

gen 产生集合 表示当前的语句给出了什么样的定义

kill 杀死集合 即被当前定义点杀死的集合编译原理 中间代码表示_第42张图片

编译原理 中间代码表示_第43张图片

编译原理 中间代码表示_第44张图片

常数传播优化,结合到达定义分析,会发现第一条语句的y=3,一直没有传递到5,6中。

编译原理 中间代码表示_第45张图片

这就是顺序对一个基本块中的所有语句进行分析。

 

编译原理 中间代码表示_第46张图片

编译原理 中间代码表示_第47张图片

不动点算法:

对于所有的基本块

在循环的计算过程中,只要有一个发生变化,就可能影响后面,因此要持续的对循环进行计算。

编译原理 中间代码表示_第48张图片

这是对每一句都进行分析,而不单单是block

编译原理 中间代码表示_第49张图片

不动点算法为什么会终止.....我感觉只要是静态的就一定会中止啊。

 

活性分析:

编译原理 中间代码表示_第50张图片

编译原理 中间代码表示_第51张图片

有交集的就不能共用一个寄存器了。

c=b+3,b和c可以共用一个寄存器r

编译原理 中间代码表示_第52张图片

变量在边上活跃:

编译原理 中间代码表示_第53张图片

return c 返回c是一定要在寄存器中的

编译原理 中间代码表示_第54张图片

编译原理 中间代码表示_第55张图片

编译原理 中间代码表示_第56张图片

编译原理 中间代码表示_第57张图片

从尾部向上推出活跃集合

编译原理 中间代码表示_第58张图片

观察每个活跃集合中的变量,即可明确需要几个寄存器。

in = 本块所使用的(依赖的)+(输出的-本块定义的)。后向!!!

编译原理 中间代码表示_第59张图片

每个语句都计算 in out两个集合,共n*2个集合

编译原理 中间代码表示_第60张图片

按照1,2,3,4,5,6的顺序进行计算

编译原理 中间代码表示_第61张图片

b黄色,与a红色不冲突,a恰好在内部没有使用寄存器的需要。

根据变量之间是否干扰,生成干扰图:

编译原理 中间代码表示_第62张图片

有边的变量相互冲突,不能共用一个寄存器,而a和b可以。

编译原理 中间代码表示_第63张图片

可以对图进行着色,即有几个寄存器就有几种色彩。

 

 

 

 

 

 

你可能感兴趣的:(编译原理)