MimiC is a compiler of C subset (extended SysY language) by USTB NSCSCC team.
使用说明 源语言定义 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 comp_unit ::= {decl | type_def | func_def};decl ::= var_decl | func_decl;type_def ::= struct_def | enum_def | type_alias;func_def ::= func_header block;var_decl ::= type var_def {"," var_def} ";" ;var_def ::= ID_VAL {"[" expr "]" } ["=" init_val];init_val ::= expr | "{" [init_val {"," init_val}] "}" ;func_decl ::= func_header ";" ;func_header ::= type ID_VAL "(" [func_params] ")" ;func_params ::= func_param {"," func_param};func_param ::= type ID_VAL ["[" [expr] "]" {"[" expr "]" }];struct_def ::= "struct" ID_VAL "{" {struct_elem} "}" ";" ;enum_def ::= "enum" [ID_VAL] "{" enum_elems "}" ";" ;type_alias ::= "typedef" type ID_VAL ";" ;struct_elem ::= type struct_elem_def {"," struct_elem_def} ";" ;struct_elem_def ::= ID_VAL {"[" expr "]" };enum_elems ::= ID_VAL ["=" expr] ["," enum_elems] ["," ];block ::= "{" {block_item} "}" ;block_item ::= decl | type_def | stmt;stmt ::= bare | block | if_else | while | control;bare ::= expr ";" ;if_else ::= "if" "(" expr ")" stmt ["else" stmt];while ::= "while" "(" expr ")" stmt;control ::= ("break" | "continue" | ("return" [expr])) ";" ;expr ::= cast {bin_op cast};cast ::= {"(" type ")" } unary;unary ::= {unary_op} factor | "sizeof" (factor | "(" type ")" );factor ::= value | index | func_call | access | "(" expr ")" ;bin_op ::= "+" | "-" | "*" | "/" | "%" | "&" | "|" | "^" | "&&" | "||" | "<<" | ">>" | "==" | "!=" | "<" | "<=" | ">" | ">=" | "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" ; unary_op ::= "+" | "-" | "!" | "~" | "*" | "&" ;value ::= INT_VAL | CHAR_VAL | STR_VAL | ID_VAL;index ::= expr "[" expr "]" ;func_call ::= expr "(" [expr {"," expr}] ")" ;access ::= factor ("." | "->" ) ID_VAL;type ::= prim_type | struct_type | enum_type | const | pointer | user_type; prim_type ::= "void" | ["unsigned" ] "int" | "char" ;struct_type ::= "struct" ID_VAL;enum_type ::= "enum" ID_VAL;const ::= "const" type;pointer ::= type "*" {"*" };user_type ::= ID_VAL;
目标语言 构建&使用 1 2 3 mkdir build && cd buildcmake .. make -j32
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ./mmcc -h Usage: mmcc <INPUT> [OPTIONS...] Arguments: input input source file Options: -h, --help show this message -v, --version show version info -S, --asm dump assembly -O2, --opt-2 enable level-2 optimization -o, --output <ARG> output file, default to stdout -V, --verbose use verbose output -Werror, --warn-error treat warnings as errors -Wall, --warn-all enable all warnings -da, --dump-ast dump AST to output -di, --dump-ir dump IR to output -ps, --pass-stage <ARG> optimize until specific stage -ta, --target-arch <ARG> specify target architecture
实现 模块划分 back/
define/
driver
front
mid
opt
utils
类设计
Pass注册 利用static
变量最先执行的特性,由PassManager
提供一个注册函数,用于保存当前pass。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class PassManager { public : template <typename T> static PassInfo &RegisterPass (std::string_view name) { static_assert (!std::is_base_of_v<HelperPass, T>, "helper pass is unregisterable" ); auto &passes = GetPasses (); assert (!passes.count (name) && "pass has already been registered" ); return passes.insert ({name, PassInfo (std::make_unique <T>(), name)}) .first->second; } private : static PassInfoMap &GetPasses () ; }; PassManager::PassInfoMap &PassManager::GetPasses () { static PassInfoMap passes; return passes; } #define REGISTER_PASS(cls, name) \ static PassInfo &pass_##name = PassManager::RegisterPass<cls> (#name)
1 2 3 4 REGISTER_PASS (PhiSimplifyPass, phi_simp) .set_min_opt_level (1 ) .set_stages (PassStage::Promote);