69 lines
2.4 KiB
Markdown
69 lines
2.4 KiB
Markdown
# Lab2:中间表示生成
|
||
|
||
## 1. 本实验定位
|
||
|
||
Lab2 的目标是在该示例基础上扩展语义覆盖范围,逐步把更多 SysY 语法正确翻译为 IR。
|
||
|
||
## 2. Lab2 要求
|
||
|
||
需要同学完成:
|
||
|
||
1. 熟悉 IR 相关数据结构与构建接口。
|
||
2. 理解当前语法树 -> IR 的最小实现流程。
|
||
3. 在现有框架上扩展 IR 生成能力,使其覆盖课程要求的Sysy语法。
|
||
|
||
## 3. 相关文件
|
||
|
||
以下文件与本实验内容相关,建议优先阅读。
|
||
|
||
- `include/ir/IR.h`
|
||
- `include/irgen/IRGen.h`
|
||
- `src/irgen/IRGenDecl.cpp`
|
||
- `src/irgen/IRGenStmt.cpp`
|
||
- `src/irgen/IRGenExp.cpp`
|
||
|
||
## 4. 当前最小示例实现说明
|
||
|
||
当前语法树 -> IR 仅覆盖最小子集:
|
||
|
||
1. 常量整数、变量引用、二元加法表达式。
|
||
2. 局部变量声明(当前采用 LLVM 前端常见的 `alloca/load/store` 内存模型)。
|
||
3. `return` 语句。
|
||
4. 单函数 `main` 的最小流程。
|
||
|
||
|
||
说明:当前阶段变量统一采用内存模型:先 `alloca` 分配栈槽,再通过 `store/load` 读写。即使变量由常量初始化(如 `int a = 1;`),也会先 `store` 到栈槽,而不是直接把变量替换成 SSA 值。后续实验中,同学可按需求再重构。
|
||
|
||
此外,当前 IR 还维护了最基本的 use-def 关系:每个 `Value` 会记录哪些 `Instruction` 使用了它。
|
||
这对后续做数据流分析、死代码删除、常量传播等优化会很有帮助;但目前相关实现,接口仍不完整,后续实验中还需要同学继续补充和完善。
|
||
|
||
## 5. 构建与运行
|
||
|
||
```bash
|
||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||
cmake --build build -j "$(nproc)"
|
||
```
|
||
|
||
## 6. Lab2 验证方式
|
||
|
||
可先用单个样例检查 IR 输出是否基本正确:
|
||
|
||
```bash
|
||
./build/bin/compiler --emit-ir test/test_case/functional/simple_add.sy
|
||
```
|
||
|
||
如需打印语法树:
|
||
|
||
```bash
|
||
./build/bin/compiler --emit-parse-tree test/test_case/functional/simple_add.sy
|
||
```
|
||
|
||
推荐使用统一脚本验证 “IR -> LLVM 后端 -> 可执行程序” 整体链路。`--run` 模式下会自动读取同名 `.in`,并将程序输出与退出码和同名 `.out` 比对,用于验证 IR 的正确性:
|
||
|
||
|
||
```bash
|
||
./scripts/verify_ir.sh test/test_case/functional/simple_add.sy test/test_result/function/ir --run
|
||
```
|
||
|
||
但最终不能只检查 `simple_add`。完成 Lab2 后,应对 `test/test_case` 下全部测试用例逐个回归,确认 IR 生成与 `--run` 链路都能通过;如有需要,也可以自行编写批量测试脚本统一执行。
|