Commit 0f13b694 authored by Ricolove's avatar Ricolove
Browse files

add mofm 1-3

parent 1440e7e5
# Assignment 1-3
相信大家都已经写完了这三个 Assignment,为了方便后来人,还是写写这三个实验的《手册的手册》
如何使用本《手册的手册》?请先自己阅读手册,尝试看一下代码框架,如果你遇到了一些问题,就可以来这里查查,说不定这里提供了一些大家都踩过的坑。
## Where Should I Start
Assignment 1 非常容易,主要是为了让大家感受一下 Tai-e 和它的数据流分析框架,同时熟悉一些 Java 编写知识。
这边我的建议是从 Solver 开始写,再去写 LVA 的逻辑,因为函数的大框架在 Solver 里,具体功能才是在 LVA 里面实现的。
随后的 Assignment 2 也是,从顶层的 WorkListSolver 开始。
Assignment 3 只有一个函数要写,所以没有啥「从哪开始」的概念,按要求写就是了。
## Tai-e FAQ You Need to Know
### Assignment 1
用一张图告诉你算法的哪个部分在哪里实现
![image-20211101205624301](img/Assigment 1-3/image-20211101205624301.png)
#### `Solver/IterativeSolver`
* `cfg` 是用来管理节点的,`result` 是用来管理数据流分析的结果的。无论是这次实验还是以后的几个实验,都是从 `cfg` 获取节点,再在 `result` 里索取或修改数据流分析结果。
* `Solver` 是一个抽象的分析框架,因此 `Node``Fact` 都是未确定的,不能做 `new Node()` 这样的操作。
* 为了支持 `meetInto`,你需要初始化 `InFact``OutFact`。手册有说的,但是蛮多人漏了。
* `analysis.transferNode` 是有返回值的,你可以充分利用这一点。
* Java 知识:你可以用 `for(Node node: cfg) {...}` 来遍历 `cfg`,也可以用 `cfg.forEach(lambda)` 来遍历,但是后者作为 lambda 表达式存在着无法重新赋值变量的问题,如果你不了解 lambda 表达式,要谨慎使用。
* 在这里举一个用 `forEach` 的例子。请看上图中 `meetInto` 这一行在 `InterativeSolver` 里面是怎么写的:
```java
cfg.succsOf(node).forEach(succ ->{
// do something with succ and out[B], using analysis.meetInto()
});
```
* 另一个 Java 知识:你在寻找 C++ `auto` 在 Java 里的对应体吗?请使用 `var`,然后 IDEA 会自动告诉你推导所得类型。
![image-20211101210155421](img/Assigment 1-3/image-20211101210155421.png)
#### `LiveVariableAnalysis`
* 你可能注意到了,`newBoundaryFact` 有一个参数 `cfg`。但是 Assignment 1 是用不到这个参数的,因为算法要求初始化为 empty。在 Assignment 2,就会需要 `cfg` 的信息来初始化了。
* 课堂上教学的时候使用的 data fact 是 bit vector,但是这需要事先收集程序中的所有出现过的变量:这显然是比较麻烦的。因此,本次实验使用的 data fact 是 set,即集合。类型的名字就是 `SetFact`,里面很多涉及集合的操作。这就得你自己去看 API 了。
* 有些人并不是太了解 Java 的变量模型的。简单来说,你可以把它理解成 python 那样的模型:
```python
>>> a = []
>>> b = a
>>> b.append(1)
>>> a
[1]
```
这意味着什么呢?你可能会在 API 看到一个方法叫做 `copy()`。你可能会想,通过这个方法是否可以获得源 SetFact 对象的副本呢?像这样:
```java
var tempFact = out.copy();
// do something to tempFact
if (tempFact != out){
// do something when "out" changes
}
```
但是其实你在做的是(从 C/C++ 的视角):
```C++
auto *tempFact = &out;
if (&tempFact != &out){
// ...
}
```
那这样真是比较了个寂寞,还改了不应该修改的 `out` 本身。所以你应该使用另一个方法 `SetFact.set()` 来创造一个深拷贝。
* `stmt.getUses()` 返回的是一个 `List<RValue>`。在 `RValue` 下,有立即数也有变量。怎么判断一个 `RValue` 变量是不是指向了一个 `Var` 对象呢?Java 里的解决方法就是 `instaceof`
* 依然是那个问题,`SetFact<Var>` 储存的是 `Var`,如何把 `RValue use` 内对象放进去呢?方法就是强制类型转换 `(Var) use;`
### Assignment 2
#### `Solver/WorkListSolver`
* 前向算法和后向算法几乎是一样的,直接复制粘贴然后改改就行了。
* 然而,`workList` 算法是有一个队列的,而不是在有改变的时候再把整个 CFG 跑一次。因此你需要考虑怎么维护队列。在这里我推荐使用 `Queue`,但是 Java 的 `Queue` 只是一个接口类型,内部实现是自己挑的,我这里使用的是 `LinkedList`,具体的使用方法可以去搜搜。
* IDEA 教了我一个很有意思的写法:`cfg.succsof(node).forEach(workList::offer)`,这比 `forEach(node -> {workList.offer(node)})` 更加简洁。
#### `ConstantPropagation`
* `o.f = v`,在这个式子的处理上,我们提供 "identity function"。这个函数的意思就是,直接把 `in` 拷贝到 `out` 上,不做任何操作,就当这条指令是 `nop`
* 你可能想知道 `getUses()``x = y` 这条语句之外都返回些什么。我们举点例子吧:
* `x = y op z `: `[y, z, y op z]`
* `x = m(n)`: `[mClass, n, invokevirtual mClass.m(n)]`
* 手册里也有说 `DefinitionStmt` 的使用,于是你可能会想把 `Stmt` 类型转换到 `DefinitionStmt` 上。但是作为最顶层的方法,`getUses()` 其实也是够用的。如果你依然想做类型转换,那么可能会遇到模板参数不知道怎么填的问题。解决方法就是使用通配符:
`DefinitionStmt<?, ?> definitionStmt = (DefinitionStmt<?, ?>) stmt;`
* API 里面的 `restrictTo`是用来做 `meetInto` 反向操作的,请不要在意它。
*`meetInto` 里面,如何优雅地遍历两个 map 并且将其合并呢?请看 Issues #15.
* 不要忘了除零操作返回 `UNDEF`
### Assignment 3
#### Tai-e Classes You Need to Copy and Paste
这个实验需要你把:
* pascal/taie/analysis/dataflow/analysis/constprop/ConstantPropagation.java
* pascal/taie/analysis/dataflow/analysis/LiveVariableAnalysis.java
* pascal/taie/analysis/dataflow/solver/Solver.java
* pascal/taie/analysis/dataflow/solver/WorkListSolver.java
复制过来。不需要修改,只需要记得把前后向分析的代码合并一下。
#### `analyze(IR ir)`
* 死代码的消除过程一次 CFG 遍历就可以完成,所以不需要额外增加什么函数来处理,直接在 `analysis` 内完成所有逻辑就行了。
* `Set<Stmt> deadCode = new TreeSet<>(Comparator.comparing(Stmt::getIndex));` 使用红黑树实现的集合数据类型,并且提供了一个比较器来为 `Stmt` 排序,所以你不用担心 `deadCode` 里面的 `Stmt` 会乱掉。
* 遍历方法由你自己选,DFS BFS 都行。不要忘记处理环路就行了。
* 你可以把 IF 和 SWITCH 语句的 dot 图画出来,观察他们的边情况,然后决定怎么处理。
......@@ -9,7 +9,7 @@
1.
2.
3. 我决定合并成一个,但是现在咕了。
3. ✔ - 已发布
4. ✔ - 已发布
## Issues 的更新情况
......
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