From a9a340f4824ae8adcbf81fb94844804654ac8f86 Mon Sep 17 00:00:00 2001 From: ridethepig Date: Wed, 17 May 2023 00:25:13 +0800 Subject: [PATCH] Rename API, Make emit IR optional --- CMakeLists.txt | 2 +- include/llir_instruction.h | 4 +- include/llir_value.h | 8 +-- scripts/mytester.py | 2 +- src/main.cpp | 16 +++-- src/visitor.cpp | 13 +++- src/visitor_factory.cpp | 4 +- src/visitor_llir_gen.cpp | 140 ++++++++++++++++++------------------- 8 files changed, 101 insertions(+), 88 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ccfe04..a6ec762 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ file(GLOB MY_HEADERS "include/*.h") include(formatting.cmake) clang_format(format ${MY_SOURCES} ${MY_HEADERS}) -clang_format_check(format_check ${MY_SOURCES} ${MY_HEADERS}) +# clang_format_check(format_check ${MY_SOURCES} ${MY_HEADERS}) add_executable(sysy ${SOURCES}) # message(STATUS "${SOURCES}") diff --git a/include/llir_instruction.h b/include/llir_instruction.h index 6ace1e8..946ec2f 100644 --- a/include/llir_instruction.h +++ b/include/llir_instruction.h @@ -192,10 +192,10 @@ public: TypePtr_t element_type; InstGEP(ValuePtr_t pointer, const std::vector &indices, BasicBlockPtr_t parent_bb) : Instruction(InstTag::GEP, std::make_shared(extract_type(pointer, indices)), parent_bb) { - if (Value::isValueType(pointer)) { + if (Value::is(pointer)) { aim_to = std::dynamic_pointer_cast(pointer)->aim_to; } - else if (Value::isValueType(pointer) || Value::isValueType(pointer)) { + else if (Value::is(pointer) || Value::is(pointer)) { aim_to = pointer; } else { diff --git a/include/llir_value.h b/include/llir_value.h index 6fc93bf..2d6065e 100644 --- a/include/llir_value.h +++ b/include/llir_value.h @@ -20,7 +20,7 @@ public: virtual ~Value() = default; template - static bool isValueType(std::shared_ptr ptr) { + static bool is(std::shared_ptr ptr) { if (ptr.get()) { // auto &r = *ptr.get(); // return typeid(r) == typeid(TT); @@ -33,7 +33,7 @@ public: // it is caller's duty to check before use `asType` template - static std::shared_ptr asValueType(std::shared_ptr ptr) { + static std::shared_ptr as(std::shared_ptr ptr) { return std::dynamic_pointer_cast(ptr); } @@ -94,8 +94,8 @@ public: std::vector> inst_list; std::shared_ptr parent; BasicBlockListNode_t itr; - std::vector> successors; - std::vector> predecessors; + std::list> successors; + std::list> predecessors; BasicBlock(const std::string &name, std::shared_ptr parent) : Value(name, TypeHelper::TYPE_LABEL) { this->parent = parent; } diff --git a/scripts/mytester.py b/scripts/mytester.py index 88eb89a..012ba6c 100644 --- a/scripts/mytester.py +++ b/scripts/mytester.py @@ -228,7 +228,7 @@ scheme_ref = { scheme_my = { "name": "my", - "sy_ir": f"build/sysy -S {{sy}} -o {{ir}}", + "sy_ir": f"build/sysy -S {{sy}} -o {{ir}} -emit-llvm", "ir_asm": "llc --march=x86 --relocation-model=pic {ir} -o {asm}", "asm_obj": "as --32 {asm} -o {obj}", "obj_bin": f"clang -m32 -Ofast -fPIE {{obj}} {LIB_PATH} -o {{bin}}", diff --git a/src/main.cpp b/src/main.cpp index b45c6ab..f2d630e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,6 +39,7 @@ int main(int argc, const char **argv) { arg_parser.add_argument("-S").implicit_value(true).help("Useless but required by the contest").required(); arg_parser.add_argument("-o").help("Output file name").required(); arg_parser.add_argument("-O1").implicit_value(true).default_value(false).help("Performance mode"); + arg_parser.add_argument("-emit-llvm").implicit_value(true).default_value(false).help("Generate llvm ir"); arg_parser.add_argument("--v").default_value(0); try { arg_parser.parse_args(argc, argv); @@ -50,6 +51,7 @@ int main(int argc, const char **argv) { auto source_file = arg_parser.get("source"); auto output_file = arg_parser.get("-o"); auto flg_O1 = arg_parser["-O1"] == true; + auto emit_llvm = arg_parser["-emit-llvm"] == true; // std::cout << source_file << " " << output_file << " " << flg_O1 << // std::endl; #pragma endregion @@ -86,13 +88,15 @@ int main(int argc, const char **argv) { auto tree = parser.program(); Visitor visitor(lexer); visitor.visitProgram(tree); - auto llir_file = output_file.substr(0, output_file.rfind(".")) + ".ll"; - std::ofstream ofs_llir_file(llir_file); - if (!ofs_llir_file.good()) { - LOG(ERROR) << "Failed to create/overwrite LLIR output file " << llir_file; - return 1; + if (emit_llvm) { + auto llir_file = output_file.substr(0, output_file.rfind(".")) + ".ll"; + std::ofstream ofs_llir_file(llir_file); + if (!ofs_llir_file.good()) { + LOG(ERROR) << "Failed to create/overwrite LLIR output file " << llir_file; + return 1; + } + visitor.llir_gen(ofs_llir_file); } - visitor.llir_gen(ofs_llir_file); #if 0 std::cout << tree->toStringTree(&parser) << std::endl << std::endl; #endif diff --git a/src/visitor.cpp b/src/visitor.cpp index ae3e664..63e4398 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -293,7 +293,7 @@ std::any Visitor::visitInitVal(SysyParser::InitValContext *ctx) { if (_state.isGlobalIint) { auto const_value = any_to_Value(visitInitVal(init_val)); // should evaluate to const int - sysy_assert(Value::isValueType(const_value)); + sysy_assert(Value::is(const_value)); cur_arr.push_back(const_value); } else { @@ -834,6 +834,15 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) { pointed_type = array_type->element_type; ptr = build_InstGEP(ptr, {CONST0, CONST0}, _state.current_bb); } + // for (int i = 0; i < exp_list.size() - 1; ++ i) { + // sysy_assert(pointed_type->type_tag == Type::TypeTag::ArrayType); + // auto array_type = std::dynamic_pointer_cast(pointed_type); + // auto exp_val = any_to_Value(visitExp(exp_list[i])); + // if (Value::isValueType(exp_val)){ + // exp_val = build_InstLoad(exp_val, pointed_type, _state.current_bb); + // } + // ptr = build_InstGEP(ptr, {CONST0, exp_val}, _state.current_bb); + // } auto exp_val = any_to_Value(visitExp(exp_list.back())); auto inst_add = build_InstBinary(InstTag::Add, offset, exp_val, _state.current_bb); offset = inst_add; // finally, we get the offset @@ -887,7 +896,7 @@ std::any Visitor::visitFuncDef(SysyParser::FuncDefContext *ctx) { func_obj->bb_list.pop_back(); } if (func_obj->bb_list.back()->inst_list.size()==0 - || !Value::isValueType(func_obj->bb_list.back()->inst_list.back())){ + || !Value::is(func_obj->bb_list.back()->inst_list.back())){ if (func_ret_type->type_tag == Type::TypeTag::VoidType) { build_InstReturn(_state.current_bb); } diff --git a/src/visitor_factory.cpp b/src/visitor_factory.cpp index db7940e..ffaa194 100644 --- a/src/visitor_factory.cpp +++ b/src/visitor_factory.cpp @@ -75,8 +75,8 @@ std::shared_ptr build_InstBinary( assert(Type::isType(op1->type)); assert(Type::isType(op2->type)); if (!(Type::asType(op1->type)->int_type == Type::asType(op2->type)->int_type)) { - if (!(Value::isValueType(op1) && Value::asValueType(op1)->value == 0) - && !(Value::isValueType(op2) && Value::asValueType(op2)->value == 0)) { + if (!(Value::is(op1) && Value::as(op1)->value == 0) + && !(Value::is(op2) && Value::as(op2)->value == 0)) { LOG(ERROR) << op1->to_string() << ",\t" << op2->to_string(); assert(0); } diff --git a/src/visitor_llir_gen.cpp b/src/visitor_llir_gen.cpp index 3a4c2c5..ec00047 100644 --- a/src/visitor_llir_gen.cpp +++ b/src/visitor_llir_gen.cpp @@ -158,21 +158,21 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl VLOG(5) << "Build inst" << _inst->ir_seqno << ": " << _inst->to_string(); switch (_inst->tag) { case InstTag::Br: { - auto inst = Value::asValueType(_inst); + auto inst = Value::as(_inst); assert(inst->ir_seqno == -1); ostr << "br "; if (inst->operand_list.size() == 1) { - assert(Value::isValueType(inst->operand_list[0])); - auto bb_dest = Value::asValueType(inst->operand_list[0]); + assert(Value::is(inst->operand_list[0])); + auto bb_dest = Value::as(inst->operand_list[0]); assert(bb_dest->ir_seqno >= 0); ostr << "label %" << bb_dest->ir_seqno; } else { - assert(Value::isValueType(inst->operand_list[0])); + assert(Value::is(inst->operand_list[0])); assert(Type::isType(inst->operand_list[0]->type)); - auto cond = Value::asValueType(inst->operand_list[0]); - auto bb_true = Value::asValueType(inst->operand_list[1]); - auto bb_false = Value::asValueType(inst->operand_list[2]); + auto cond = Value::as(inst->operand_list[0]); + auto bb_true = Value::as(inst->operand_list[1]); + auto bb_false = Value::as(inst->operand_list[2]); if (!Type::asType(cond->type)->isI1()) { LOG(ERROR) << "Expect cond evals to i1: " << cond->to_string(); panic("Grammar check"); @@ -185,7 +185,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl break; } case InstTag::Ret: { - auto inst = Value::asValueType(_inst); + auto inst = Value::as(_inst); assert(inst->ir_seqno == -1); ostr << "ret "; if (inst->operand_list.size() == 0) { @@ -193,17 +193,17 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl ostr << "void"; } else { - if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); assert(op0->ir_seqno >= 0); ostr << op0->type->to_IR_string() << " %" << op0->ir_seqno; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string(); } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string(); } else { @@ -214,38 +214,38 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl break; } case InstTag::Store: { - auto inst = Value::asValueType(_inst); + auto inst = Value::as(_inst); assert(inst->ir_seqno == -1); ostr << "store "; - if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); assert(op0->ir_seqno >= 0); ostr << op0->type->to_IR_string() << " %" << op0->ir_seqno << ", "; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string() << ", "; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string() << ", "; } else { LOG(ERROR) << "Unexpected type of op0: " << inst->operand_list[0]->to_string(); assert(0); } - if (Value::isValueType(inst->operand_list[1])) { - auto op1 = Value::asValueType(inst->operand_list[1]); + if (Value::is(inst->operand_list[1])) { + auto op1 = Value::as(inst->operand_list[1]); ostr << op1->type->to_IR_string() << " @" << op1->name; } - else if (Value::isValueType(inst->operand_list[1])) { - auto op1 = Value::asValueType(inst->operand_list[1]); + else if (Value::is(inst->operand_list[1])) { + auto op1 = Value::as(inst->operand_list[1]); assert(op1->ir_seqno >= 0); ostr << op1->type->to_IR_string() << " %" << op1->ir_seqno; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string(); } else { @@ -257,9 +257,9 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl } // Call's seqno is dependent on its return type case InstTag::Call: { - auto inst = Value::asValueType(_inst); + auto inst = Value::as(_inst); LOG(DEBUG) << inst->operand_list[0]->to_string(); - auto func = Value::asValueType(inst->operand_list[0]); + auto func = Value::as(inst->operand_list[0]); auto func_type = Type::asType(func->type); if (Type::isType(func_type->return_type)) { assert(inst->ir_seqno == -1); @@ -272,17 +272,17 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl ostr << func->name << "("; if (inst->operand_list.size() > 1) { for (int i = 1; i < inst->operand_list.size(); ++i) { - if (Value::isValueType(inst->operand_list[i])) { - auto op0 = Value::asValueType(inst->operand_list[i]); + if (Value::is(inst->operand_list[i])) { + auto op0 = Value::as(inst->operand_list[i]); assert(op0->ir_seqno >= 0); ostr << op0->type->to_IR_string() << " %" << op0->ir_seqno; } - else if (Value::isValueType(inst->operand_list[i])) { - auto op0 = Value::asValueType(inst->operand_list[i]); + else if (Value::is(inst->operand_list[i])) { + auto op0 = Value::as(inst->operand_list[i]); ostr << op0->to_IR_string(); } - else if (Value::isValueType(inst->operand_list[i])) { - auto op0 = Value::asValueType(inst->operand_list[i]); + else if (Value::is(inst->operand_list[i])) { + auto op0 = Value::as(inst->operand_list[i]); ostr << op0->to_IR_string() << ", "; } else { @@ -309,36 +309,36 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl case InstTag::Ne: case InstTag::And: case InstTag::Or: { - auto inst = Value::asValueType(_inst); + auto inst = Value::as(_inst); ostr << "%" << inst->ir_seqno << " = " << inst->to_string() << " "; - if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); assert(op0->ir_seqno >= 0); ostr << op0->type->to_IR_string() << " %" << op0->ir_seqno << ", "; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string() << ", "; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string() << ", "; } else { LOG(ERROR) << "Unexpected type of op0: " << inst->operand_list[0]->to_string(); assert(0); } - if (Value::isValueType(inst->operand_list[1])) { - auto op1 = Value::asValueType(inst->operand_list[1]); + if (Value::is(inst->operand_list[1])) { + auto op1 = Value::as(inst->operand_list[1]); assert(op1->ir_seqno >= 0); ostr << "%" << op1->ir_seqno; } - else if (Value::isValueType(inst->operand_list[1])) { - auto op1 = Value::asValueType(inst->operand_list[1]); + else if (Value::is(inst->operand_list[1])) { + auto op1 = Value::as(inst->operand_list[1]); ostr << op1->value; } - else if (Value::isValueType(inst->operand_list[1])) { - auto op1 = Value::asValueType(inst->operand_list[1]); + else if (Value::is(inst->operand_list[1])) { + auto op1 = Value::as(inst->operand_list[1]); ostr << "%" << op1->ir_seqno; } else { @@ -348,21 +348,21 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl break; } case InstTag::Load: { - auto inst = Value::asValueType(_inst); + auto inst = Value::as(_inst); assert(inst->ir_seqno != -1); assert(Type::isType(inst->operand_list[0]->type)); ostr << "%" << inst->ir_seqno << " = load " << inst->type->to_IR_string() << ", "; - if (Value::isValueType(inst->operand_list[0])) { - auto op1 = Value::asValueType(inst->operand_list[0]); + if (Value::is(inst->operand_list[0])) { + auto op1 = Value::as(inst->operand_list[0]); ostr << op1->type->to_IR_string() << " @" << op1->name; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op1 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op1 = Value::as(inst->operand_list[0]); assert(op1->ir_seqno >= 0); ostr << op1->type->to_IR_string() << " %" << op1->ir_seqno; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string(); } else { @@ -372,21 +372,21 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl break; } case InstTag::GEP: { - auto inst = Value::asValueType(_inst); + auto inst = Value::as(_inst); assert(inst->ir_seqno >= 0); auto pointer_type = Type::asType(inst->operand_list[0]->type); ostr << "%" << inst->ir_seqno << " = getelementptr " << pointer_type->pointed_type->to_IR_string() << ", "; - if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string(); } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->type->to_IR_string() << " %" << op0->ir_seqno; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string(); } else { @@ -399,7 +399,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl break; } case InstTag::Alloca: { - auto inst = Value::asValueType(_inst); + auto inst = Value::as(_inst); assert(inst->ir_seqno != -1); auto pointer_type = Type::asType(inst->type); ostr << "%" << inst->ir_seqno << " = alloca " << pointer_type->pointed_type->to_IR_string() << ", align 4"; @@ -407,20 +407,20 @@ static void _gen_blocks(std::ostream &ostr, const std::list &bl break; } case InstTag::Zext: { - auto inst = Value::asValueType(_inst); + auto inst = Value::as(_inst); assert(inst->ir_seqno >= 0); ostr << "%" << inst->ir_seqno << " = zext "; - if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); assert(op0->ir_seqno >= 0); ostr << op0->type->to_IR_string() << " %" << op0->ir_seqno << "to "; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string() << "to "; } - else if (Value::isValueType(inst->operand_list[0])) { - auto op0 = Value::asValueType(inst->operand_list[0]); + else if (Value::is(inst->operand_list[0])) { + auto op0 = Value::as(inst->operand_list[0]); ostr << op0->to_IR_string() << "to "; } else {