From c47d67263f783afb8e598f32f75f9723c6e11312 Mon Sep 17 00:00:00 2001 From: llh21 Date: Wed, 13 Dec 2023 08:50:46 +0800 Subject: [PATCH] =?UTF-8?q?Part2=E7=9A=84=E4=B8=AD=E9=97=B4=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Student/task2/cpp/func_gen.cpp | 135 ++++++++++++++++++++++++++++++++- Student/task2/cpp/if_gen.cpp | 80 ++++++++++++++++++- 2 files changed, 211 insertions(+), 4 deletions(-) diff --git a/Student/task2/cpp/func_gen.cpp b/Student/task2/cpp/func_gen.cpp index c30d8f1..77dd1e6 100644 --- a/Student/task2/cpp/func_gen.cpp +++ b/Student/task2/cpp/func_gen.cpp @@ -1,3 +1,134 @@ -int main(){ - return 0; +#include "BasicBlock.h" +#include "Constant.h" +#include "Function.h" +#include "IRStmtBuilder.h" +#include "Module.h" +#include "Type.h" + +#include +#include + +#ifdef DEBUG // 用于调试信息,大家可以在编译过程中通过" -DDEBUG"来开启这一选项 +#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例 +#else +#define DEBUG_OUTPUT +#endif + +#define CONST_INT(num) \ + ConstantInt::create(num, module) + +#define CONST_FP(num) \ + ConstantFloat::create(num, module) // 得到常数值的表示,方便后面多次用到 + +using namespace SysYF::IR; + +int main() { + auto module = Module::create("SysYF code"); // module name是什么无关紧要 + auto builder = IRStmtBuilder::create(nullptr, module); + SysYF::Ptr Int32Type = Type::get_int32_type(module); + + + // add函数 + // 函数参数类型的vector + std::vector> Ints(2, Int32Type); + + //通过返回值类型与参数类型列表得到函数类型 + auto addFunTy = FunctionType::create(Int32Type, Ints); + + // 由函数类型得到函数 + auto addFun = Function::create(addFunTy, + "addFun", module); + + // BB的名字在生成中无所谓,但是可以方便阅读 + auto bb = BasicBlock::create(module, "entry", addFun); + + builder->set_insert_point(bb); // 一个BB的开始,将当前插入指令点的位置设在bb + + + auto retAlloca = builder->create_alloca(Int32Type); // 在内存中分配返回值的位置 + auto aAlloca = builder->create_alloca(Int32Type); // 在内存中分配参数a的位置 + auto bAlloca = builder->create_alloca(Int32Type); // 在内存中分配参数b的位置 + + std::vector> args; // 获取climbStairs函数的形参,通过Function中的iterator + for (auto arg = addFun->arg_begin(); arg != addFun->arg_end(); arg++) { + args.push_back(*arg); // * 号运算符是从迭代器中取出迭代器当前指向的元素 + } + + + builder->create_store(args[0], aAlloca); // store参数n + + builder->create_store(args[1], bAlloca); // store参数n + + + auto aLoad = builder->create_load(aAlloca); + auto bLoad = builder->create_load(bAlloca); + + auto add = builder->create_iadd(aLoad, bLoad); + auto sub = builder->create_isub(add, CONST_INT(1)); + + // ret + builder->create_ret(sub); + + + // main函数 + auto mainFun = Function::create(FunctionType::create(Int32Type, {}), + "main", module); + bb = BasicBlock::create(module, "entry", mainFun); + // BasicBlock的名字在生成中无所谓,但是可以方便阅读 + builder->set_insert_point(bb); + + retAlloca = builder->create_alloca(Int32Type); + auto resAlloca = builder->create_alloca(Int32Type); + + aAlloca = builder->create_alloca(Int32Type); + bAlloca = builder->create_alloca(Int32Type); + auto cAlloca = builder->create_alloca(Int32Type); + builder->create_store(CONST_INT(3), aAlloca); + builder->create_store(CONST_INT(2), bAlloca); + builder->create_store(CONST_INT(5), cAlloca); + + aLoad = builder->create_load(aAlloca); + bLoad = builder->create_load(bAlloca); + auto cLoad = builder->create_load(cAlloca); + + auto call = builder->create_call(addFun, {aLoad, bLoad}); // 为什么这里传的是{add}呢? + add = builder->create_iadd(cLoad, call); + + builder->create_ret(add); + +// auto num0Gep = builder->create_gep(num, {CONST_INT(0), CONST_INT(0)}); // GEP: 这里为什么是{0, 0}呢? (实验报告相关) +// auto num0Load = builder->create_load(num0Gep); +// builder->create_store(num0Load, n); + +// auto tmpLoad = builder->create_load(tmp); +// auto numGep = builder->create_gep(num, {CONST_INT(0), tmpLoad}); +// auto numLoad = builder->create_load(numGep); +// auto x0Gep = builder->create_gep(x, {CONST_INT(0), CONST_INT(0)}); +// builder->create_store(numLoad, x0Gep); + +// nLoad = builder->create_load(n); +// tmpLoad = builder->create_load(tmp); +// add = builder->create_iadd(nLoad, tmpLoad); +// auto call = builder->create_call(addFun, {add}); // 为什么这里传的是{add}呢? +// builder->create_store(call, resAlloca); + +// auto resLoad = builder->create_load(resAlloca); +// x0Gep = builder->create_gep(x, {CONST_INT(0), CONST_INT(0)}); +// auto x0Load = builder->create_load(x0Gep); +// sub = builder->create_isub(resLoad, x0Load); +// builder->create_store(sub, retAlloca); +// retLoad = builder->create_load(retAlloca); +// builder->create_ret(retLoad); + + // 给这么多注释了,但是可能你们还是会弄很多bug + // 所以强烈建议配置AutoComplete,效率会大大提高! + // 别人配了AutoComplete,只花1小时coding + // 你没有配AutoComplete,找method花5小时,debug花5小时,肯定哭唧唧! + // 最后,如果猜不到某个IR指令对应的C++的函数,建议把指令翻译成英语然后在method列表中搜索一下 + // 最后的最后,这个例子只涉及到了一点基本的指令生成, + // 对于额外的指令,包括数组,在之后的实验中可能需要大家好好搜索一下思考一下, + // 还有涉及到的C++语法,可以在gitlab上发issue提问或者向大家提供指导 + // 对于这个例子里的代码风格/用法,如果有好的建议也欢迎提出! + std::cout << module->print(); + return 0; } diff --git a/Student/task2/cpp/if_gen.cpp b/Student/task2/cpp/if_gen.cpp index c30d8f1..773525c 100644 --- a/Student/task2/cpp/if_gen.cpp +++ b/Student/task2/cpp/if_gen.cpp @@ -1,3 +1,79 @@ -int main(){ - return 0; +#include "BasicBlock.h" +#include "Constant.h" +#include "Function.h" +#include "IRStmtBuilder.h" +#include "Module.h" +#include "Type.h" + +#include +#include + +#ifdef DEBUG // 用于调试信息,大家可以在编译过程中通过" -DDEBUG"来开启这一选项 +#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例 +#else +#define DEBUG_OUTPUT +#endif + +#define CONST_INT(num) \ + ConstantInt::create(num, module) + +#define CONST_FP(num) \ + ConstantFloat::create(num, module) // 得到常数值的表示,方便后面多次用到 + +using namespace SysYF::IR; + +int main() { + auto module = Module::create("SysYF code"); // module name是什么无关紧要 + auto builder = IRStmtBuilder::create(nullptr, module); + SysYF::Ptr Int32Type = Type::get_int32_type(module); + + auto zero_initializer = ConstantZero::create(Int32Type, module); + auto a = GlobalVariable::create("a", module, Int32Type, false, zero_initializer); + + // climbStairs函数 + // 函数参数类型的vector + std::vector> Ints(1, Int32Type); + + //通过返回值类型与参数类型列表得到函数类型 + auto climbStairsFunTy = FunctionType::create(Int32Type, Ints); + + // main函数 + auto mainFun = Function::create(FunctionType::create(Int32Type, {}), + "main", module); + auto bb = BasicBlock::create(module, "entry", mainFun); + // BasicBlock的名字在生成中无所谓,但是可以方便阅读 + builder->set_insert_point(bb); + + + + builder->create_store(CONST_INT(10), a); + auto aLoad = builder->create_load(a); + + auto trueBB = BasicBlock::create(module, "trueBB_if", mainFun); // true分支 + auto falseBB = BasicBlock::create(module, "falseBB_if", mainFun); // false分支 + + + auto icmp = builder->create_icmp_lt(CONST_INT(0), aLoad); + builder->create_cond_br(icmp, trueBB, falseBB); + + builder->set_insert_point(trueBB); + + builder->create_ret(aLoad); + + + builder->set_insert_point(falseBB); + + builder->create_ret(CONST_INT(0)); + + // 给这么多注释了,但是可能你们还是会弄很多bug + // 所以强烈建议配置AutoComplete,效率会大大提高! + // 别人配了AutoComplete,只花1小时coding + // 你没有配AutoComplete,找method花5小时,debug花5小时,肯定哭唧唧! + // 最后,如果猜不到某个IR指令对应的C++的函数,建议把指令翻译成英语然后在method列表中搜索一下 + // 最后的最后,这个例子只涉及到了一点基本的指令生成, + // 对于额外的指令,包括数组,在之后的实验中可能需要大家好好搜索一下思考一下, + // 还有涉及到的C++语法,可以在gitlab上发issue提问或者向大家提供指导 + // 对于这个例子里的代码风格/用法,如果有好的建议也欢迎提出! + std::cout << module->print(); + return 0; }