From 68725fe94fdf88194c755842d8a8a2db7e331ce3 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 1 Mar 2022 17:05:57 -0500 Subject: [PATCH] loads and stores are working now --- cerise/backend/ssa/codegen.c | 246 +++++++++++++---------------------- cerise/inc/cerise.h | 5 +- cerise/src/grammar.c | 4 +- cerise/src/ssa.c | 43 ++++-- cerise/tests/Module.m | 37 +++--- 5 files changed, 147 insertions(+), 188 deletions(-) diff --git a/cerise/backend/ssa/codegen.c b/cerise/backend/ssa/codegen.c index b891aef..7baaf67 100644 --- a/cerise/backend/ssa/codegen.c +++ b/cerise/backend/ssa/codegen.c @@ -3,7 +3,7 @@ #include Type VoidType = { - .form = FORM_VOID, + .form = FORM_VOID }; Type BoolType = { @@ -166,17 +166,21 @@ static void print_ident(Parser* p, SsaVar* var) { Symbol* s = symbol_getbyid(p, var->symid); char* name = (s->name[0] == '$' ? "" : s->name); - bool is_global = (s->global || s->class == SYM_PROC) && (s->class != SYM_TYPE); - char scope = (is_global ? '@' : '%'); - printf("%c%s.%lu", scope, name, var->symver); + if ((s->global || s->class == SYM_PROC) && (s->class != SYM_TYPE)) + { + printf("@%s", name); + } + else + { + printf("%%%s.%lu", name, var->symver); + } } static void print_const(Type* type, SsaValue* val) { - emit_type(type); if (type->form == FORM_INT) { - printf(" %d", val->val.i); + printf(" %lld", val->val.i); } else if (type->form == FORM_REAL) { @@ -188,15 +192,6 @@ static void print_const(Type* type, SsaValue* val) } } -char* BinOpNames[NUM_TOKENS] = { - ['+'] = "add", - ['-'] = "sub", - ['*'] = "mul", - ['/'] = "div", - ['%'] = "rem", - -}; - char* binop_name(SsaNode* node) { char* name = NULL; @@ -204,16 +199,16 @@ char* binop_name(SsaNode* node) { switch(node->code) { - case '+': name = "add"; break; - case '-': name = "sub"; break; - case '*': name = "mul"; break; - case '/': name = "div"; break; - case '%': name = "rem"; break; + case '+': name = "add"; break; + case '-': name = "sub"; break; + case '*': name = "mul"; break; + case '/': name = "sdiv"; break; + case '%': name = "srem"; break; case EQ: name = "icmp eq"; break; case NEQ: name = "icmp ne"; break; - case LT: name = "icmp slt"; break; - case GT: name = "icmp sgt"; break; + case '<': name = "icmp slt"; break; + case '>': name = "icmp sgt"; break; case LTEQ: name = "icmp sle"; break; case GTEQ: name = "icmp sge"; break; } @@ -222,11 +217,11 @@ char* binop_name(SsaNode* node) { switch(node->code) { - case '+': name = "fadd"; break; - case '-': name = "fsub"; break; - case '*': name = "fmul"; break; - case '/': name = "fdiv"; break; - case '%': name = "frem"; break; + case '+': name = "fadd"; break; + case '-': name = "fsub"; break; + case '*': name = "fmul"; break; + case '/': name = "fdiv"; break; + case '%': name = "frem"; break; case EQ: name = "fcmp eq"; break; case NEQ: name = "fcmp ne"; break; @@ -240,117 +235,51 @@ char* binop_name(SsaNode* node) { assert(!"not implemented"); } + return name; } - -//static void print_dest(Parser* p, SsaNode* node) -//{ -// if (node->mode != MODE_CONTROL) -// { -// print_ident(p, &(node->dest)); -// printf(" = "); -// } -//} -// -//static void print_opcode(SsaNode* node) -//{ -// int op = node->code; -// if (op < 256) -// { -// printf(" %c ", op); -// } -// else if (op == RETURN) -// { -// printf(" return "); -// } -// else if (op == IF) -// { -// printf("if "); -// } -// else if (op == EQ) -// { -// printf(" == "); -// } -// else if (op == NEQ) -// { -// printf(" != "); -// } -// else if (op == LTEQ) -// { -// printf(" <= "); -// } -// else if (op == GTEQ) -// { -// printf(" >= "); -// } -// else -// { -// printf("%d\n", op); -// } -//} -// -//void print_op(Parser* p, SsaNode* expr) -//{ -// (void)p; -// switch(expr->code) -// { -// case IDENT: -// print_ident(p, &(expr->left.var)); -// break; -// -// case BOOL: -// printf("load %%Bool, %d", ssa_asbool(expr)); -// break; -// -// case INT: -// printf("internal constant %%Int %lld", ssa_asint(expr)); -// break; -// -// case REAL: -// printf("load %%Real, %f", ssa_asreal(expr)); -// break; -// -// case IF: -// printf("if "); -// print_ident(p, &(expr->dest)); -// printf(" then block%lu else block%lu", expr->left.block->id, expr->right.block->id); -// break; -// -// case RETURN: -// printf("return "); -// print_ident(p, &(expr->dest)); -// break; -// -// default: -// if (expr->mode == MODE_VAR) -// { -// print_ident(p, &(expr->left.var)); -// } -// else if (expr->mode == MODE_UNOP) -// { -// print_opcode(expr); -// print_ident(p, &(expr->left.var)); -// } -// else if (expr->mode == MODE_BINOP) -// { -// print_ident(p, &(expr->left.var)); -// print_opcode(expr); -// print_ident(p, &(expr->right.var)); -// } -// else -// { -// printf("??? M:%d C:%d\n", expr->mode, expr->code); -// } -// break; -// } -//} -// - void print_op(Parser* p, SsaNode* expr) { switch(expr->mode) { + case MODE_MEMORY: + if (expr->code == LOAD) + { + printf(" "); + print_ident(p, &(expr->dest)); + printf(" = load "); + emit_type(expr->type); + printf(", "); + emit_type(expr->type); + printf("* "); + print_ident(p, &(expr->left.var)); + puts(""); + } + else if (expr->code == STORE) + { + printf(" store "); + emit_type(expr->type); + printf(" "); + print_ident(p, &(expr->left.var)); + printf(", "); + emit_type(expr->type); + printf("* "); + print_ident(p, &(expr->dest)); + puts(""); + } + else + { + assert(!"not implemented"); + } + break; + case MODE_CONTROL: + if (expr->code == RETURN) + { + printf(" ret "); + emit_type(expr); + puts(""); + } break; case MODE_UNOP: @@ -366,18 +295,21 @@ void print_op(Parser* p, SsaNode* expr) break; case MODE_BINOP_LC: - printf(" %%"); + printf(" "); print_ident(p, &(expr->dest)); - printf(" = add "); + printf(" = %s ", binop_name(expr)); emit_type(expr->type); - print_ident(p, &(expr->dest)); + printf(" "); + print_const(expr->type, &(expr->left)); + printf(", "); + print_ident(p, &(expr->right.var)); printf("\n"); break; case MODE_BINOP_RC: printf(" "); print_ident(p, &(expr->dest)); - printf(" = %s ", BinOpNames[expr->code]); + printf(" = %s ", binop_name(expr)); emit_type(expr->type); printf(" "); print_ident(p, &(expr->left.var)); @@ -400,6 +332,7 @@ void print_op(Parser* p, SsaNode* expr) default: printf("OP ????\n"); + assert(!"not implemented"); break; } } @@ -416,33 +349,36 @@ void codegen_block(Parser* p, SsaBlock* block) printf("{\n"); for (SsaBlock* curr = sorted; curr; curr = curr->next) { - if (curr->phis || curr->head) + if (curr->head) { - printf("L%lu:\n", curr->id); - } + if (curr->head) + { + printf("L%lu:\n", curr->id); + } - /* print the phis */ - for (SsaPhi* phi = curr->phis; phi; phi = phi->next) - { - Symbol* s = symbol_getbyid(p, phi->symid); - printf(" %%%s.%lu = phi ", s->name, phi->latest_ver); - emit_type(s->type); - printf(" "); - for (SsaPhiVar* var = phi->vars; var; var = var->next) + /* print the phis */ + for (SsaPhi* phi = curr->phis; phi; phi = phi->next) { - printf("[%%%s.%lu, %%L%lu]", s->name, var->version, var->block); - if (var->next) + Symbol* s = symbol_getbyid(p, phi->symid); + printf(" %%%s.%lu = phi ", s->name, phi->latest_ver); + emit_type(s->type); + printf(" "); + for (SsaPhiVar* var = phi->vars; var; var = var->next) { - printf(", "); + printf("[%%%s.%lu, %%L%lu]", s->name, var->version, var->block); + if (var->next) + { + printf(", "); + } } + puts(""); } - puts(""); - } - /* print the instructions */ - for (SsaNode* node = curr->head; node; node = node->next) - { - print_op(p, node); + /* print the instructions */ + for (SsaNode* node = curr->head; node; node = node->next) + { + print_op(p, node); + } } } printf("}\n"); diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index a3d83c6..c1af2d7 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -56,8 +56,8 @@ typedef enum { WHILE, COUNT, CALL, - - NUM_TOKENS, + LOAD, + STORE, ERROR = -2, END_FILE = -1 } TokType; @@ -167,6 +167,7 @@ enum { MODE_BINOP = 4, MODE_BINOP_LC = 5, MODE_BINOP_RC = 6, + MODE_MEMORY = 7, }; typedef struct Symbol { diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 5709ce6..57f9ed3 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -659,14 +659,14 @@ static void module(Parser* p) SsaBlock* seqblock = statement_seq(p); block->links[0] = seqblock; } + ssa_return(p, NULL); expect(p, END); ssa_join(p); /* debug dump the result */ - printf("define void initialize()\n"); + printf("define void @initialize()\n"); codegen_block(p, block); - // ssa_print_asm(p, block); } diff --git a/cerise/src/ssa.c b/cerise/src/ssa.c index 93a3d5f..30a3880 100644 --- a/cerise/src/ssa.c +++ b/cerise/src/ssa.c @@ -137,7 +137,7 @@ SsaNode* ssa_ident(Parser* p, long long index) { node = ssa_node(IDENT, MODE_VAR); node->type = sym->type; - node->loaded = 1; + node->loaded = !sym->global; node->dest.symid = index; node->dest.symver = sym->version; node->left.var.symid = index; @@ -183,7 +183,7 @@ SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right) SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value) { load(p, value); - SsaNode* node = ssa_node('=', MODE_VAR); + SsaNode* node = ssa_node(STORE, MODE_MEMORY); node->type = dest->type; node->dest = dest->left.var; node->left.var = value->dest; @@ -243,11 +243,19 @@ SsaNode* ssa_if(Parser* p, SsaNode* cond, SsaBlock* br1, SsaBlock* br2) SsaNode* ssa_return(Parser* p, SsaNode* expr) { - load(p, expr); SsaNode* node = ssa_node(RETURN, MODE_CONTROL); - node->type = expr->type; - node = load(p, node); - node->dest = expr->dest; + if (expr) + { + load(p, expr); + node->type = expr->type; + node = load(p, node); + node->dest = expr->dest; + } + else + { + node->type = &VoidType; + node = load(p, node); + } return node; } @@ -263,24 +271,23 @@ static SsaNode* binop(Parser* p, int op, SsaNode* left, SsaNode* right) } else { + left = load(p, left); + right = load(p, right); + if (left->mode == MODE_CONST) { - right = load(p, right); node = ssa_node(op, MODE_BINOP_LC); node->left = left->left; node->right.var = right->dest; } else if (right->mode == MODE_CONST) { - left = load(p, left); node = ssa_node(op, MODE_BINOP_RC); node->left.var = left->dest; node->right = right->left; } else { - left = load(p, left); - right = load(p, right); node = ssa_node(op, MODE_BINOP); node->left.var = left->dest; node->right.var = right->dest; @@ -460,8 +467,22 @@ static SsaNode* const_unop(int op, SsaNode* a) static SsaNode* load(Parser* p, SsaNode* node) { // if (!node->loaded && (node->mode != MODE_CONST) && (node->mode != MODE_VAR)) - if (!node->loaded) +// if (node->mode == MODE_VAR && node->dest.symid != 0) +// { +// Symbol* sym = symbol_getbyid(p, node->dest.symid); +// printf("load %s\n", sym->name); +// } +// else + if (!node->loaded && (node->mode != MODE_CONST)) { + if (node->mode == MODE_VAR) + { + node->left.var = node->dest; + node->dest.symid = 0; + node->mode = MODE_MEMORY; + node->code = LOAD; + } + if (node->dest.symid == 0) { Symbol* sym = symbol_getbyid(p, 0); diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index f224888..0bd2020 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -110,26 +110,27 @@ begin # # Unary ops # b = +b; # b = -b; -# -# # Arithmetic ops -# c = b + 1; -# c = b - 1; -# c = b * 1; -# c = b / 1; -# c = b % 1; -# + + # Arithmetic ops + c = b + 1; + c = 1 + b; + c = b - 1; + c = 1 - b; + c = b * 1; + c = 1 * b; + c = b / 1; + c = 1 / b; + c = b % 1; + c = 1 % b; + # # Comparison ops - c = b == 1; - c = b != 1; - c = b < 1; - c = b > 1; - c = b <= 1; - c = b >= 1; +# c = b == 1; +# c = b != 1; +# c = b < 1; +# c = b > 1; +# c = b <= 1; +# c = b >= 1; # -# # Register ops -# c = 1 + b; -# c = 1 - b; -# c = 1 * b; # # c = b + b; # -- 2.49.0