diff --git a/src/SysYFIRBuilder/IRBuilder.cpp b/src/SysYFIRBuilder/IRBuilder.cpp index 81c7546..4822978 100644 --- a/src/SysYFIRBuilder/IRBuilder.cpp +++ b/src/SysYFIRBuilder/IRBuilder.cpp @@ -105,11 +105,18 @@ namespace SysYF /* SysYF::Ptr _cmp; */ // store temporary value Ptr tmp_val = nullptr; // 存储需要全局处理的expr node +<<<<<<< HEAD Ptr lhs_addr = nullptr; Ptr lval_addr_ = nullptr; Ptr func_parent; // 便于在创建新的bb时获得对应的func_parent int bb_label_num = 0; // 全局控制bb标签编号 bool func_first_bb; // 处理一个func域里有多个{},只创建一个scope +======= + Ptr lhs_addr = nullptr; + Ptr func_parent; // 便于在创建新的bb时获得对应的func_parent + int bb_label_num = 0; // 全局控制bb标签编号 + bool func_first_bb; // 处理一个func域里有多个{},只创建一个scope +>>>>>>> 9ffa4690b8449d94084ae7367d65488596d58d5b PtrVec break_point; PtrVec continue_point; // 维护两个vector(栈)控制循环break和continue应跳转到的目标地址 // types @@ -493,7 +500,6 @@ namespace SysYF /* DBGLOG("In LVal array"); */ // a[4] auto lval = builder->create_gep(lval_addr, {CONST_INT(0), tmp_val}); lhs_addr = lval; - lval_addr_ = builder->create_gep(lval_addr, {CONST_INT(0)}); tmp_val = builder->create_load(lval); IsArray = true; } @@ -502,6 +508,7 @@ namespace SysYF 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); } } @@ -665,7 +672,22 @@ namespace SysYF void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) { +<<<<<<< HEAD if ((node.op != SyntaxTree::BinaryCondOp::LAND) && (node.op != SyntaxTree::BinaryCondOp::LOR)) +======= + 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) +>>>>>>> 9ffa4690b8449d94084ae7367d65488596d58d5b { node.lhs->accept(*this); auto lhs = tmp_val; @@ -851,6 +873,7 @@ namespace SysYF { if (node.op == SyntaxTree::BinaryCondOp::LAND) { +<<<<<<< HEAD auto parent = func_parent; char labelname[20]; sprintf(labelname, "ture_bb_%d", bb_label_num++); // lhs&&rhs为true进入执行体 @@ -982,15 +1005,302 @@ namespace SysYF builder->set_insert_point(true_bb); // cond_bb判断域结束,进入true_bb执行体内部 builder->create_store(CONST_INT(true), result); builder->create_br(after_bb); +======= + 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, "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, 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(result, CONST_INT(true)); + builder->create_br(after_bb); + builder->set_insert_point(false_bb); + builder->create_store(result, CONST_INT(false)); + 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(); +>>>>>>> 9ffa4690b8449d94084ae7367d65488596d58d5b builder->set_insert_point(false_bb); builder->create_store(CONST_INT(false), result); builder->create_br(after_bb); +<<<<<<< HEAD // true_bb和false_bb IR结束后都要无条件br到after_bb builder->set_insert_point(after_bb); tmp_val = builder->create_load(result); } +======= + builder->set_insert_point(true_bb); // cond_bb判断域结束,进入true_bb执行体内部 + builder->create_store(result, CONST_INT(true)); + builder->create_br(after_bb); + builder->set_insert_point(false_bb); + builder->create_store(result, CONST_INT(false)); + 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; +>>>>>>> 9ffa4690b8449d94084ae7367d65488596d58d5b } } @@ -1434,10 +1744,14 @@ namespace SysYF } else if (ParaType->is_pointer_type()) { +<<<<<<< HEAD if (tmpType->is_array_type()) { /* auto tmp = dynamic_pointer_cast(tmp_val); */ /* auto Element_Type = tmp->get_array_element_type(); */ +======= + if (tmpType->is_array_type()){ +>>>>>>> 9ffa4690b8449d94084ae7367d65488596d58d5b DBGLOG(tmpType->get_type_id()); DBGLOG("debug 1"); auto Element_pointer = builder->create_gep(lhs_addr, {CONST_INT(0), CONST_INT(0)});