Files
nudt-compiler-cpp/doc/Lab2-中间表示生成.md

90 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Lab2生成中间表示IR
## 1. 本实验定位
Lab2 的目标是在该示例基础上扩展语义覆盖范围,逐步把更多 SysY 语法正确翻译为 IR。
## 2. Lab2 要求
需要同学完成:
1. 熟悉 IR 相关数据结构与构建接口。
2. 理解当前语法树 -> IR 的最小实现流程。
3. 在现有框架上扩展 IR 生成能力使其覆盖课程要求的Sysy语法。
## 3. 当前代码框架(与 Lab2 直接相关)
1. IR 定义与打印
- `src/ir/IR.h`
- `src/ir/IRBuilder.cpp`
- `src/ir/IRPrinter.cpp`
2. 语法树 -> IR 生成器
- `src/irgen/IRGen.h`
- `src/irgen/IRGenDriver.cpp`
- `src/irgen/IRGenFunc.cpp`
- `src/irgen/IRGenDecl.cpp`
- `src/irgen/IRGenStmt.cpp`
- `src/irgen/IRGenExp.cpp`
3. 入口流程
- `src/main.cpp`
## 4. Lab2 需要补充的内容
1. 必须修改的文件
- `src/irgen/IRGenDecl.cpp`
- `src/irgen/IRGenStmt.cpp`
- `src/irgen/IRGenExp.cpp`
- `src/ir/IR.h`(当现有 IR 指令/类型不够用时)
- `src/ir/IRBuilder.cpp`(当需要新增构建接口时)
- `src/ir/IRPrinter.cpp`(新增 IR 指令后补齐打印)
- `src/irgen/IRGen.h`(当需要扩展状态或辅助接口时)
2. 视实现需要可能修改
- `src/main.cpp`(当需要调整输出阶段行为)
## 5. 当前最小示例实现说明
当前语法树 -> IR 仅覆盖最小子集:
1. 常量整数、变量引用、二元加法表达式。
2. 局部变量声明(当前采用 LLVM 前端常见的 `alloca/load/store` 内存模型)。
3. `return` 语句。
4. 单函数 `main` 的最小流程。
说明:当前阶段变量统一采用内存模型:先 `alloca` 分配栈槽,再通过 `store/load` 读写。即使变量由常量初始化(如 `int a = 1;`),也会先 `store` 到栈槽,而不是直接把变量替换成 SSA 值。后续实验中,同学可按需求再重构。
此外,当前 IR 还维护了最基本的 use-def 关系:每个 `Value` 会记录哪些 `Instruction` 使用了它。
这对后续做数据流分析、死代码删除、常量传播等优化会很有帮助;但目前相关实现,接口仍不完整,后续实验中还需要同学继续补充和完善。
## 6. 构建与运行
```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j "$(nproc)"
```
## 7. Lab2 验证方式
项目编译后按提供测试输入回归:
```bash
./build/bin/compiler --emit-ir test/test_case/simple_add.sy
```
如需打印语法树:
```bash
./build/bin/compiler --emit-parse-tree test/test_case/simple_add.sy
```
推荐使用统一脚本验证 “IR -> LLVM 后端 -> 可执行程序” 整体链路,用于验证 IR 的正确性:
```bash
./scripts/verify_ir.sh test/test_case/simple_add.sy test/test_result/ir --run
```