本仓库是一个面向 SysY 语言的 C++ 编译器实验实现,当前 Lab1-Lab6 的主链路已经补齐:ANTLR 前端解析、语义检查、LLVM 风格 IR 生成、IR 优化、MIR/AArch64 汇编生成、线性扫描寄存器分配、后端窥孔与循环/向量化专项优化。
主流程如下:
SysY 源码
-> ANTLR Lexer/Parser
-> Sema 名称绑定与语义检查
-> IRGen 生成 LLVM 风格 IR
-> IR PassManager 优化
-> MIR Lowering
-> RegAlloc + Peephole + FrameLowering
-> AArch64 汇编
| 实验 | 名称 | 当前实现范围 |
|---|---|---|
| Lab1 | 语法树构建 | 基于 src/antlr4/SysY.g4 支持 SysY 主要语法,包括 int/float/void、全局声明、函数、数组、控制流、表达式、注释与多进制/浮点字面量;支持 --emit-parse-tree 打印语法树。 |
| Lab2 | 中间表示生成 | 已实现 Sema 与 IRGen:多层作用域、内建库函数、函数/变量/常量/数组检查,生成类型、全局变量、函数、基本块、表达式、GEP、调用、控制流、短路逻辑与类型转换 IR。 |
| Lab3 | 指令选择与汇编生成 | 已实现 IR 到 MIR/AArch64 的 lowering,覆盖整数、浮点、数组地址、全局变量、函数调用、分支、返回和 PHI 边拷贝等后端主链路。 |
| Lab4 | 基本标量优化 | 已接入默认 IR Pass 流程,包括 Mem2Reg、常量折叠/传播、CSE、DCE、CFG 简化、简单内联、GEP 拆分、局部内存优化等。 |
| Lab5 | 寄存器分配与后端优化 | 已实现基于 live interval 的线性扫描寄存器分配、spill/reload、callee-saved 保存恢复、栈帧布局和多类机器级窥孔优化。 |
| Lab6 | 并行与循环优化 | 已实现循环分析、LICM、数组归约折叠、重复纯调用循环折叠,以及若干 AArch64/NEON 机器级向量化与循环专项优化。 |
更详细的实现说明见:
doc/实验进度与测试方法.mddoc/Lab1-6实现方法详解.mddoc/Lab1-语法树构建.mddoc/Lab2-中间表示生成.mddoc/Lab3-指令选择与汇编生成.mddoc/Lab4-基本标量优化.mddoc/Lab5-寄存器分配.mddoc/Lab6-并行与循环优化.md
建议使用 Ubuntu 22.04 或 WSL Ubuntu 22.04。
基础构建依赖:
sudo apt update
sudo apt install -y build-essential cmake git openjdk-11-jreIR 运行验证需要 LLVM 工具链:
sudo apt install -y llvm clangAArch64 汇编链接与运行验证需要交叉工具链和 QEMU:
sudo apt install -y gcc-aarch64-linux-gnu qemu-user仓库内置 ANTLR jar:third_party/antlr-4.13.2-complete.jar。当前 CMake 不自动调用 ANTLR,首次构建前需要手动生成 C++ Lexer/Parser 文件:
mkdir -p build/generated/antlr4
java -jar third_party/antlr-4.13.2-complete.jar \
-Dlanguage=Cpp \
-visitor -no-listener \
-Xexact-output-dir \
-o build/generated/antlr4 \
src/antlr4/SysY.g4cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=ON
cmake --build build -j "$(nproc)"运行语法树打印:
./build/bin/compiler --emit-parse-tree test/test_case/functional/simple_add.sycmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF
cmake --build build -j "$(nproc)"常用输出:
./build/bin/compiler --emit-ir test/test_case/functional/simple_add.sy
./build/bin/compiler --emit-asm test/test_case/functional/simple_add.sy
./build/bin/compiler --emit-ir --disable-ir-opt test/test_case/functional/simple_add.sy说明:
- 默认输出 IR,并默认启用 IR 优化。
--disable-ir-opt用于观察优化前 IR 基线。--emit-asm会继续执行 MIR lowering、寄存器分配、窥孔优化、栈帧落地和汇编打印。
单用例 IR 链路验证:
./scripts/verify_ir.sh test/test_case/functional/simple_add.sy test/test_result/ir --run单用例 AArch64 汇编链路验证:
./scripts/verify_asm.sh test/test_case/functional/simple_add.sy test/test_result/asm --run各 Lab 推荐脚本:
./scripts/test_lab1.sh test/test_case
./scripts/test_lab2_full.sh
./scripts/test_lab3_final.sh
./scripts/test_lab4.sh
./scripts/test_lab4_noopt.sh
./scripts/test_lab5.shLab6 当前没有单独的 test_lab6.sh;循环/向量化优化通过 Lab4/Lab5 的全量功能与性能样例回归,并结合 --disable-ir-opt、汇编统计和性能用例运行时间观察收益。
如果基于头歌平台协作,推荐流程如下:
- 组长在课程仓库页面点击
Fork,创建小组仓库副本。 - 组长在 fork 后的仓库页面查看邀请码,并发给组员。
- 组员通过右上角
+菜单选择加入项目,提交加入申请。 - 组长在待办事项中审批申请。
- 所有成员从小组仓库复制 HTTPS 地址,在本地 clone。
相关页面示意图仍保留在 doc/images/:
doc/images/01.png:组长 fork 课程仓库doc/images/02.png:组长查看邀请码doc/images/03.png:组员加入项目入口doc/images/04.png:组长审批组员申请doc/images/05.png:复制仓库 HTTPS 地址
克隆示例:
git clone <仓库 HTTPS 地址>
cd nudt-compiler-cpp如果需要同步课程主仓库更新,可以增加 upstream:
git remote add upstream https://bdgit.educoder.net/NUDT-compiler/nudt-compiler-cpp.git
git fetch upstream推荐使用分支和 PR/MR 做协作开发。提交信息可以采用:
<type>(<scope>): <subject>
常见 type:
feat:新增功能fix:修复 bugrefactor:重构但不改变外部行为docs:文档修改test:测试相关chore:杂项维护
示例:
feat(irgen): 支持数组初始化 IR 生成
fix(mir): 修复超过 8 个参数的栈传参
docs(doc): 补充 Lab1-6 实现说明