From 8d314198c458c34e86367d2c39e93d6341e9a235 Mon Sep 17 00:00:00 2001 From: origami-b <972397381@qq.com> Date: Sat, 9 Dec 2023 22:00:38 +0800 Subject: [PATCH] task2: while and func - Done --- Student/task2/cpp/func_gen.cpp | 112 +++++++++++++++++++++++++++++++- Student/task2/cpp/while_gen.cpp | 84 +++++++++++++++++++++++- 2 files changed, 193 insertions(+), 3 deletions(-) diff --git a/Student/task2/cpp/func_gen.cpp b/Student/task2/cpp/func_gen.cpp index c30d8f1..e8b0fc0 100644 --- a/Student/task2/cpp/func_gen.cpp +++ b/Student/task2/cpp/func_gen.cpp @@ -1,3 +1,113 @@ -int main(){ +#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(a, b) + // 函数参数类型的vector + std::vector> Ints(2, Int32Type); + + //通过返回值类型与参数类型列表得到函数类型 + auto addFunTy = FunctionType::create(Int32Type, Ints); + + // 由函数类型得到函数 + auto addFun = Function::create(addFunTy, + "add", 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; // 获取add函数的形参,通过Function中的iterator + for (auto arg = addFun->arg_begin(); arg != addFun->arg_end(); arg++) { + args.push_back(*arg); // * 号运算符是从迭代器中取出迭代器当前指向的元素 + } + + builder->create_store(args[0], aAlloca); // store参数a + builder->create_store(args[1], bAlloca); // store参数b + + auto aLoad = builder->create_load(aAlloca); // load参数a + auto bLoad = builder->create_load(bAlloca); // load参数b + + // a+b + auto add = builder->create_iadd(aLoad, bLoad); + + // a+b-1 + auto sub = builder->create_isub(add, CONST_INT(1)); + + builder->create_store(sub, retAlloca); + auto retLoad = builder->create_load(retAlloca); + builder->create_ret(retLoad); + builder->create_ret(retLoad); + + // 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); + + // int a; + auto a = builder->create_alloca(Int32Type); + + // int b; + auto b = builder->create_alloca(Int32Type); + + // int c; + auto c = builder->create_alloca(Int32Type); + + // a = 3; + builder->create_store(CONST_INT(3), a); + + // b = 2; + builder->create_store(CONST_INT(2), b); + + // c = 5; + builder->create_store(CONST_INT(5), c); + + // tmp = add(a, b); + aLoad = builder->create_load(a); + bLoad = builder->create_load(b); + auto tmp = builder->create_call(addFun, {aLoad, bLoad}); + + // ret = c + tmp; + auto cLoad = builder->create_load(c); + auto ret = builder->create_iadd(cLoad, tmp); + builder->create_store(ret, retAlloca); + retLoad = builder->create_load(retAlloca); + builder->create_ret(retLoad); + + std::cout << module->print(); return 0; } diff --git a/Student/task2/cpp/while_gen.cpp b/Student/task2/cpp/while_gen.cpp index c30d8f1..c9ef562 100644 --- a/Student/task2/cpp/while_gen.cpp +++ b/Student/task2/cpp/while_gen.cpp @@ -1,3 +1,83 @@ -int main(){ +#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); + + // int a; + auto a = GlobalVariable::create("a", module, Int32Type, false, CONST_INT(0)); + + // int b; + auto b = GlobalVariable::create("b", module, Int32Type, false, CONST_INT(0)); + + // main函数 + auto mainFun = Function::create(FunctionType::create(Int32Type, {}), + "main", module); + auto bb = BasicBlock::create(module, "entry", mainFun); + // BasicBlock的名字在生成中无所谓,但是可以方便阅读 + builder->set_insert_point(bb); + + auto retAlloca = builder->create_alloca(Int32Type); + + // b=0; + builder->create_store(CONST_INT(0), b); + + // a = 3; + builder->create_store(CONST_INT(3), a); + + // whileBBs + auto condBB = BasicBlock::create(module, "condBB_while", mainFun); + auto trueBB = BasicBlock::create(module, "trueBB_while", mainFun); + auto falseBB = BasicBlock::create(module, "falseBB_while", mainFun); + + builder->create_br(condBB); + + // condBB + builder->set_insert_point(condBB); + auto aLoad = builder->create_load(a); + auto icmp = builder->create_icmp_gt(aLoad, CONST_INT(0)); + builder->create_cond_br(icmp, trueBB, falseBB); + + // trueBB + builder->set_insert_point(trueBB); + aLoad = builder->create_load(a); + auto bLoad = builder->create_load(b); + auto add = builder->create_iadd(bLoad, aLoad); + builder->create_store(add, b); + auto sub = builder->create_isub(aLoad, CONST_INT(1)); + builder->create_store(sub, a); + builder->create_br(condBB); + + // falseBB + builder->set_insert_point(falseBB); + bLoad = builder->create_load(b); + builder->create_store(bLoad, retAlloca); + auto retLoad = builder->create_load(retAlloca); + builder->create_ret(retLoad); + + std::cout << module->print(); return 0; -} +} \ No newline at end of file