Commit c3f529bd authored by Ricolove's avatar Ricolove
Browse files

assign 5 half way

parent 774f600e
# Assignment 5
## Where Should I Start?
本次实验对接口阅读的需求非常大,我习惯从最顶层的 `analyze` 开始,然后先实现 `propagate``addEdge` 这两个过程内分析也需要的函数,然后再是过程间分析的 `processCall``addReachable`.
## From Algorithm To Implement
本章关注的是如何将抽象的分析算法落实到代码实现,其中的坑会有哪些。至于某个算法的具体实现的坑,请看 FAQ 章节。
### `S, S_m` 在哪?
之所以我想把这个章节特别拿出来记录,主要是 Assignment 1 的恐惧又回来了。
你应该记得,课堂上介绍 data fact 的时候,采用的是 bit vector。然而在实现中,并没有采用 bit vector,而是采用了 set fact。本次实验也有着类似的改动,使得你直接对着代码去寻找,是找不到一些算法里的数据结构的。
`initialize` 中,框架已经帮你初始化好了一些实用的工具,其中包括算法的 `WL, PFG, CG, RM`。其中,`RM` 在上一次实验中已经见过,是在 `CG` 中维护的,所以现在的问题就是:我的 `S` 哪去了?
这里就要介绍实验框架的修改。在算法的很多地方,我们需要 `foreach x... in S do`,这时候我们要找出和 `x` 相关的语句,并且根据对应类型来施加不同的操作。
这就带来了问题:我要去遍历 `S` 集合,然后一个个 `instanceof`,这太不优雅了。
实验框架的处理方式是:把各种与 `x` 有关且比较特殊的语句存在其内部,即,在 `Var` 类里面实现了一个 `RelevantStmts`
举个例子,如果此时有一个 `y = x.f` 的语句出现,那么在这条 `LoadField` 语句初始化的时候,框架就会往 `x` 添加这条语句。(你可以自己去看看构造函数的实现)
所以,当我们想 `foreach x... in S do` 的时候,只需要 `x.getXXX().forEach(...);` 就可以了。(详情请见 2.3 `pascal.taie.ir.exp.Var` 一节)
诶,等会,`S_m` 去哪里了?`AddReachable` 里面的 `S U= S_m` 怎么办?
是的,在框架里面,因为每个方法都生成了 IR,相应地也会为每个变量添加好 `RelevantStmts`。这会导致一些空间的消耗,但是因为变量都是局部的,当你访问到一个变量时,其相关语句必然也是 `reachable` 的。(死代码在之前已经消除过了)
总之助教说没事就没事,芜湖!
### 静态方法的处理
本节主要是介绍新引入的 static/array 部分如何处理。
回想一下,为什么要在 `propagate` 完了之后再去给 `x.f = y` 这些变量做处理呢?因为 `x` 能指向的对象变了,因此对应对象的 `o_i.f` 也要修改。
而如果是 `T.f = y` 这种静态域的修改,没有「变量指向对象」的概念,也就不需要修改什么 `o_i.f`
所以:
* array 的处理是和 `x.f = y` 并列的;
![image-20211112135335878](img/Assignment 5/image-20211112135335878.png)
* 静态域放在 `AddReachable` 上,和 `x = y` 并列……或者本来你就可以把它当做一种特殊的 `x = y`
* 静态调用也在 `AddReachable` 上。
![image-20211112135420868](img/Assignment 5/image-20211112135420868.png)
当然,手册也已经给了相应的 hint 了,请 Ctrl + F 搜索 `handle` 一词来查找哪些新规则要引入到哪里。
### Visitor 模式
在手册里介绍了 `addReachable` 可以用 visitor 模式来实现。本节将快速带你了解为什么可以利用这个模式。
假设没有 visitor 模式,我们要实现 `addReachable`,那么我们就要 `getIR().getStmts.forEach(stmt -> ...)`,然后里面用大量的 `stmt instanceof XXX` 判断来做相应的处理。
当然这也是可行的。但是,因为框架提供了对 visitor 模式的支持,那么我们就可以直接让所有的 `stmt``accept` 我们的 `StmtProcessor`
使用 visitor 模式的优雅在于,我们对每个可能的 `Stmt` 都做了相应的 `visit` 函数实现,这就使得 `stmt.accept` 会自动解析出应该调用哪个处理方法,不需要我们手动地去 `instanceof`。整体上代码就变得非常简洁。
## Tai-e FAQ You Need to Know
......@@ -11,10 +11,12 @@
2.
3. ✔ - 已发布
4. ✔ - 已发布
5. 💭 - 施工中。但是已经有部分内容了。
## Issues 的更新情况
1. ✖ Assignment 1 的时候还没有此仓库。
2. ✔ - #1 ~ #15
3. ✔ - #16 (此部分难度不高,因此没有收集太多的 issues)
4. ✔ - #17 ~ #33
4. ✔ - #17 ~ #34
5. 💭 施工中。建议先看 Assignment 5 的手册的手册。
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment