diff --git a/src/AST/AST.cpp b/src/AST/AST.cpp index b59723225da403bc02493245882d0694b7b3782d..e963cbd1a48c3f296e743a579e11538b90ba7042 100644 --- a/src/AST/AST.cpp +++ b/src/AST/AST.cpp @@ -64,23 +64,70 @@ void BlockItemAST::Dump() const{ } void StmtAST::Dump() const{ - std::cout << "StmtAST{"; switch(tag){ - case StmtAST::Return_Exp: + case MatchedStmt: + matched_stmt->Dump(); + break; + case OpenStmt: + open_stmt->Dump(); + break; + default: + assert(false); + } +} + +void MatchedStmtAST::Dump() const{ + switch(tag){ + case If_Exp_MatchedStmt_Else_MatchedStmt: exp->Dump(); + if_matched_stmt->Dump(); + else_matched_stmt->Dump(); break; - case StmtAST::LVal_Assign_Exp: - l_val->Dump(); - std::cout << "="; + case OtherStmt: + other_stmt->Dump(); + break; + default: + assert(false); + } +} + +void OpenStmtAST::Dump() const{ + std::cout << "OpenStmtAST{"; + switch(tag){ + case If_Exp_Stmt: exp->Dump(); + if_stmt->Dump(); break; - case StmtAST::Exp: + case If_Exp_MatchedStmt_Else_OpenStmt: exp->Dump(); + if_matched_stmt->Dump(); + else_open_stmt->Dump(); break; - case StmtAST::Block: + default: + assert(false); + } + std::cout << "}"; +} + +void OtherStmtAST::Dump() const{ + std::cout << "OtherStmtAST{"; + switch(tag){ + case Exp: + exp->Dump(); + break; + case Block: block->Dump(); break; - case StmtAST::Empty: + case Return_Exp: + std::cout << "return "; + exp->Dump(); + break; + case LVal_Assign_Exp: + l_val->Dump(); + std::cout << "="; + exp->Dump(); + break; + case Empty: break; default: assert(false); diff --git a/src/AST/AST.hpp b/src/AST/AST.hpp index 7b2ca6320867b5bebe214df7f44df1af834d1636..13e7deb2086d497199346a79b8710b25b06a80b5 100644 --- a/src/AST/AST.hpp +++ b/src/AST/AST.hpp @@ -11,6 +11,9 @@ class FuncTypeAST; class BlockAST; class BlockItemAST; class StmtAST; +class MatchedStmtAST; +class OpenStmtAST; +class OtherStmtAST; class ExpAST; class LOrExpAST; @@ -88,6 +91,49 @@ public: }; class StmtAST : public BaseAST{ +public: + enum Tag{ + MatchedStmt, + OpenStmt + } tag; + std::unique_ptr<MatchedStmtAST> matched_stmt; + std::unique_ptr<OpenStmtAST> open_stmt; + + StmtAST(Tag _tag):tag(_tag){} + void Dump() const override; +}; + +class MatchedStmtAST : public BaseAST{ +public: + enum Tag{ + If_Exp_MatchedStmt_Else_MatchedStmt, + OtherStmt + } tag; + std::unique_ptr<ExpAST> exp; + std::unique_ptr<MatchedStmtAST> if_matched_stmt; + std::unique_ptr<MatchedStmtAST> else_matched_stmt; + std::unique_ptr<OtherStmtAST> other_stmt; + + MatchedStmtAST(Tag _tag):tag(_tag){} + void Dump() const override; +}; + +class OpenStmtAST : public BaseAST{ +public: + enum Tag{ + If_Exp_Stmt, + If_Exp_MatchedStmt_Else_OpenStmt + } tag; + std::unique_ptr<ExpAST> exp; + std::unique_ptr<StmtAST> if_stmt; + std::unique_ptr<MatchedStmtAST> if_matched_stmt; + std::unique_ptr<OpenStmtAST> else_open_stmt; + + OpenStmtAST(Tag _tag):tag(_tag){} + void Dump() const override; +}; + +class OtherStmtAST : public BaseAST{ public: enum Tag{ Return_Exp, @@ -100,7 +146,7 @@ public: std::unique_ptr<LValAST> l_val; std::unique_ptr<BlockAST> block; - StmtAST(Tag _tag):tag(_tag){} + OtherStmtAST(Tag _tag):tag(_tag){} void Dump() const override; }; diff --git a/src/Koopa/KoopaBuilder.cpp b/src/Koopa/KoopaBuilder.cpp index 0f158c9485e456b0ef754f5fe21e9d20cffbabcc..6084b310c5df07a1fd344b386b8186b5482ce3cb 100644 --- a/src/Koopa/KoopaBuilder.cpp +++ b/src/Koopa/KoopaBuilder.cpp @@ -11,16 +11,6 @@ koopa_raw_program_t KoopaBuilder::GenerateKoopaIR(const BaseAST& ast) { return GenerateProgram(*comp_unit); } -// Generate Program -/* -program的结构体定义如下: -typedef struct { - /// Global values (global allocations only). - koopa_raw_slice_t values; - /// Function definitions. - koopa_raw_slice_t funcs; //æ¯ä¸ªå‡½æ•°æ˜¯ä¸€ä¸ª koopa_raw_function_t ç±»åž‹çš„å®žä¾‹ï¼ŒæŒ‡å‘ koopa_raw_function_data_t。 -} koopa_raw_program_t; -*/ koopa_raw_program_t KoopaBuilder::GenerateProgram(const CompUnitAST& ast) { std::vector<const void *> funcs; @@ -31,22 +21,10 @@ koopa_raw_program_t KoopaBuilder::GenerateProgram(const CompUnitAST& ast) { koopa_raw_program_t program; program.values = CreateSlice(KOOPA_RSIK_VALUE); program.funcs = CreateSlice(funcs,KOOPA_RSIK_FUNCTION); + return program; } -// Generate -/* -typedef struct { - /// Type of function. - koopa_raw_type_t ty; - /// Name of function. - const char *name; - /// Parameters. - koopa_raw_slice_t params; - /// Basic blocks, empty if is a function declaration. - koopa_raw_slice_t bbs; -} koopa_raw_function_data_t; -*/ koopa_raw_function_t KoopaBuilder::GenerateFunction(const FuncDefAST& func_def) { koopa_raw_type_kind_t* ptype =new koopa_raw_type_kind_t(); ptype->tag = KOOPA_RTT_FUNCTION; @@ -55,13 +33,13 @@ koopa_raw_function_t KoopaBuilder::GenerateFunction(const FuncDefAST& func_def) std::vector<const void *> basic_blocks; for (auto& block : func_def.block_vec) { - // basic_blocks.push_back(GenerateBlock(*block)); GenerateBlock(*block); } - for (auto& block : block_manager.block_vec) { - basic_blocks.push_back(block); + block_manager.UpdataBlock(); + block_manager.DeleteUnreachableBlock(); + for(auto& block : block_manager.block_vec){ + basic_blocks.push_back(block.block); } - block_manager.block_vec.clear(); koopa_raw_function_data_t* function = new koopa_raw_function_data_t(); function->ty = ptype; @@ -71,21 +49,10 @@ koopa_raw_function_t KoopaBuilder::GenerateFunction(const FuncDefAST& func_def) return function; } -// Generate Block -/* -typedef struct { - /// Name of basic block, null if no name. - const char *name; - /// Parameters. - koopa_raw_slice_t params; - /// Values that this basic block is used by. - koopa_raw_slice_t used_by; - /// Instructions in this basic block. - koopa_raw_slice_t insts; -} koopa_raw_basic_block_data_t; -*/ koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const BlockAST& block) { - value_manager.CreateValueManager(); + koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t(); + block_manager.AddBlock(basic_block); + int block_index = block_manager.current_block_index; symbol_table.EnterScope(); std::vector<const void *> insts; for(auto& block_item : block.block_item_vec){ @@ -99,80 +66,143 @@ koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const BlockAST& block) { default: throw std::runtime_error("Invalid block item type."); } - if(block_item->tag==BlockItemAST::Tag::Stmt&&block_item->stmt->tag == StmtAST::Tag::Return_Exp){ - break; - } } - for(auto& value : value_manager.value_vec[value_manager.current_value_manager]){ + for(auto& value : block_manager.block_vec[block_index].value_manager.value_vec){ insts.push_back(value); if(value->kind.tag == KOOPA_RVT_RETURN){ break; } } - value_manager.DestroyValueManager(); - koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t(); + // koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t(); basic_block->name = strdup(("%block" + std::to_string(block_manager.block_vec.size())).c_str()); basic_block->params = CreateSlice(KOOPA_RSIK_VALUE); basic_block->used_by = CreateSlice(KOOPA_RSIK_VALUE); basic_block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE); - if(insts.size()>0){ - block_manager.block_vec.push_back(basic_block); - } - // block_manager.block_vec.push_back(basic_block); symbol_table.ExitScope(); return basic_block; } -// Generate Statement -/* -struct koopa_raw_value_data { - /// Type of value. - koopa_raw_type_t ty; - /// Name of value, null if no name. - const char *name; - /// Values that this value is used by. - koopa_raw_slice_t used_by; - /// Kind of value. - koopa_raw_value_kind_t kind; -}; -*/ koopa_raw_value_t KoopaBuilder::GenerateValue(const StmtAST& stmt) { + switch (stmt.tag) { + case StmtAST::Tag::MatchedStmt: + return GenerateValue(*stmt.matched_stmt); + case StmtAST::Tag::OpenStmt: + return GenerateValue(*stmt.open_stmt); + default: + throw std::runtime_error("Invalid statement type."); + } + return nullptr; +} + +koopa_raw_value_t KoopaBuilder::GenerateValue(const MatchedStmtAST& matched_stmt) { + koopa_raw_value_data_t* value = new koopa_raw_value_data_t(); + koopa_raw_basic_block_data_t* continue_block = new koopa_raw_basic_block_data_t(); + int block_index = block_manager.current_block_index; + switch (matched_stmt.tag) { + case MatchedStmtAST::Tag::If_Exp_MatchedStmt_Else_MatchedStmt: + value->ty = CreateTypeKind(KOOPA_RTT_UNIT); + value->name = nullptr; + value->used_by = CreateSlice(KOOPA_RSIK_VALUE); + value->kind.tag = KOOPA_RVT_BRANCH; + value->kind.data.branch.cond = GenerateValue(*matched_stmt.exp); + value->kind.data.branch.true_bb = GenerateBlock(*matched_stmt.if_matched_stmt,"%true",continue_block); + value->kind.data.branch.true_args = CreateSlice(KOOPA_RSIK_VALUE); + value->kind.data.branch.false_bb = GenerateBlock(*matched_stmt.else_matched_stmt,"%false",continue_block); + value->kind.data.branch.false_args = CreateSlice(KOOPA_RSIK_VALUE); + + block_manager.block_vec[block_index].AddValue(value); + block_manager.AddBlock(continue_block); + return value; + break; + case MatchedStmtAST::Tag::OtherStmt: + return GenerateValue(*matched_stmt.other_stmt); + default: + throw std::runtime_error("Invalid matched statement type."); + } +} +koopa_raw_value_t KoopaBuilder::GenerateValue(const OpenStmtAST& open_stmt) { + koopa_raw_value_data_t* value = new koopa_raw_value_data_t(); + koopa_raw_basic_block_data_t* continue_block = new koopa_raw_basic_block_data_t(); + int block_index = block_manager.current_block_index; + switch (open_stmt.tag) { + case OpenStmtAST::Tag::If_Exp_Stmt: + value->ty = CreateTypeKind(KOOPA_RTT_UNIT); + value->name = nullptr; + value->used_by = CreateSlice(KOOPA_RSIK_VALUE); + value->kind.tag = KOOPA_RVT_BRANCH; + value->kind.data.branch.cond = GenerateValue(*open_stmt.exp); + value->kind.data.branch.true_bb = GenerateBlock(*open_stmt.if_stmt,"%true"); + value->kind.data.branch.true_args = CreateSlice(KOOPA_RSIK_VALUE); + continue_block->name = strdup(std::string("%false").c_str()); + continue_block->params = CreateSlice(KOOPA_RSIK_VALUE); + continue_block->used_by = CreateSlice(KOOPA_RSIK_VALUE); + value->kind.data.branch.false_bb = continue_block; + value->kind.data.branch.false_args = CreateSlice(KOOPA_RSIK_VALUE); + + block_manager.block_vec[block_index].AddValue(value); + GenerateValue(continue_block); + block_manager.AddBlock(continue_block); + return value; + break; + case OpenStmtAST::Tag::If_Exp_MatchedStmt_Else_OpenStmt: + value->ty = CreateTypeKind(KOOPA_RTT_UNIT); + value->name = nullptr; + value->used_by = CreateSlice(KOOPA_RSIK_VALUE); + value->kind.tag = KOOPA_RVT_BRANCH; + value->kind.data.branch.cond = GenerateValue(*open_stmt.exp); + value->kind.data.branch.true_bb = GenerateBlock(*open_stmt.if_matched_stmt,"%true",continue_block); + value->kind.data.branch.true_args = CreateSlice(KOOPA_RSIK_VALUE); + value->kind.data.branch.false_bb = GenerateBlock(*open_stmt.else_open_stmt,"%false",continue_block); + value->kind.data.branch.false_args = CreateSlice(KOOPA_RSIK_VALUE); + + block_manager.block_vec[block_index].AddValue(value); + block_manager.AddBlock(continue_block); + return value; + break; + default: + throw std::runtime_error("Invalid open statement type."); + } +} +koopa_raw_value_t KoopaBuilder::GenerateValue(const OtherStmtAST& other_stmt) { koopa_raw_value_data_t* value = new koopa_raw_value_data_t(); SymbolEntry symbol_entry; - switch (stmt.tag){ - case StmtAST::Tag::Return_Exp: + switch (other_stmt.tag){ + case OtherStmtAST::Tag::Return_Exp: value->ty = CreateTypeKind(KOOPA_RTT_UNIT); value->name = nullptr; value->used_by = CreateSlice(KOOPA_RSIK_VALUE); value->kind.tag = KOOPA_RVT_RETURN; - value->kind.data.ret.value = GenerateValue(*stmt.exp); + value->kind.data.ret.value = GenerateValue(*other_stmt.exp); - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; break; - case StmtAST::Tag::LVal_Assign_Exp: - symbol_entry = *symbol_table.GetSymbol(stmt.l_val->ident); + + case OtherStmtAST::Tag::LVal_Assign_Exp: + symbol_entry = *symbol_table.GetSymbol(other_stmt.l_val->ident); value->ty = CreateTypeKind(KOOPA_RTT_UNIT); value->name = nullptr; value->used_by = CreateSlice(KOOPA_RSIK_VALUE); value->kind.tag = KOOPA_RVT_STORE; value->kind.data.store.dest = symbol_entry.symbol_value.var_value; - value->kind.data.store.value = GenerateValue(*stmt.exp); + value->kind.data.store.value = GenerateValue(*other_stmt.exp); - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; break; - case StmtAST::Tag::Exp: - GenerateValue(*stmt.exp); + + case OtherStmtAST::Tag::Exp: + GenerateValue(*other_stmt.exp); break; - case StmtAST::Tag::Block: + + case OtherStmtAST::Tag::Block: symbol_table.EnterScope(); - for(auto& block_item : stmt.block->block_item_vec){ + for(auto& block_item : other_stmt.block->block_item_vec){ switch (block_item->tag) { case BlockItemAST::Tag::Stmt: GenerateValue(*block_item->stmt); @@ -186,10 +216,89 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const StmtAST& stmt) { } symbol_table.ExitScope(); break; - case StmtAST::Tag::Empty: + case OtherStmtAST::Tag::Empty: break; + default: throw std::runtime_error("Invalid statement type."); } return nullptr; } + + +koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const MatchedStmtAST& matched_stmt, std::string block_name, koopa_raw_basic_block_data_t* continue_block) { + koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t(); + block_manager.AddBlock(basic_block); + symbol_table.EnterScope(); + std::vector<const void *> insts; + + GenerateValue(matched_stmt); + GenerateValue(continue_block); + for(auto& value : block_manager.block_vec[block_manager.current_block_index].value_manager.value_vec){ + insts.push_back(value); + } + + basic_block->name = strdup(block_name.c_str()); + basic_block->params = CreateSlice(KOOPA_RSIK_VALUE); + basic_block->used_by = CreateSlice(KOOPA_RSIK_VALUE); + basic_block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE); + + symbol_table.ExitScope(); + return basic_block; +} +koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const StmtAST& stmt, std::string block_name ) { + koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t(); + block_manager.AddBlock(basic_block); + symbol_table.EnterScope(); + std::vector<const void *> insts; + + GenerateValue(stmt); + + for(auto& value : block_manager.block_vec[block_manager.current_block_index].value_manager.value_vec){ + insts.push_back(value); + } + + basic_block->name = strdup(block_name.c_str()); + basic_block->params = CreateSlice(KOOPA_RSIK_VALUE); + basic_block->used_by = CreateSlice(KOOPA_RSIK_VALUE); + basic_block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE); + + symbol_table.ExitScope(); + return basic_block; +} +koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const OpenStmtAST& open_stmt, std::string block_name, koopa_raw_basic_block_data_t* continue_block) { + koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t(); + block_manager.AddBlock(basic_block); + int block_index = block_manager.current_block_index; + symbol_table.EnterScope(); + std::vector<const void *> insts; + + GenerateValue(open_stmt); + GenerateValue(continue_block); + for(auto& value : block_manager.block_vec[block_index].value_manager.value_vec){ + insts.push_back(value); + if(value->kind.tag == KOOPA_RVT_RETURN){ + break; + } + } + + basic_block->name = strdup(block_name.c_str()); + basic_block->params = CreateSlice(KOOPA_RSIK_VALUE); + basic_block->used_by = CreateSlice(KOOPA_RSIK_VALUE); + basic_block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE); + + symbol_table.ExitScope(); + return basic_block; +} + +koopa_raw_value_t KoopaBuilder::GenerateValue(koopa_raw_basic_block_t block) { + koopa_raw_value_data_t* value = new koopa_raw_value_data_t(); + value->ty = CreateTypeKind(KOOPA_RTT_UNIT); + value->name = nullptr; + value->used_by = CreateSlice(KOOPA_RSIK_VALUE); + value->kind.tag = KOOPA_RVT_JUMP; + value->kind.data.jump.target = block; + value->kind.data.jump.args = CreateSlice(KOOPA_RSIK_VALUE); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); + return value; +} \ No newline at end of file diff --git a/src/Koopa/KoopaBuilder.hpp b/src/Koopa/KoopaBuilder.hpp index 7bc643e054b70fe7229c682455c1e7aa5764f595..6355197f17dee3a143c751252a30ef1db6100a54 100644 --- a/src/Koopa/KoopaBuilder.hpp +++ b/src/Koopa/KoopaBuilder.hpp @@ -1,13 +1,14 @@ #pragma once #include "AST/AST.hpp" #include "Utils/utils.hpp" +#include "Utils/UtilsBlock.hpp" +#include "Utils/UtilsSymbol.hpp" #include <koopa.h> #include <vector> #include <memory> class KoopaBuilder { public: - ValueManager value_manager; BlockManager block_manager; koopa_raw_program_t GenerateKoopaIR(const BaseAST& ast); @@ -16,6 +17,15 @@ public: koopa_raw_basic_block_t GenerateBlock(const BlockAST& block); koopa_raw_value_t GenerateValue(const BlockItemAST& block_item); koopa_raw_value_t GenerateValue(const StmtAST& stmt); + koopa_raw_value_t GenerateValue(const MatchedStmtAST& matched_stmt); + koopa_raw_basic_block_t GenerateBlock(const MatchedStmtAST& matched_stmt, std::string block_name, koopa_raw_basic_block_data_t* continue_block); + koopa_raw_value_t GenerateValue(const OpenStmtAST& open_stmt); + koopa_raw_basic_block_t GenerateBlock(const StmtAST& stmt, std::string block_name); + koopa_raw_basic_block_t GenerateBlock(const OpenStmtAST& open_stmt); + koopa_raw_basic_block_t GenerateBlock(const OpenStmtAST& open_stmt, std::string block_name, koopa_raw_basic_block_data_t* continue_block); + koopa_raw_value_t GenerateValue(const OtherStmtAST& other_stmt); + koopa_raw_value_t GenerateValue(koopa_raw_basic_block_t block); + koopa_raw_value_t GenerateValue(const ExpAST& exp); koopa_raw_value_t GenerateValue(const LOrExpAST& l_or_exp); koopa_raw_value_t GenerateValue(const LOrExpAST& l_or_exp,LOrExpAST::Op op,const LAndExpAST& l_and_exp); diff --git a/src/Koopa/KoopaBuilderDecl.cpp b/src/Koopa/KoopaBuilderDecl.cpp index f08f53aae28580de6d0b15f3d817fdef3d9e64ac..536be1b18c2953bb00b95189a7c4b6e35436f1af 100644 --- a/src/Koopa/KoopaBuilderDecl.cpp +++ b/src/Koopa/KoopaBuilderDecl.cpp @@ -44,8 +44,8 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const ConstDefAST& const_def) { store_value->kind.data.store.dest = alloc_value; store_value->kind.data.store.value = GenerateValue(*const_def.const_init_val); - value_manager.AddValue(alloc_value); - value_manager.AddValue(store_value); + block_manager.block_vec[block_manager.current_block_index].AddValue(alloc_value); + block_manager.block_vec[block_manager.current_block_index].AddValue(store_value); return nullptr; } @@ -93,8 +93,8 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const VarDefAST& var_def) { throw std::runtime_error("Invalid variable definition type."); } - value_manager.AddValue(alloc_value); - value_manager.AddValue(store_value); + block_manager.block_vec[block_manager.current_block_index].AddValue(alloc_value); + block_manager.block_vec[block_manager.current_block_index].AddValue(store_value); return nullptr; } diff --git a/src/Koopa/KoopaBuilderExp.cpp b/src/Koopa/KoopaBuilderExp.cpp index 758eed1bee2fccc32104b5131417d8cb6da1e496..1fb1163813b8992099acb6d7111df0e1b88fc231 100644 --- a/src/Koopa/KoopaBuilderExp.cpp +++ b/src/Koopa/KoopaBuilderExp.cpp @@ -49,7 +49,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const LAndExpAST& l_and_exp, LAndE value->kind.data.binary.rhs = eq_bool_value; UpdateUsedBy(value->kind.data.binary.rhs, value); - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; } @@ -85,7 +85,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const EqExpAST& eq_exp, EqExpAST:: value->kind.data.binary.rhs = GenerateValue(rel_exp); UpdateUsedBy(value->kind.data.binary.rhs, value); - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; } @@ -127,7 +127,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const RelExpAST& rel_exp, RelExpAS value->kind.data.binary.rhs = GenerateValue(add_exp); UpdateUsedBy(value->kind.data.binary.rhs, value); - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; } @@ -148,7 +148,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const LOrExpAST& l_or_exp, LOrExpA value->kind.data.binary.rhs = l_and_bool_value; UpdateUsedBy(value->kind.data.binary.rhs, value); - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; } @@ -184,7 +184,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const AddExpAST& add_exp, char op, value->kind.data.binary.rhs = GenerateValue(mul_exp); UpdateUsedBy(value->kind.data.binary.rhs, value); - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; } koopa_raw_value_t KoopaBuilder::GenerateValue(const MulExpAST& mul_exp) { @@ -222,7 +222,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const MulExpAST& mul_exp, char op, value->kind.data.binary.rhs = GenerateValue(unary_exp); UpdateUsedBy(value->kind.data.binary.rhs, value); - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; } koopa_raw_value_t KoopaBuilder::GenerateValue(const UnaryExpAST& unary_exp) { @@ -259,7 +259,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const LValAST& l_val) { value->kind.tag = KOOPA_RVT_LOAD; value->kind.data.load.src = symbol_entry.symbol_value.var_value; - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; } @@ -287,7 +287,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const UnaryOpAST& unary_op, const value->kind.data.binary.rhs = GenerateValue(unary_exp); UpdateUsedBy(value->kind.data.binary.rhs, value); - value_manager.AddValue(value); + block_manager.block_vec[block_manager.current_block_index].AddValue(value); return value; } // Generate Number @@ -313,6 +313,6 @@ koopa_raw_value_t KoopaBuilder::CreateBoolValue(koopa_raw_value_t value) { UpdateUsedBy(bool_value->kind.data.binary.lhs, bool_value); UpdateUsedBy(bool_value->kind.data.binary.rhs, bool_value); - value_manager.AddValue(bool_value); + block_manager.block_vec[block_manager.current_block_index].AddValue(bool_value); return bool_value; } \ No newline at end of file diff --git a/src/Utils/UtilsBlock.cpp b/src/Utils/UtilsBlock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..249f089ce065075d190c11ddfc78b174af0b9aa1 --- /dev/null +++ b/src/Utils/UtilsBlock.cpp @@ -0,0 +1,10 @@ +# include "Utils/UtilsBlock.hpp" + +void Block::AddValue(koopa_raw_value_t value) { + value_manager.AddValue(value); +} + +void ValueManager::AddValue(koopa_raw_value_t value) { + value_vec.push_back(value); +} + diff --git a/src/Utils/UtilsBlock.hpp b/src/Utils/UtilsBlock.hpp new file mode 100644 index 0000000000000000000000000000000000000000..97f5a4df2712866f6b4fbd994b058db8cdc62cdc --- /dev/null +++ b/src/Utils/UtilsBlock.hpp @@ -0,0 +1,87 @@ +# pragma once +# include <vector> +# include <cstring> +# include "koopa.h" + +# include "Utils/utils.hpp" + +class ValueManager{ + public: + std::vector<koopa_raw_value_t> value_vec; + void AddValue(koopa_raw_value_t value); +}; + +class Block{ + public: + koopa_raw_basic_block_data_t *block; + ValueManager value_manager; + Block(koopa_raw_basic_block_data_t *_block) : block(_block) {} + void AddValue(koopa_raw_value_t value); +}; + +class BlockManager{ + public: + int current_block_index; + std::vector<Block> block_vec; + BlockManager() : current_block_index(-1) {} + + void UpdataBlock(){ + for(auto& block : block_vec){ + std::vector<const void *> insts; + for(auto& value : block.value_manager.value_vec){ + insts.push_back(value); + if(value->kind.tag == KOOPA_RVT_RETURN){ + break; + } + } + block.block->params = CreateSlice(KOOPA_RSIK_VALUE); + block.block->used_by = CreateSlice(KOOPA_RSIK_VALUE); + block.block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE); + } + } + + void AddBlock(koopa_raw_basic_block_data_t *block){ + block_vec.emplace_back(Block(block)); + current_block_index++; + } + + void DeleteUnreachableBlock(){ + std::map<koopa_raw_basic_block_t, bool> reachable; + if (block_vec.size() > 0){ + for(auto block : block_vec){ + reachable[block.block] = false; + if (block.block == block_vec[0].block){ + reachable[block.block] = true; + } + } + for(auto block : block_vec){ + if(!reachable[block.block]){ + continue; + } + for (size_t j = 0; j < block.block->insts.len; j++){ + auto inst = (koopa_raw_value_t)block.block->insts.buffer[j]; + if (inst->kind.tag == KOOPA_RVT_JUMP){ + reachable[inst->kind.data.jump.target] = true; + break; + } else if (inst->kind.tag == KOOPA_RVT_BRANCH){ + reachable[inst->kind.data.branch.true_bb] = true; + reachable[inst->kind.data.branch.false_bb] = true; + break; + } + else if (inst->kind.tag == KOOPA_RVT_RETURN){ + break; + } + } + } + for(auto it = block_vec.begin(); it != block_vec.end();){ + if (!reachable[it->block]){ + it = block_vec.erase(it); + } else { + ++it; + } + } + } + } +}; + +extern BlockManager block_manager; \ No newline at end of file diff --git a/src/Utils/utils.cpp b/src/Utils/utils.cpp index ddef7096400abf3710a9ae5528c3e4d316b3b1f2..2b2e208ac77000507873735b81dfeb1ef0d3013d 100644 --- a/src/Utils/utils.cpp +++ b/src/Utils/utils.cpp @@ -30,6 +30,15 @@ koopa_raw_slice_t CreateSlice(std::vector<const void *> &vec, koopa_raw_slice_it return slice; } +koopa_raw_slice_t CreateSlice(std::vector<koopa_raw_value_t> &vec, koopa_raw_slice_item_kind_t kind) { + koopa_raw_slice_t slice; + slice.buffer = new const void*[vec.size()]; + std::copy(vec.begin(), vec.end(), slice.buffer); + slice.len = vec.size(); + slice.kind = kind; + return slice; +} + koopa_raw_slice_t CreateSlice(koopa_raw_slice_item_kind_t kind) { koopa_raw_slice_t slice; slice.buffer = nullptr; @@ -66,19 +75,3 @@ koopa_raw_type_t CreatePointerTypeKind(koopa_raw_type_tag_t tag) { type->data.pointer.base = CreateTypeKind(tag); return type; } - -void ValueManager::CreateValueManager() { - current_value_manager++; - value_vec.emplace_back(); -} - -void ValueManager::DestroyValueManager() { - if(current_value_manager > 0) { - current_value_manager--; - value_vec.pop_back(); - } -} - -void ValueManager::AddValue(koopa_raw_value_t value) { - value_vec[current_value_manager].push_back(value); -} \ No newline at end of file diff --git a/src/Utils/utils.hpp b/src/Utils/utils.hpp index 85903420069165fb553609be85a1147312debe7d..cbbe5072355a2cb24c638c914c66ee4e2fe56679 100644 --- a/src/Utils/utils.hpp +++ b/src/Utils/utils.hpp @@ -1,4 +1,4 @@ -#pragma once +# pragma once # include <koopa.h> # include <vector> # include <stack> @@ -8,28 +8,8 @@ koopa_raw_slice_t CreateEmptySlice(); koopa_raw_slice_t CreateSlice(koopa_raw_value_t value, koopa_raw_slice_item_kind_t kind); koopa_raw_slice_t CreateSlice(std::vector<const void *> &vec, koopa_raw_slice_item_kind_t kind); +koopa_raw_slice_t CreateSlice(std::vector<koopa_raw_value_t> &vec, koopa_raw_slice_item_kind_t kind); koopa_raw_slice_t CreateSlice(koopa_raw_slice_item_kind_t kind); void UpdateUsedBy(const koopa_raw_value_t value,const koopa_raw_value_t user); koopa_raw_type_t CreateTypeKind(koopa_raw_type_tag_t tag); koopa_raw_type_t CreatePointerTypeKind(koopa_raw_type_tag_t tag); - -class ValueManager{ -public: - int current_value_manager; - std::vector<std::vector<koopa_raw_value_t>> value_vec; - - void CreateValueManager(); - void DestroyValueManager(); - void AddValue(koopa_raw_value_t value); - std::vector<koopa_raw_value_t>& GetCurrentValueVec(); - - ValueManager(): current_value_manager(-1){} -}; - -class BlockManager{ -public: - std::vector<koopa_raw_basic_block_t> block_vec; -}; - -extern ValueManager value_manager; -extern BlockManager block_manager; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f9f12b62f1ce6efc6a7e03fd7aad9787db2d2c88..98adc8ce317d4987975d0a4a77e9d5ded77b38f9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,8 +30,8 @@ int main(int argc,const char *argv[]) assert(!ret); //打å°AST - ast->Dump(); - cout << endl; + // ast->Dump(); + // cout << endl; KoopaBuilder koopa_builder; koopa_raw_program_t raw_program = koopa_builder.GenerateKoopaIR(*ast); diff --git a/src/sysy.l b/src/sysy.l index b16073373d20554f02fdceac0c4ed801b0fcfc10..ee1cecb417a0065b8970b309ee9c4465f030da86 100644 --- a/src/sysy.l +++ b/src/sysy.l @@ -30,6 +30,9 @@ Hexadecimal 0[xX][0-9a-fA-F]+ "return" { return RETURN; } "const" { return CONST; } +"if" { return IF; } +"else" { return ELSE; } + "&&" { yylval.str_val = new string(yytext); return AND; } "||" { yylval.str_val = new string(yytext); return OR; } diff --git a/src/sysy.y b/src/sysy.y index 3a7efb32a489dddf47a74a052cd8d73674330f8a..ccc4cf2c146a0591dc0b73397f06b39ad58fae49 100644 --- a/src/sysy.y +++ b/src/sysy.y @@ -33,11 +33,11 @@ std::vector<std::unique_ptr<BaseAST>> *ast_vec; } -%token INT RETURN CONST +%token INT RETURN CONST IF ELSE %token <int_val> INT_CONST %token <str_val> IDENT AND OR EQ NE LT LE GT GE -%type <ast_val> CompUnit FuncDef FuncType BlockItem Block Stmt +%type <ast_val> CompUnit FuncDef FuncType BlockItem Block Stmt MatchedStmt OpenStmt OtherStmt %type <ast_val> Exp LOrExp LAndExp EqExp RelExp AddExp MulExp UnaryExp PrimaryExp Number %type <ast_val> UnaryOp %type <ast_val> Decl ConstDecl VarDecl ConstDef VarDef InitVal ConstInitVal BType ConstExp LVal @@ -213,30 +213,72 @@ ConstExp const_exp->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($1)); $$ = const_exp.release(); } + ; Stmt + : MatchedStmt { + auto stmt = std::make_unique<StmtAST>(StmtAST::MatchedStmt); + stmt->matched_stmt = std::unique_ptr<MatchedStmtAST>(static_cast<MatchedStmtAST*>($1)); + $$ = stmt.release(); + } + | OpenStmt { + auto stmt = std::make_unique<StmtAST>(StmtAST::OpenStmt); + stmt->open_stmt = std::unique_ptr<OpenStmtAST>(static_cast<OpenStmtAST*>($1)); + $$ = stmt.release(); + } + ; +MatchedStmt + : IF '(' Exp ')' MatchedStmt ELSE MatchedStmt { + auto matched_stmt = std::make_unique<MatchedStmtAST>(MatchedStmtAST::If_Exp_MatchedStmt_Else_MatchedStmt); + matched_stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($3)); + matched_stmt->if_matched_stmt = std::unique_ptr<MatchedStmtAST>(static_cast<MatchedStmtAST*>($5)); + matched_stmt->else_matched_stmt = std::unique_ptr<MatchedStmtAST>(static_cast<MatchedStmtAST*>($7)); + $$ = matched_stmt.release(); + } + | OtherStmt { + auto matched_stmt = std::make_unique<MatchedStmtAST>(MatchedStmtAST::OtherStmt); + matched_stmt->other_stmt = std::unique_ptr<OtherStmtAST>(static_cast<OtherStmtAST*>($1)); + $$ = matched_stmt.release(); + } + ; +OpenStmt + : IF '(' Exp ')' Stmt { + auto open_stmt = std::make_unique<OpenStmtAST>(OpenStmtAST::If_Exp_Stmt); + open_stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($3)); + open_stmt->if_stmt = std::unique_ptr<StmtAST>(static_cast<StmtAST*>($5)); + $$ = open_stmt.release(); + } + | IF '(' Exp ')' MatchedStmt ELSE OpenStmt { + auto open_stmt = std::make_unique<OpenStmtAST>(OpenStmtAST::If_Exp_MatchedStmt_Else_OpenStmt); + open_stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($3)); + open_stmt->if_matched_stmt = std::unique_ptr<MatchedStmtAST>(static_cast<MatchedStmtAST*>($5)); + open_stmt->else_open_stmt = std::unique_ptr<OpenStmtAST>(static_cast<OpenStmtAST*>($7)); + $$ = open_stmt.release(); + } + ; +OtherStmt : RETURN Exp ';' { - auto stmt = std::make_unique<StmtAST>(StmtAST::Return_Exp); + auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::Return_Exp); stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($2)); $$ = stmt.release(); } | LVal '=' Exp ';' { - auto stmt = std::make_unique<StmtAST>(StmtAST::LVal_Assign_Exp); + auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::LVal_Assign_Exp); stmt->l_val = std::unique_ptr<LValAST>(static_cast<LValAST*>($1)); stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($3)); $$ = stmt.release(); } | Block { - auto stmt = std::make_unique<StmtAST>(StmtAST::Block); + auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::Block); stmt->block = std::unique_ptr<BlockAST>(static_cast<BlockAST*>($1)); $$ = stmt.release(); } | Exp ';' { - auto stmt = std::make_unique<StmtAST>(StmtAST::Exp); + auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::Exp); stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($1)); $$ = stmt.release(); } | ';' { - auto stmt = std::make_unique<StmtAST>(StmtAST::Empty); + auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::Empty); $$ = stmt.release(); } ;