From 82919f4edec7b05fee6cc9106e9ab692fc94e1de Mon Sep 17 00:00:00 2001 From: Odeinjul Date: Mon, 18 Dec 2023 12:38:12 +0800 Subject: [PATCH] FINISH ALL --- .../task3/function_test2021/061_sort_test1.sy | 4 +- Student/task3/test.py | 8 +- doc/phase3.md | 2 +- src/SysYFIRBuilder/IRBuilder.cpp | 234 +++++++++++------- 4 files changed, 150 insertions(+), 98 deletions(-) diff --git a/Student/task3/function_test2021/061_sort_test1.sy b/Student/task3/function_test2021/061_sort_test1.sy index 8491e90..02635e1 100644 --- a/Student/task3/function_test2021/061_sort_test1.sy +++ b/Student/task3/function_test2021/061_sort_test1.sy @@ -3,13 +3,13 @@ int bubblesort(int arr[]) { int i; int j; - i =0; + i =0; while(i < n-1){ // Last i elements are already in place j = 0; while(j < n-i-1){ if (arr[j] > arr[j+1]) { - // swap(&arr[j], &arr[j+1]); + // swap(&arr[j], &arr[j+1]); int tmp; tmp = arr[j+1]; arr[j+1] = arr[j]; diff --git a/Student/task3/test.py b/Student/task3/test.py index 08457e8..a023c79 100644 --- a/Student/task3/test.py +++ b/Student/task3/test.py @@ -7,10 +7,13 @@ ExeGen_ptn = '"clang" "{}" "-o" "{}" "{}" "../../lib/lib.c"' Exe_ptn = '"{}"' def eval(EXE_PATH, TEST_BASE_PATH, optimization): + cnt = 0 + passed = 0 print('===========TEST START===========') print('now in {}'.format(TEST_BASE_PATH)) dir_succ = True for case in testcases: + cnt += 1 print('Case %s:' % case, end='') TEST_PATH = TEST_BASE_PATH + case SY_PATH = TEST_BASE_PATH + case + '.sy' @@ -49,6 +52,7 @@ def eval(EXE_PATH, TEST_BASE_PATH, optimization): case_succ = False i = i + 1 if case_succ: + passed += 1 print('\t\033[32mPass\033[0m') else: print('\t\033[31mWrong Answer\033[0m') @@ -68,7 +72,7 @@ def eval(EXE_PATH, TEST_BASE_PATH, optimization): print('\t\033[32mSuccess\033[0m in dir {}'.format(TEST_BASE_PATH)) else: print('\t\033[31mFail\033[0m in dir {}'.format(TEST_BASE_PATH)) - + print(f'\t\033[32mPassed: {passed}, Total: {cnt} \033[0m') print('============TEST END============') @@ -81,7 +85,7 @@ if __name__ == "__main__": ] # you can only modify this to add your testcase - optimization = "-O0" # -O0 -O1 -O2 -O3 -O4(currently = -O3) -Ofast + optimization = "-O3" # -O0 -O1 -O2 -O3 -O4(currently = -O3) -Ofast for TEST_BASE_PATH in TEST_DIRS: testcases = {} # { name: need_input } EXE_PATH = os.path.abspath('../../build/SysYFCompiler') diff --git a/doc/phase3.md b/doc/phase3.md index 376599b..1690e6d 100644 --- a/doc/phase3.md +++ b/doc/phase3.md @@ -78,7 +78,7 @@ make 当需要对 sy 文件测试时,可以这样使用: ```sh -SysYFCompiler test.sy -emit-ir -o test.ll +SysYFCompiler test.c -emit-ir -o test.ll ``` 得到对应的ll文件。 diff --git a/src/SysYFIRBuilder/IRBuilder.cpp b/src/SysYFIRBuilder/IRBuilder.cpp index 106570b..fe3b33d 100644 --- a/src/SysYFIRBuilder/IRBuilder.cpp +++ b/src/SysYFIRBuilder/IRBuilder.cpp @@ -15,6 +15,12 @@ namespace IR std::vector> funcFParam; +struct CondBlock { + Ptr trueBB; + Ptr falseBB; +}; +auto curCondBlock = CondBlock{nullptr, nullptr}; + struct WhileBlock { Ptr condBB; Ptr bodyBB; @@ -27,7 +33,7 @@ Ptr retAlloca; Ptr tmpInst; Ptr arrayInitializer; -Ptr>> constArrayInit; +Ptr>> constArrayInit; // types @@ -39,47 +45,35 @@ Ptr INT32PTR_T; Ptr FLOATPTR_T; void IRBuilder::ArrayInitTraverser(Ptr initVal, int depth, int index, Ptr varType, std::vector arrayDim) { + auto tmpIndex = index; if(initVal->isExp) { initVal->expr->accept(*this); - TypeConvert(tmpInst, varType); - //set constArrayInit[index] = tmpInst - constArrayInit->at(index) = dynamic_pointer_cast(tmpInst); + constArrayInit->at(index) = tmpInst; } else { + auto tmp = 1; + for (int j = depth + 1; j < arrayDim.size(); j++) { + tmp *= arrayDim[j]; + } for (int i = 0; i < initVal->elementList.size(); i++) { - auto tmpIndex = 1; - for (int j = depth + 1; j < arrayDim.size(); j++) { - tmpIndex *= arrayDim[j]; + if(initVal->elementList[i]->isExp) { + ArrayInitTraverser(initVal->elementList[i], depth + 1, tmpIndex, varType, arrayDim); + tmpIndex += 1; + } else { + auto sub = tmpIndex - index; + tmpIndex = tmpIndex - (sub % tmp) + ((sub % tmp) ? tmp : 0); + //std ::cout << depth << ", " << tmpIndex << std::endl; + ArrayInitTraverser(initVal->elementList[i], depth + 1, tmpIndex, varType, arrayDim); + tmpIndex += tmp; } - ArrayInitTraverser(initVal->elementList[i], depth + 1, index + i * tmpIndex, varType, arrayDim); } } } - void IRBuilder::GetArrayInit(Ptr initVal, std::vector arrayDim, Ptr varType, bool global = true) { - /* - arrayInitializer.reset(); - // 一维数组 - std::vector> varInit; - for(auto initValPtr : initVal->elementList){ - initValPtr->expr->accept(*this); - TypeConvert(tmpInst, varType); - varInit.push_back(dynamic_pointer_cast(tmpInst)); - } - auto arrayLen = arrayDim[0]; - auto otherLen = arrayLen - initVal->elementList.size(); - auto tmpZero = CONST_INT(0); - TypeConvert(tmpZero, varType); - for (auto i = 0u; i < otherLen; i++) { - varInit.push_back(dynamic_pointer_cast(tmpInst)); - } - auto arrayType = varType->get_array_type(varType, arrayLen); - arrayInitializer = ConstantArray::create(arrayType, varInit); - */ auto arraySize = 1; for(auto i : arrayDim){ arraySize *= i; } - constArrayInit = std::make_shared>>(arraySize); + constArrayInit = std::make_shared>>(arraySize); ArrayInitTraverser(initVal, 0, 0, varType, arrayDim); auto arrayType = varType->get_array_type(varType, arraySize); //iterate constArrayInit to get arrayInitializer @@ -92,14 +86,19 @@ void IRBuilder::GetArrayInit(Ptr initVal, std::vector } else{ tmpZero = CONST_FLOAT(0.0); } - TypeConvert(tmpZero, varType); + tmpInst = tmpZero; + TypeConvert(tmpInst, varType); varInit.push_back(dynamic_pointer_cast(tmpInst)); } else { - varInit.push_back(i); + tmpInst = i; + TypeConvert(tmpInst, varType); + varInit.push_back(dynamic_pointer_cast(tmpInst)); } } - arrayInitializer = ConstantArray::create(arrayType, varInit); - + // + if (global) { + arrayInitializer = ConstantArray::create(arrayType, varInit); + } } Ptr GetBaseType(SyntaxTree::Type type){ @@ -434,8 +433,6 @@ void IRBuilder::visit(SyntaxTree::Assembly &node) { } } -// You need to fill them - // FINISH void IRBuilder::visit(SyntaxTree::InitVal &node) { node.expr->accept(*this); @@ -443,7 +440,7 @@ void IRBuilder::visit(SyntaxTree::InitVal &node) { // FINISH void IRBuilder::visit(SyntaxTree::FuncDef &node) { - + //std::cout <accept(*this); auto funcType = FunctionType::create(funcRetType, funcFParam); @@ -530,7 +527,7 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) { arrayType = ArrayType::create(varType, arraySize); std::reverse(arrayDim.begin(), arrayDim.end()); } - + //std::cout << node.name << ", "<< arraySize << std::endl; Ptr identAlloca; if (scope.in_global()) { if (!node.is_inited || (!node.array_length.empty() && node.initializers->elementList.empty())) { @@ -547,7 +544,7 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) { } } else { if (!node.array_length.empty()) { - GetArrayInit(node.initializers, arrayDim, varType); + GetArrayInit(node.initializers, arrayDim, varType, true); identAlloca = GlobalVariable::create(node.name, module, arrayType, node.is_constant, arrayInitializer); // auto tmpIdent = dynamic_pointer_cast(identAlloca); @@ -586,31 +583,51 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) { } return ; } else { - GetArrayInit(node.initializers, arrayDim, varType); - // - identAlloca = builder->create_alloca(arrayType); - auto tmpIdent = dynamic_pointer_cast(identAlloca); - tmpIdent->set_array(std::make_shared>(arrayDim)); - // - identAlloca = dynamic_pointer_cast(tmpIdent); - scope.push(node.name, identAlloca); - auto varInit = constArrayInit.get(); - std::cout << arraySize << std::endl; - Ptr tmpZero; - if (varType->is_integer_type()) { - tmpZero = CONST_INT(0); + if(node.is_inited) { + GetArrayInit(node.initializers, arrayDim, varType, false); + identAlloca = builder->create_alloca(arrayType); + auto tmpIdent = dynamic_pointer_cast(identAlloca); + tmpIdent->set_array(std::make_shared>(arrayDim)); + // + identAlloca = dynamic_pointer_cast(tmpIdent); + scope.push(node.name, identAlloca); + Ptr tmpZero; + if (varType->is_integer_type()) { + tmpZero = CONST_INT(0); + } else { + tmpZero = CONST_FLOAT(0.0); + } + for (int i = 0u; i < arraySize; i++) { + auto index = CONST_INT(i); + auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index}); + if ((*constArrayInit)[i] == nullptr) { + builder->create_store(tmpZero, ptr); + } else { + //std :: cout << i << std::endl; + tmpInst = (*constArrayInit)[i]; + TypeConvert(tmpInst, varType); + builder->create_store(tmpInst, ptr); + } + } } else { - tmpZero = CONST_FLOAT(0.0); - } - for (int i = 0u; i < arraySize; i++) { - auto index = CONST_INT(i); - auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index}); - if ((*varInit)[i] == nullptr) { - builder->create_store(tmpZero, ptr); + identAlloca = builder->create_alloca(arrayType); + auto tmpIdent = dynamic_pointer_cast(identAlloca); + tmpIdent->set_array(std::make_shared>(arrayDim)); + identAlloca = dynamic_pointer_cast(tmpIdent); + scope.push(node.name, identAlloca); + Ptr tmpZero; + if (varType->is_integer_type()) { + tmpZero = CONST_INT(0); } else { - builder->create_store((*varInit)[i], ptr); + tmpZero = CONST_FLOAT(0.0); + } + for (int i = 0u; i < arraySize; i++) { + auto index = CONST_INT(i); + auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index}); + builder->create_store(tmpZero, ptr); } } + } } } @@ -618,9 +635,9 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) { // FINISH void IRBuilder::visit(SyntaxTree::LVal &node) { + //std::cout << node.name << std::endl; auto ident = scope.find(node.name, false); if (!node.array_index.empty()) { - /*node.array_index[0]->accept(*this); auto constIndex = dynamic_pointer_cast(tmpInst); auto globalIdent = dynamic_pointer_cast(ident); @@ -631,7 +648,6 @@ void IRBuilder::visit(SyntaxTree::LVal &node) { tmpInst = builder->create_gep(ident, {CONST_INT(0), tmpInst}); } */ - int index = 0; auto globalIdent = dynamic_pointer_cast(ident); auto localIdent = dynamic_pointer_cast(ident); Ptr> arrayDimPtr; @@ -641,26 +657,39 @@ void IRBuilder::visit(SyntaxTree::LVal &node) { arrayDimPtr = localIdent->get_array_dim(); } bool index_is_constant = true; + Ptr index = CONST_INT(0); for (int i = 0; i < node.array_index.size(); i++) { node.array_index[i]->accept(*this); - auto constIndex = dynamic_pointer_cast(tmpInst); - if(constIndex == nullptr) { - index_is_constant = false; - } int tmpIndex = 1; for (int j = i + 1; j < node.array_index.size(); j++) { tmpIndex *= (*arrayDimPtr)[j]; } - index += constIndex->get_value() * tmpIndex; + if(dynamic_pointer_cast(tmpInst) != nullptr) { + //std::cout << dynamic_pointer_cast(tmpInst)->get_value() * tmpIndex <(tmpInst)->get_value() * tmpIndex), SyntaxTree::BinOp::PLUS); + } else { + index_is_constant = false; + BinaryExprGen(tmpInst, CONST_INT(tmpIndex), SyntaxTree::BinOp::MULTIPLY); + BinaryExprGen(index, tmpInst, SyntaxTree::BinOp::PLUS); + } + index = tmpInst; } if(globalIdent != nullptr && globalIdent->is_const() && index_is_constant) { auto arrayInit = dynamic_pointer_cast(globalIdent->get_init()); - tmpInst = arrayInit->get_element_value(index); + tmpInst = arrayInit->get_element_value(dynamic_pointer_cast(index)->get_value()); } else { - tmpInst = builder->create_gep(ident, {CONST_INT(0), CONST_INT(index)}); + if(globalIdent != nullptr) { + tmpInst = builder->create_gep(ident, {CONST_INT(0), index}); + } + else { + if(localIdent->get_type()->is_pointer_type() && localIdent->get_type()->get_pointer_element_type()->is_pointer_type()) { + auto trash = builder->create_load(localIdent); + tmpInst = builder->create_gep(trash, {index}); + } else { + tmpInst = builder->create_gep(ident, {CONST_INT(0), index}); + } + } } - - } else { if (ident->get_type()->is_pointer_type() && ident->get_type()->get_pointer_element_type()->is_array_type()) { @@ -715,8 +744,9 @@ void IRBuilder::visit(SyntaxTree::BlockStmt &node) { scope.enter(); auto i = 0; for (const auto &stmt : node.body) { - //std::cout << stmt->loc <accept(*this); + //std::cout << i << std::endl; + i++; } scope.exit(); } @@ -737,7 +767,10 @@ void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) { auto constInt = dynamic_pointer_cast(tmpInst); auto constFloat = dynamic_pointer_cast(tmpInst); if (constInt == nullptr && constFloat == nullptr) { + TypeConvert(tmpInst, INT1_T); + tmpInst = builder->create_zext(tmpInst, INT32_T); tmpInst = builder->create_icmp_eq(tmpInst, CONST_INT(0)); + tmpInst = builder->create_zext(tmpInst, INT32_T); } else { tmpInst = CONST_INT((constInt->get_value() == 0 || constFloat->get_value() == 0 ) ? 1 : 0); } @@ -747,42 +780,56 @@ void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) { // FINISH void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) { auto curFunc = builder->get_insert_block()->get_parent(); - Ptr trueBB; - Ptr falseBB; + Ptr tmpLhs; + Ptr lhsTrueBB, lhsFalseBB, trueBB, falseBB; + trueBB = curCondBlock.trueBB; + falseBB = curCondBlock.falseBB; Ptr cond; + auto tmpCondBlock = curCondBlock; switch (node.op) { case SyntaxTree::BinaryCondOp::LAND: - trueBB = BasicBlock::create(module, "", curFunc); - falseBB = BasicBlock::create(module, "", curFunc); + lhsTrueBB = BasicBlock::create(module, "", curFunc); + lhsFalseBB = BasicBlock::create(module, "", curFunc); + curCondBlock = CondBlock{lhsTrueBB, lhsFalseBB}; node.lhs->accept(*this); + curCondBlock = tmpCondBlock; + tmpLhs = tmpInst; TypeConvert(tmpInst, INT1_T); - builder->create_cond_br(tmpInst, trueBB, falseBB); + builder->create_cond_br(tmpInst, lhsTrueBB, lhsFalseBB); - // True - continue - builder->set_insert_point(trueBB); + builder->set_insert_point(lhsTrueBB); + curCondBlock = CondBlock{trueBB, falseBB}; node.rhs->accept(*this); + curCondBlock = tmpCondBlock; TypeConvert(tmpInst, INT1_T); + builder->create_cond_br(tmpInst, trueBB, falseBB); - // False - builder->set_insert_point(falseBB); + builder->set_insert_point(lhsFalseBB); + tmpInst = tmpLhs; TypeConvert(tmpInst, INT1_T); - + builder->create_br(falseBB); break; case SyntaxTree::BinaryCondOp::LOR: - trueBB = BasicBlock::create(module, "", curFunc); - falseBB = BasicBlock::create(module, "", curFunc); + lhsTrueBB = BasicBlock::create(module, "", curFunc); + lhsFalseBB = BasicBlock::create(module, "", curFunc); + curCondBlock = CondBlock{lhsTrueBB, lhsFalseBB}; node.lhs->accept(*this); + curCondBlock = tmpCondBlock; + tmpLhs = tmpInst; TypeConvert(tmpInst, INT1_T); - builder->create_cond_br(tmpInst, trueBB, falseBB); + builder->create_cond_br(tmpInst, lhsTrueBB, lhsFalseBB); - // False - continue - builder->set_insert_point(falseBB); + builder->set_insert_point(lhsFalseBB); + curCondBlock = CondBlock{trueBB, falseBB}; node.rhs->accept(*this); + curCondBlock = tmpCondBlock; TypeConvert(tmpInst, INT1_T); + builder->create_cond_br(tmpInst, trueBB, falseBB); - // True - builder->set_insert_point(trueBB); + builder->set_insert_point(lhsTrueBB); + tmpInst = tmpLhs; TypeConvert(tmpInst, INT1_T); + builder->create_br(trueBB); break; default: node.lhs->accept(*this); @@ -851,9 +898,10 @@ void IRBuilder::visit(SyntaxTree::IfStmt &node) { auto trueBB = BasicBlock::create(module, "", curFunc); auto falseBB = BasicBlock::create(module, "", curFunc); auto afterBB = node.else_statement == nullptr ? falseBB : BasicBlock::create(module, "", curFunc); - + auto tmpCondBlock = curCondBlock; + curCondBlock = CondBlock{trueBB, falseBB}; node.cond_exp->accept(*this); - + curCondBlock = tmpCondBlock; TypeConvert(tmpInst, INT1_T); builder->create_cond_br(tmpInst, trueBB, falseBB); @@ -880,18 +928,18 @@ void IRBuilder::visit(SyntaxTree::WhileStmt &node) { auto afterBB = BasicBlock::create(module, "", curFunc); auto tmpWhileBlock = curWhileBlock; curWhileBlock = WhileBlock{condBB, bodyBB, afterBB}; - builder->create_br(condBB); builder->set_insert_point(condBB); + auto tmpCondBlock = curCondBlock; + curCondBlock = CondBlock{bodyBB, afterBB}; node.cond_exp->accept(*this); + curCondBlock = tmpCondBlock; TypeConvert(tmpInst, INT1_T); builder->create_cond_br(tmpInst, bodyBB, afterBB); - builder->set_insert_point(bodyBB); node.statement->accept(*this); builder->create_br(condBB); - builder->set_insert_point(afterBB); curWhileBlock = tmpWhileBlock; }