From ab6069e86721c2fb6db2131f2668e5ad8f03b20b Mon Sep 17 00:00:00 2001 From: lxq <877250099@qq.com> Date: Wed, 1 Nov 2023 19:00:42 +0800 Subject: [PATCH 1/4] lab3: fix qemu output of version --- docs/lab3/environment.md | 5 ++--- docs/lab3/stack_allocation.md | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/lab3/environment.md b/docs/lab3/environment.md index bf1ad12..b5df253 100644 --- a/docs/lab3/environment.md +++ b/docs/lab3/environment.md @@ -81,15 +81,14 @@ $ echo "export PATH=\$PATH:/opt/cross-tools.gcc_glibc/bin:/opt/gdb/bin:/opt/qemu ```shell $ qemu-loongarch64 -version - qemu-loongarch64 version 8.1.1 - Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers + qemu-loongarch64 version 6.2.50 (v6.0.0-7567-gac069a8ffb) + Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers ``` ??? info "检查龙芯 gdb 版本" ```shell $ loongarch64-unknown-linux-gnu-gdb -v - GNU gdb (GDB) 12.0.50.20210713-git Copyright (C) 2021 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later diff --git a/docs/lab3/stack_allocation.md b/docs/lab3/stack_allocation.md index 27604d6..3c9bd7b 100644 --- a/docs/lab3/stack_allocation.md +++ b/docs/lab3/stack_allocation.md @@ -17,7 +17,6 @@ 而在寄存器分配策略下,变量活跃期间数据都保留在各自的寄存器中,不需要 2.a 的 load 和 2.c 的 store。所以性能上,栈式分配不如寄存器分配,而在实现难度上,栈式分配要简单许多。 - ## 实验方案 关于变量分配,我们需要为函数中每个变量分配一段栈空间,这个并没有固定的标准,我们提供并已经为你实现好的方案如下: @@ -35,9 +34,9 @@ !!! note "注意" 为变量分配空间,实际上就是移动栈指针,这里注意 `$sp` 和 `$fp` 需要**对齐到 16 字节**,详见[汇编介绍中的栈帧布局章节](../common/asm_intro.md/#栈帧布局)。 - + !!! note "代码" - + 查阅框架中的代码实现:`src/codegen/CodeGen.cpp` 中 `CodeGen::allocate()` ## 举个例子 @@ -78,7 +77,7 @@ label_entry: 2. 指令选择:以 IR 中第 5 行的 `%op1 = load i32, i32* %op0` 为例,首先需要将 `%op0` 的值从栈帧加载到寄存器中,然后使用汇编指令 `ld.w` 读取内存,结果即为 `%op1` 的值,最后将其保存回 `%op1` 所在的栈帧位置。 -得到的汇编指令如下(建议你读懂数字的来由): +得到的汇编指令如下(建议你读懂数字的来由): ```asm .text From c98a375d2da20cb08c79ab6f487c263b24c6b8fb Mon Sep 17 00:00:00 2001 From: lxq <877250099@qq.com> Date: Thu, 2 Nov 2023 00:33:42 +0800 Subject: [PATCH 2/4] lab3: refactor doc --- docs/lab3/framework.md | 23 +------------ docs/lab3/guidance.md | 75 +++++++++++++++++------------------------- docs/lab3/index.md | 73 +++++++++++++++++++++------------------- mkdocs.yml | 2 +- 4 files changed, 73 insertions(+), 100 deletions(-) diff --git a/docs/lab3/framework.md b/docs/lab3/framework.md index 8e716a0..5683ea2 100644 --- a/docs/lab3/framework.md +++ b/docs/lab3/framework.md @@ -1,27 +1,6 @@ # 后端框架介绍 -本次更新的相关文件如下: - -``` -. -├── ... -├── include -│ ├── ... -│ └── codegen -│ ├── ASMInstruction.hpp # 描述汇编指令 -│ ├── CodeGen.hpp # 后端框架顶层设计 -│ ├── CodeGenUtil.hpp # 一些辅助函数及宏的定义 -│ └── Register.hpp # 描述寄存器 -├── src -│ ├── ... -│ └── codegen -│ ├── CMakeLists.txt -│ ├── CodeGen.cpp <-- 你需要修改的文件 -│ └── Register.cpp -└── tests - ├── ... - └── 3-codegen/* # lab3 测试 -``` +本篇文档将介绍后端的代码框架。阅读前,你应该浏览下[这里的目录结构](../#同步实验仓库),对框架的文件布局有总体的印象。 ## 极简框架 diff --git a/docs/lab3/guidance.md b/docs/lab3/guidance.md index 4dad60b..66a89a4 100644 --- a/docs/lab3/guidance.md +++ b/docs/lab3/guidance.md @@ -1,37 +1,14 @@ # Lab3 实验指导 -一个典型的编译器后端从中间代码获取信息,进行活跃变量分析、寄存器分配、指令选择、指令优化等一系列流程,最终生成高质量的后端代码。 +## 阶段一:预热实验 -本次实验,我们将这些复杂的流程简化,仅追求实现的完整性,要求同学们采用栈式分配的策略,完成后端代码生成。 - -## 栈式分配 - -阅读[栈式分配介绍](stack_allocation.md)章节,了解其思想。 - -## 实验框架 - -阅读[后端框架介绍](framework.md)章节,了解实验代码框架设计。 - -## 实现约定 - -出于简化实验的目的,我们只考核最核心的功能点,对如下情况不做要求: - -- phi 指令:本实验不考核对于 phi 指令的处理 -- 函数调用传参:本次实验只考核使用寄存器传参的情况,即对于超多参数的栈上传参不做要求 - -此外,存在部分 `void main() {...}` 的样例,其返回值是未定义的,我们要求这样的主函数通过寄存器 `$a0` 返回 0,以顺利进行测评。 - -## 实验 - -### 阶段一:预热实验 - -#### 实验内容 +### 实验内容 实验在 `tests/3-codegen/warmup/ll_cases/` 目录下提供了六个 `.ll` 文件。学生需要在 `tests/3-codegen/warmup/stu_cpp/` 目录中,依次完成 `assign_codegen.cpp`、`float_codegen.cpp`、`global_codegen.cpp`、`function_codegen.cpp`、`icmp_codegen.cpp` 和 `fcmp_codegen.cpp` 六个 C++ 程序中的 TODO。这六个程序运行后应该能够生成 `tests/3-codegen/warmup/ll_cases/` 目录下六个 `.ll` 文件对应的汇编程序。 -#### 编译、运行、测试 +### 编译、运行、测试 -##### 编译 +#### 编译 ```shell $ cd 2023ustc-jianmu-compiler @@ -45,7 +22,7 @@ $ make 如果构建成功,你会在 `build` 文件夹下找到 `stu_assign_codegen`, `stu_float_codegen` 等可执行文件。 -##### 运行与测试 +#### 运行与测试 !!! note @@ -61,7 +38,7 @@ $ echo $? 你可以通过观察原来的 `.ll` 代码来推断 `echo $?` 应该返回的正确结果,也可以直接使用 `lli` 执行 `.ll` 文件来获取正确结果。 -#### 仓库目录结构 +### 仓库目录结构 与预热实验相关的文件如下: @@ -80,9 +57,23 @@ $ echo $? └── stu_cpp <- 学生需要编写的汇编代码手动生成器 ``` -### 阶段二:编译器后端 +## 阶段二:编译器后端 -#### 编译 +### 实验内容 + +补全 `src/codegen/CodeGen.cpp` 中的 TODO,并按需修改 `include/codegen/CodeGen.hpp` 等文件,使编译器能够生成正确的汇编代码。 + +!!! info "实现约定" + + 出于简化实验的目的,我们只考核最核心的功能点,对如下情况不做要求: + + - phi 指令:本实验不考核对于 phi 指令的处理 + + - 函数调用传参:本次实验只考核使用寄存器传参的情况,即对于超多参数的栈上传参不做要求 + + 此外,存在部分 `void main() {...}` 的样例,其返回值是未定义的,我们要求这样的主函数通过寄存器 `$a0` 返回 0,以顺利进行测评。 + +### 编译 ```shell $ cd 2023ustc-jianmu-compiler @@ -96,18 +87,16 @@ $ make $ sudo make install ``` -如果构建成功,你会在 `build` 文件夹下找到 cminusfc 可执行文件,它能将 cminus 文件输出为龙芯汇编文件。 - -#### 运行 - -我们在 `tests/testcases_general` 文件夹中准备了一些通用案例。当需要对 `.cminus` 单个文件测试时,可以这样使用: - -##### 情况一:生成 IR 文件 +如果构建成功,你会在 `build` 文件夹下找到 cminusfc 可执行文件,它能将 `.cminus` 文件输出为龙芯汇编文件。 !!! note 为了让 cminusfc 在 `$PATH` 中,一定要 `sudo make install`。 +### 运行 + +完成第二阶段,编译器能够将 `.cminus` 文件翻译成正确的龙芯汇编 `.s` 文件: + ```shell # 假设 cminusfc 的路径在你的 $PATH 中,并且你现在在 test.cminus 文件所在目录中 $ cminusfc test.cminus -S @@ -115,9 +104,7 @@ $ cminusfc test.cminus -S 此时会在同目录下生成同名的汇编文件,在这里即为 `test.s`。 -##### 情况二:生成可执行文件 - -上面生成的汇编文件用于阅读,如果需要运行,需要调用龙芯交叉编译器编译链接生成二进制文件 `test` +为了运行得到的汇编文件,需要调用龙芯交叉编译器编译链接生成二进制文件 `test`: ```shell # 假设你位于 2023ustc-jianmu-compiler 目录, 否则你应该修改下面 src/io/io.c 到具体的路径 @@ -131,10 +118,10 @@ $ loongarch64-unknown-linux-gnu-gcc -static test.s src/io/io.c -o test 然后你可以使用 `qemu-loongarch64` 运行二进制文件 `test` ```shell -qemu-loongarch64 ./test +$ qemu-loongarch64 ./test ``` -#### 测试 +### 测试 在 `tests/3-codegen/autogen` 目录下,使用我们提供的 `eval_lab3.sh` 进行本地评测,其接受两个**参数**: @@ -191,7 +178,7 @@ error at line 7 column 5: syntax error 直接使用初始代码尝试评测,每个样例都会报错 `CE: cminusfc compiler error`。 -!!! detail "初始代码评测后的 log 文件" +??? detail "使用初始代码评测后的 log 文件" ``` ==========./testcases/0-io.cminus========== diff --git a/docs/lab3/index.md b/docs/lab3/index.md index 682651b..e2317ad 100644 --- a/docs/lab3/index.md +++ b/docs/lab3/index.md @@ -2,6 +2,35 @@ 经过 Lab1 和 Lab2,我们的编译器能够将 Cminusf 源代码翻译成 Light IR。本次实验要求同学们将 IR 翻译成龙芯汇编指令。 +## 同步实验仓库 + +在进行实验之前,首先拉取[实验仓库](https://cscourse.ustc.edu.cn/vdir/Gitlab/compiler_staff/2023ustc-jianmu-compiler)的最新代码,具体步骤可以参考[Lab2 中的指导](../lab2/#实验要求)。 + +本次实验仓库更新的内容如下,每个阶段的文件将在对应文档详细说明: + +``` +. +├── ... +├── include +│ ├── ... +│ └── codegen +│ ├── ASMInstruction.hpp # 描述汇编指令 +│ ├── CodeGen.hpp # 后端框架顶层设计 +│ ├── CodeGenUtil.hpp # 一些辅助函数及宏的定义 +│ └── Register.hpp # 描述寄存器 +├── src +│ ├── ... +│ └── codegen +│ ├── CMakeLists.txt +│ ├── CodeGen.cpp <-- lab3 第二阶段需要修改的文件 +│ └── Register.cpp +└── tests + ├── ... + └── 3-codegen +    ├── warmup <-- lab3 第一阶段(代码撰写) +    └── autogen <-- lab3 第二阶段的测试 +``` + ## 实验内容 @@ -10,13 +39,10 @@ 此为预热实验,主要引导同学完成环境的配置并学习相关知识。 -1. 查阅[后端环境配置](./environment.md)章节,完成龙芯交叉编译工具链的安装。 +1. 阅读[后端环境配置](./environment.md)章节,完成龙芯交叉编译工具链的安装。 2. 阅读[龙芯汇编介绍](../common/asm_intro.md)章节,了解龙芯汇编的基础知识。 -3. 阅读[Lab3 实验指导](./guidance.md)的[预热实验](./guidance.md#阶段一预热实验)章节,简要了解如何使用提供的 C++ 接口生成汇编指令,进行补全汇编的实验并测试。 - - - -阶段一需要完成 `tests/3-codegen/warmup/stu_cpp` 目录下代码的填写。 +3. 阅读[后端框架介绍](framework.md)中的[指令类介绍](framework.md/#指令类)和[辅助函数(添加指令)介绍](framework.md/#append_inst),了解如何使用提供的 C++ 接口生成汇编指令。 +4. 阅读 [Lab3 实验指导的预热实验](./guidance.md#阶段一预热实验)章节,了解实验内容,进行补全汇编的实验并测试。 !!! warning "Deadline" @@ -26,43 +52,24 @@ 来到本次实验的核心:实现编译器后端,即根据 IR 翻译得到龙芯汇编指令。 -在进行实验之前,请确保完成了[阶段一](#阶段一),并且本地仓库已经与上游仓库同步: +一个典型的编译器后端从中间代码获取信息,进行活跃变量分析、寄存器分配、指令选择、指令优化等一系列流程,最终生成高质量的后端代码。 -```shell -# 在虚拟机实验仓库的路径下输入命令 -$ git pull upstream master -``` +本次实验,我们将这些复杂的流程简化,仅追求实现的完整性,要求同学们采用栈式分配的策略,完成后端代码生成。 -阅读 [Lab3 实验指导](./guidance.md),了解实验细节,完成本次实验。 +1. 阅读[栈式分配介绍](stack_allocation.md)章节,了解其思想。 +2. 阅读[后端框架介绍](framework.md)章节,了解实验代码框架设计。 +3. 阅读 [Lab3 实验指导中的阶段二](./guidance.md/#阶段二编译器后端)章节,了解实验细节,完成本次实验。 !!! warning "Deadline" **2023 年 11 月 24 日 23:59** -## 实验要求 - -请将[实验仓库](https://cscourse.ustc.edu.cn/vdir/Gitlab/compiler_staff/2023ustc-jianmu-compiler)设置为上游仓库,并获取本次实验更新的内容,具体步骤如下: - -将上游仓库设置一个别名(alias),在这里我们用 `upstream`,你也可以改成其他你喜欢的名字。在你 fork 后的本地仓库中: - -```shell -$ git remote add upstream https://cscourse.ustc.edu.cn/vdir/Gitlab/compiler_staff/2023ustc-jianmu-compiler.git -``` - -尝试将远程的更新拉取到本地并进行 merge 操作: - -```shell -$ git pull upstream master -``` +## 提交内容 -当 merge 过程出现冲突时,请参考 [Lab0](../lab0/git.md#上下游同步和冲突处理) 来合理的解决冲突。 +阶段一、二:在希冀平台提交你实验仓库的 url(如 `https://cscourse.ustc.edu.cn/vdir/Gitlab/xxx/2023ustc-jianmu-compiler.git`)。 -最后你需要将更改同步到你 fork 得到的远程仓库中: +在提交之前,请确保你 fork 得到的远程仓库与本地同步: ```shell $ git push origin master ``` - -## 提交内容 - -- 阶段一、二:在希冀平台提交你实验仓库的 url(如 `https://cscourse.ustc.edu.cn/vdir/Gitlab/xxx/2023ustc-jianmu-compiler.git`)。 diff --git a/mkdocs.yml b/mkdocs.yml index 3367d6b..47c8a9d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -55,9 +55,9 @@ nav: - IR 自动化生成: lab2/autogen.md - Lab3: - Lab3 简介: lab3/index.md + - Lab3 实验指导: lab3/guidance.md - 后端环境配置: lab3/environment.md - 龙芯汇编介绍: common/asm_intro.md - - Lab3 实验指导: lab3/guidance.md - 栈式分配介绍: lab3/stack_allocation.md - 后端框架介绍: lab3/framework.md - FAQ: faq/README.md From 84ab658a9b7c916f2bbd47bbc8a3d7a0de995cdf Mon Sep 17 00:00:00 2001 From: lxq <877250099@qq.com> Date: Thu, 2 Nov 2023 01:02:22 +0800 Subject: [PATCH 3/4] lab3: explain file structure for stage2 --- docs/lab3/guidance.md | 57 +++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/docs/lab3/guidance.md b/docs/lab3/guidance.md index 66a89a4..c53803a 100644 --- a/docs/lab3/guidance.md +++ b/docs/lab3/guidance.md @@ -2,13 +2,30 @@ ## 阶段一:预热实验 +### 仓库目录结构 + +与预热实验相关的文件如下: + +``` +. +├── ... +├── include +│ ├── common +│ └── codegen/* +└── tests + ├── ... + └── 3-codegen + └── warmup + ├── CMakeLists.txt + ├── ll_cases <- 需要翻译的 ll 代码 + └── stu_cpp <- 学生需要编写的汇编代码手动生成器 +``` + ### 实验内容 实验在 `tests/3-codegen/warmup/ll_cases/` 目录下提供了六个 `.ll` 文件。学生需要在 `tests/3-codegen/warmup/stu_cpp/` 目录中,依次完成 `assign_codegen.cpp`、`float_codegen.cpp`、`global_codegen.cpp`、`function_codegen.cpp`、`icmp_codegen.cpp` 和 `fcmp_codegen.cpp` 六个 C++ 程序中的 TODO。这六个程序运行后应该能够生成 `tests/3-codegen/warmup/ll_cases/` 目录下六个 `.ll` 文件对应的汇编程序。 -### 编译、运行、测试 - -#### 编译 +### 编译 ```shell $ cd 2023ustc-jianmu-compiler @@ -22,7 +39,7 @@ $ make 如果构建成功,你会在 `build` 文件夹下找到 `stu_assign_codegen`, `stu_float_codegen` 等可执行文件。 -#### 运行与测试 +### 运行与测试 !!! note @@ -38,27 +55,27 @@ $ echo $? 你可以通过观察原来的 `.ll` 代码来推断 `echo $?` 应该返回的正确结果,也可以直接使用 `lli` 执行 `.ll` 文件来获取正确结果。 +## 阶段二:编译器后端 + ### 仓库目录结构 -与预热实验相关的文件如下: +与实验第二阶段相关的文件如下: ``` . -├── ... ├── include -│ ├── common -│ └── codegen/* +│ └── codegen/* # 相关头文件 +├── src +│ └── codegen +│ └── CodeGen.cpp <-- 学生需要补全的文件 └── tests - ├── ... - └── 3-codegen - └── warmup - ├── CMakeLists.txt - ├── ll_cases <- 需要翻译的 ll 代码 - └── stu_cpp <- 学生需要编写的汇编代码手动生成器 + ├── 3-codegen + │   └── autogen + │      ├── eval_lab3.sh <-- 测评脚本 + │ └── testcases <-- lab3 第二阶段的测例目录一 + └── testcases_general <-- lab3 第二阶段的测例目录二 ``` -## 阶段二:编译器后端 - ### 实验内容 补全 `src/codegen/CodeGen.cpp` 中的 TODO,并按需修改 `include/codegen/CodeGen.hpp` 等文件,使编译器能够生成正确的汇编代码。 @@ -66,11 +83,11 @@ $ echo $? !!! info "实现约定" 出于简化实验的目的,我们只考核最核心的功能点,对如下情况不做要求: - + - phi 指令:本实验不考核对于 phi 指令的处理 - + - 函数调用传参:本次实验只考核使用寄存器传参的情况,即对于超多参数的栈上传参不做要求 - + 此外,存在部分 `void main() {...}` 的样例,其返回值是未定义的,我们要求这样的主函数通过寄存器 `$a0` 返回 0,以顺利进行测评。 ### 编译 @@ -137,8 +154,6 @@ $ qemu-loongarch64 ./test 在结束测评后,你可以使用 `./cleanup.sh` **清空**上述文件/目录,以保持仓库的清爽。 -#### 测试示例 - 以下是评测脚本的**使用示例**: 以 `./testcases` 为测例目录,使用评测脚本 `test` 模式测试(我们使用正确的实现,但是故意在 `13-complex.cminus` 中制造了语法错误): From 34dfb3734c2fafd00fc65a51a4df2ae516f0e5e2 Mon Sep 17 00:00:00 2001 From: lxq <877250099@qq.com> Date: Thu, 2 Nov 2023 23:36:06 +0800 Subject: [PATCH 4/4] fix typo --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index e1e3672..ea761f4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -38,7 +38,7 @@ - 2023-09-25:第二次作业:3.1a、3.2a、3.10、3.11、3.17、3.19a(教材[1](#textbook)),Deadline:**2023 年 10 月 7 日 14:00** - 2023-10-05:[Lab2](lab2/index.md) 已发布,注意分阶段 Deadline - 2023-10-11:第三次作业:3.27、3.37、4.3、4.5、4.9(教材[1](#textbook)),Deadline:**2023 年 10 月 18 日 16:00** -- 2023-11-01: [lab3](lab3/index.md) 已发布,注意分阶段 Deadline +- 2023-11-01: [Lab3](lab3/index.md) 已发布,注意分阶段 Deadline ## 教学课件