diff --git a/src/SysYFIRBuilder/IRBuilder.cpp b/src/SysYFIRBuilder/IRBuilder.cpp index 91b0749..ea7f3e9 100644 --- a/src/SysYFIRBuilder/IRBuilder.cpp +++ b/src/SysYFIRBuilder/IRBuilder.cpp @@ -17,7 +17,7 @@ namespace SysYF BOOL, FLOAT }; - + std::vector tmp_condbb_while; std::vector tmp_falsebb_while; std::vector tmp_truebb; @@ -25,7 +25,8 @@ namespace SysYF std::map> type_map; // 把类型转换成类型指针 // store temporary value Ptr tmp_val = nullptr; - vector> init_list; + vector> init_list; + Ptr array_init_type; // types Ptr VOID_T; Ptr INT1_T; @@ -33,11 +34,52 @@ namespace SysYF Ptr FLOAT_T; Ptr INT32PTR_T; Ptr FLOATPTR_T; +#define get_true_type(left_type, right) \ + if (!scope.in_global()) \ + { \ + if (left_type == INT32_T && right->get_type() == FLOAT_T) \ + { \ + right = builder->create_fptosi(right, INT32_T); \ + } \ + else if (left_type == INT32_T && right->get_type() == INT1_T) \ + { \ + right = builder->create_zext(right, INT32_T); \ + } \ + else if (left_type == INT1_T && right->get_type() == FLOAT_T) \ + { \ + right = builder->create_fcmp_ne(right, CONST_FLOAT(0)); \ + } \ + else if (left_type == INT1_T && right->get_type() == INT32_T) \ + { \ + right = builder->create_icmp_ne(right, CONST_INT(0)); \ + } \ + else if (left_type == FLOAT_T && right->get_type() == INT32_T) \ + { \ + right = builder->create_sitofp(right, FLOAT_T); \ + } \ + else if (left_type == FLOAT_T && right->get_type() == INT1_T) \ + { \ + right = builder->create_zext(right, FLOAT_T); \ + } \ + } \ + else \ + { \ + if (left_type == FLOAT_T && right->get_type() != FLOAT_T) \ + { \ + right = CONST_FLOAT(static_cast(dynamic_pointer_cast(right)->get_value())); \ + } \ + else if (left_type == INT32_T && right->get_type() != INT32_T) \ + { \ + right = CONST_INT(static_cast(dynamic_pointer_cast(right)->get_value())); \ + } \ + } - #define LVal_to_RVal(lval) \ - if(lval->get_type()==INT32PTR_T || lval->get_type()==FLOATPTR_T){\ - lval=builder->create_load(lval);\ - } +#define LVal_to_RVal(lval) \ + if (lval->get_type() == INT32PTR_T || lval->get_type() == FLOATPTR_T) \ + { \ + auto middle = lval; \ + lval = builder->create_load(middle); \ + } void IRBuilder::visit(SyntaxTree::Assembly &node) { @@ -72,9 +114,18 @@ namespace SysYF } else // is exp, values are in node.expr { - node.expr->accept(*this); // 有可能是计算表达式,也有可能是赋值语句 + node.expr->accept(*this); // 有可能是计算表达式,也有可能是赋值语句 LVal_to_RVal(tmp_val); - init_list.push_back(tmp_val); // 把tmp_val放到init_list里面 + get_true_type(array_init_type, tmp_val); + // 把tmp_val放到init_list里面 + if (array_init_type == INT32_T) + { + init_list.push_back(dynamic_pointer_cast(tmp_val)); + } + else + { + init_list.push_back(dynamic_pointer_cast(tmp_val)); + } } } // init values @@ -123,11 +174,20 @@ namespace SysYF switch (node.ret_type) { case SyntaxTree::Type::VOID: + { builder->create_void_ret(); + break; + } case SyntaxTree::Type::INT: + { builder->create_ret(CONST_INT(0)); + break; + } case SyntaxTree::Type::FLOAT: + { builder->create_ret(CONST_FLOAT(0)); + break; + } default: break; } @@ -183,16 +243,51 @@ namespace SysYF { if (scope.in_global()) // 如果是全局变量 { - auto global_var = GlobalVariable::create(var_name, module, var_type, is_const, ConstantZero::create(var_type, module)); - if (is_initialized) + if (is_const) { - init_val->accept(*this); - LVal_to_RVal(tmp_val); - builder->create_store(tmp_val, global_var); + if (is_initialized) + { + init_val->accept(*this); + LVal_to_RVal(tmp_val); + get_true_type(var_type, tmp_val); + if (var_type == INT32_T) + { + auto global_var = GlobalVariable::create(var_name, module, var_type, true, dynamic_pointer_cast(tmp_val)); + scope.push(var_name, global_var); + } + else + { + auto global_var = GlobalVariable::create(var_name, module, var_type, true, dynamic_pointer_cast(tmp_val)); + scope.push(var_name, global_var); + } + } + else + cout << "const variable must be initialized" << endl; + } + else + { + if (is_initialized) + { + init_val->accept(*this); + LVal_to_RVal(tmp_val); + get_true_type(var_type, tmp_val); + if (var_type == INT32_T) + { + auto global_var = GlobalVariable::create(var_name, module, var_type, false, dynamic_pointer_cast(tmp_val)); + scope.push(var_name, global_var); + } + else + { + auto global_var = GlobalVariable::create(var_name, module, var_type, false, dynamic_pointer_cast(tmp_val)); + scope.push(var_name, global_var); + } + } + else + { + auto global_var = GlobalVariable::create(var_name, module, var_type, false, ConstantZero::create(var_type, module)); + scope.push(var_name, global_var); + } } - else if (is_const) // 说明是const,但是没有初始化 - cout << "const variable must be initialized" << endl; - scope.push(var_name, global_var); } else // 如果是局部变量 { @@ -201,7 +296,8 @@ namespace SysYF { init_val->accept(*this); LVal_to_RVal(tmp_val); - builder->create_store(tmp_val , var); + get_true_type(var_type, tmp_val); + builder->create_store(tmp_val, var); } else if (is_const) // 说明是const,但是没有初始化 cout << "const variable must be initialized" << endl; @@ -210,31 +306,58 @@ namespace SysYF } else // 数组 { - auto arrayType = ArrayType::get(var_type, length.size()); - + for (const auto &exp : length) + { + exp->accept(*this); + } + auto array_len = dynamic_pointer_cast(tmp_val)->get_value(); + auto arrayType = ArrayType::get(var_type, array_len); + array_init_type = var_type; if (scope.in_global()) // 如果是全局变量 { - auto global_array = GlobalVariable::create(var_name, module, arrayType, is_const, ConstantZero::create(var_type, module)); - - if (is_initialized) + if (is_const) { - init_list.clear(); // 清空init_list - init_val->accept(*this); // 把init_val里面的值放到init_list里面 - while (init_list.size() < length.size()) // 如果init_list的长度小于length的长度,就把init_list其他的值补上0 + if (is_initialized) { - init_list.push_back(ConstantZero::create(type_map[node.btype], module)); + init_list.clear(); // 清空init_list + init_val->accept(*this); // 把init_val里面的值放到init_list里面 + while (static_cast(init_list.size()) < array_len) // 如果init_list的长度小于length的长度,就把init_list其他的值补上0 + { + init_list.push_back(ConstantZero::create(type_map[node.btype], module)); + } + auto array_initializer = ConstantArray::create(arrayType, init_list); + auto global_var = GlobalVariable::create(var_name, module, arrayType, true, array_initializer); + scope.push(var_name, global_var); } - // initilize - for (auto i = 0; i < static_cast(init_list.size()); i++) + else + cout << "const variable must be initialized" << endl; + } + else + { + if (is_initialized) { - auto GEP = builder->create_gep(global_array, {CONST_INT(0), CONST_INT(i)}); - builder->create_store(init_list[i], GEP); + init_list.clear(); // 清空init_list + init_val->accept(*this); // 把init_val里面的值放到init_list里面 + while (static_cast(init_list.size()) < array_len) // 如果init_list的长度小于length的长度,就把init_list其他的值补上0 + { + init_list.push_back(ConstantZero::create(type_map[node.btype], module)); + } + auto array_initializer = ConstantArray::create(arrayType, init_list); + auto global_var = GlobalVariable::create(var_name, module, arrayType, false, array_initializer); + scope.push(var_name, global_var); + } + else + { + init_list.clear(); + while (init_list.size() < length.size()) // 如果init_list的长度小于length的长度,就把init_list其他的值补上0 + { + init_list.push_back(ConstantZero::create(type_map[node.btype], module)); + } + auto array_initializer = ConstantArray::create(arrayType, init_list); + auto global_var = GlobalVariable::create(var_name, module, arrayType, false, array_initializer); + scope.push(var_name, global_var); } } - else if (is_const) // 说明是const,但是没有初始化 - cout << "const variable must be initialized" << endl; - - scope.push(var_name, global_array); } else { @@ -262,7 +385,8 @@ namespace SysYF } } } - + // int c; + // c = 1.8; void IRBuilder::visit(SyntaxTree::LVal &node) { auto name = node.name; @@ -270,19 +394,58 @@ namespace SysYF auto lval = scope.find(name, false); if (lval) { - if (!index.empty()) + if (scope.in_global()) { - for (const auto &exp : index) + auto global_var = dynamic_pointer_cast(lval); + if (global_var->is_const()) { - exp->accept(*this); - auto tmp = tmp_val; - auto GEP = builder->create_gep(lval, {tmp}); - lval = GEP; + if (index.empty()) // + { + tmp_val = global_var->get_init(); + } + else + { + for (const auto &exp : index) + { + exp->accept(*this); + } + auto GEP = dynamic_pointer_cast(tmp_val); + tmp_val = dynamic_pointer_cast(global_var->get_init())->get_element_value(GEP->get_value()); + } + } + else + { + if (index.empty()) + { + tmp_val = global_var->get_init(); + } + else + { + for (const auto &exp : index) + { + exp->accept(*this); + } + auto GEP = dynamic_pointer_cast(tmp_val); + tmp_val = dynamic_pointer_cast(global_var->get_init())->get_element_value(GEP->get_value()); + } } } else - { // 从符号表中取出的是字面值 - tmp_val = lval; + { + if (!index.empty()) + { + for (const auto &exp : index) + { + exp->accept(*this); + } + auto tmp = tmp_val; + auto GEP = builder->create_gep(lval, {CONST_INT(0), tmp}); + tmp_val = (GEP); + } + else + { // 从符号表中取出的是字面值 + tmp_val = (lval); + } } } else @@ -294,12 +457,11 @@ namespace SysYF void IRBuilder::visit(SyntaxTree::AssignStmt &node) { node.target->accept(*this); - auto target = builder->create_load(tmp_val);//? - auto name = target->get_name(); - node.value->accept(*this);//? + auto target = tmp_val; //?Const_int(1).get_type() == INT32_T + node.value->accept(*this); //? LVal_to_RVal(tmp_val); auto value = tmp_val; - + get_true_type(target->get_type(), value); builder->create_store(value, target); } @@ -309,9 +471,15 @@ namespace SysYF switch (type) { case SyntaxTree::Type::INT: + { tmp_val = CONST_INT(node.int_const); + break; + } case SyntaxTree::Type::FLOAT: + { tmp_val = CONST_FLOAT(node.float_const); + break; + } default: break; } @@ -327,11 +495,11 @@ namespace SysYF auto value_type = tmp_val->get_type(); auto ret_type = module->get_functions().back()->get_return_type(); // 类型检查 - if(ret_type == INT32_T) + if (ret_type == INT32_T) { - if(value_type == FLOAT_T) + if (value_type == FLOAT_T) tmp_val = builder->create_fptosi(tmp_val, INT32_T); - else if(value_type == INT1_T) + else if (value_type == INT1_T) tmp_val = builder->create_zext(tmp_val, INT32_T); } auto value = tmp_val; @@ -359,7 +527,6 @@ namespace SysYF void IRBuilder::visit(SyntaxTree::EmptyStmt &node) { - node.accept(*this); } void IRBuilder::visit(SyntaxTree::ExprStmt &node) @@ -375,13 +542,13 @@ namespace SysYF // 整数 if (rhs->get_type() == INT32_T) { - auto UnaryCondExpr = builder->create_icmp_eq(rhs, CONST_INT(0)); - scope.push("CondExpr", UnaryCondExpr); + tmp_val = builder->create_icmp_eq(rhs, CONST_INT(0)); + // scope.push("CondExpr", UnaryCondExpr); } else { - auto UnaryCondExpr = builder->create_fcmp_eq(rhs, CONST_FLOAT(0)); - scope.push("CondExpr", UnaryCondExpr); + tmp_val = builder->create_fcmp_eq(rhs, CONST_FLOAT(0)); + // scope.push("CondExpr", UnaryCondExpr); } } @@ -448,32 +615,32 @@ namespace SysYF if (lhs_type == INT1_T && rhs_type == INT32_T) { - lhs = dynamic_pointer_cast(builder->create_zext(lhs, INT32_T)); + lhs = builder->create_zext(lhs, INT32_T); } else if (lhs_type == INT1_T && rhs_type == FLOAT_T) { - lhs = dynamic_pointer_cast(builder->create_zext(lhs, FLOAT_T)); + lhs = (builder->create_zext(lhs, FLOAT_T)); } else if (lhs_type == INT32_T && rhs_type == INT1_T) { - rhs = dynamic_pointer_cast(builder->create_zext(rhs, INT32_T)); + rhs = (builder->create_zext(rhs, INT32_T)); } else if (lhs_type == FLOAT_T && rhs_type == INT1_T) { - rhs = dynamic_pointer_cast(builder->create_zext(rhs, FLOAT_T)); + rhs = (builder->create_zext(rhs, FLOAT_T)); } else if (lhs_type == FLOAT_T && rhs_type == INT32_T) { - rhs = dynamic_pointer_cast(builder->create_sitofp(rhs, FLOAT_T)); + rhs = (builder->create_sitofp(rhs, FLOAT_T)); } else if (lhs_type == INT32_T && rhs_type == FLOAT_T) { - lhs = dynamic_pointer_cast(builder->create_sitofp(lhs, FLOAT_T)); + lhs = (builder->create_sitofp(lhs, FLOAT_T)); } else if (lhs_type == INT1_T && rhs_type == INT1_T) { - lhs = dynamic_pointer_cast(builder->create_zext(lhs, INT32_T)); - rhs = dynamic_pointer_cast(builder->create_zext(rhs, INT32_T)); + lhs = (builder->create_zext(lhs, INT32_T)); + rhs = (builder->create_zext(rhs, INT32_T)); } // 整数 if (rhs->get_type() == INT32_T) @@ -506,6 +673,12 @@ namespace SysYF case SysYF::SyntaxTree::BinaryCondOp::EQ: { tmp_val = builder->create_icmp_eq(lhs, rhs); + break; + } + case SysYF::SyntaxTree::BinaryCondOp::NEQ: + { + tmp_val = builder->create_icmp_ne(lhs, rhs); + break; } default: break; @@ -541,6 +714,12 @@ namespace SysYF case SysYF::SyntaxTree::BinaryCondOp::EQ: { tmp_val = builder->create_fcmp_eq(lhs, rhs); + break; + } + case SysYF::SyntaxTree::BinaryCondOp::NEQ: + { + tmp_val = builder->create_icmp_ne(lhs, rhs); + break; } default: break; @@ -553,25 +732,26 @@ namespace SysYF { // 整数 node.rhs->accept(*this); - LVal_to_RVal(tmp_val); auto rhs = tmp_val; + LVal_to_RVal(rhs); auto rhs_type = rhs->get_type(); + node.lhs->accept(*this); - LVal_to_RVal(tmp_val); auto lhs = tmp_val; + LVal_to_RVal(lhs); auto lhs_type = lhs->get_type(); if (lhs_type == FLOAT_T && rhs_type == INT32_T) { - rhs = dynamic_pointer_cast(builder->create_sitofp(rhs, FLOAT_T)); + rhs = builder->create_sitofp(rhs, FLOAT_T); } else if (lhs_type == INT32_T && rhs_type == FLOAT_T) { - lhs = dynamic_pointer_cast(builder->create_sitofp(lhs, FLOAT_T)); + lhs = builder->create_sitofp(lhs, FLOAT_T); } auto expr_type = lhs->get_type(); // 计算出可以直接计算的值 - if ((dynamic_pointer_cast(lhs) || dynamic_pointer_cast(lhs)) && (dynamic_pointer_cast(rhs) || dynamic_pointer_cast(rhs))) + if (((dynamic_pointer_cast(lhs) || dynamic_pointer_cast(lhs)) && (dynamic_pointer_cast(rhs) || dynamic_pointer_cast(rhs))) || scope.in_global()) { // 简单字面量计算 int lhs_int; int rhs_int; @@ -643,60 +823,60 @@ namespace SysYF } return; } - if (lhs_type == INT32_T) + else if (expr_type == INT32_T) { switch (node.op) { case SyntaxTree::BinOp::PLUS: { - builder->create_iadd(lhs, rhs); + tmp_val = builder->create_iadd(lhs, rhs); break; } case SyntaxTree::BinOp::MINUS: { - builder->create_isub(lhs, rhs); + tmp_val = builder->create_isub(lhs, rhs); break; } case SyntaxTree::BinOp::MULTIPLY: { - builder->create_imul(lhs, rhs); + tmp_val = builder->create_imul(lhs, rhs); break; } case SyntaxTree::BinOp::DIVIDE: { - builder->create_isdiv(lhs, rhs); + tmp_val = builder->create_isdiv(lhs, rhs); break; } case SyntaxTree::BinOp::MODULO: { - builder->create_isrem(lhs, rhs); + tmp_val = builder->create_isrem(lhs, rhs); break; } } } - else if (lhs_type == FLOAT_T) + else if (expr_type == FLOAT_T) { switch (node.op) { case SyntaxTree::BinOp::PLUS: { - builder->create_fadd(lhs, rhs); + tmp_val = builder->create_fadd(lhs, rhs); break; } case SyntaxTree::BinOp::MINUS: { - builder->create_fsub(lhs, rhs); + tmp_val = builder->create_fsub(lhs, rhs); break; } case SyntaxTree::BinOp::MULTIPLY: { - builder->create_fmul(lhs, rhs); + tmp_val = builder->create_fmul(lhs, rhs); break; } case SyntaxTree::BinOp::DIVIDE: { - builder->create_fdiv(lhs, rhs); + tmp_val = builder->create_fdiv(lhs, rhs); break; } case SyntaxTree::BinOp::MODULO: @@ -760,12 +940,12 @@ namespace SysYF { case SyntaxTree::UnaryOp::PLUS: { - builder->create_iadd(rhs, CONST_INT(0)); + tmp_val = builder->create_iadd(rhs, CONST_INT(0)); break; } case SyntaxTree::UnaryOp::MINUS: { - builder->create_isub(CONST_INT(0), rhs); + tmp_val = builder->create_isub(CONST_INT(0), rhs); break; } } @@ -776,12 +956,12 @@ namespace SysYF { case SyntaxTree::UnaryOp::PLUS: { - builder->create_fadd(rhs, CONST_FLOAT(0)); + tmp_val = builder->create_fadd(rhs, CONST_FLOAT(0)); break; } case SyntaxTree::UnaryOp::MINUS: { - builder->create_fsub(CONST_FLOAT(0), rhs); + tmp_val = builder->create_fsub(CONST_FLOAT(0), rhs); break; } } @@ -826,12 +1006,16 @@ namespace SysYF { tmp_val = builder->create_fptosi(value, INT32_T); } + else + { + tmp_val = value; + } } args.push_back(tmp_val); } - builder->create_call(func, args); + tmp_val = builder->create_call(func, args); } } @@ -873,31 +1057,38 @@ namespace SysYF auto falseBB = BasicBlock::create(module, "falseBB_while", module->get_functions().back()); - scope.push("condBB", condBB); - scope.push("trueBB", trueBB); - scope.push("falseBB", falseBB); + scope.push("condBB_while", condBB); + scope.push("trueBB_while", trueBB); + scope.push("falseBB_while", falseBB); builder->create_br(condBB); + + builder->set_insert_point(condBB); + node.cond_exp->accept(*this); LVal_to_RVal(tmp_val); auto cond = tmp_val; builder->create_cond_br(cond, trueBB, falseBB); - auto cond_val = tmp_val; + builder->set_insert_point(trueBB); + node.statement->accept(*this); + + builder->create_br(condBB); + + builder->set_insert_point(falseBB); + // auto cond_val = tmp_val; scope.exit(); } void IRBuilder::visit(SyntaxTree::BreakStmt &node) { - node.accept(*this); - auto falseBB = scope.find("falseBB", 0); + auto falseBB = scope.find("falseBB_while", 0); builder->create_br(dynamic_pointer_cast(falseBB)); } void IRBuilder::visit(SyntaxTree::ContinueStmt &node) { - node.accept(*this); - auto condBB = scope.find("condBB", 0); + auto condBB = scope.find("condBB_while", 0); builder->create_br(dynamic_pointer_cast(condBB)); } }