master
GreenDay 2 years ago
parent b326312136
commit 38a70ce170

4
.gitignore vendored

@ -1,3 +1,3 @@
.vscode
build
.vscode
build

@ -1,3 +1,50 @@
int main(){
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRStmtBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
#include <memory>
#ifdef DEBUG
#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");
auto builder = IRStmtBuilder::create(nullptr, module);
SysYF::Ptr<Type> Int32Type = Type::get_int32_type(module);
SysYF::Ptr<Type> FloatType = Type::get_float_type(module);
SysYF::Ptr<Type> ArrayType = Type::get_array_type(Int32Type, 2);
auto mainFun = Function::create(FunctionType::create(Int32Type, {}),
"main", module);
auto bb = BasicBlock::create(module, "entry", mainFun);
builder->set_insert_point(bb);
auto bAlloca = builder->create_alloca(FloatType);
auto aAlloca = builder->create_alloca(ArrayType);
builder->create_store(CONST_FP(1.8), bAlloca);
auto bLoad = builder->create_load(bAlloca);
auto a0Gep = builder->create_gep(aAlloca, {CONST_INT(0), CONST_INT(0)});
builder->create_store(CONST_INT(2), a0Gep);
auto a0Load = builder->create_load(a0Gep);
auto a0siToFp = builder->create_sitofp(a0Load, FloatType);
auto fmul = builder->create_fmul(a0siToFp, bLoad);
auto FpToSi = builder->create_fptosi(fmul, Int32Type);
auto a1Gep = builder->create_gep(aAlloca, {CONST_INT(0), CONST_INT(1)});
builder->create_store(FpToSi, a1Gep);
auto a1Load = builder->create_load(a1Gep);
builder->create_ret(a1Load);
std::cout << module->print();
return 0;
}

@ -1,3 +1,79 @@
int main(){
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRStmtBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
#include <memory>
#ifdef DEBUG
#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(int argc, const char * argv[]) {
auto module = Module::create("SysYF code");
auto builder = IRStmtBuilder::create(nullptr, module);
SysYF::Ptr<Type> Int32Type = Type::get_int32_type(module);
SysYF::Ptr<Type> FloatType = Type::get_float_type(module);
SysYF::Ptr<Type> ArrayType = Type::get_array_type(Int32Type, 2);
std::vector<SysYF::Ptr<Type>> Ints(2, Int32Type);
//add函数
auto addFunTy = FunctionType::create(Int32Type, Ints);
auto addFun = Function::create(addFunTy,
"add", module);
auto bb = BasicBlock::create(module, "entry", addFun);
builder->set_insert_point(bb);
auto a_add_alloc = builder->create_alloca(Int32Type);
auto b_add_alloc = builder->create_alloca(Int32Type);
auto ret_add_alloc = builder->create_alloca(Int32Type);
std::vector<SysYF::Ptr<Value>> args; // 获取climbStairs函数的形参,通过Function中的iterator
for (auto arg = addFun->arg_begin(); arg != addFun->arg_end(); arg++) {
args.push_back(*arg); // * 号运算符是从迭代器中取出迭代器当前指向的元素
}
builder->create_store(args[0], a_add_alloc);
builder->create_store(args[1], b_add_alloc);
auto a_add_load = builder->create_load(a_add_alloc);
auto b_add_load = builder->create_load(b_add_alloc);
auto add = builder->create_iadd(a_add_load, b_add_load);
auto sub = builder->create_isub(add, CONST_INT(1));
builder->create_store(sub, ret_add_alloc);
auto ret_add_load = builder->create_load(ret_add_alloc);
builder->create_ret(ret_add_load);
//main函数
auto mainFun = Function::create(FunctionType::create(Int32Type, {}),
"main", module);
bb = BasicBlock::create(module, "entry", mainFun);
builder->set_insert_point(bb);
auto a_main_alloc = builder->create_alloca(Int32Type);
auto b_main_alloc = builder->create_alloca(Int32Type);
auto c_main_alloc = builder->create_alloca(Int32Type);
builder->create_store(CONST_INT(2), a_main_alloc);
builder->create_store(CONST_INT(3), b_main_alloc);
builder->create_store(CONST_INT(5), c_main_alloc );
auto a_main_load = builder->create_load(a_main_alloc);
auto b_main_load = builder->create_load(b_main_alloc);
auto c_main_load = builder->create_load(c_main_alloc);
auto call = builder->create_call(addFun, {a_main_load,b_main_load});
auto add_main = builder->create_iadd(call, c_main_load);
builder->create_ret(add_main);
std::cout << module->print();
return 0;
}

@ -1,3 +1,67 @@
int main(){
return 0;
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRStmtBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
#include <memory>
#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("if_test.sy"); // module name是if_test
auto builder = IRStmtBuilder::create(nullptr, module);
SysYF::Ptr<Type> Int32Type = Type::get_int32_type(module);
// 生成一个全局变量a
auto zero_initializer = ConstantZero::create(Int32Type, module);
auto a = GlobalVariable::create("a", module, Int32Type, false, zero_initializer);
// 生成main函数
auto mainFun = Function::create(FunctionType::create(Int32Type, {}),
"main", module);
// 生成一个基本块并进入
auto entry = BasicBlock::create(module, "entry", mainFun);
builder->set_insert_point(entry);
// 给a赋值给10。
builder->create_store(CONST_INT(10), a); // store参数n
// 把a加载到寄存器
auto aReg = builder->create_load(a);
// 创造一个比较语句就是说a>0
auto icmp = builder->create_icmp_gt(aReg, CONST_INT(0)); // n和4的比较
// 创造两个基本块,真 or 假
auto trueBB = BasicBlock::create(module, "true", mainFun); // true分支
auto falseBB = BasicBlock::create(module, "false", mainFun); // false分支
// 创建一个分支br
builder->create_cond_br(icmp, trueBB, falseBB);
// 构建真的返回
builder->set_insert_point(trueBB);
builder->create_ret(aReg);
// 构建假的返回
builder->set_insert_point(falseBB);
builder->create_ret(CONST_INT(0));
std::cout << module->print();
return 0;
}

@ -1,3 +1,84 @@
int main(){
return 0;
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRStmtBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
#include <memory>
#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("if_test.sy"); // module name是if_test
auto builder = IRStmtBuilder::create(nullptr, module);
SysYF::Ptr<Type> Int32Type = Type::get_int32_type(module);
// 生成全局变量a, b
auto zero_initializer = ConstantZero::create(Int32Type, module);
auto a = GlobalVariable::create("a", module, Int32Type, false, zero_initializer);
auto b = GlobalVariable::create("b", module, Int32Type, false, zero_initializer);
// 生成main函数
auto mainFun = Function::create(FunctionType::create(Int32Type, {}),
"main", module);
// 生成一个基本块并进入
auto entry = BasicBlock::create(module, "entry", mainFun);
builder->set_insert_point(entry);
// 给b,a赋值0,3
builder->create_store(CONST_INT(0), b);
builder->create_store(CONST_INT(3), a);
// 设置三个BasicBlock
auto while_cond = BasicBlock::create(module, "while_cond", mainFun);
auto while_body = BasicBlock::create(module, "while_body", mainFun);
auto while_end = BasicBlock::create(module, "while_end", mainFun);
// 跳转while_cond
builder->create_br(while_cond);
// while_cond
builder->set_insert_point(while_cond);
// 把a加载到寄存器
auto aReg = builder->create_load(a);
// 创造一个比较语句就是说a>0
auto icmp = builder->create_icmp_gt(aReg, CONST_INT(0)); // n和4的比较
// 创建一个分支br
builder->create_cond_br(icmp, while_body, while_end);
// while_body
builder->set_insert_point(while_body);
// b = b + 1
auto aReg2 = builder->create_load(a);
auto bReg2 = builder->create_load(b);
auto abReg = builder->create_iadd(aReg2, bReg2);
builder->create_store(abReg, b);
// a = a - 1此时可以优化编译流程不重新加载a
auto aReg3 = builder->create_isub(aReg2, CONST_INT(1));
builder->create_store(aReg3, a);
// 跳转
builder->create_br(while_cond);
// while_body
builder->set_insert_point(while_end);
// 构建假的返回
auto bReg3 = builder->create_load(b);
builder->create_ret(bReg3);
std::cout << module->print();
return 0;
}

@ -11,6 +11,8 @@
1-2 函数调用语句的格式是call <return-type> @<func-name>(<para-type> <para-reg>),包含了返回值类型,参数类型及其具体值。
2-1 两种 LLVM IR 的不同之处在于第一行getelementptr有4个参数其中前两个参数分别代表数组类型和指针类型后两个参数代表数组相对于的基址偏移量。第三个参数应当为0代表数组的序号。因为`[10 x i32]* %1`被认为是一个指向数组的指针所以应当首先确定该指针指向第几个数组因为只有一个数组因此第三个参数只能为0然后再确定数组内部的偏移量。第二行getelementptr有3个参数前两个参数与第一行含义相同第三个参数等效于第一行的第四个参数因为`i32* %1`本身就指向整形,因此只用一个参数就能确定偏移量。
## 实验设计
## 实验难点及解决方案

Loading…
Cancel
Save