stage3

stage-3

郭高旭 ggx21@mails.tsinghua.edu.cn 2021010803

实验内容

增加块语句的支持。

前端

主要是修改了重复声明的检查。只有在同一个作用域里,变量才不能重复声明

具体而言,定义了ScopeStack替换原有的单一scope,重新实现lookup,declare,使得它们仅仅在当前ScopeStack的栈顶生效

  • lookupCurrent:在Declaration时,只在当前(栈顶)查找符号表

  • lookup:在visitIdentifier等中,从栈顶反向查找,直至查找到声明或者失败,这样保证查找到最近的声明

  • declare:在栈顶scope(当前scope)scope

  • namer语义检查时的visitBlock中,新作用域入栈,访问结束后,此作用域出栈

中端

本步骤中无须新增新的 TAC 指令。

后端

数据流分析:新增了判断基本块是否可达的代码,为每一个BasicBlock添加reachable属性,通过dfs找到所有可达块,并更新reachable

在寄存器分配函数bruteregalloc.py中 ,仅仅为可达的基本块分配寄存器.

1
2
3
4
5
for bb in graph.iterator():
if bb.label is not None:
subEmitter.emitLabel(bb.label)
if bb.reachable:
self.localAlloc(bb, subEmitter)

思考题

请画出下面 MiniDecaf 代码的控制流图。

1
2
3
4
5
6
7
8
9
10
int main(){
int a = 2;
if (a < 3) {
{
int a = 3;
return a;
}
return a;
}
}

由于控制流图是根据TACinstr构造的,所以这里先给出上述代码的TAC表示(bb为含注释行到上一注释行后)

1
2
3
4
5
6
7
8
9
10
11
12
FUNCTION<main>:
_T1 = 2
_T0 = _T1
_T2 = 3
_T3 = (_T0 < _T2)
if (_T3 == 0) branch _L1 #---------------bb1
_T5 = 3
_T4 = _T5
return _T4#---------------bb2
return _T0#---------------bb3
_L1:
return#---------------bb4

则上述4个基本块构造的控制流图如下

graph TD
A[bb1]-->B[bb2]
A[bb1]-->C[bb4]
D[bb3:不可达]



本文总阅读量