diff --git a/src/SysYFIRBuilder/IRBuilder.cpp b/src/SysYFIRBuilder/IRBuilder.cpp index 9102f68..64ac4eb 100644 --- a/src/SysYFIRBuilder/IRBuilder.cpp +++ b/src/SysYFIRBuilder/IRBuilder.cpp @@ -29,15 +29,6 @@ Ptr retAlloca; Ptr tmpInst; -int tmpConstVal = 0; -Ptr tmpVal = nullptr; -std::vector> arrayInitializer; -std::string curFuncName = ""; -bool isFloat = false; -bool isAddr = false; -Ptr curCondBB; -Ptr curAfterBB; - // types Ptr VOID_T; Ptr INT1_T; @@ -371,7 +362,6 @@ void IRBuilder::visit(SyntaxTree::Assembly &node) { INT32PTR_T = Type::get_int32_ptr_type(module); FLOATPTR_T = Type::get_float_ptr_type(module); for (const auto &def : node.global_defs) { - //std::cout << "4" << std::endl; def->accept(*this); } } @@ -399,26 +389,23 @@ void IRBuilder::visit(SyntaxTree::FuncDef &node) { auto para = node.param_list->params.begin(); auto para_end = node.param_list->params.end(); - for (auto arg = func->arg_begin(); arg != func->arg_end() ; arg++) { - if(para == para_end) { + auto funcArgs = func->get_args(); + for (const auto &arg : funcArgs) { + if(para == para_end) break; - } + auto name = (*para)->name; - auto val = (*arg); - auto argAlloca = builder->create_alloca(val->get_type()); - builder->create_store(val, argAlloca); + auto argAlloca = builder->create_alloca(arg->get_type()); + builder->create_store(arg, argAlloca); scope.push(name, argAlloca); para++; } - if (funcRetType == VOID_T) { ; } else { retAlloca = builder->create_alloca(funcRetType); } - node.body->accept(*this); - if (builder->get_insert_block()->get_terminator() == nullptr) { if (funcRetType == INT32_T) { builder->create_store(CONST_INT(0), retAlloca); @@ -435,7 +422,6 @@ void IRBuilder::visit(SyntaxTree::FuncDef &node) { auto ret_val = builder->create_load(retAlloca); builder->create_ret(ret_val); } - scope.exit(); } @@ -449,141 +435,105 @@ void IRBuilder::visit(SyntaxTree::FuncFParamList &node) { // FINISH void IRBuilder::visit(SyntaxTree::FuncParam &node) { - auto tmpType = GetParamType(node.param_type, node.array_index[0] != nullptr); + auto tmpType = GetParamType(node.param_type, node.array_index.empty()); funcFParam.push_back(tmpType); } -// TODO +// FINISH void IRBuilder::visit(SyntaxTree::VarDef &node) { - int arrayLength; - Ptr initVal; - if (node.is_constant) { - assert(node.is_inited); - switch (node.btype) { - case (SyntaxTree::Type::INT): - if (!node.array_length.empty()) { - node.array_length[0]->accept(*this); - // expr need to return ConstVal if possible - arrayLength = tmpConstVal; - auto arrayType = ArrayType::get(INT32_T, arrayLength); - auto alloca = builder->create_alloca(arrayType); - arrayInitializer.clear(); - // const int a[] = {}; - int i = 0; - for ( const auto &expr : node.initializers->elementList) { - expr->accept(*this); - auto tmpInit = tmpInst; - tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)}); - builder->create_store(tmpInit, tmpInst); - i ++; - } - } else { - // const int a = 1; - auto alloca = builder->create_alloca(INT32_T); + // type + auto varType = GetBaseType(node.btype); + Ptr arrayType; + if (!node.array_length.empty()) { + node.array_length[0]->accept(*this); + auto constInt = dynamic_pointer_cast(tmpInst); + arrayType = ArrayType::create(varType, constInt->get_value()); + } + + Ptr identAlloca; + if (scope.in_global()) { + if (!node.is_inited || (!node.array_length.empty() && node.initializers->elementList.empty())) { + auto zeroInit = ConstantZero::create(varType, module); + identAlloca = GlobalVariable::create(node.name, module, varType, false, zeroInit); + + } else { + if (!node.array_length.empty()) { + std::vector> varInit; + for (const auto &init : node.initializers->elementList) { + init->accept(*this); + TypeConvert(tmpInst, varType); + varInit.push_back(dynamic_pointer_cast(tmpInst)); + } + auto otherLen = arrayType->get_num_of_elements() - node.initializers->elementList.size(); + auto tmpZero = CONST_INT(0); + TypeConvert(tmpZero, varType); + for (int i = 0; i < otherLen; i++) { + varInit.push_back(dynamic_pointer_cast(tmpInst)); + } + auto zeroInit = ConstantZero::create(varType, module); + identAlloca = GlobalVariable::create(node.name, module, arrayType, false, zeroInit); + for (int i = 0; i < varInit.size(); i++) { + auto index = CONST_INT(i); + auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index}); + builder->create_store(varInit[i], ptr); + } + //alter + //auto tmpInit = ConstantArray::create(static_pointer_cast(varType), varInit); + //identAlloca = GlobalVariable::create(node.name, module, varType, false, tmpInit); + } else { + if (node.is_constant) { node.initializers->expr->accept(*this); - initVal = tmpInst; - builder->create_store(initVal, alloca); - } - break; - case (SyntaxTree::Type::FLOAT): - if (!node.array_length.empty()) { - node.array_length[0]->accept(*this); - // expr need to return ConstVal if possible - arrayLength = tmpConstVal; - auto arrayType = ArrayType::get(FLOAT_T, arrayLength); - auto alloca = builder->create_alloca(arrayType); - arrayInitializer.clear(); - // const int a[] = {}; - int i = 0; - for ( const auto &expr : node.initializers->elementList) { - expr->accept(*this); - auto tmpInit = tmpInst; - tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)}); - builder->create_store(tmpInit, tmpInst); - i ++; - } + TypeConvert(tmpInst, varType); + identAlloca = tmpInst; } else { - // const float a = 1.0; - auto alloca = builder->create_alloca(FLOAT_T); node.initializers->expr->accept(*this); - initVal = tmpInst; - builder->create_store(initVal, alloca); + TypeConvert(tmpInst, varType); + auto constInit = dynamic_pointer_cast(tmpInst); + identAlloca = GlobalVariable::create(node.name, module, varType, + false, constInit); } - break; - default: - break; + } } + scope.push(node.name, identAlloca); } else { - switch (node.btype) { - case (SyntaxTree::Type::INT): - if (!node.array_length.empty()) { - node.array_length[0]->accept(*this); - // expr need to return ConstVal if possible - arrayLength = tmpConstVal; - auto arrayType = ArrayType::get(INT32_T, arrayLength); - auto alloca = builder->create_alloca(arrayType); - if (node.is_inited) { - int i = 0; - for ( const auto &expr : node.initializers->elementList) { - expr->accept(*this); - auto tmpInit = tmpInst; - tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)}); - builder->create_store(tmpInit, tmpInst); - i ++; - } - } else { - ; - } - } else { - auto alloca = builder->create_alloca(INT32_T); - if (node.is_inited) { - node.initializers->expr->accept(*this); - initVal = tmpInst; - builder->create_store(initVal, alloca); - } else { - builder->create_store(CONST_INT(0), alloca); - scope.push(node.name, alloca); - } - } - break; - case (SyntaxTree::Type::FLOAT): - if (!node.array_length.empty()) { - node.array_length[0]->accept(*this); - // expr need to return ConstVal if possible - arrayLength = tmpConstVal; - auto arrayType = ArrayType::get(FLOAT_T, arrayLength); - auto alloca = builder->create_alloca(arrayType); - if (node.is_inited) { - int i = 0; - for ( const auto &expr : node.initializers->elementList) { - expr->accept(*this); - auto tmpInit = tmpInst; - tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)}); - builder->create_store(tmpInit, tmpInst); - i ++; - } - } else { - ; - } - - } else { - auto alloca = builder->create_alloca(FLOAT_T); - if (node.is_inited) { - node.initializers->expr->accept(*this); - initVal = tmpInst; - builder->create_store(initVal, alloca); - } else { - builder->create_store(CONST_FLOAT(0.0), alloca); - scope.push(node.name, alloca); - } + if (node.is_constant && node.array_length.empty()) { + node.initializers->expr->accept(*this); + TypeConvert(tmpInst, varType); + identAlloca = tmpInst; + scope.push(node.name, identAlloca); + return ; + } else { + identAlloca = builder->create_alloca(varType); + scope.push(node.name, identAlloca); + if (node.array_length.empty()) { + node.initializers->expr->accept(*this); + TypeConvert(tmpInst, varType); + builder->create_store(tmpInst, identAlloca); + return ; + } else { + std::vector> varInit; + for (const auto &init : node.initializers->elementList) { + init->accept(*this); + TypeConvert(tmpInst, varType); + varInit.push_back(dynamic_pointer_cast(tmpInst)); + } + auto otherLen = arrayType->get_num_of_elements() - node.initializers->elementList.size(); + auto tmpZero = CONST_INT(0); + TypeConvert(tmpZero, varType); + for (int i = 0; i < otherLen; i++) { + varInit.push_back(dynamic_pointer_cast(tmpInst)); + } + auto zeroInit = ConstantZero::create(varType, module); + identAlloca = GlobalVariable::create(node.name, module, arrayType, false, zeroInit); + for (int i = 0; i < varInit.size(); i++) { + auto index = CONST_INT(i); + auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index}); + builder->create_store(varInit[i], ptr); } - break; - default: - break; + } } } - } // FINISH @@ -626,13 +576,13 @@ void IRBuilder::visit(SyntaxTree::AssignStmt &node) { void IRBuilder::visit(SyntaxTree::Literal &node) { switch(node.literal_type) { case SyntaxTree::Type::INT: - tmpVal = CONST_INT(node.int_const); + tmpInst = CONST_INT(node.int_const); break; case SyntaxTree::Type::FLOAT: - tmpVal = CONST_FLOAT(node.float_const); + tmpInst = CONST_FLOAT(node.float_const); break; default: - tmpVal = CONST_INT(0); + tmpInst = CONST_INT(0); break; } } @@ -746,12 +696,14 @@ void IRBuilder::visit(SyntaxTree::BinaryExpr &node) { // FINISH void IRBuilder::visit(SyntaxTree::UnaryExpr &node) { node.rhs->accept(*this); + Ptr constInt; + Ptr constFloat; switch (node.op) { case SyntaxTree::UnaryOp::PLUS: break; case SyntaxTree::UnaryOp::MINUS: - auto constInt = dynamic_pointer_cast(tmpInst); - auto constFloat = dynamic_pointer_cast(tmpInst); + constInt = dynamic_pointer_cast(tmpInst); + constFloat = dynamic_pointer_cast(tmpInst); if (constInt != nullptr) { tmpInst = CONST_INT(-constInt->get_value()); } else if (constFloat != nullptr) {