Professional Documents
Culture Documents
Hcm 编译原理 第10讲 源程序中间表示 20221006
Hcm 编译原理 第10讲 源程序中间表示 20221006
Compiler Techniques
胡春明
hucm@buaa.edu.cn
2022.8-2022.12
北京航空航天大学计算机学院、软件学院
编译过程
编译过程是指将高级语言程序翻译为等价的目标程
序的过程。
习惯上是将编译过程划分为5个基本阶段:
词法分析
语法分析
语义分析、生成中间代码
代码优化
生成目标程序
北京航空航天大学计算机学院 2
北京航空航天大学计算机学院
第七章 源程序的中间形式
• 波兰表示
• N-元表示
• 抽象机代码
北京航空航天大学计算机学院 3
中间表示 IR
北京航空航天大学计算机学院 4
回顾:编译器的前端、中端和后端
根据编译程序各部分功能,将编译程序分成前端和后端。
源语言1 源语言2 …….. 源语言K
分析(前端)
体系结构
中端 中间表示(IR) 无关优化
综合(后端) 体系结构
相关优化
北京航空航天大学计算机学院 5
中间表示:Intermediate Representation
广义上讲,编译的运行过程中任何形式的
中间表示都可以称为“IR”
一般编译程序都生成中间代码,然后再生成目
标代码,主要优点是可移植 (与具体目标程序无关),
且易于共性的、目标平台无关的代码优化
北京航空航天大学计算机学院 6
现代编译器设计实践:多层IR
LLVM IR Machine IR
层次较高 层次较低
保留更多 反映更多目标
程序语义 体系结构特点
不同层次的IR代表了不同层次的抽象(类型、操作)
通过分层抽象,实现最大限度的重用
北京航空航天大学计算机学院 7
现代编译器设计实践:多层IR
重用LLVM→ASM后端框架
面向特定任务
拓展更高层的IR LLVM IR Machine IR
层次较高 层次较低
更高层IR 保留更多 反映更多目标
体现更高层的抽象 程序语义 体系结构特点
(比如:类、张量)
北京航空航天大学计算机学院 8
现代编译器设计实践:多层IR
重用LLVM→ASM后端框架
面向特定任务
拓展更高层的IR
用于支撑更高层的领域相关语言
(Tensorflow是一个典型的例子)
北京航空航天大学计算机学院 9
波兰表示
北京航空航天大学计算机学院 10
7.1 波兰表示
有多种中间代码形式:
波兰表示 N-元组表示 抽象机代码
由波兰逻辑学家 J.Lukasiewicz 提出
波兰表示
• 前缀表示:<操作符><操作数序列>
• 后缀表示:<操作数序列><操作符>
前缀表达:(波兰表达) +35
后缀表达:(逆波兰表达) 35+
北京航空航天大学计算机学院 11
7.1 波兰表示
一般编译程序都生成中间代码,然后再生成目
标代码,主要优点是可移植(与具体目标程序无关),
且易于目标代码优化。有多种中间代码形式:
波兰表示 N-元组表示 抽象机代码
波兰表示
算术表达式: F*3.1416*R*(H+R)
转换成波兰表示: F3.1416*R*HR+*
赋值语句: A := F * 3.1416 * R * ( H + R )
波兰表示: AF3.1416 * R * HR + * :=
北京航空航天大学计算机学院 12
7.1 波兰表示
波兰表示 从语法树的角度看“波兰表示”
算术表达式: F*3.1416*R*(H+R)
前序遍历
* +
中序遍历
* R H R
后序遍历
F 3.1416
北京航空航天大学计算机学院 13
7.1 波兰表示
波兰表示 从语法树的角度看“波兰表示”
算术表达式: F*3.1416*R*(H+R)
* +
* R H R
北京航空航天大学计算机学院 14
7.1 波兰表示
波兰表示 从语法树的角度看“波兰表示”
:= 赋值语句: A := F * 3.1416 * R * ( H + R )
A *
前序遍历
* +
中序遍历
* R H R
后序遍历
F 3.1416
北京航空航天大学计算机学院 15
7.1 波兰表示
波兰表示 从语法树的角度看“波兰表示”
:= 赋值语句: A := F * 3.1416 * R * ( H + R )
A *
前序遍历
* +
中序遍历
* R H R
后序遍历
北京航空航天大学计算机学院 16
例: (A+B * C) / ( D*E – (F+G) / (H+I))
+ -
A * * /
B C D E + +
F G H I
前序遍历(根左右):/+A*BC-*DE/+FG+HI (波兰表达)
后序遍历(左右根):ABC*+DE*FG+HI+/-/ (逆波兰表达)
中序遍历(左根右):A+B*C/D*E-F+G/H+I
北京航空航天大学计算机学院 17
构造一个算法,生成“波兰表示”
#a+b# ab+
+
操作符栈
#
#优先级最低
算法:
设一个操作符栈;当读到操作数时,立即输出该操作数,
当扫描到操作符时,与栈顶操作符比较优先级,若栈顶操作
符优先级高于栈外,则输出该栈顶操作符,反之,则栈外操
作符入栈。
北京航空航天大学计算机学院 18
转换算法
波兰表示: F3.1416 * R * HR + *
北京航空航天大学计算机学院 19
if 语句的波兰表示
label1 label2
if 语句 :if <expr> then <stmt1> else <stmt2>
expr
<expr>?
bz :lable1
stmt1 stmt2 stmt1
:label1 br :lable1
stmt2
:label2
北京航空航天大学计算机学院 20
if 语句的波兰表示
label1 label2
if 语句 :if <expr> then <stmt1> else <stmt2>
波兰表示为 :<expr><label1>BZ<stmt1><label2>BR<stmt2>
北京航空航天大学计算机学院 21
波兰表示为 :<expr><label1>BZ<stmt1><label2>BR<stmt2>
由if语句的波兰表示可生成如下的目标程序框架:
<expr>
BZ label1
<stmt1>
BR label2
label1:<stmt2>
label2:
其他语言结构也很容易将其翻译成波兰表示,
使用波兰表示的问题:优化不是十分方便
北京航空航天大学计算机学院 22
波兰表达式 隐含了 “栈操作”
能否将波兰表达式拆成一组“原子操作”?
北京航空航天大学计算机学院 23
N元表示
北京航空航天大学计算机学院 24
7.2 N-元表示
在该表示中,每条指令由n个域组成,通常第一
个域表示操作符,其余为操作数。
表达式的三元式: w * x + ( y + z )
第三个三元
(1) *, w, x 式中的操作数(1)
(2) +, y, z (2)表示第(1)和第
(3) +, (1), (2) (2)条三元式的计
算结果。
北京航空航天大学计算机学院 25
条件语句的三元式:
if x > y then
z := x;
else z := y+1;
(1) -, x, y
(2) BMZ, (1), (5) 其中:
(3) :=, z, x BMZ:是二元操作符,测试第二
(4) BR, , (7) 个域的值,若≤0,则按
(5) +, y, 1 第3个域的地址转移,
(6) :=, z, (5) 若>0,则顺序执行。
(7) BR: 一元操作符,按第3个域
: 作无条件转移。
:
北京航空航天大学计算机学院 26
使用三元式不便于代码优化,因为优化要删除
一些三元式,或对某些三元式的位置要进行变更,由
于三元式的结果(表示为编号),可以是某个三元式的
操作数,随着三元式位置的变更也将作相应的修改,
很费事。
间接三元式:
为了便于在三元式上作优化处理,可使用间接三元式
三元式的执行次序用另一张表表示,这样在优化时,
三元式可以不变,而仅仅改变其执行顺序表。
北京航空航天大学计算机学院 27
例: A:=B+C*D/E
F:=C*D
用间接三元式表示为:
操作 三元式
1. (1) (1) * , C, D
2. (2) (2) / , (1), E
3. (3) (3) + , B, (2)
4. (4) (4) := , A, (3)
5. (1) (5) := , F, (1)
6. (5)
北京航空航天大学计算机学院 28
四元式表示
(三地址表示) 操作符 操作数1 操作数2 结果
(TAC)
结果:通常是由编译引入的临时变量,可由编译程序
分配一个寄存器或主存单元。
例: (A+ B ) * (C + D ) - E
+, A, B, T1 式中T1,T2,T3,T4
+, C, D, T2 为临时变量,由四
*, T1, T2, T3 元式优化比较方便
一, T3, E, T4
北京航空航天大学计算机学院 29
四元式表示
(三地址表示) 操作符 操作数1 操作数2 结果
(TAC)
北京航空航天大学计算机学院 30
四元式表示
(三地址表示) 操作符 操作数1 操作数2 结果
(TAC)
北京航空航天大学计算机学院 31
四元式表示
(三地址表示) 操作符 操作数1 操作数2 结果
(TAC)
北京航空航天大学计算机学院 32
四元式表示
(三地址表示) 操作符 操作数1 操作数2 结果
(TAC)
北京航空航天大学计算机学院 33
四元式表示
(三地址表示) 操作符 操作数1 操作数2 结果
(TAC)
北京航空航天大学计算机学院 34
一种特殊的四元式表达方式:SSA
北京航空航天大学计算机学院
SSA可以从普通的四元式转化而来。如何转化?
北京航空航天大学计算机学院 36
抽象语法树
北京航空航天大学计算机学院 37
7.3 抽象语法树
中间代码的图结构表示
抽象语法树:
用树型图的方式表示中间代码
操作数出现在叶节点上,操作符出现在中间结点
DAG图:
Directed Acyclic Graphs 有向无环图
语法树的一种归约表达方式
北京航空航天大学计算机学院 38
例: (A+B * C) / ( D*E – (F+G) / (H+I))
+ -
A * * /
B C D E + +
F G H I
前序遍历(根左右):/+A*BC-*DE/+FG+HI (波兰表达)
后序遍历(左右根):ABC*+DE*FG+HI+/-/ (逆波兰表达)
中序遍历(左根右):A+B*C/D*E-F+G/H+I
北京航空航天大学计算机学院 39
例: (A+B * C) / ( D*E – (F+G) / (H+I))
与三元式的关系
/
+ -
A * * /
① *, B, C
② +, A, ① B C D E + +
③ *, D, E
① *, B, C ③ *, D, E
④ +, F, G F G H I
⑤ +, H, I
② +, A, ① ④ +, F, G ⑤ +, H, I
⑥ /, ④, ⑤
⑦ -, ③, ⑥ ⑥ /, ④, ⑤
⑧ /, ②, ⑦
⑦ -, ③, ⑥
北京航空航天大学计算机学院 40
⑧ /, ②, ⑦
例:赋值语句:a:=b*(-c) + b*(-c)
:= :=
a + a +
* *
*
b - b -
b -
c c
c
抽象语法树
(其中有重复部分) 有向无环图(DAG)
北京航空航天大学计算机学院 41
例:赋值语句:a:=b*(-c) + b*(-c) 对应的TAC
t1 := - c := t1 := - c
:=
t2 := b * t1 t2 := b * t1
a a +
t3 := - c + t3 := - c
t4 := b * t3 * * t4 := b * t3
*
t5 := t2 + t4 t5 := t2 + t2
b - b - (t4)
a := t5 b -
c c a := t5
c
抽象语法树
(其中有重复部分) 有向无环图(DAG)
北京航空航天大学计算机学院 42
现代编译器设计实践:多层IR
LLVM IR Machine IR
层次较高 层次较低
保留更多 反映更多目标
程序语义 体系结构特点
不同层次的IR代表了不同层次的抽象(类型、操作)
通过分层抽象,实现最大限度的重用
北京航空航天大学计算机学院 43
例子:LLVM IR
北京航空航天大学计算机学院 44
• LLVM IR is a low-level RISC-like virtual instruction set
– supports linear sequences of simple instructions like add,
subtract, compare, and branch.
– These instructions are in three address form,
– LLVM IR supports labels and generally looks like a weird form of
assembly language.
• Unlike a low-level RISC-like virtual instruction set
– Strong Typed Language
– Doesn’t use a fixed set of registers
• Formatts
– Textual Formats
– In-memory data structure
– Binary Formats
北京航空航天大学计算机学院 45
define i32 @add1(i32 %a, i32 %b) {
entry:
unsigned add1(unsigned a,
%tmp1 = add i32 %a, %b
unsigned b) {
ret i32 %tmp1
return a+b; }
}
define i32 @add2(i32 %a, i32 %b) {
entry:
unsigned add2(unsigned a, %tmp1 = icmp eq i32 %a, 0
unsigned b) { br i1 %tmp1, label %done, label
if (a == 0) return b; %recurse
done:
ret i32 %b
}
北京航空航天大学计算机学院 46
例子:方舟编译器的Maple IR
北京航空航天大学计算机学院 47
IR例子:方舟编译器Maple IR
Maple IR:是华为方舟编译器的
“统一中间表示(IR)” ,支持多语言、层次式构建、不丢失
语言信息的高层次抽象
程序的表达:
声明语句(Declaration statements)
可执行语句(Executable statements)
叶子节点:代表一个值
表达式节点:代表一个表达式,赋值
语句节点:代表一个控制流结构
形式:
opcode fields (opnd0, opnd1, opnd2)
北京航空航天大学计算机学院 48
IR例子:方舟编译器Maple IR
例1:C语言 a=b;
dassign $a (dread i32 $b)
例2:C语言 a=b+c;
dassign $a (
add i32 (dread i32 $b, dread i32 $c)
)
北京航空航天大学计算机学院 49
IR例子:方舟编译器Maple IR
例3:C语言 a=b+c-d;
dassign $a (
sub i32 (
add i32 (
dread i32 $b,
dread i32 $c
), dread i32 $d
)
)
北京航空航天大学计算机学院 50
IR例子:方舟编译器Maple IR
几个完整的程序例子
北京航空航天大学计算机学院 51
其他:方舟编译器Maple IR
词法分析:
/maple_ir/mir_lexer.cpp
输入:
Maple IR的 ASCII源码
输出:
调用NextToken() 返回下
一个 Token
北京航空航天大学计算机学院 52
其他:方舟编译器Maple IR
语法分析:递归下降法
/maple_ir/mir_parser.cpp
北京航空航天大学计算机学院 53
其他:方舟编译器Maple IR
插入符号表
/maple_ir/mir_parser.cpp
处理变量声明语句 var
/maple_ir/global_tables.cpp
做重复符号检查
北京航空航天大学计算机学院 54
其他:方舟编译器Maple IR
符号表的查询
/maple_ir/mir_parser.cpp
在对语句中的名字进行分析
时
说明
1733 将名字转换为id
1740 如果是全局变量名
查全局符号表
1746 如果是局部名
查局部符号表
北京航空航天大学计算机学院 55
例子:P-Code的抽象机
北京航空航天大学计算机学院 56
7.3 抽象机代码
许多pascal编译系统生成的中间代码是一种称为
P-code的抽象代码,P-code的“P”即“Pseudo”
抽象机:
寄存器
保存程序指令的存储器
堆栈式数据及操作存储
北京航空航天大学计算机学院 57
寄存器有:
1. PC-程序计数器
2. NP-New指针,指向“堆”的顶部。“堆”用来存放由New
生成的动态数据。
3. SP- 运行栈指针,存放所有可按源程序的数据声明直接
寻址的数据。
4. BP-基地址指针,即指向当前活动记录的起始位置指针。
5. 其他,(如MP-栈标志指针,EP-极限栈指针等)
北京航空航天大学计算机学院 58
计算机的存储大致情况如下:
栈底
基地址指针 运行栈
P-code指令 BP
当前模块
SP 活动记录AR
运行栈指针 (数据段)
PC NP
New指针
程序寄存器 堆
堆底 常量区
程序指令存储器
北京航空航天大学计算机学院 59
运行P-code的抽象机没有专门的运算器或
累加器,所有的运算(操作)都在运行栈的栈顶进
行,如要进行d:=(a+b)*c的运算,生成P-code序
列为:
北京航空航天大学计算机学院 60
public class TestDate { public void test4();
Code:
private int count = 0;
北京航空航天大学计算机学院
P-Code指令集(p184, 10.2)
北京航空航天大学计算机学院 62
bp=0
0 a LDA 1
1 b LDA 2
2 c ADI
3
d
LDA 3
sp=4 ADI
STO 0
np
LDA 0
LDA 0
MULT
LDA 1
gp LDA 1
MULT
ADI
STO 1
code pc
北京航空航天大学计算机学院 63
bp=0
0 x LDA 0
1 y LDA 1
2 z LES
3 sp=3 BRF :lable1
LDA 0
STO 2
np
BR :label2
label1: LDA 1
STO 2
label2: LDA 2
gp LDA 2
MULT
STO 2
code pc
北京航空航天大学计算机学院 64
bp=0
0 x label1: LDA 0
1 y LDA 1
2 sp=2 LES
BRF :lable2
LDA 0
LDI 2
np
MULT
STO 0
BR :lable1
label2: LDA 0
gp STO 1
code pc
北京航空航天大学计算机学院 65
LDA 0
LDA 0
bp=0 MULT
0 x
1 LDA 1
y
2 LDA 1
m2
3 sp=3 MULT
ADI
STO 2
label1: LDA 2
np LDI 5
GT
BRF :label2
gp LDA 2
LDA 0
SUB
STO 2
code pc BR :label1
label2: …
北京航空航天大学计算机学院 66
label1: ALLOCATE 3
LDA 3
bp=0 LDA 4
0 <return addr>
1 <prev abp>=0 MULT
2 LDA 2
z=137
3 MULT
x
4 STO 3
y LDA 1
5 sp=5
STO bp
np BR :label2
…
LDI :label2
gp LDI 0
LDI 137
BR :label1
label2: …
code pc
北京航空航天大学计算机学院 67
编译程序生成P-code指令程序后,我们可
以用一个解释执行程序(interpreter)来解释执
行P-code,当然也可以把P-code再变成某一机
器的目标代码。
显然,生成抽象机P-code的编译程序是很
容易移植的。
北京航空航天大学计算机学院 68
作业
• P144.练习:第1题、第2题、第3题、第4题
• 补充作业:
1.请写出下列控制流语句的逆波兰表达和三地址表达
(1)do <stmt> while <expr>;
(2)for (<expr1>; <expr2>; <expr3>) <stmt>;
其中,<expr1>计算循环变量初值,<expr2>为循环条件表
达式,<expr3>更新循环变量,<stmt>为循环体。
北京航空航天大学计算机学院 69
补充阅读
• 补充阅读:
[1] LLVM-IR、Maple-IR、Open64-IR
[2] Fred Chow: The increasing significance of IR in
compilers
[3] David Chisnall, Modern Intermediate
Representations (IR)
北京航空航天大学计算机学院 70
谢谢!
北京航空航天大学计算机学院 71