From bcb3705ce2b2b68e9eb675e4e38888cdb34fc246 Mon Sep 17 00:00:00 2001 From: Gjmustc Date: Fri, 22 Dec 2023 22:09:55 +0800 Subject: [PATCH] rm builder.cpp --- src/SysYFIRBuilder/builder.cpp | 1625 -------------------------------- 1 file changed, 1625 deletions(-) delete mode 100644 src/SysYFIRBuilder/builder.cpp diff --git a/src/SysYFIRBuilder/builder.cpp b/src/SysYFIRBuilder/builder.cpp deleted file mode 100644 index bb5091a..0000000 --- a/src/SysYFIRBuilder/builder.cpp +++ /dev/null @@ -1,1625 +0,0 @@ -#include "IRBuilder.h" - -#include -#include -#include - -#define DEBUG - -#ifdef DEBUG -#define DBGLOG(text) std::cout << text << std::endl -#define DEBUG_OUTPUT ; -#endif -#ifndef DEBUG -#define DBGLOG(text) -#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl -#endif - -namespace SysYF -{ - namespace IR - { -#define CONST_INT(num) ConstantInt::create(num, module) -#define CONST_FLOAT(num) ConstantFloat::create(num, module) - - // You can define global variables here - // to store state - typedef struct - { - bool is_int; - int ival; - float fval; - } Oprand; - Oprand expr_cal_result; // 便于全局变量中表达式计算值中转 - std::vector multi_arr_init; - class GlobalConst - { - public: - GlobalConst() {} - ~GlobalConst() = default; - void add_int_const(std::string name, int val) - { - if (iconst_map.find(name) == iconst_map.end()) - { // 新加入的不是数组元素 - std::vector temp(1, val); - iconst_map.insert(std::make_pair(name, temp)); - } - else // 新加入的是数组元素 - iconst_map[name].push_back(val); - } - void add_float_const(std::string name, float val) - { - if (fconst_map.find(name) == fconst_map.end()) - { // 新加入的不是数组元素 - std::vector temp(1, val); - fconst_map.insert(std::make_pair(name, temp)); - } - else // 新加入的是数组元素 - fconst_map[name].push_back(val); - } - bool get_int_const(std::string name, int offset, int &val) // 若非数组则offset=0 - { - if (iconst_map.find(name) != iconst_map.end()) - { - val = iconst_map[name][offset]; - return true; - } - else - return false; - } - bool get_float_const(std::string name, int offset, float &val) - { - if (fconst_map.find(name) != fconst_map.end()) - { - val = fconst_map[name][offset]; - return true; - } - else - return false; - } - - private: - std::map> iconst_map; - std::map> fconst_map; - }; - GlobalConst _const_table = GlobalConst(); - - std::vector> FuncParas; - SysYF::Ptr Para; - std::string name_; - std::vector names; - - int Ifnum = 0; - int ReturnNum = 0; - Ptr retAlloca; - SysYF::Ptr retbb; - - /* enum Condtype - { - equal, - greater, - less, - ge, - le, - notequal - - }condtype_; */ - /* SysYF::Ptr _cmp; */ - // store temporary value - Ptr tmp_val = nullptr; // 存储需要全局处理的expr node - Ptr lhs_addr = nullptr; - Ptr func_parent; // 便于在创建新的bb时获得对应的func_parent - int bb_label_num = 0; // 全局控制bb标签编号 - bool func_first_bb; // 处理一个func域里有多个{},只创建一个scope - PtrVec break_point; - PtrVec continue_point; // 维护两个vector(栈)控制循环break和continue应跳转到的目标地址 - // types - Ptr VOID_T; - Ptr INT1_T; - Ptr INT32_T; - Ptr FLOAT_T; - Ptr INT32PTR_T; - Ptr FLOATPTR_T; - - void IRBuilder::visit(SyntaxTree::Assembly &node) - { - VOID_T = Type::get_void_type(module); - INT1_T = Type::get_int1_type(module); - INT32_T = Type::get_int32_type(module); - FLOAT_T = Type::get_float_type(module); - INT32PTR_T = Type::get_int32_ptr_type(module); - FLOATPTR_T = Type::get_float_ptr_type(module); - for (const auto &def : node.global_defs) - { - def->accept(*this); - } - } - - // You need to fill them - - void IRBuilder::visit(SyntaxTree::InitVal &node) - { - /* DBGLOG("Begin of Initval"); */ - // 可能有一个或多个value需要初始化,elementList方便迭代accept - if (node.isExp) - { - node.expr->accept(*this); - multi_arr_init.push_back(expr_cal_result); - } - else - { - for (auto item : node.elementList) - { - item->accept(*this); - } - } - /* DBGLOG("End of Initval"); */ - } - - void IRBuilder::visit(SyntaxTree::FuncDef &node) - { - /* DBGLOG("Begin of FuncDef"); */ - Ptr RetType; - switch (node.ret_type) - { - case SysYF::SyntaxTree::Type::VOID: - RetType = VOID_T; - break; - case SysYF::SyntaxTree::Type::INT: - RetType = INT32_T; - break; - case SysYF::SyntaxTree::Type::FLOAT: - RetType = FLOAT_T; - break; - default: - break; - } - node.param_list->accept(*this); - auto FuncTY = FunctionType::create(RetType, FuncParas); - auto Func = Function::create(FuncTY, node.name, module); - func_parent = Func; // 标记当前func_parent(便于后续bb调用) - - scope.push(node.name, Func); - scope.enter(); - auto bb = BasicBlock::create(module, node.name + "_entry", Func); - builder->set_insert_point(bb); - func_first_bb = true; // 设置为第一次进入该func的bb{} - - ReturnNum = 0; - - if (RetType != VOID_T) - { - retAlloca = builder->create_alloca(RetType); - if (RetType == INT32_T) - builder->create_store(CONST_INT(0), retAlloca); - else if (RetType == FLOAT_T) - builder->create_store(CONST_FLOAT(0), retAlloca); - } - - std::vector> args; - for (auto arg = Func->arg_begin(); arg != Func->arg_end(); arg++) - { - args.push_back(*arg); - } - for (size_t i = 0; i < names.size(); i++) - { - auto pAlloca = builder->create_alloca(FuncParas[i]); - builder->create_store(args[i], pAlloca); - scope.push(names[i], pAlloca); - } - - retbb = BasicBlock::create(module, node.name + "_ret", Func); - - node.body->accept(*this); - - if (!builder->get_insert_block()->get_terminator()) - builder->create_br(retbb); - - builder->set_insert_point(retbb); - if (RetType == VOID_T) - { - builder->create_void_ret(); - } - else - { - auto retLoad = builder->create_load(retAlloca); - builder->create_ret(retLoad); - } - /* builder->create_br(retbb); */ - /* scope.exit(); */ - /* DBGLOG("End of FuncDef"); */ - } - - void IRBuilder::visit(SyntaxTree::FuncFParamList &node) - { - FuncParas.clear(); - names.clear(); - for (auto &p : node.params) - { - p->accept(*this); - FuncParas.push_back(Para); - names.push_back(name_); - } - assert(FuncParas.size() == names.size()); - } - - void IRBuilder::visit(SyntaxTree::FuncParam &node) - { - name_ = node.name; - if (node.array_index.size()) - { - // 数组 - if (node.param_type == SysYF::SyntaxTree::Type::INT) - Para = INT32PTR_T; - else if (node.param_type == SysYF::SyntaxTree::Type::FLOAT) - Para = FLOATPTR_T; - } - else - { - // 非数组 - if (node.param_type == SysYF::SyntaxTree::Type::INT) - Para = INT32_T; - else if (node.param_type == SysYF::SyntaxTree::Type::FLOAT) - Para = FLOAT_T; - } - } - - void IRBuilder::visit(SyntaxTree::VarDef &node) - { - /* DBGLOG("Begin of VarDef"); */ - // 变量定义:判断是否是全局变量,判断是否是const,判断是否是数组类型 - // 获取变量类型和变量名字,分配变量存储空间,若有需要初始化变量 - Ptr vartype; - if (node.btype == SyntaxTree::Type::INT) - vartype = INT32_T; - else - vartype = FLOAT_T; - // if分级判断逻辑:全局or局部->数组or单变量->const of 非const(本次实验不涉及局部数组常量)->初始化or未初始化 - if (scope.in_global()) // 全局变量 - { - if (!node.array_length.empty()) // 数组类型 - { - // 目前只考虑一维数组,多维数组需要处理vector类型的array_length得到各维度长度 - std::vector arr_len; - unsigned total_ = 1; - for (int i = 0; i < node.array_length.size(); i++) - { - node.array_length[i]->accept(*this); - arr_len.push_back(expr_cal_result.ival); - total_ *= expr_cal_result.ival; - } - Ptr arr_type = ArrayType::create(vartype, total_); - if (node.is_inited) - { - PtrVec init_val; // 待push_back,多维转线性排列 - int last_dim = arr_len.back(); - int line_idx = 0; - for (auto val : node.initializers->elementList) // 每一个val都是一个InitVal,可能是expr,也可能是elementlist - { - multi_arr_init.clear(); - val->accept(*this); - for (int i = 0; i < multi_arr_init.size(); i++) - { - Oprand tmp = multi_arr_init[i]; - if (vartype == INT32_T) - { - int temp = (tmp.is_int) ? tmp.ival : int(tmp.fval); - init_val.push_back(std::static_pointer_cast(CONST_INT(temp))); - if (node.is_constant) - _const_table.add_int_const(node.name, temp); - } - else if (vartype == FLOAT_T) - { - float temp = (tmp.is_int) ? float(tmp.ival) : tmp.fval; - init_val.push_back(std::static_pointer_cast(CONST_FLOAT(temp))); - if (node.is_constant) - _const_table.add_float_const(node.name, temp); - } - - } - } - // 全局变量剩余部分初始化为0 - for (int i = init_val.size(); i < arr_len; i++) - { - if (vartype == INT32_T) - { - init_val.push_back(std::static_pointer_cast(CONST_INT(0))); - if (node.is_constant) - _const_table.add_int_const(node.name, 0); - } - else if (vartype == FLOAT_T) - { - init_val.push_back(std::static_pointer_cast(CONST_FLOAT(0))); - if (node.is_constant) - _const_table.add_float_const(node.name, 0.0f); - } - } - auto initializer = ConstantArray::create(arr_type, init_val); - auto Global_array = GlobalVariable::create(node.name, module, arr_type, node.is_constant, std::static_pointer_cast(initializer)); - scope.push(node.name, Global_array); - } - else // 未显式初始化,全为0 - { - if (node.is_constant) - { - for (int i = 0; i < arr_len; i++) - { - if (vartype == INT32_T) - _const_table.add_int_const(node.name, 0); - else - _const_table.add_float_const(node.name, 0.0f); - } - } - auto initializer = ConstantZero::create(arr_type, module); - auto Global_array = GlobalVariable::create(node.name, module, arr_type, node.is_constant, std::static_pointer_cast(initializer)); - scope.push(node.name, Global_array); - } - } - else // 单变量 - { - if (node.is_inited) - { // 只能是Ptr类型 - node.initializers->expr->accept(*this); - Ptr init_val; - if (vartype == INT32_T) - { - int temp = (expr_cal_result.is_int) ? expr_cal_result.ival : int(expr_cal_result.fval); - init_val = std::static_pointer_cast(CONST_INT(temp)); - if (node.is_constant) - _const_table.add_int_const(node.name, temp); - } - else if (vartype == FLOAT_T) - { - float temp = (expr_cal_result.is_int) ? float(expr_cal_result.ival) : expr_cal_result.fval; - init_val = std::static_pointer_cast(CONST_FLOAT(temp)); - if (node.is_constant) - _const_table.add_float_const(node.name, temp); - } - auto Global_val = GlobalVariable::create(node.name, module, vartype, node.is_constant, init_val); - scope.push(node.name, Global_val); - } - else - { - if (node.is_constant) - { - if (vartype == INT32_T) - _const_table.add_int_const(node.name, 0); - else - _const_table.add_float_const(node.name, 0.0f); - } - auto init_val = ConstantZero::create(vartype, module); - auto Global_val = GlobalVariable::create(node.name, module, vartype, node.is_constant, std::static_pointer_cast(init_val)); - scope.push(node.name, Global_val); - } - } - } - else // 局部变量 - { - if (!node.array_length.empty()) // 数组类型(不考虑const数组) - { - node.array_length[0]->accept(*this); - int arr_len = expr_cal_result.ival; - /* DBGLOG(arr_len); */ - Ptr arr_type = ArrayType::get(vartype, arr_len); - /* Ptr arr_type = PointerType::get(vartype); */ - auto arr_val_alloca = builder->create_alloca(arr_type); - - if (node.is_inited) // 若未显式初始化,则初始值未知 - { - /* DBGLOG(node.initializers->elementList.size()); */ - int arrIdx = 0; // gep类指令计算每个元素地址 - for (auto val : node.initializers->elementList) - { - val->expr->accept(*this); - // 此时的类型转换IR指令为显式的 - if (tmp_val->get_type() != vartype) // tmp_val为Ptr类型,便于生成类型转换IR - { - if (vartype == INT32_T) - tmp_val = builder->create_fptosi(tmp_val, INT32_T); - else - tmp_val = builder->create_sitofp(tmp_val, FLOAT_T); - } - // 根据初始化值store到对应的gep地址中 - auto val_addr = builder->create_gep(arr_val_alloca, {CONST_INT(0), CONST_INT(arrIdx)}); - builder->create_store(tmp_val, val_addr); - arrIdx++; - } - } - scope.push(node.name, arr_val_alloca); - } - else // 单变量, tmp_val便于发射类型转换ir,expr_cal_result便于维护常量表 - { - auto var_alloca = builder->create_alloca(vartype); - if (node.is_inited) - { - node.initializers->expr->accept(*this); - if (tmp_val->get_type() != vartype) - { - if (vartype == INT32_T) - tmp_val = builder->create_fptosi(tmp_val, INT32_T); - else - tmp_val = builder->create_sitofp(tmp_val, FLOAT_T); - } - if (node.is_constant) - { - if (vartype == INT32_T) - { - int temp = (expr_cal_result.is_int) ? expr_cal_result.ival : int(expr_cal_result.fval); - _const_table.add_int_const(node.name, temp); - } - else - { - float temp = (expr_cal_result.is_int) ? float(expr_cal_result.ival) : expr_cal_result.fval; - _const_table.add_float_const(node.name, temp); - } - } - builder->create_store(tmp_val, var_alloca); - } - scope.push(node.name, var_alloca); - } - } - /* DBGLOG("End of VarDef"); */ - } - - void IRBuilder::visit(SyntaxTree::LVal &node) - { - /* DBGLOG("Begin of LVal"); */ - /* DBGLOG(node.name); */ - if (scope.in_global()) // 在全局变量初始化时,InitVal 中的初始值为 Exp时可以引用左值变量 - { - /* DBGLOG("Begin of LVal if"); */ - int tmp1; - float tmp2; - int offset = 0; - if (!node.array_index.empty()) - { - // 暂时只考虑一维数组 - node.array_index[0]->accept(*this); - offset = expr_cal_result.ival; - } - if (_const_table.get_int_const(node.name, offset, tmp1)) - { - expr_cal_result.is_int = true; - expr_cal_result.ival = tmp1; - } - else if (_const_table.get_float_const(node.name, offset, tmp2)) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = tmp2; - } - } - else // 并非处于全局域,左值为被赋值对象(store)或赋值对象(load)(函数调用的情形在funcall里处理) - { - /* DBGLOG("Begin of LVal else"); */ - auto lval_addr = scope.find(node.name, false); - bool IsArray = false; - if (!node.array_index.empty()) // 数组左值, 需要先发射gep指令,再发射load指令 - { - /* DBGLOG("array"); */ - node.array_index[0]->accept(*this); - assert(lval_addr != nullptr); - /* DBGLOG(node.name); - DBGLOG(lval_addr->get_type()->get_type_id()); */ - // DEBUG_OUTPUT; - - if (lval_addr->get_type()->get_pointer_element_type()->is_array_type()) // 左值非指针 - { - /* DBGLOG("In LVal array"); */ // a[4] - auto lval = builder->create_gep(lval_addr, {CONST_INT(0), tmp_val}); - lhs_addr = lval; - tmp_val = builder->create_load(lval); - IsArray = true; - } - else // 左值是指针 - { //(*a)[4] - - auto ptr = builder->create_load(lval_addr); - auto lval = builder->create_gep(ptr, {tmp_val}); // 没有CONST_INT(0),基址是ptr - lhs_addr = lval; - tmp_val = builder->create_load(lval); - } - } - else if (lval_addr->get_type()->get_pointer_element_type()->is_pointer_type()) - { //*a - tmp_val = builder->create_load(lval_addr); // load得到的是指针值 - lhs_addr = lval_addr; - } - else - { // a - tmp_val = builder->create_load(lval_addr); - lhs_addr = lval_addr; - } - } - /* DBGLOG("End of LVal"); */ - } - - void IRBuilder::visit(SyntaxTree::AssignStmt &node) - { - /* DBGLOG("Begin of Assign"); - */ - /* DBGLOG(node.target->name); */ - node.target->accept(*this); - auto lhs = tmp_val; - auto lhs_addr_ = lhs_addr; - node.value->accept(*this); - auto rhs = tmp_val; - auto lhstype = lhs->get_type(); // 获左值类型 - - /* DBGLOG(lhstype->get_type_id()); */ - auto rhstype = rhs->get_type(); - /* DBGLOG(rhstype->get_type_id()); */ - // 检查是否需要显式类型转换和符号扩展ir指令 - if (rhstype == INT1_T) - { - rhs = builder->create_zext(rhs, INT32_T); - rhstype = INT32_T; - } - if (lhstype != rhstype) - { - if (lhstype == INT32_T) - rhs = builder->create_fptosi(rhs, INT32_T); - else - { - /* DBGLOG("create "); */ - rhs = builder->create_sitofp(rhs, FLOAT_T); - } - } - builder->create_store(rhs, lhs_addr_); - /* DBGLOG("End of Assign"); */ - } - - void IRBuilder::visit(SyntaxTree::Literal &node) - { - /* DBGLOG("Begin of Literal"); */ - if (node.literal_type == SyntaxTree::Type::INT) - { - tmp_val = CONST_INT(node.int_const); - expr_cal_result.is_int = true; - expr_cal_result.ival = node.int_const; - } - else if (node.literal_type == SyntaxTree::Type::FLOAT) - { - tmp_val = CONST_FLOAT(node.float_const); - expr_cal_result.is_int = false; - expr_cal_result.fval = node.float_const; - } - else - { - // DBGLOG("error at literal"); - } - - /* DBGLOG("End of Literal"); */ - } - - void IRBuilder::visit(SyntaxTree::ReturnStmt &node) - { - /* DBGLOG("Begin of Return"); */ - auto RetType = builder->get_insert_block()->get_parent()->get_return_type(); - /* auto funName = builder->get_insert_block()->get_parent()->get_name(); - char num_[10]; - sprintf(num_, "%d", ReturnNum++); */ - /* retbb = BasicBlock::create(module, funName + "_ret_" + num_, func_parent); - */ - if (!RetType->is_void_type()) - { - node.ret->accept(*this); - auto tmpType = tmp_val->get_type(); - /* builder->create_br(retbb); - builder->set_insert_point(retbb); */ - if (tmpType != RetType) - { - if (RetType == FLOAT_T) - { - if (tmpType == INT1_T) - // INT1 to INT32 - tmp_val = builder->create_zext(tmp_val, INT32_T); - // INT32 to FLOAT - tmp_val = builder->create_sitofp(tmp_val, FLOAT_T); - } - else if (RetType == INT32_T) - { - // INT1 to INT32 - if (tmpType == INT1_T) - tmp_val = builder->create_zext(tmp_val, INT32_T); - else if (tmpType == FLOAT_T) - // FLOAT to INT32 - tmp_val = builder->create_fptosi(tmp_val, INT32_T); - } - } - builder->create_store(tmp_val, retAlloca); - } - builder->create_br(retbb); - /* DBGLOG("End of Return"); */ - } - - void IRBuilder::visit(SyntaxTree::BlockStmt &node) - { - if (func_first_bb == true) - func_first_bb = false; // 后续不是firstbb - else - scope.enter(); - for (auto stmt : node.body) - { - stmt->accept(*this); - } - scope.exit(); - } - - void IRBuilder::visit(SyntaxTree::EmptyStmt &node) {} - - void IRBuilder::visit(SyntaxTree::ExprStmt &node) - { - node.exp->accept(*this); - } - - void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) - { - // 返回icmp或/fcmp与0相比的结果到全局变量tmp_val,发射对应ir指令 - node.rhs->accept(*this); - auto rhs = tmp_val; - auto rhstype = rhs->get_type(); - if (node.op == SyntaxTree::UnaryCondOp::NOT) // 只有!非号需要处理,否则不形成UnaryCondExpr结点 - { - if (rhstype->is_integer_type()) // 整型分1bit和32bit - { - if (Type::is_eq_type(rhstype, INT1_T)) - { - auto zext = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_icmp_eq(CONST_INT(0), zext); - } - else - tmp_val = builder->create_icmp_eq(CONST_INT(0), rhs); - } - else if (rhstype->is_float_type()) - tmp_val = builder->create_fcmp_eq(CONST_FLOAT(0), rhs); - else // rhs是指针类型 - tmp_val = CONST_INT(true); // true 则为非零值 - } - } - - void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) - { - Ptr lhs, rhs; - Ptr lhstype, rhstype; - if ((node.op != SyntaxTree::BinaryCondOp::LAND) && (node.op != SyntaxTree::BinaryCondOp::LOR)) - { - node.lhs->accept(*this); - lhs = tmp_val; - lhstype = lhs->get_type(); - node.rhs->accept(*this); - rhs = tmp_val; - rhstype = rhs->get_type(); - } - - switch (node.op) - { - case SyntaxTree::BinaryCondOp::LT: - if (lhstype->is_float_type() && rhstype->is_float_type()) - { - tmp_val = builder->create_fcmp_lt(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_icmp_lt(lhs, rhs); - } - else if (lhstype->is_float_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - rhs = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fcmp_lt(lhs, rhs); - } - else if (rhstype->is_float_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - lhs = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fcmp_lt(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::LTE: - if (lhstype->is_float_type() && rhstype->is_float_type()) - { - tmp_val = builder->create_fcmp_le(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_icmp_le(lhs, rhs); - } - else if (lhstype->is_float_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - rhs = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fcmp_le(lhs, rhs); - } - else if (rhstype->is_float_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - lhs = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fcmp_le(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::GT: - if (lhstype->is_float_type() && rhstype->is_float_type()) - { - tmp_val = builder->create_fcmp_gt(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_icmp_gt(lhs, rhs); - } - else if (lhstype->is_float_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - rhs = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fcmp_gt(lhs, rhs); - } - else if (rhstype->is_float_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - lhs = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fcmp_gt(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::GTE: - if (lhstype->is_float_type() && rhstype->is_float_type()) - { - tmp_val = builder->create_fcmp_ge(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_icmp_ge(lhs, rhs); - } - else if (lhstype->is_float_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - rhs = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fcmp_ge(lhs, rhs); - } - else if (rhstype->is_float_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - lhs = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fcmp_ge(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::EQ: - if (lhstype->is_float_type() && rhstype->is_float_type()) - { - tmp_val = builder->create_fcmp_eq(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_icmp_eq(lhs, rhs); - } - else if (lhstype->is_float_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - rhs = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fcmp_eq(lhs, rhs); - } - else if (rhstype->is_float_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - lhs = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fcmp_eq(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::NEQ: - if (lhstype->is_float_type() && rhstype->is_float_type()) - { - tmp_val = builder->create_fcmp_ne(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_icmp_ne(lhs, rhs); - } - else if (lhstype->is_float_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - rhs = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fcmp_ne(lhs, rhs); - } - else if (rhstype->is_float_type()) - { - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - lhs = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fcmp_ne(lhs, rhs); - } - break; - // 非常关键的控制流语句br(逻辑与/或) - case SyntaxTree::BinaryCondOp::LAND: - // lhs和rhs都应该是INT1_T - { - auto parent = func_parent; - char labelname[20]; - sprintf(labelname, "true_bb_%d", bb_label_num++); // lhs&&rhs为true进入执行体 - auto true_bb = BasicBlock::create(module, labelname, parent); - sprintf(labelname, "false_bb_%d", bb_label_num++); // lhs为false(应该就是after cond bb吧?也可能进入下一个cond bb) - auto false_bb = BasicBlock::create(module, labelname, parent); - sprintf(labelname, "next_bb_%d", bb_label_num++); // rhs判断域 - auto next_bb = BasicBlock::create(module, labelname, parent); - sprintf(labelname, "after_bb_%d", bb_label_num++); // - auto after_bb = BasicBlock::create(module, labelname, parent); - - auto result = builder->create_alloca(INT1_T); - node.lhs->accept(*this); - lhs = tmp_val; - lhstype = lhs->get_type(); - if (Type::is_eq_type(lhstype, INT1_T)) - { - builder->create_cond_br(lhs, next_bb, false_bb); // if true直接跳转到nextbb(rhs判断的bb),否则跳转到falsebb - } - else if (Type::is_eq_type(lhstype, INT32_T)) - { - tmp_val = builder->create_icmp_ne(lhs, CONST_INT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br,先判断真假 - builder->create_cond_br(lhs, next_bb, false_bb); - } - else if (Type::is_eq_type(lhstype, FLOAT_T)) - { - tmp_val = builder->create_fcmp_ne(lhs, CONST_FLOAT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br,先判断真假 - builder->create_cond_br(tmp_val, next_bb, false_bb); - } - else // 为无条件跳转 - { - builder->create_br(next_bb); - } - builder->set_insert_point(next_bb); // rhs判断域 - - node.rhs->accept(*this); - rhs = tmp_val; - rhstype = rhs->get_type(); - if (Type::is_eq_type(rhstype, INT1_T)) - { - builder->create_cond_br(rhs, true_bb, false_bb); // if true直接跳转到truebb,否则跳转到falsebb - } - else if (Type::is_eq_type(rhstype, INT32_T)) - { - tmp_val = builder->create_icmp_ne(rhs, CONST_INT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br,先判断真假 - builder->create_cond_br(rhs, true_bb, false_bb); - } - else if (Type::is_eq_type(rhstype, FLOAT_T)) - { - tmp_val = builder->create_fcmp_ne(rhs, CONST_FLOAT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br,先判断真假 - builder->create_cond_br(tmp_val, true_bb, false_bb); - } - else // 为无条件跳转 - { - builder->create_br(true_bb); - } - - builder->set_insert_point(true_bb); // cond_bb判断域结束,进入true_bb执行体内部 - builder->create_store(CONST_INT(true), result); - builder->create_br(after_bb); - builder->set_insert_point(false_bb); - builder->create_store(CONST_INT(false), result); - builder->create_br(after_bb); - // true_bb和false_bb IR结束后都要无条件br到after_bb - builder->set_insert_point(after_bb); - tmp_val = builder->create_load(result); - break; - } - case SyntaxTree::BinaryCondOp::LOR: - // lhs和rhs都应该是INT1_T, 与LAND稍有区别(使用短路计算) - auto parent = func_parent; - char labelname[20]; - sprintf(labelname, "ture_bb_%d", bb_label_num++); // lhs&&rhs为true进入执行体 - auto true_bb = BasicBlock::create(module, labelname, parent); - sprintf(labelname, "false_bb_%d", bb_label_num++); // lhs为false(应该就是after cond bb吧?也可能进入下一个cond bb) - auto false_bb = BasicBlock::create(module, labelname, parent); - sprintf(labelname, "next_bb_%d", bb_label_num++); // rhs判断域 - auto next_bb = BasicBlock::create(module, labelname, parent); - sprintf(labelname, "after_bb_%d", bb_label_num++); // - auto after_bb = BasicBlock::create(module, labelname, parent); - - auto result = builder->create_alloca(INT1_T); - node.lhs->accept(*this); - lhs = tmp_val; - lhstype = lhs->get_type(); - if (Type::is_eq_type(lhstype, INT1_T)) - { - builder->create_cond_br(lhs, true_bb, next_bb); // if true直接跳转到turebb执行体内,否则跳转到nextbb(rhs判断域) - } - else if (Type::is_eq_type(lhstype, INT32_T)) - { - tmp_val = builder->create_icmp_ne(lhs, CONST_INT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br,先判断真假 - builder->create_cond_br(tmp_val, true_bb, next_bb); - } - else if (Type::is_eq_type(lhstype, FLOAT_T)) - { - tmp_val = builder->create_fcmp_ne(lhs, CONST_FLOAT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br,先判断真假 - builder->create_cond_br(tmp_val, true_bb, next_bb); - } - else // 为无条件跳转 - { - builder->create_br(true_bb); - } - builder->set_insert_point(next_bb); // rhs判断域 - node.rhs->accept(*this); - rhs = tmp_val; - rhstype = rhs->get_type(); - - if (Type::is_eq_type(rhstype, INT1_T)) - { - builder->create_cond_br(rhs, true_bb, false_bb); // if true直接跳转到truebb,否则跳转到falsebb - } - else if (Type::is_eq_type(rhstype, INT32_T)) - { - tmp_val = builder->create_icmp_ne(rhs, CONST_INT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br,先判断真假 - builder->create_cond_br(tmp_val, true_bb, false_bb); - } - else if (Type::is_eq_type(rhstype, FLOAT_T)) - { - tmp_val = builder->create_fcmp_ne(rhs, CONST_FLOAT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br,先判断真假 - builder->create_cond_br(tmp_val, true_bb, false_bb); - } - else // 为无条件跳转 - { - builder->create_br(true_bb); - } - - builder->set_insert_point(true_bb); // cond_bb判断域结束,进入true_bb执行体内部 - builder->create_store(CONST_INT(true), result); - builder->create_br(after_bb); - builder->set_insert_point(false_bb); - builder->create_store(CONST_INT(false), result); - builder->create_br(after_bb); - // true_bb和false_bb IR结束后都要无条件br到after_bb - builder->set_insert_point(after_bb); - tmp_val = builder->create_load(result); - break; - } - } - - void IRBuilder::visit(SyntaxTree::BinaryExpr &node) - { - if (scope.in_global()) // 需要计算全局变量声明中某些表达式 - { - int lhs_ival, rhs_ival; - float lhs_fval, rhs_fval; - bool lhs_is_int, rhs_is_int; - node.lhs->accept(*this); - if (expr_cal_result.is_int) - lhs_ival = expr_cal_result.ival; - else - lhs_fval = expr_cal_result.fval; - lhs_is_int = expr_cal_result.is_int; - node.rhs->accept(*this); - if (expr_cal_result.is_int) - rhs_ival = expr_cal_result.ival; - else - rhs_fval = expr_cal_result.fval; - rhs_is_int = expr_cal_result.is_int; - switch (node.op) - { - case SyntaxTree::BinOp::PLUS: - if (lhs_is_int && rhs_is_int) - { - expr_cal_result.is_int = true; - expr_cal_result.ival = lhs_ival + rhs_ival; - } - else if (!lhs_is_int && rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_fval + rhs_ival; - } - else if (lhs_is_int && !rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_ival + rhs_fval; - } - else if (!lhs_is_int && !rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_fval + rhs_fval; - } - break; - case SyntaxTree::BinOp::MINUS: - if (lhs_is_int && rhs_is_int) - { - expr_cal_result.is_int = true; - expr_cal_result.ival = lhs_ival - rhs_ival; - } - else if (!lhs_is_int && rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_fval - rhs_ival; - } - else if (lhs_is_int && !rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_ival - rhs_fval; - } - else if (!lhs_is_int && !rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_fval - rhs_fval; - } - break; - case SyntaxTree::BinOp::MULTIPLY: - if (lhs_is_int && rhs_is_int) - { - expr_cal_result.is_int = true; - expr_cal_result.ival = lhs_ival * rhs_ival; - } - else if (!lhs_is_int && rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_fval * rhs_ival; - } - else if (lhs_is_int && !rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_ival * rhs_fval; - } - else if (!lhs_is_int && !rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_fval * rhs_fval; - } - break; - case SyntaxTree::BinOp::DIVIDE: - if (lhs_is_int && rhs_is_int) - { - expr_cal_result.is_int = true; - expr_cal_result.ival = lhs_ival / rhs_ival; - } - else if (!lhs_is_int && rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_fval / rhs_ival; - } - else if (lhs_is_int && !rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_ival / rhs_fval; - } - else if (!lhs_is_int && !rhs_is_int) - { - expr_cal_result.is_int = false; - expr_cal_result.fval = lhs_fval / rhs_fval; - } - break; - case SyntaxTree::BinOp::MODULO: - expr_cal_result.is_int = true; - if (lhs_is_int && rhs_is_int) - expr_cal_result.ival = lhs_ival % rhs_ival; - else if (!lhs_is_int && rhs_is_int) - expr_cal_result.fval = int(lhs_fval) % rhs_ival; - else if (lhs_is_int && !rhs_is_int) - expr_cal_result.fval = lhs_ival % int(rhs_fval); - else if (!lhs_is_int && !rhs_is_int) - expr_cal_result.fval = int(lhs_fval) % int(rhs_fval); - break; - } - } - else // 生成相应计算ir指令, 根据最终指令形式分为float、int和指针计算三种 - { - node.lhs->accept(*this); - auto lhs = tmp_val; - auto lhstype = lhs->get_type(); - node.rhs->accept(*this); - auto rhs = tmp_val; - auto rhstype = rhs->get_type(); - switch (node.op) - { - case SyntaxTree::BinOp::PLUS: - if (Type::is_eq_type(lhstype, FLOAT_T) || Type::is_eq_type(rhstype, FLOAT_T)) - { // 目标ir为float加法 - if (lhstype->is_integer_type()) // 类型不匹配 - { - if (Type::is_eq_type(lhstype, INT1_T)) - { - auto zext = builder->create_zext(lhs, INT32_T); - auto itof = builder->create_sitofp(zext, FLOAT_T); - tmp_val = builder->create_fadd(itof, rhs); - } - else - { - auto itof = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fadd(itof, rhs); - } - } - else if (rhstype->is_integer_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - { - auto zext = builder->create_zext(rhs, INT32_T); - auto itof = builder->create_sitofp(zext, FLOAT_T); - tmp_val = builder->create_fadd(lhs, itof); - } - else - { - auto itof = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fadd(lhs, itof); - } - } - else - tmp_val = builder->create_fadd(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { // 目标ir为32位加法 - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_iadd(lhs, rhs); - } - else - { // 目标ir为指针计算(地址计算gep) - PtrVec ptr_idx; // 为适配多维数组或结构体的多个idx寻址,设置为vector类型 - if (lhstype->is_pointer_type()) - { - ptr_idx.push_back(rhs); - tmp_val = builder->create_gep(lhs, ptr_idx); - } - else if (rhstype->is_pointer_type()) - { - ptr_idx.push_back(lhs); - tmp_val = builder->create_gep(rhs, ptr_idx); - } - } - break; - case SyntaxTree::BinOp::MINUS: - if (Type::is_eq_type(lhstype, FLOAT_T) || Type::is_eq_type(rhstype, FLOAT_T)) - { // 目标ir为float减法 - if (lhstype->is_integer_type()) // 类型不匹配 - { - if (Type::is_eq_type(lhstype, INT1_T)) - { - auto zext = builder->create_zext(lhs, INT32_T); - auto itof = builder->create_sitofp(zext, FLOAT_T); - tmp_val = builder->create_fsub(itof, rhs); - } - else - { - auto itof = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fsub(itof, rhs); - } - } - else if (rhstype->is_integer_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - { - auto zext = builder->create_zext(rhs, INT32_T); - auto itof = builder->create_sitofp(zext, FLOAT_T); - tmp_val = builder->create_fsub(lhs, itof); - } - else - { - auto itof = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fsub(lhs, itof); - } - } - else - tmp_val = builder->create_fsub(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { // 目标ir为32位减法 - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_isub(lhs, rhs); - } - else - { // 目标ir为指针计算(地址计算gep), 只能lhs为指针类型 - PtrVec ptr_idx; // 为适配多维数组或结构体的多个idx寻址,设置为vector类型 - if (lhstype->is_pointer_type()) - { - ptr_idx.push_back(rhs); - tmp_val = builder->create_gep(lhs, ptr_idx); - } - } - break; - case SyntaxTree::BinOp::MULTIPLY: - if (Type::is_eq_type(lhstype, FLOAT_T) || Type::is_eq_type(rhstype, FLOAT_T)) - { // 目标ir为float乘法 - if (lhstype->is_integer_type()) // 类型不匹配 - { - if (Type::is_eq_type(lhstype, INT1_T)) - { - auto zext = builder->create_zext(lhs, INT32_T); - auto itof = builder->create_sitofp(zext, FLOAT_T); - tmp_val = builder->create_fmul(itof, rhs); - } - else - { - auto itof = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fmul(itof, rhs); - } - } - else if (rhstype->is_integer_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - { - auto zext = builder->create_zext(rhs, INT32_T); - auto itof = builder->create_sitofp(zext, FLOAT_T); - tmp_val = builder->create_fmul(lhs, itof); - } - else - { - auto itof = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fmul(lhs, itof); - } - } - else - tmp_val = builder->create_fmul(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { // 目标ir为32位乘法 - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_imul(lhs, rhs); - } - break; - case SyntaxTree::BinOp::DIVIDE: - if (Type::is_eq_type(lhstype, FLOAT_T) || Type::is_eq_type(rhstype, FLOAT_T)) - { // 目标ir为float除法 - if (lhstype->is_integer_type()) // 类型不匹配 - { - if (Type::is_eq_type(lhstype, INT1_T)) - { - auto zext = builder->create_zext(lhs, INT32_T); - auto itof = builder->create_sitofp(zext, FLOAT_T); - tmp_val = builder->create_fdiv(itof, rhs); - } - else - { - auto itof = builder->create_sitofp(lhs, FLOAT_T); - tmp_val = builder->create_fdiv(itof, rhs); - } - } - else if (rhstype->is_integer_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - { - auto zext = builder->create_zext(rhs, INT32_T); - auto itof = builder->create_sitofp(zext, FLOAT_T); - tmp_val = builder->create_fdiv(lhs, itof); - } - else - { - auto itof = builder->create_sitofp(rhs, FLOAT_T); - tmp_val = builder->create_fdiv(lhs, itof); - } - } - else - tmp_val = builder->create_fdiv(lhs, rhs); - } - else if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { // 目标ir为32位除法 - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_isdiv(lhs, rhs); - } - break; - case SyntaxTree::BinOp::MODULO: // 取模运算只能是int类型(不能通过ir将float类型转换,这是不合法的) - if (lhstype->is_integer_type() && rhstype->is_integer_type()) - { // 目标ir为32位取模 - if (Type::is_eq_type(lhstype, INT1_T)) - lhs = builder->create_zext(lhs, INT32_T); - if (Type::is_eq_type(rhstype, INT1_T)) - rhs = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_isrem(lhs, rhs); - } - break; - } - } - } - - void IRBuilder::visit(SyntaxTree::UnaryExpr &node) - { - if (scope.in_global()) // 需要计算全局变量声明中某些表达式 - { // 只有minus需要修改值,否则值和类型都不用修改 - node.rhs->accept(*this); - if (expr_cal_result.is_int) - { - if (node.op == SyntaxTree::UnaryOp::MINUS) - expr_cal_result.ival = -expr_cal_result.ival; - else if (node.op == SyntaxTree::UnaryOp::MINUS) - expr_cal_result.fval = -expr_cal_result.fval; - } - } - else // 需要更新tmp_val - { - node.rhs->accept(*this); - auto rhs = tmp_val; - auto rhstype = rhs->get_type(); - switch (node.op) - { - case SyntaxTree::UnaryOp::PLUS: - break; - case SyntaxTree::UnaryOp::MINUS: - if (rhstype->is_integer_type()) - { - if (Type::is_eq_type(rhstype, INT1_T)) - { - auto zext = builder->create_zext(rhs, INT32_T); - tmp_val = builder->create_isub(CONST_INT(0), zext); - } - else - tmp_val = builder->create_isub(CONST_INT(0), rhs); - } - else if (rhstype->is_float_type()) - tmp_val = builder->create_fsub(CONST_FLOAT(0), rhs); - break; - } - } - } - - void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) - { - auto Func = dynamic_pointer_cast(scope.find(node.name, true)); - auto RetType = Func->get_return_type(); - PtrVec param; - param.clear(); - auto FuncPara = Func->get_args(); - int idx = 0; - - // DBGLOG("begin the funccall"); - for (auto funp : FuncPara) - { - node.params[idx]->accept(*this); - auto tmpType = tmp_val->get_type(); - auto ParaType = funp->get_type(); - - if (ParaType == tmpType) - param.push_back(tmp_val); - else if (ParaType == INT32_T) - { - switch (tmpType->get_type_id()) - { - // INT1 to INT32 - case SysYF::IR::Type::TypeID::IntegerTyID: - tmp_val = builder->create_zext(tmp_val, INT32_T); - param.push_back(tmp_val); - break; - // FLOAT to INT32 - case SysYF::IR::Type::TypeID::FloatTyID: - tmp_val = builder->create_fptosi(tmp_val, INT32_T); - param.push_back(tmp_val); - break; - // other - default: - // DBGLOG("Error type to INT32_T"); - // DBGLOG(tmpType->get_type_id()); - break; - } - } - else if (ParaType == FLOAT_T) - { - switch (tmpType->get_type_id()) - { - // INT1/32 to FLOAT - case SysYF::IR::Type::TypeID::IntegerTyID: - if (tmpType == INT1_T) - tmp_val = builder->create_zext(tmp_val, INT32_T); - tmp_val = builder->create_sitofp(tmp_val, FLOAT_T); - param.push_back(tmp_val); - break; - // other - default: - // DBGLOG("Error type to FLOAT_T"); - // DBGLOG(tmpType->get_type_id()); - break; - } - } - else if (ParaType->is_pointer_type()) - { - if (tmpType->is_array_type()) - { - // DBGLOG(tmpType->get_type_id()); - // DBGLOG("debug 1"); - auto Element_pointer = builder->create_gep(lhs_addr, {CONST_INT(0), CONST_INT(0)}); - // DBGLOG("debug 2"); - param.push_back(Element_pointer); - } - else - { - // DBGLOG("ParaType == pointer"); - // DBGLOG(tmpType->get_type_id()); - } - } - else - { - // DBGLOG("Error ParaType"); - // DBGLOG(ParaType->get_type_id()); - // other - } - - idx++; - } - - if (RetType == VOID_T) - { - builder->create_call(Func, param); - } - else - { - tmp_val = builder->create_call(Func, param); - } - // DBGLOG("end the funccall"); - } - - void IRBuilder::visit(SyntaxTree::IfStmt &node) - { - /* DBGLOG("begin the IF"); */ - SysYF::Ptr bbTrue, bbAfter, bbFalse, bbCond; - auto ParentFunc = builder->get_insert_block()->get_parent(); - char num[10]; - // itoa(Ifnum, num, 10); - /* DBGLOG("before the sprintf"); */ - sprintf(num, "%d", Ifnum++); - /* DBGLOG("after the sprintf"); */ - /* std::string s = "if_cond_"; - bbCond = BasicBlock::create(module, s + num, ParentFunc); */ - std::string s = "if_true_"; - bbTrue = BasicBlock::create(module, s + num, ParentFunc); - if (node.else_statement) - { - s = "if_false_"; - bbFalse = BasicBlock::create(module, s + num, ParentFunc); - } - s = "after_if_"; - bbAfter = BasicBlock::create(module, s + num, ParentFunc); - - /* DBGLOG("before visit cond"); */ - /* builder->create_br(bbCond); */ - /* builder->set_insert_point(bbCond); */ - node.cond_exp->accept(*this); - /* DBGLOG("after visit cond"); */ - - SysYF::Ptr _cmp; - auto condType = tmp_val->get_type(); - if (condType == INT1_T) - _cmp = tmp_val; - else if (condType == INT32_T) - _cmp = builder->create_icmp_ne(tmp_val, CONST_INT(0)); - else if (condType == FLOAT_T) - _cmp = builder->create_fcmp_ne(tmp_val, CONST_FLOAT(0)); - else - { - } - /* DBGLOG("after Init cmp"); */ - if (!_cmp) - builder->create_br(bbTrue); - else if (node.else_statement) - builder->create_cond_br(_cmp, bbTrue, bbFalse); - else - builder->create_cond_br(_cmp, bbTrue, bbAfter); - - builder->set_insert_point(bbTrue); - /* DBGLOG("before visit if_stmt"); */ - - node.if_statement->accept(*this); - /* DBGLOG("after visit if_stmt"); */ - - if (!builder->get_insert_block()->get_terminator()) - builder->create_br(bbAfter); - - if (node.else_statement) - { - builder->set_insert_point(bbFalse); - /* DBGLOG("before visit else"); */ - node.else_statement->accept(*this); - if (!builder->get_insert_block()->get_terminator()) - builder->create_br(bbAfter); - } - - builder->set_insert_point(bbAfter); - /* DBGLOG("end the IF"); */ - } - - void IRBuilder::visit(SyntaxTree::WhileStmt &node) - { - // 类比condexpr和ifstmt,需要创建bb label并控制跳转 - char labelname[20]; - auto parent = func_parent; - sprintf(labelname, "cond_bb_%d", bb_label_num++); - auto cond_bb = BasicBlock::create(module, labelname, parent); - sprintf(labelname, "true_bb_%d", bb_label_num++); - auto true_bb = BasicBlock::create(module, labelname, parent); - sprintf(labelname, "after_bb_%d", bb_label_num++); - auto after_bb = BasicBlock::create(module, labelname, parent); - - break_point.push_back(after_bb); // break后直接跳转至afterbb(循环语句后紧接的bb) - continue_point.push_back(cond_bb); // continue后跳转至条件判断域condbb - - builder->create_br(cond_bb); // 进入AST的whilrnode后先无条件进行一次条件判断 - builder->set_insert_point(cond_bb); - node.cond_exp->accept(*this); - auto cond_judge = tmp_val; - auto cond_type = cond_judge->get_type(); - // 只有当cond是INT1_T类型时才能直接生成cond_br, 否则要先判断cond是否为零值 - if (Type::is_eq_type(cond_type, INT1_T)) - { - builder->create_cond_br(cond_judge, true_bb, after_bb); - } - else if (Type::is_eq_type(cond_type, INT32_T)) - { - cond_judge = builder->create_icmp_ne(cond_judge, CONST_INT(0)); - builder->create_cond_br(cond_judge, true_bb, after_bb); - } - else if (Type::is_eq_type(cond_type, FLOAT_T)) - { - cond_judge = builder->create_fcmp_ne(cond_judge, CONST_FLOAT(0)); - builder->create_cond_br(cond_judge, true_bb, after_bb); - } - else // 说明能无条件跳转, while(1) - { - builder->create_br(true_bb); - } - - builder->set_insert_point(true_bb); // 进入循环执行体内部生成IR - node.statement->accept(*this); // 访问循环体内部stmt, 自会生成IR - - if (!(builder->get_insert_block()->get_terminator())) // ret与br都是Terminator Instructions也就是终止指令, 若没有则补充(while语句里没有) - builder->create_br(cond_bb); - - builder->set_insert_point(after_bb); - // 离开前别忘了维护break和continue栈 - break_point.pop_back(); - continue_point.pop_back(); - } - - void IRBuilder::visit(SyntaxTree::BreakStmt &node) - { // 控制跳转目的地址 - char labelname[20]; - auto parent = func_parent; - sprintf(labelname, "break_dest_%d", bb_label_num++); - auto break_dest_bb = BasicBlock::create(module, labelname, parent); - builder->create_br(break_point.back()); // 还不需要pop, while语句中会pop - builder->set_insert_point(break_dest_bb); - } - - void IRBuilder::visit(SyntaxTree::ContinueStmt &node) - { // 控制跳转目的地址 - char labelname[20]; - auto parent = func_parent; - sprintf(labelname, "cond_dest_%d", bb_label_num++); - auto cond_dest_bb = BasicBlock::create(module, labelname, parent); - builder->create_br(continue_point.back()); // 还不需要pop, while语句中会pop - builder->set_insert_point(cond_dest_bb); - } - - } -} \ No newline at end of file