From: Michael D. Lowis Date: Tue, 8 Feb 2022 21:28:37 +0000 (-0500) Subject: started implementing llvm assembly code generation X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=dc017eb974c3f1dee2abbf20bbfc42ef0ac69a33;p=proto%2Fobnc.git started implementing llvm assembly code generation --- diff --git a/cerise/backend/ssa/codegen.c b/cerise/backend/ssa/codegen.c index b76a471..140d9ec 100644 --- a/cerise/backend/ssa/codegen.c +++ b/cerise/backend/ssa/codegen.c @@ -25,3 +25,45 @@ Type StringType = { .form = FORM_STRING, .size = -1 }; + +void emit_type(Type* type) +{ + switch (type->form) + { + case FORM_BOOL: printf("@Bool"); break; + case FORM_INT: printf("@Int"); break; + case FORM_REAL: printf("@Real"); break; + case FORM_VOID: printf("@Void"); break; + default: + printf("????"); + break; + } +} + +void codegen_symbol(Parser* p, Symbol* sym) +{ + (void)p; + if (sym->class == SYM_VAR) + { + printf("@%s = %s global ", + sym->name, + (sym->export ? "dso_local" : "internal")); + emit_type(sym->type); + printf(" 0\n"); + } + else if (sym->class == SYM_TYPE) + { + printf("%c%s = type \n", (sym->global ? '@' : '%'), sym->name); + } + else if (sym->class == SYM_PROC) + { + printf("define %c%s\n", (sym->global ? '@' : '%'), sym->name); + } + puts(""); +} + +void codegen_block(Parser* p, SsaBlock* block) +{ + (void)p; + (void)block; +} diff --git a/cerise/backend/test/codegen.c b/cerise/backend/test/codegen.c index b76a471..7905613 100644 --- a/cerise/backend/test/codegen.c +++ b/cerise/backend/test/codegen.c @@ -25,3 +25,15 @@ Type StringType = { .form = FORM_STRING, .size = -1 }; + +void codegen_symbol(Parser* p, Symbol* sym) +{ + (void)p; + (void)sym; +} + +void codegen_block(Parser* p, SsaBlock* block) +{ + (void)p; + (void)block; +} diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index c66d620..f2ccfbe 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -281,9 +281,11 @@ SsaNode* ssa_call(SsaNode* func); void ssa_call_add(SsaBlock* call, SsaNode* arg); void ssa_print(Parser* p, SsaNode* expr); -void ssa_print_block(Parser* p, Bitset* set, SsaBlock* block); -void ssa_print_graph(Parser* p, SsaBlock* block); +void ssa_print_asm(Parser* p, SsaBlock* block); /* Backend Code Generation and Base Type Definitions *****************************************************************************/ extern Type VoidType, BoolType, IntType, RealType, StringType; + +void codegen_symbol(Parser* p, Symbol* sym); +void codegen_block(Parser* p, SsaBlock* block); diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index a7c884f..17ad0fa 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -472,6 +472,7 @@ static void var_decl(Parser* p) Symbol* sym = symbol_new(p, 0, name, SYM_VAR, export); expect(p, ':'); sym->type = type(p); + codegen_symbol(p, sym); } while (matches(p, IDENT)); EXIT_RULE(); @@ -491,6 +492,7 @@ static void type_decl(Parser* p) sym = symbol_new(p, 0, name, SYM_TYPE, export); expect(p, '='); sym->type = type(p); + codegen_symbol(p, sym); } while (matches(p, IDENT)); @@ -535,6 +537,7 @@ void proc_decl(Parser* p) Type* proctype = symbol_newtype(p); proctype->form = FORM_PROC; proc->type = proctype; + codegen_symbol(p, proc); /* start scope and parse argument list */ size_t scope = symbol_openscope(p); @@ -585,7 +588,7 @@ void proc_decl(Parser* p) ssa_return(p, retval); } expect(p, END); - ssa_print_graph(p, block); + codegen_block(p, block); EXIT_RULE(); } @@ -660,9 +663,7 @@ static void module(Parser* p) ssa_join(p); /* debug dump the result */ - ssa_print_graph(p, block); - extern void ssa_print_asm(Parser* p, SsaBlock* block); - ssa_print_asm(p, block); +// ssa_print_asm(p, block); } if (!matches(p, END_FILE)) diff --git a/cerise/src/ssa.c b/cerise/src/ssa.c index 8c83492..699bf0e 100644 --- a/cerise/src/ssa.c +++ b/cerise/src/ssa.c @@ -34,10 +34,6 @@ double ssa_asreal(SsaNode* node) static size_t phi_add(Parser* p, SsaVar var) { Symbol* sym = symbol_getbyid(p, var.symid); - printf("phi_add()\n"); - - printf(" %s.%lu\n", sym->name, sym->version); - /* first, append the phi function to the list */ SsaPhi** phis = &(p->curr_join->phis); for (; *phis; phis = &((*phis)->next)) @@ -49,7 +45,6 @@ static size_t phi_add(Parser* p, SsaVar var) } if (!*phis) { - puts("new phi()"); *phis = calloc(1, sizeof(SsaPhi)); (*phis)->symid = var.symid; (*phis)->backup_ver = sym->version; @@ -57,7 +52,6 @@ static size_t phi_add(Parser* p, SsaVar var) else if ((*phis)->latest_ver > sym->version) { sym->version = (*phis)->latest_ver; - printf(" setting to latest: %s.%lu\n", sym->name, sym->version); } /* now add or update the variable entry */ @@ -73,22 +67,18 @@ static size_t phi_add(Parser* p, SsaVar var) { *vars = calloc(1, sizeof(SsaPhiVar)); (*vars)->block = p->curr_block->id; - printf(" new var %s from block %lu\n", sym->name, p->curr_block->id); } sym->version++; (*vars)->version = sym->version; (*phis)->latest_ver = (*vars)->version; - printf(" %s.%lu\n", sym->name, sym->version); - return sym->version; } void ssa_reset_vars(Parser* p) { - puts("ssa_reset_vars"); for (SsaPhi* phi = p->curr_join->phis; phi; phi = phi->next) { Symbol* s = symbol_getbyid(p, phi->symid); @@ -98,7 +88,6 @@ void ssa_reset_vars(Parser* p) void ssa_join(Parser* p) { - puts("ssa_join"); ssa_reset_vars(p); /* pop the join node off the list since we're done with it */ @@ -112,7 +101,6 @@ void ssa_join(Parser* p) Symbol* s = symbol_getbyid(p, phi->symid); s->version = phi->latest_ver; phi->latest_ver++; - printf("block %lu: %s.%lu\n", block->id, s->name, s->version); if (p->curr_join) { @@ -121,8 +109,6 @@ void ssa_join(Parser* p) .symver = s->version }); } - - printf("block %lu: %s.%lu\n", block->id, s->name, s->version); } } @@ -319,7 +305,6 @@ static SsaNode* unop(Parser* p, int op, SsaNode* operand) static SsaNode* const_binop(int op, SsaNode* a, SsaNode* b) { - printf("binop: %d %d\n", op, a->type->form); if (a->type->form == FORM_INT || a->type->form == FORM_BOOL) { switch (op) @@ -580,43 +565,6 @@ void ssa_print(Parser* p, SsaNode* expr) } } -void ssa_print_block(Parser* p, Bitset* set, SsaBlock* block) -{ - /* print the phis */ - printf("L%lu:\n", block->id); - for (SsaPhi* phi = block->phis; phi; phi = phi->next) - { - Symbol* s = symbol_getbyid(p, phi->symid); - printf(" %s.%lu = phi(", s->name, s->version); - for (SsaPhiVar* var = phi->vars; var; var = var->next) - { - printf("%s.%lu", s->name, var->version); - if (var->next) - { - printf(", "); - } - } - puts(")"); - } - /* print the instructions */ - for (SsaNode* node = block->head; node; node = node->next) - { - printf(" "); - print_dest(p, node); - ssa_print(p, node); - puts(""); - } - /* print the next node */ - if (block->links[0]) - { - ssa_print_block(p, set, block->links[0]); - } - if (block->links[1]) - { - ssa_print_block(p, set, block->links[1]); - } -} - static void topsort(Bitset* set, SsaBlock** sorted, SsaBlock* block) { if (block && !bitset_has(set, block->id)) @@ -632,60 +580,6 @@ static void topsort(Bitset* set, SsaBlock** sorted, SsaBlock* block) } } -void ssa_print_graph(Parser* p, SsaBlock* block) -{ -// /* perform a topological sort of the nodes */ -// SsaBlock* sorted = NULL; -// Bitset* set = bitset_new(p->blockid); -// topsort(set, &sorted, block); -// -// -// /* now let's print the plantuml representation */ -// printf("@startuml\n"); -// printf("[*] --> block%lu\n", block->id); -// for (SsaBlock* curr = sorted; curr; curr = curr->next) -// { -// /* print the phis */ -// for (SsaPhi* phi = curr->phis; phi; phi = phi->next) -// { -// Symbol* s = symbol_getbyid(p, phi->symid); -// printf("block%lu: %s.%lu = phi(", curr->id, s->name, s->version); -// for (SsaPhiVar* var = phi->vars; var; var = var->next) -// { -// printf("%s.%lu", s->name, var->version); -// if (var->next) -// { -// printf(", "); -// } -// } -// puts(")"); -// } -// -// /* print the instructions */ -// for (SsaNode* node = curr->head; node; node = node->next) -// { -// printf("block%lu : ", curr->id); -// print_dest(p, node); -// ssa_print(p, node); -// puts(""); -// } -// -// /* print the links */ -// if (curr->links[1]) -// { -// printf("block%lu --> block%lu\n", curr->id, curr->links[1]->id); -// } -// if (curr->links[0]) -// { -// printf("block%lu --> block%lu\n", curr->id, curr->links[0]->id); -// } -// -// puts(""); -// } -// printf("@enduml\n\n"); -} - - void ssa_print_asm(Parser* p, SsaBlock* block) { /* perform a topological sort of the nodes */ diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 45ffc3b..53c6946 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -6,30 +6,30 @@ import const A* = true -# B* = 42 -# C* = 42.0 -# D = -B -# E = -C -# F = not A -# G = B + 2 - 2 * 2 -# H = false or A + B* = 42 + C* = 42.0 + D = -B + E = -C + F = not A + G = B + 2 - 2 * 2 + H = false or A -#type -# TypeA* = Int -# TypeB* = array 5*B of Int -# TypeC* = array 5 of array 10 of Int -# TypeD* = record -# x,y : Int -# label : array 10 of Int -# dim : record -# w,h : Int -# end -# end -# TypeE* = record -# i : Int -# a : array 5 of Int -# end -# TypeF* = array 5 of TypeE +type + TypeA* = Int + TypeB* = array 5*B of Int + TypeC* = array 5 of array 10 of Int + TypeD* = record + x,y : Int + label : array 10 of Int + dim : record + w,h : Int + end + end + TypeE* = record + i : Int + a : array 5 of Int + end + TypeF* = array 5 of TypeE var a* : Bool @@ -37,9 +37,9 @@ var c : Int d : Real e : array 5 of array 10 of Int -# f : TypeD + f : TypeD g : array 5 of Int -# h : TypeF + h : TypeF #procedure Foo*(e : Int, z : Int, q1 : TypeD, q2 : array 5 of Int) : Int # const FOO = 2