From: Michael D. Lowis Date: Thu, 8 Dec 2022 01:56:51 +0000 (-0500) Subject: added imported module compilation and fixed forward and extern declarations X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=765e3f0fedabdb8a12fef35955045f9097028ca0;p=proto%2Fobnc.git added imported module compilation and fixed forward and extern declarations --- diff --git a/cerise/backend/ssa/codegen.c b/cerise/backend/ssa/codegen.c index d234662..c002c17 100644 --- a/cerise/backend/ssa/codegen.c +++ b/cerise/backend/ssa/codegen.c @@ -113,7 +113,6 @@ void emit_type(Parser* p, Type* type) void codegen_init(Parser* p) { - p->codegen = true; fout(p, "%%Bool = type i1\n"); fout(p, "%%Int = type i64\n"); fout(p, "%%Real = type double\n"); @@ -122,8 +121,6 @@ void codegen_init(Parser* p) void codegen_symbol(Parser* p, Symbol* sym) { - if (!p->codegen) return; // Bail if just importing symbols - if (sym->class == SYM_VAR) { char* modname = (sym->module == 0 @@ -486,8 +483,6 @@ void print_op(Parser* p, SsaNode* expr) void codegen_block(Parser* p, SsaBlock* block) { - if (!p->codegen) return; // Bail if just importing symbols - /* perform a topological sort of the nodes */ SsaBlock* sorted = NULL; Bitset* set = bitset_new(p->blockid); @@ -535,7 +530,7 @@ void codegen_block(Parser* p, SsaBlock* block) void codegen_main(Parser* p) { - if (!p->codegen) return; // Bail if just importing symbols + if (!p->genmain) return; // Bail if no main required fout(p, "define i32 @main(i32 %%0, i8* %%1)\n{\n"); for (size_t i = 0; i < p->nsyms; i++) { diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 2f69062..25338cc 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -236,7 +236,7 @@ typedef struct { size_t ntypes; Type** types; - bool codegen; + bool genmain; } Parser; // src/stdlib.c @@ -250,6 +250,7 @@ char* fs_read(char* path); char* fs_modname(char* path); char* fs_modfind(Parser* p, char* path); bool fs_exists(char* path); +long fs_modtime(char* path); // src/lex.c void lexfile(Parser* ctx, char* path); diff --git a/cerise/src/fs.c b/cerise/src/fs.c index 5c70c43..aaa8ecb 100644 --- a/cerise/src/fs.c +++ b/cerise/src/fs.c @@ -111,3 +111,9 @@ bool fs_exists(char* path) return (access(path, F_OK) == 0); } +long fs_modtime(char* path) +{ + struct stat sb = {0}; + (void)stat(path, &sb); + return sb.st_mtime; +} \ No newline at end of file diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 3d08f08..79fff62 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -563,13 +563,6 @@ Symbol* proc_type(Parser* p) } expect(p, ')'); proctype->base = (accept(p, ':') ? type(p) : &VoidType); - - if (proc->forward) - { - // TODO: check the type here - proc->defined = 1; - } - codegen_symbol(p, proc); return proc; } @@ -618,12 +611,21 @@ void proc_decl(Parser* p) var_decl(p); } - if (accept(p, FORWARD) || accept(p, EXTERN)) + if (accept(p, FORWARD)) { + /* type only, no codegen for forward declarations */ proc->forward = 1; } - else // if (!accept(p, EXTERN)) + else if (accept(p, EXTERN)) { + proc->forward = 1; + codegen_symbol(p, proc); + proc->forward = 0; + } + else + { + proc->forward = 0; + codegen_symbol(p, proc); proc_body(p, proc->type); } @@ -735,7 +737,7 @@ static char* get_fpath(char* base, char ext) return path; } -static void init_parser(Parser* p, char* path) +static void init_parser(Parser* p, char* path, bool genmain) { char* fcontents = fs_read(path); p->name = fs_modname(path); @@ -746,6 +748,7 @@ static void init_parser(Parser* p, char* path) p->curr_reg = 0; p->outpath = get_fpath(path, 'l'); p->out = fopen(p->outpath, "wb"); + p->genmain = genmain; if (p->name == NULL) { fatal("could not determine module name from path"); @@ -763,17 +766,51 @@ static void init_parser(Parser* p, char* path) p->types[p->ntypes++] = &StringType; } +static void compile_module(Parser* p, char* path, bool genmain) +{ + /* parser the file and generate the code */ + init_parser(p, path, genmain); + codegen_init(p); + module(p); + fclose(p->out); + + char* asm_path = get_fpath(path, 's'); + char* obj_path = get_fpath(path, 'o'); + if (fs_modtime(obj_path) < fs_modtime(path)) + { + /* run llc to generate assembly listing */ + char* llc_cmd = strmcat("llc -o \"", asm_path , "\" \"", p->outpath, "\"", 0); + printf("%s\n", llc_cmd); + if (system(llc_cmd) != 0) + { + fatal("assembler failed"); + } + remove(p->outpath); + + /* compile the object file now */ + char* as_cmd = strmcat("cc -c -o \"", obj_path, "\" \"", asm_path, "\"", 0); + printf("%s\n", as_cmd); + if (system(as_cmd) != 0) + { + fatal("assembler failed"); + } + remove(asm_path); + } +} + + static void import(Parser* curr, char* modname, char* alias) { - /* parse the module */ - Parser p = {0}; + /* locate the module */ char* path = fs_modfind(curr, modname); if (!path) { error(curr, "unable to find module '%s'", modname); } - init_parser(&p, path); - module(&p); + + /* parse the module */ + Parser p = {0}; + compile_module(&p, path, false); (void)alias; /* copy exported symbols to our symbol table */ @@ -797,31 +834,5 @@ static void import(Parser* curr, char* modname, char* alias) void compile(char* path) { Parser p = {0}; - init_parser(&p, path); - codegen_init(&p); - module(&p); - fclose(p.out); - - char* asm_path = get_fpath(path, 's'); -// char* c_path = get_fpath(path, 'c'); - char* obj_path = get_fpath(path, 'o'); - - /* run llc to generate assembly listing */ - char* llc_cmd = strmcat("llc -o \"", asm_path , "\" \"", p.outpath, "\"", 0); - printf("%s\n", llc_cmd); - if (system(llc_cmd) != 0) - { - fatal("assembler failed"); - } - remove(p.outpath); - - char* as_cmd = strmcat("cc -c -o \"", obj_path, "\" \"", asm_path, "\" ", -// (fs_exists(c_path) ? strmcat("\"", c_path, "\"", 0) : ""), - 0); - printf("%s\n", as_cmd); - if (system(as_cmd) != 0) - { - fatal("assembler failed"); - } - remove(asm_path); + compile_module(&p, path, true); } diff --git a/cerise/tests/A.l b/cerise/tests/A.l index e69de29..904f5a9 100644 --- a/cerise/tests/A.l +++ b/cerise/tests/A.l @@ -0,0 +1,23 @@ +%Bool = type i1 +%Int = type i64 +%Real = type double +%String = type { i64, i8* } +define %Int @A_Bar() +{ +L3: + %.1 = call %Int @A_Foo() + ret %Int %.1 +} + +define %Int @A_Foo() +{ +L6: + ret %Int 0 +} + +define void @A() +{ +L9: + ret void +} + diff --git a/cerise/tests/A.m b/cerise/tests/A.m index b1b8685..0f159fd 100644 --- a/cerise/tests/A.m +++ b/cerise/tests/A.m @@ -4,7 +4,13 @@ const procedure Foo*() : Int forward +procedure Bar*() : Int +begin + return Foo(); +end + procedure Foo*() : Int begin return 0; -end \ No newline at end of file +end + diff --git a/cerise/tests/Module.l b/cerise/tests/Module.l new file mode 100644 index 0000000..70cd878 --- /dev/null +++ b/cerise/tests/Module.l @@ -0,0 +1,421 @@ +%Bool = type i1 +%Int = type i64 +%Real = type double +%String = type { i64, i8* } +declare void @A() +declare %Int @A_Foo() +declare %Int @A_Bar() +%struct.0x703000000150 = type { %Int } +%struct.0x7030000000c0 = type { %Int, %struct.0x703000000150, [5 x %Int] } +%FooRec = type %struct.0x7030000000c0 +@Module_vBool = global %Bool 0 + +@Module_vInt = global %Int 0 + +@Module_vReal = global %Real 0.0 + +@Module_vIntArray = global [42 x %Int] zeroinitializer + +@Module_vIntArray2 = global [5 x [5 x %Int]] zeroinitializer + +@Module_vRec1 = global %struct.0x7030000000c0 zeroinitializer + +@Module_vRec2 = global { %Int, [5 x %Int] } zeroinitializer + +define void @Module_TestReturnVoid() +{ +L3: + ret void +} + +define %Int @Module_TestReturnIntLiteral() +{ +L6: + ret %Int 0 +} + +define %Real @Module_TestReturnRealLiteral() +{ +L9: + ret %Real 0.000000 +} + +define %Bool @Module_TestReturnBoolLiteral() +{ +L12: + ret %Bool 0 +} + +define void @Module_TestStoreLiterals() +{ +L15: + store %Bool 1, %Bool* @Module_vBool + store %Int 42, %Int* @Module_vInt + store %Real 42.000000, %Real* @Module_vReal + ret void +} + +define void @Module_TestIntArithOps() +{ +L18: + %.6 = load %Int, %Int* @Module_vInt + %.7 = add %Int %.6, 1 + store %Int %.7, %Int* @Module_vInt + %.8 = load %Int, %Int* @Module_vInt + %.9 = add %Int 1, %.8 + store %Int %.9, %Int* @Module_vInt + %.10 = load %Int, %Int* @Module_vInt + %.11 = load %Int, %Int* @Module_vInt + %.12 = add %Int %.10, %.11 + store %Int %.12, %Int* @Module_vInt + %.13 = load %Int, %Int* @Module_vInt + %.14 = sub %Int %.13, 1 + store %Int %.14, %Int* @Module_vInt + %.15 = load %Int, %Int* @Module_vInt + %.16 = sub %Int 1, %.15 + store %Int %.16, %Int* @Module_vInt + %.17 = load %Int, %Int* @Module_vInt + %.18 = load %Int, %Int* @Module_vInt + %.19 = sub %Int %.17, %.18 + store %Int %.19, %Int* @Module_vInt + %.20 = load %Int, %Int* @Module_vInt + %.21 = mul %Int %.20, 1 + store %Int %.21, %Int* @Module_vInt + %.22 = load %Int, %Int* @Module_vInt + %.23 = mul %Int 1, %.22 + store %Int %.23, %Int* @Module_vInt + %.24 = load %Int, %Int* @Module_vInt + %.25 = load %Int, %Int* @Module_vInt + %.26 = mul %Int %.24, %.25 + store %Int %.26, %Int* @Module_vInt + %.27 = load %Int, %Int* @Module_vInt + %.28 = sdiv %Int %.27, 1 + store %Int %.28, %Int* @Module_vInt + %.29 = load %Int, %Int* @Module_vInt + %.30 = sdiv %Int 1, %.29 + store %Int %.30, %Int* @Module_vInt + %.31 = load %Int, %Int* @Module_vInt + %.32 = load %Int, %Int* @Module_vInt + %.33 = sdiv %Int %.31, %.32 + store %Int %.33, %Int* @Module_vInt + %.34 = load %Int, %Int* @Module_vInt + %.35 = srem %Int %.34, 1 + store %Int %.35, %Int* @Module_vInt + %.36 = load %Int, %Int* @Module_vInt + %.37 = srem %Int 1, %.36 + store %Int %.37, %Int* @Module_vInt + %.38 = load %Int, %Int* @Module_vInt + %.39 = load %Int, %Int* @Module_vInt + %.40 = srem %Int %.38, %.39 + store %Int %.40, %Int* @Module_vInt + ret void +} + +define void @Module_TestIntCompOps() +{ +L21: + %.42 = load %Int, %Int* @Module_vInt + %.43 = icmp eq %Int %.42, 1 + store %Bool %.43, %Bool* @Module_vBool + %.44 = load %Int, %Int* @Module_vInt + %.45 = icmp eq %Int 1, %.44 + store %Bool %.45, %Bool* @Module_vBool + %.46 = load %Int, %Int* @Module_vInt + %.47 = load %Int, %Int* @Module_vInt + %.48 = icmp eq %Int %.46, %.47 + store %Bool %.48, %Bool* @Module_vBool + %.49 = load %Int, %Int* @Module_vInt + %.50 = icmp ne %Int %.49, 1 + store %Bool %.50, %Bool* @Module_vBool + %.51 = load %Int, %Int* @Module_vInt + %.52 = icmp ne %Int 1, %.51 + store %Bool %.52, %Bool* @Module_vBool + %.53 = load %Int, %Int* @Module_vInt + %.54 = load %Int, %Int* @Module_vInt + %.55 = icmp ne %Int %.53, %.54 + store %Bool %.55, %Bool* @Module_vBool + %.56 = load %Int, %Int* @Module_vInt + %.57 = icmp slt %Int %.56, 1 + store %Bool %.57, %Bool* @Module_vBool + %.58 = load %Int, %Int* @Module_vInt + %.59 = icmp slt %Int 1, %.58 + store %Bool %.59, %Bool* @Module_vBool + %.60 = load %Int, %Int* @Module_vInt + %.61 = load %Int, %Int* @Module_vInt + %.62 = icmp slt %Int %.60, %.61 + store %Bool %.62, %Bool* @Module_vBool + %.63 = load %Int, %Int* @Module_vInt + %.64 = icmp sgt %Int %.63, 1 + store %Bool %.64, %Bool* @Module_vBool + %.65 = load %Int, %Int* @Module_vInt + %.66 = icmp sgt %Int 1, %.65 + store %Bool %.66, %Bool* @Module_vBool + %.67 = load %Int, %Int* @Module_vInt + %.68 = load %Int, %Int* @Module_vInt + %.69 = icmp sgt %Int %.67, %.68 + store %Bool %.69, %Bool* @Module_vBool + %.70 = load %Int, %Int* @Module_vInt + %.71 = icmp sle %Int %.70, 1 + store %Bool %.71, %Bool* @Module_vBool + %.72 = load %Int, %Int* @Module_vInt + %.73 = icmp sle %Int 1, %.72 + store %Bool %.73, %Bool* @Module_vBool + %.74 = load %Int, %Int* @Module_vInt + %.75 = load %Int, %Int* @Module_vInt + %.76 = icmp sle %Int %.74, %.75 + store %Bool %.76, %Bool* @Module_vBool + %.77 = load %Int, %Int* @Module_vInt + %.78 = icmp sge %Int %.77, 1 + store %Bool %.78, %Bool* @Module_vBool + %.79 = load %Int, %Int* @Module_vInt + %.80 = icmp sge %Int 1, %.79 + store %Bool %.80, %Bool* @Module_vBool + %.81 = load %Int, %Int* @Module_vInt + %.82 = load %Int, %Int* @Module_vInt + %.83 = icmp sge %Int %.81, %.82 + store %Bool %.83, %Bool* @Module_vBool + ret void +} + +define void @Module_TestRealArithOps() +{ +L24: + %.85 = load %Real, %Real* @Module_vReal + %.86 = fadd %Real %.85, 1.000000 + store %Real %.86, %Real* @Module_vReal + %.87 = load %Real, %Real* @Module_vReal + %.88 = fadd %Real 1.000000, %.87 + store %Real %.88, %Real* @Module_vReal + %.89 = load %Real, %Real* @Module_vReal + %.90 = load %Real, %Real* @Module_vReal + %.91 = fadd %Real %.89, %.90 + store %Real %.91, %Real* @Module_vReal + %.92 = load %Real, %Real* @Module_vReal + %.93 = fsub %Real %.92, 1.000000 + store %Real %.93, %Real* @Module_vReal + %.94 = load %Real, %Real* @Module_vReal + %.95 = fsub %Real 1.000000, %.94 + store %Real %.95, %Real* @Module_vReal + %.96 = load %Real, %Real* @Module_vReal + %.97 = load %Real, %Real* @Module_vReal + %.98 = fsub %Real %.96, %.97 + store %Real %.98, %Real* @Module_vReal + %.99 = load %Real, %Real* @Module_vReal + %.100 = fmul %Real %.99, 1.000000 + store %Real %.100, %Real* @Module_vReal + %.101 = load %Real, %Real* @Module_vReal + %.102 = fmul %Real 1.000000, %.101 + store %Real %.102, %Real* @Module_vReal + %.103 = load %Real, %Real* @Module_vReal + %.104 = load %Real, %Real* @Module_vReal + %.105 = fmul %Real %.103, %.104 + store %Real %.105, %Real* @Module_vReal + %.106 = load %Real, %Real* @Module_vReal + %.107 = fdiv %Real %.106, 1.000000 + store %Real %.107, %Real* @Module_vReal + %.108 = load %Real, %Real* @Module_vReal + %.109 = fdiv %Real 1.000000, %.108 + store %Real %.109, %Real* @Module_vReal + %.110 = load %Real, %Real* @Module_vReal + %.111 = load %Real, %Real* @Module_vReal + %.112 = fdiv %Real %.110, %.111 + store %Real %.112, %Real* @Module_vReal + %.113 = load %Real, %Real* @Module_vReal + %.114 = frem %Real %.113, 1.000000 + store %Real %.114, %Real* @Module_vReal + %.115 = load %Real, %Real* @Module_vReal + %.116 = frem %Real 1.000000, %.115 + store %Real %.116, %Real* @Module_vReal + %.117 = load %Real, %Real* @Module_vReal + %.118 = load %Real, %Real* @Module_vReal + %.119 = frem %Real %.117, %.118 + store %Real %.119, %Real* @Module_vReal + ret void +} + +define void @Module_TestRealCompOps() +{ +L27: + %.121 = load %Real, %Real* @Module_vReal + %.122 = fcmp oeq %Real %.121, 1.000000 + store %Bool %.122, %Bool* @Module_vBool + %.123 = load %Real, %Real* @Module_vReal + %.124 = fcmp oeq %Real 1.000000, %.123 + store %Bool %.124, %Bool* @Module_vBool + %.125 = load %Real, %Real* @Module_vReal + %.126 = load %Real, %Real* @Module_vReal + %.127 = fcmp oeq %Real %.125, %.126 + store %Bool %.127, %Bool* @Module_vBool + %.128 = load %Real, %Real* @Module_vReal + %.129 = fcmp une %Real %.128, 1.000000 + store %Bool %.129, %Bool* @Module_vBool + %.130 = load %Real, %Real* @Module_vReal + %.131 = fcmp une %Real 1.000000, %.130 + store %Bool %.131, %Bool* @Module_vBool + %.132 = load %Real, %Real* @Module_vReal + %.133 = load %Real, %Real* @Module_vReal + %.134 = fcmp une %Real %.132, %.133 + store %Bool %.134, %Bool* @Module_vBool + %.135 = load %Real, %Real* @Module_vReal + %.136 = fcmp olt %Real %.135, 1.000000 + store %Bool %.136, %Bool* @Module_vBool + %.137 = load %Real, %Real* @Module_vReal + %.138 = fcmp olt %Real 1.000000, %.137 + store %Bool %.138, %Bool* @Module_vBool + %.139 = load %Real, %Real* @Module_vReal + %.140 = load %Real, %Real* @Module_vReal + %.141 = fcmp olt %Real %.139, %.140 + store %Bool %.141, %Bool* @Module_vBool + %.142 = load %Real, %Real* @Module_vReal + %.143 = fcmp ogt %Real %.142, 1.000000 + store %Bool %.143, %Bool* @Module_vBool + %.144 = load %Real, %Real* @Module_vReal + %.145 = fcmp ogt %Real 1.000000, %.144 + store %Bool %.145, %Bool* @Module_vBool + %.146 = load %Real, %Real* @Module_vReal + %.147 = load %Real, %Real* @Module_vReal + %.148 = fcmp ogt %Real %.146, %.147 + store %Bool %.148, %Bool* @Module_vBool + %.149 = load %Real, %Real* @Module_vReal + %.150 = fcmp ole %Real %.149, 1.000000 + store %Bool %.150, %Bool* @Module_vBool + %.151 = load %Real, %Real* @Module_vReal + %.152 = fcmp ole %Real 1.000000, %.151 + store %Bool %.152, %Bool* @Module_vBool + %.153 = load %Real, %Real* @Module_vReal + %.154 = load %Real, %Real* @Module_vReal + %.155 = fcmp ole %Real %.153, %.154 + store %Bool %.155, %Bool* @Module_vBool + %.156 = load %Real, %Real* @Module_vReal + %.157 = fcmp oge %Real %.156, 1.000000 + store %Bool %.157, %Bool* @Module_vBool + %.158 = load %Real, %Real* @Module_vReal + %.159 = fcmp oge %Real 1.000000, %.158 + store %Bool %.159, %Bool* @Module_vBool + %.160 = load %Real, %Real* @Module_vReal + %.161 = load %Real, %Real* @Module_vReal + %.162 = fcmp oge %Real %.160, %.161 + store %Bool %.162, %Bool* @Module_vBool + ret void +} + +define void @Module_TestIfStatements() +{ +L30: + %.164 = load %Int, %Int* @Module_vInt + %.165 = icmp eq %Int %.164, 1 + br %Bool %.165, label %L32, label %L31 +L32: + store %Int 42, %Int* @Module_vInt + br label %L31 +L31: + %.167 = load %Int, %Int* @Module_vInt + %.168 = icmp eq %Int %.167, 1 + br %Bool %.168, label %L34, label %L35 +L34: + store %Int 42, %Int* @Module_vInt + br label %L33 +L35: + store %Int 24, %Int* @Module_vInt + br label %L33 +L33: + ret void +} + +define void @Module_TestFlatArrayAccess() +{ +L38: + %.171 = getelementptr [42 x %Int], [42 x %Int]* @Module_vIntArray, %Int 0, %Int 1 + %.172 = load %Int, %Int* %.171 + %.173 = getelementptr [42 x %Int], [42 x %Int]* @Module_vIntArray, %Int 0, %Int 2 + %.174 = load %Int, %Int* %.173 + %.175 = add %Int %.172, %.174 + %.176 = getelementptr [42 x %Int], [42 x %Int]* @Module_vIntArray, %Int 0, %Int 0 + store %Int %.175, %Int* %.176 + %.178 = getelementptr [42 x %Int], [42 x %Int]* @Module_vIntArray, %Int 0, %Int 1 + %.179 = load %Int, %Int* %.178 + %.180 = getelementptr [42 x %Int], [42 x %Int]* @Module_vIntArray, %Int 0, %Int 2 + %.181 = load %Int, %Int* %.180 + %.182 = add %Int %.179, %.181 + store %Int %.182, %Int* @Module_vInt + ret void +} + +define void @Module_TestNestedArrayAccess() +{ +L41: + %.184 = getelementptr [5 x [5 x %Int]], [5 x [5 x %Int]]* @Module_vIntArray2, %Int 0, %Int 0 + %.185 = getelementptr [5 x [5 x %Int]], [5 x [5 x %Int]]* @Module_vIntArray2, %Int 0, %Int 1 + %.186 = getelementptr [5 x [5 x %Int]], [5 x [5 x %Int]]* @Module_vIntArray2, %Int 0, %Int 2 + %.187 = getelementptr [5 x %Int], [5 x %Int]* %.185, %Int 0, %Int 1 + %.188 = load %Int, %Int* %.187 + %.189 = getelementptr [5 x %Int], [5 x %Int]* %.186, %Int 0, %Int 1 + %.190 = load %Int, %Int* %.189 + %.191 = add %Int %.188, %.190 + %.192 = getelementptr [5 x %Int], [5 x %Int]* %.184, %Int 0, %Int 1 + store %Int %.191, %Int* %.192 + ret void +} + +define void @Module_TestRecordAccess() +{ +L44: + %.195 = getelementptr { %Int, [5 x %Int] }, { %Int, [5 x %Int] }* @Module_vRec2, i64 0, i32 0 + %.196 = load %Int, %Int* %.195 + %.197 = getelementptr { %Int, [5 x %Int] }, { %Int, [5 x %Int] }* @Module_vRec2, i64 0, i32 0 + %.198 = load %Int, %Int* %.197 + %.199 = add %Int %.196, %.198 + %.200 = getelementptr { %Int, [5 x %Int] }, { %Int, [5 x %Int] }* @Module_vRec2, i64 0, i32 0 + store %Int %.199, %Int* %.200 + %.202 = getelementptr { %Int, [5 x %Int] }, { %Int, [5 x %Int] }* @Module_vRec2, i64 0, i32 0 + %.203 = load %Int, %Int* %.202 + store %Int %.203, %Int* @Module_vInt + ret void +} + +define void @Module_TestNestedRecordAccess() +{ +L47: + %.205 = getelementptr %struct.0x7030000000c0, %struct.0x7030000000c0* @Module_vRec1, i64 0, i32 1 + %.206 = getelementptr %struct.0x7030000000c0, %struct.0x7030000000c0* @Module_vRec1, i64 0, i32 1 + %.207 = getelementptr %struct.0x7030000000c0, %struct.0x7030000000c0* @Module_vRec1, i64 0, i32 1 + %.208 = getelementptr %struct.0x703000000150, %struct.0x703000000150* %.206, i64 0, i32 0 + %.209 = load %Int, %Int* %.208 + %.210 = getelementptr %struct.0x703000000150, %struct.0x703000000150* %.207, i64 0, i32 0 + %.211 = load %Int, %Int* %.210 + %.212 = add %Int %.209, %.211 + %.213 = getelementptr %struct.0x703000000150, %struct.0x703000000150* %.205, i64 0, i32 0 + store %Int %.212, %Int* %.213 + ret void +} + +define %Int @Module_Sum(%Int %a.0, %Int %b.0) +{ +L50: + %.216 = add %Int %a.0, %b.0 + ret %Int %.216 +} + +define void @Module_TestFunctionCalls() +{ +L53: + call void @Module_TestReturnVoid() + %.218 = call %Int @Module_TestReturnIntLiteral() + store %Int %.218, %Int* @Module_vInt + %.219 = call %Int @Module_Sum(%Int 1, %Int 2) + store %Int %.219, %Int* @Module_vInt + ret void +} + +define void @Module() +{ +L56: + ret void +} + +define i32 @main(i32 %0, i8* %1) +{ + call void @A() + call void @Module() + ret i32 0 +}