From 57094c9afec7e49ac3673544fcf3ff5147969962 Mon Sep 17 00:00:00 2001 From: ridethepig Date: Tue, 16 May 2023 00:41:02 +0800 Subject: [PATCH] functional all pass --- .gitignore | 3 ++- include/llir_instruction.h | 2 +- include/llir_value.h | 9 +++++-- include/visitor.h | 6 ++++- scripts/mytester.py | 4 ++- src/visitor.cpp | 52 ++++++++++++++++++++++++-------------- src/visitor_factory.cpp | 11 +++++--- src/visitor_llir_gen.cpp | 6 +++-- 8 files changed, 63 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index 50c5e73..3716ef4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ build/ .antlr/ *.log __pycache__/ -*.o \ No newline at end of file +*.o +testcases/ \ No newline at end of file diff --git a/include/llir_instruction.h b/include/llir_instruction.h index 516200e..6ace1e8 100644 --- a/include/llir_instruction.h +++ b/include/llir_instruction.h @@ -219,7 +219,7 @@ public: if (pointed_type->type_tag == Type::TypeTag::IntegerType) { return pointed_type; } - else if (Type::isType(pointed_type)){ + else if (Type::isType(pointed_type)) { for (int i = 1; i < indices.size(); ++i) { pointed_type = std::dynamic_pointer_cast(pointed_type)->element_type; } diff --git a/include/llir_value.h b/include/llir_value.h index 4e4a048..6fc93bf 100644 --- a/include/llir_value.h +++ b/include/llir_value.h @@ -167,8 +167,13 @@ public: bool is_const; GlobalVar(const std::string &name, TypePtr_t type, ConstantPtr_t init_value, bool is_const) : Value(name, PointerType::make_shared(type)), init_value(init_value), is_const(is_const) {} - static std::shared_ptr make_shared(const std::string &name, TypePtr_t type, ConstantPtr_t init_value, bool is_const) { - return std::make_shared(name, type ,init_value, is_const); + static std::shared_ptr make_shared( + const std::string &name, + TypePtr_t type, + ConstantPtr_t init_value, + bool is_const + ) { + return std::make_shared(name, type, init_value, is_const); } virtual std::string to_IR_string() override { std::string str = type->to_IR_string() + " @" + name; diff --git a/include/visitor.h b/include/visitor.h index 39716c9..157898d 100644 --- a/include/visitor.h +++ b/include/visitor.h @@ -41,7 +41,11 @@ std::shared_ptr build_InstStore( std::shared_ptr parent_bb ); -std::shared_ptr build_InstAlloca(const std::string &str, TypePtr_t type, std::shared_ptr parent_bb); +std::shared_ptr build_InstAlloca( + const std::string &str, + TypePtr_t type, + std::shared_ptr parent_bb +); std::shared_ptr build_InstBinary( InstTag inst_tag, diff --git a/scripts/mytester.py b/scripts/mytester.py index e5c566f..88eb89a 100644 --- a/scripts/mytester.py +++ b/scripts/mytester.py @@ -193,6 +193,7 @@ class BatTest: self.diffout_template = f"{compiler.target_dir}/{{testcase}}/{self.label}.diff" def bat_case(self, testcase, compile=False): + Print_C.print_subheader(f"Diff test {self.label} on {testcase}") if compile: self.compiler.clean_case(testcase) self.compiler_rf.clean_case(testcase) @@ -212,6 +213,7 @@ class BatTest: return True def bat_all_tests(self, compile=False): + for testcase in self.testcases: if not self.bat_case(testcase, compile): break @@ -254,7 +256,7 @@ if __name__ == "__main__": args = parser.parse_args() print(args) testcases = case_collector(args.case_selector, args.case_prefix) - target_dir = os.path.join(BUILD_DIR, args.case_prefix) + target_dir = os.path.join(BUILD_DIR, args.case_prefix.replace("../", "").replace("./", "")) if args.clean: os.system(f"rm -rfI {target_dir}") if not os.path.exists(target_dir): diff --git a/src/visitor.cpp b/src/visitor.cpp index bcf6b81..ae3e664 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -95,7 +95,7 @@ Visitor::Visitor(SysyLexer &) { _func_tab.push_name("putch", func_putch); auto func_putarray = std::make_shared("putarray", TypeHelper::TYPE_VOID); - func_putarray->fparam_list = {fparam_ptr_i32, fparam_i32}; + func_putarray->fparam_list = {fparam_i32, fparam_ptr_i32}; _func_tab.push_name("putarray", func_putarray); // auto func_putf = std::make_shared("putf", TypeHelper::TYPE_VOID); @@ -152,7 +152,7 @@ std::any Visitor::visitConstDef(SysyParser::ConstDefContext *ctx) { if (_scope_tab.get_level()) { // local const array // Keep a pointer to the base address, alloca_ = &array, *alloca_ = &array[0] - auto alloca_ = build_InstAlloca(const_name , array_type, _state.current_bb); + auto alloca_ = build_InstAlloca(const_name, array_type, _state.current_bb); _scope_tab.push_name(const_name, alloca_); // first dim base, ptr = *alloca_ = &array[0] auto base_ptr = build_InstGEP(alloca_, {CONST0, CONST0}, _state.current_bb); @@ -193,12 +193,12 @@ std::any Visitor::visitVarDef(SysyParser::VarDefContext *ctx) { _state.isGlobalIint = true; auto result = std::any_cast>(visitInitVal(ctx->initVal())); _state.isGlobalIint = false; - auto global_var_int = GlobalVar::make_shared(var_name, result->type,result, false); + auto global_var_int = GlobalVar::make_shared(var_name, result->type, result, false); module.global_var_list.push_back(global_var_int); _scope_tab.push_name(var_name, global_var_int); } else { - auto global_var_int = GlobalVar::make_shared(var_name, CONST0->type,CONST0, false); + auto global_var_int = GlobalVar::make_shared(var_name, CONST0->type, CONST0, false); module.global_var_list.push_back(global_var_int); _scope_tab.push_name(var_name, global_var_int); } @@ -393,9 +393,9 @@ std::any Visitor::visitAddExp(SysyParser::AddExpContext *ctx) { return {result}; } else { - auto mul_exp = any_to_Value(visitMulExp(ctx->mulExp())); if (ctx->addExp()) { auto add_exp = any_to_Value(visitAddExp(ctx->addExp())); + auto mul_exp = any_to_Value(visitMulExp(ctx->mulExp())); if (std::dynamic_pointer_cast(add_exp->type)->isI1()) { add_exp = build_InstZext(add_exp, _state.current_bb); } @@ -410,8 +410,11 @@ std::any Visitor::visitAddExp(SysyParser::AddExpContext *ctx) { } else panic("Unreachable"); + return mul_exp; + } + else { + return visitMulExp(ctx->mulExp()); } - return mul_exp; } } @@ -435,9 +438,9 @@ std::any Visitor::visitMulExp(SysyParser::MulExpContext *ctx) { return {result}; } else { - auto unary_exp = any_to_Value(visitUnaryExp(ctx->unaryExp())); if (ctx->mulExp()) { - auto mul_exp = any_to_Value(visitMulExp(ctx->mulExp())); + auto mul_exp = any_to_Value(visitMulExp(ctx->mulExp())); + auto unary_exp = any_to_Value(visitUnaryExp(ctx->unaryExp())); if (std::dynamic_pointer_cast(unary_exp->type)->isI1()) { unary_exp = build_InstZext(unary_exp, _state.current_bb); } @@ -455,15 +458,18 @@ std::any Visitor::visitMulExp(SysyParser::MulExpContext *ctx) { } else panic("Unreachable"); + return {unary_exp}; + } + else { + return visitUnaryExp(ctx->unaryExp()); } - return {unary_exp}; } } // relExp: addExp | relExp ('<' | '>' | '<=' | '>=') addExp; std::any Visitor::visitRelExp(SysyParser::RelExpContext *ctx) { - auto add_exp = any_to_Value(visitAddExp(ctx->addExp())); if (ctx->relExp()) { auto rel_exp = any_to_Value(visitRelExp(ctx->relExp())); + auto add_exp = any_to_Value(visitAddExp(ctx->addExp())); sysy_assert(TypeHelper::isIntegerTypeI32(rel_exp->type)); if (ctx->LE()) { add_exp = build_InstBinary(InstTag::Le, rel_exp, add_exp, _state.current_bb); @@ -481,16 +487,19 @@ std::any Visitor::visitRelExp(SysyParser::RelExpContext *ctx) { LOG(ERROR) << ctx->relExp()->getStart()->getLine() << ":" << ctx->relExp()->getText(); panic("Unreachable"); } + return add_exp; + } + else { + return visitAddExp(ctx->addExp()); } - return add_exp; } // eqExp: relExp | eqExp ('==' | '!=') relExp; std::any Visitor::visitEqExp(SysyParser::EqExpContext *ctx) { - auto rel_exp = any_to_Value(visitRelExp(ctx->relExp())); - bool need_zext = false; if (ctx->eqExp()) { - auto eq_exp = any_to_Value(visitEqExp(ctx->eqExp())); + bool need_zext = false; + auto eq_exp = any_to_Value(visitEqExp(ctx->eqExp())); + auto rel_exp = any_to_Value(visitRelExp(ctx->relExp())); if (TypeHelper::isIntegerTypeI32(eq_exp->type) || TypeHelper::isIntegerTypeI32(rel_exp->type)) { need_zext = true; } @@ -508,12 +517,16 @@ std::any Visitor::visitEqExp(SysyParser::EqExpContext *ctx) { } else panic("Unreachable"); + return rel_exp; + } + else { + return visitRelExp(ctx->relExp()); } - return rel_exp; } // Notes about SideEffect: except for || and &&, other sub-expression evaluations are unsequenced // as long as they are calculated before the operator +// BUT, in sysy test, it seems that, it is a must ti compute from left to right // lAndExp: eqExp | lAndExp '&&' eqExp; // Luckily, there is only one path to lOrExp, which is `stmt` -> `cond` -> `lOrExp` // Thus, there is no need to care about what if it appears in a arithmetic expression @@ -729,8 +742,7 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) { return lval; } else { - LOG(WARNING) << "Unexpected array referece" << lval->to_string() - << " : "<< ctx->getStart()->getLine(); + LOG(WARNING) << "Unexpected array referece" << lval->to_string() << " : " << ctx->getStart()->getLine(); // array index, perhaps // @retval: InstGEP auto gep = lval; @@ -793,7 +805,9 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) { return arr_elem_ptr; } else { - panic("Should be int"); + LOG(WARNING) << "Should be int"; + auto arr_ptr = build_InstGEP(ptr, {CONST0, offset}, _state.current_bb); + return arr_ptr; } } } @@ -833,7 +847,7 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) { // return the address of an sub array auto array_type = std::dynamic_pointer_cast(pointed_type); auto dim_size = ConstantInt::make_shared(array_type->element_count); - auto inst_mul = build_InstBinary(InstTag::Mul, offset, dim_size, _state.current_bb); + offset = build_InstBinary(InstTag::Mul, offset, dim_size, _state.current_bb); auto arr_elem_ptr = build_InstGEP(ptr, {CONST0, offset}, _state.current_bb); return arr_elem_ptr; } diff --git a/src/visitor_factory.cpp b/src/visitor_factory.cpp index 2b0a356..db7940e 100644 --- a/src/visitor_factory.cpp +++ b/src/visitor_factory.cpp @@ -43,10 +43,15 @@ std::shared_ptr build_InstStore( } // a little bit different, we put all alloca in the head of each basic block -std::shared_ptr build_InstAlloca(const std::string & name, TypePtr_t type, std::shared_ptr parent_bb) { - auto inst_alloca = std::make_shared(type, parent_bb); +std::shared_ptr build_InstAlloca( + const std::string &name, + TypePtr_t type, + std::shared_ptr parent_bb +) { + auto inst_alloca = std::make_shared(type, parent_bb); inst_alloca->name = name; - parent_bb->inst_list.insert(parent_bb->inst_list.begin(), inst_alloca); + auto func_head_bb = parent_bb->parent->bb_list.front(); + func_head_bb->inst_list.insert(func_head_bb->inst_list.begin(), inst_alloca); // parent_bb->inst_list.push_back(inst_alloca); return inst_alloca; } diff --git a/src/visitor_llir_gen.cpp b/src/visitor_llir_gen.cpp index e8ac4f4..3a4c2c5 100644 --- a/src/visitor_llir_gen.cpp +++ b/src/visitor_llir_gen.cpp @@ -153,6 +153,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl ostr << block->ir_seqno << ":" << std::endl; } for (int j = 0; j < block->inst_list.size(); ++j) { + ostr << " "; auto _inst = block->inst_list[j]; VLOG(5) << "Build inst" << _inst->ir_seqno << ": " << _inst->to_string(); switch (_inst->tag) { @@ -251,6 +252,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl LOG(ERROR) << "Unexpected type of op1: " << inst->operand_list[1]->to_string(); assert(0); } + ostr << ", align 4"; break; } // Call's seqno is dependent on its return type @@ -470,8 +472,8 @@ void Visitor::llir_gen(std::ostream &ostr) { } else if (global_var_type->pointed_type->type_tag == Type::TypeTag::ArrayType) { // sysy_assert(global_var->) - auto array_type = std::dynamic_pointer_cast(global_var_type->pointed_type); - auto init_value = std::dynamic_pointer_cast(global_var->init_value); + auto array_type = std::dynamic_pointer_cast(global_var_type->pointed_type); + auto init_value = std::dynamic_pointer_cast(global_var->init_value); if (init_value != nullptr) { auto hierarchy_array = gen_arr_hierarchy(array_type, init_value->value_list, 0, init_value->value_list.size()); if (hierarchy_array) {