diff --git a/CMakeLists.txt b/CMakeLists.txt index d65578f4c0c5c180baee26f6ad37c5b561b9f0bd..e505a456b6ed56aa5df01d803f1dabd2ff7c38c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,10 +7,12 @@ endif() # åŠ è½½cmakeä¸å‡½æ•°å’Œå˜é‡ include(cmake/utils.cmake) -project(SCNUcc LANGUAGES CXX) +project(SCNUcc LANGUAGES CXX C) add_subdirectory(frontend) +add_library(sysYarm STATIC test_cases/lib/sylib.c) + #add_executable(test test.cpp) #add_subdirectory(midend) #add_subdirectory(backend) diff --git a/dependencies/lib/libsysYarm.a b/dependencies/lib/libsysYarm.a new file mode 100644 index 0000000000000000000000000000000000000000..6f92d2cd649e97d4bff5e391f121fe4ba2486804 Binary files /dev/null and b/dependencies/lib/libsysYarm.a differ diff --git a/frontend/include/MyVisitor.h b/frontend/include/MyVisitor.h index b957ef84b40488e3f1762575574d99c3c74e263f..bb60e2cee21b9956babcb38fd3a9598212c9299e 100644 --- a/frontend/include/MyVisitor.h +++ b/frontend/include/MyVisitor.h @@ -227,8 +227,9 @@ private: std::vector<std::shared_ptr<ControlFlowGraph>> cfgs_; std::map<std::string, IRPtr> gbl_vars; std::shared_ptr<GblInitBlock> gbl_init_blk; - std::vector<std::shared_ptr<BRIR>> false_list; // 真出å£é“¾ - std::vector<std::shared_ptr<BRIR>> true_list; // å‡å‡ºå£é“¾ + // 真å‡å‡ºå£é“¾å’Œbackpatch的设计å¯ä»¥å‚考https://gitlab.eduxiji.net/T202410574202994/scnucc/-/issues/30 + std::vector<std::vector<std::shared_ptr<BRIR>>> false_list; // 真出å£é“¾ + std::vector<std::vector<std::shared_ptr<BRIR>>> true_list; // å‡å‡ºå£é“¾ BLOCK::BLOCK return_flag_; // 这个block有没有被æå‰return掉 std::shared_ptr<Block> return_block_; // ret std::vector<WhileBlocks> while_list_; // 当å‰å¤„于的while循环0:entry 1: body 2:exit diff --git a/frontend/src/ExpVisitor.cpp b/frontend/src/ExpVisitor.cpp index 6f79dc8ebb9f4af44098f5a3eb51384f7e34469a..ab5b160d66416aa47d02ea23eb6252904703d67f 100644 --- a/frontend/src/ExpVisitor.cpp +++ b/frontend/src/ExpVisitor.cpp @@ -29,13 +29,13 @@ std::any MyVisitor::visitExp(SysYParser::ExpContext *ctx) { // runtime库头文件有计时函数的å®å®šä¹‰ï¼Œéœ€è¦æ”¹ä¸‹åå— - if(func_name == "stoptime") func_name = "_sysy_stoptime"; - else if(func_name == "starttime") func_name = "_sysy_starttime"; + if (func_name == "stoptime") func_name = "_sysy_stoptime"; + else if (func_name == "starttime") func_name = "_sysy_starttime"; auto func_symbol = sym_table_->FuncLookUp(func_name); - + // 特判计时函数 - if(func_name=="_sysy_stoptime" || func_name =="_sysy_starttime"){ + if (func_name == "_sysy_stoptime" || func_name == "_sysy_starttime") { int lineno = ctx->getStart()->getLine(); auto call_ir = std::make_shared<CallIR>(IRTYPE::IR_VOID, func_name, func_symbol->GetAllParams()); IRPtr numIR = std::make_shared<ConstantIR>(lineno, IRTYPE::IR_CONST_INT); @@ -63,23 +63,23 @@ std::any MyVisitor::visitExp(SysYParser::ExpContext *ctx) { // freopen("../debug.txt","w",stdout); // putfçš„ç¬¬äºŒä¸ªå‚æ•°æ˜¯å¯å˜å‚数,扫æåŽæ‰èƒ½ç¡®å®šï¼Œå› æ¤åœ¨è¿™é‡Œæ·»åŠ - if(func_name == "putf"){ + if (func_name == "putf") { //é‡ç½®putfçš„funcsymbol func_symbol->ResetParams(); func_symbol->PushPackParam(Type(BaseType::STRING, SymKind::VAR, false, false)); // %d %c %f std::string rpstring = ctx->funcRParams()->string()->getText(); - rpstring = rpstring.substr(1,rpstring.size()-2); //去掉åŒå¼•å· + rpstring = rpstring.substr(1, rpstring.size() - 2); //去掉åŒå¼•å· Util::PushBackgstring(rpstring); //将第一个实å‚(å³å—符串)åŠ è¿›å…¨å±€å—ç¬¦ä¸²ä¸ - - for(int i=0;i<rpstring.size()-1;i++){ - if(rpstring[i]=='%'){ - char t = rpstring[i+1]; - - if(t == 'd'){func_symbol->PushPackParam(Type(BaseType::INT, SymKind::VAR, false, false));} - else if(t == 'c'){func_symbol->PushPackParam(Type(BaseType::INT, SymKind::VAR, false, false));} - else if(t == 'f'){func_symbol->PushPackParam(Type(BaseType::FLOAT, SymKind::VAR, false, false));} - else{ + + for (int i = 0; i < rpstring.size() - 1; i++) { + if (rpstring[i] == '%') { + char t = rpstring[i + 1]; + + if (t == 'd') { func_symbol->PushPackParam(Type(BaseType::INT, SymKind::VAR, false, false)); } + else if (t == 'c') { func_symbol->PushPackParam(Type(BaseType::INT, SymKind::VAR, false, false)); } + else if (t == 'f') { func_symbol->PushPackParam(Type(BaseType::FLOAT, SymKind::VAR, false, false)); } + else { std::string msg = "Error: unsupported type for putf"; throw std::runtime_error(msg); } @@ -88,9 +88,9 @@ std::any MyVisitor::visitExp(SysYParser::ExpContext *ctx) { } - // freopen("/dev/tty", "a+", stdout); - /* dddddddddddddddddddddddddddeeeeeeeeeeeeeeeeebbbbbbbbbbbbbbbbbbbbuuuuuuuuuuuuuuuugggggggggggg */ - + // freopen("/dev/tty", "a+", stdout); + /* dddddddddddddddddddddddddddeeeeeeeeeeeeeeeeebbbbbbbbbbbbbbbbbbbbuuuuuuuuuuuuuuuugggggggggggg */ + std::vector<Type> all_params = func_symbol->GetAllParams(); auto call_ir = std::make_shared<CallIR>(ret_type, func_name, all_params); @@ -106,7 +106,7 @@ std::any MyVisitor::visitExp(SysYParser::ExpContext *ctx) { LoadVar(exp_ir); // 如果是GEP,需è¦load ZeroExtend(exp_ir); // 这里先åªè€ƒè™‘ç±»åž‹è½¬æ¢ - if (all_params[i].base_type_ == BaseType::INT) { + if (all_params[i].base_type_ == BaseType::INT) { Float2Int(exp_ir); } else if (all_params[i].base_type_ == BaseType::FLOAT) { Int2Float(exp_ir); @@ -154,7 +154,8 @@ std::any MyVisitor::visitLVal(SysYParser::LValContext *ctx) { // 在当å‰ä½œç”¨åŸŸæŸ¥æ‰¾ std::shared_ptr<Scope> cur_scope = sym_table_->GetCurrentScope(); // 这个肯定是VarSymbol - std::shared_ptr<VarSymbol> var_sym = std::dynamic_pointer_cast<VarSymbol>(cur_scope->VarLookUp(var_name, SearchScope::CUR_SCOPE)); + std::shared_ptr<VarSymbol> var_sym = std::dynamic_pointer_cast<VarSymbol>( + cur_scope->VarLookUp(var_name, SearchScope::CUR_SCOPE)); // 如果这个作用域没找到,就å¯ä»¥åŽ»åˆ°çˆ¶ä½œç”¨åŸŸæ‰¾ if (var_sym == nullptr) { var_sym = std::dynamic_pointer_cast<VarSymbol>(cur_scope->VarLookUp(var_name, SearchScope::ALL_SCOPE)); @@ -171,7 +172,8 @@ std::any MyVisitor::visitLVal(SysYParser::LValContext *ctx) { auto exp_ir = std::any_cast<IRPtr>(visit(ctx->exp(i))); LoadVar(exp_ir); indices.push_back(exp_ir); - IRPtr new_gep = std::make_shared<GEPIR>(type == BaseType::INT ? IRTYPE::IR_I32 : IRTYPE::IR_FLOAT, var_sym, indices); + IRPtr new_gep = std::make_shared<GEPIR>(type == BaseType::INT ? IRTYPE::IR_I32 : IRTYPE::IR_FLOAT, var_sym, + indices); if (i == 0) { new_gep->AddOprnd(var_ir); // åŠ å…¥æ•°ç»„çš„å£°æ˜ŽIR } else { @@ -179,7 +181,7 @@ std::any MyVisitor::visitLVal(SysYParser::LValContext *ctx) { } gep = new_gep; blk->AddStatement(gep); - } + } if (gep == nullptr) { // æ¤æ—¶åªç»™äº†æ•°ç»„å indices.push_back(std::make_shared<ConstantIR>(0, IRTYPE::IR_CONST_INT)); gep = std::make_shared<GEPIR>(type == BaseType::INT ? IRTYPE::IR_I32 : IRTYPE::IR_FLOAT, var_sym, indices); @@ -188,8 +190,8 @@ std::any MyVisitor::visitLVal(SysYParser::LValContext *ctx) { } return gep; } else { - auto var_ir = std::any_cast<IRPtr>(MyVisitor::ReadVariable(var_name)); - return var_ir; + auto var_ir = std::any_cast<IRPtr>(MyVisitor::ReadVariable(var_name)); + return var_ir; } return nullptr; } @@ -210,7 +212,7 @@ std::any MyVisitor::visitUnaryExp(SysYParser::ExpContext *ctx) { // +a +b // load一下 return IR; - + } else if (ctx->unaryOp()->SUB()) { // 如果是负数 // a @@ -372,7 +374,7 @@ std::any MyVisitor::visitCond(SysYParser::CondContext *ctx) { LoadVar(ir); // å…ˆ0扩展 ZeroExtend(ir); - + if ((logic_parent && (logic_parent->op->getText() == "&&" || logic_parent->op->getText() == "||")) || (stmt_parent && (stmt_parent->IF() != nullptr || stmt_parent->WHILE() != nullptr))) { @@ -401,15 +403,17 @@ std::any MyVisitor::visitCond(SysYParser::CondContext *ctx) { // 新建一个BRIR auto br = std::make_shared<BRIR>(IRTYPE::IR_I1, blk); br->AddOprnd(cmpIR); - true_list.push_back(br); - false_list.push_back(br); + true_list.emplace_back(); + true_list.back().push_back(br); + false_list.emplace_back(); + false_list.back().push_back(br); blk->AddStatement(br); return cmpIR; } else { return ir; } - } else if (ctx->op->getText() == "&&" || ctx->op->getText() == "||") { // 逻辑与è¿ç®— + } else if (ctx->op->getText() == "&&" || ctx->op->getText() == "||") { // 逻辑è¿ç®— auto cfg = cfgs_.back(); auto left_block = cfg->GetLastBlock(); // æž„é€ ç¬¬ä¸€ä¸ªcond block @@ -417,9 +421,23 @@ std::any MyVisitor::visitCond(SysYParser::CondContext *ctx) { // back patch auto right_block = std::make_shared<Block>(sym_table_, ctx->while_entry, ctx->while_exit); if (ctx->op->getText() == "&&") { - backPatch(true_list, right_block, true); + backPatch(true_list.back(), right_block, true); + true_list.pop_back(); + // false_list没有办法处ç†å°±åˆå¹¶åˆ°çˆ¶èŠ‚ç‚¹çš„false_listä¸ï¼Œè®©çˆ¶èŠ‚ç‚¹åŽ»å¤„ç† + // é¿å…出现这ç§é—®é¢˜çš„问题是https://gitlab.eduxiji.net/T202410574202994/scnucc/-/issues/30 + if (false_list.size() >= 2) { + auto& parent_list = false_list[false_list.size() - 2]; + parent_list.insert(parent_list.end(), false_list.back().begin(), false_list.back().end()); + false_list.pop_back(); + } } else { - backPatch(false_list, right_block, false); + backPatch(false_list.back(), right_block, false); + false_list.pop_back(); + if (true_list.size() >= 2) { + auto& parent_list = true_list[true_list.size() - 2]; + parent_list.insert(parent_list.end(), true_list.back().begin(), true_list.back().end()); + true_list.pop_back(); + } } // 在back patchä¸å·²ç»å®Œæˆäº†è¿žæŽ¥ï¼Œæ‰€ä»¥åªéœ€è¦AddBlock cfg->AddBlock(right_block); @@ -428,7 +446,20 @@ std::any MyVisitor::visitCond(SysYParser::CondContext *ctx) { // æž„é€ ç¬¬äºŒä¸ªcond block,产生的IR将会放在right_blockä¸ visit(ctx->cond(1)); + if (false_list.size() >= 2) { + auto& parent_list = false_list[false_list.size() - 2]; + false_list[false_list.size() - 2].insert(parent_list.end(), false_list.back().begin(), false_list.back().end()); + false_list.pop_back(); + } + + if (true_list.size() >= 2) { + auto& parent_list = true_list[true_list.size() - 2]; + parent_list.insert(parent_list.end(), true_list.back().begin(), true_list.back().end()); + true_list.pop_back(); + } + // 如果父节点是比较è¿ç®—符,那么需è¦è¿”回一个phiè¯å¥ + // 处ç†çš„æ˜¯" (con1) == (cond2) " è¿™ç§æƒ…况 auto parent = dynamic_cast<SysYParser::CondContext *>(ctx->parent); if (parent && !(parent->op->getText() == "&&" || parent->op->getText() == "||")) { return genPhiForCond(ctx); @@ -443,8 +474,10 @@ std::any MyVisitor::visitCond(SysYParser::CondContext *ctx) { auto br = std::make_shared<BRIR>(IRTYPE::IR_I1, blk); blk->AddStatement(br); br->AddOprnd(cmp_ir); - true_list.push_back(br); - false_list.push_back(br); + true_list.emplace_back(); + false_list.emplace_back(); + true_list.back().push_back(br); + false_list.back().push_back(br); } return cmp_ir; } diff --git a/frontend/src/MyVisitor.cpp b/frontend/src/MyVisitor.cpp index da0aa9c8fa934baac0255d3ff287733370bfdf33..18e2ccf15f8c6facfa52b50beb27596b71824495 100644 --- a/frontend/src/MyVisitor.cpp +++ b/frontend/src/MyVisitor.cpp @@ -618,8 +618,10 @@ std::any MyVisitor::visitStmt(SysYParser::StmtContext *ctx) { // 访问æ¡ä»¶è¡¨è¾¾å¼ visit(ctx->cond()); // 在back patchä¸ï¼Œå·²ç»å®Œæˆäº†if_then与if_entry的许多block的连接 - backPatch(true_list, if_then, true); - backPatch(false_list, if_else == nullptr ? if_end : if_else, false); + backPatch(true_list.back(), if_then, true); + backPatch(false_list.back(), if_else == nullptr ? if_end : if_else, false); + true_list.pop_back(); + false_list.pop_back(); if_entry->Seal(); // æž„é€ then part @@ -687,8 +689,10 @@ std::any MyVisitor::visitStmt(SysYParser::StmtContext *ctx) { blk_before_entry->AddStatement(br1); cfg->Concat(while_entry); visit(ctx->cond()); - backPatch(true_list, while_body, true); - backPatch(false_list, while_exit, false); + backPatch(true_list.back(), while_body, true); + backPatch(false_list.back(), while_exit, false); + true_list.pop_back(); + false_list.pop_back(); // 到这里entry还没seal while_body->Seal(); // 到这里bodyçš„å‰é©±å·²ç»å®Œå…¨ diff --git a/frontend/src/PrivateVisitor.cpp b/frontend/src/PrivateVisitor.cpp index 7b68a5137ba00aaae7639cc7b4fd7dd48edabac1..5bb6c90c29d85cda1adff8a2864390be01c3b5fd 100644 --- a/frontend/src/PrivateVisitor.cpp +++ b/frontend/src/PrivateVisitor.cpp @@ -378,8 +378,10 @@ auto MyVisitor::backPatch(std::vector<std::shared_ptr<BRIR>> &list, const std::s auto MyVisitor::genPhiForCond(SysYParser::CondContext *ctx) -> IRPtr { // back patch auto next_block = std::make_shared<Block>(sym_table_, ctx->while_entry, ctx->while_exit); - backPatch(true_list, next_block, true); - backPatch(false_list, next_block, false); + backPatch(true_list.back(), next_block, true); + backPatch(false_list.back(), next_block, false); + true_list.pop_back(); + false_list.pop_back(); // back patch 找到了next_block的所有父block,所以这里åªéœ€è¦AddBlock cfgs_.back()->AddBlock(next_block); next_block->Seal();