From: Michael D. Lowis Date: Mon, 26 Jul 2021 18:34:55 +0000 (-0400) Subject: added basic phi function handling for straight line code. Next up is if statements X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=b965041e0c7f81a3cd1d1fe8ea2951eec5cf563e;p=proto%2Fobnc.git added basic phi function handling for straight line code. Next up is if statements --- diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 866d583..97f6286 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -126,8 +126,21 @@ typedef struct SsaNode { SsaValue right; } SsaNode; +typedef struct SsaPhiVar { + struct SsaPhiVar* next; + size_t block; + size_t version; +} SsaPhiVar; + +typedef struct SsaPhi { + struct SsaPhi* next; + size_t symid; + SsaPhiVar* vars; +} SsaPhi; + typedef struct { size_t id; + SsaPhi* phis; SsaNode* head; SsaNode* tail; } SsaBlock; @@ -167,7 +180,6 @@ typedef struct { SsaBlock* curr_block; SsaBlock* curr_join; - size_t msyms; size_t nsyms; Symbol* syms; diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index f2dbed1..e3961db 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -531,7 +531,6 @@ void proc_decl(Parser* p) /* parse the private declarations */ if (accept(p, CONST)) { - p->curr_block = ssa_block(p); const_decl(p); } @@ -626,12 +625,13 @@ static void module(Parser* p) if (accept(p, BEGIN)) { -// p->curr_join = ast_block(); + p->curr_block = ssa_block(p); + p->curr_join = ssa_block(p); if (!matches(p, END)) { -// p->curr_block = ssa_block(); SsaBlock* block = statement_seq(p); ssa_print_block(p, block); + ssa_print_block(p, p->curr_join); (void)block; } expect(p, END); diff --git a/cerise/src/ssa.c b/cerise/src/ssa.c index 9daf689..e24695b 100644 --- a/cerise/src/ssa.c +++ b/cerise/src/ssa.c @@ -92,6 +92,41 @@ SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right) : unop(p, op, left); } +static void phi_add(Parser* p, SsaVar var) +{ + /* first, append the phi function to the list */ + SsaPhi** phis = &(p->curr_join->phis); + for (; *phis; phis = &((*phis)->next)) + { + if ((*phis)->symid == var.symid) + { + break; + } + } + if (!*phis) + { + *phis = calloc(1, sizeof(SsaPhi)); + (*phis)->symid = var.symid; + } + + /* now add or update the variable entry */ + SsaPhiVar** vars = &((*phis)->vars); + for (; *vars; vars = &((*vars)->next)) + { + if ((*vars)->block == p->curr_block->id) + { + (*vars)->version = var.symver; + break; + } + } + if (!*vars) + { + *vars = calloc(1, sizeof(SsaPhiVar)); + (*vars)->block = p->curr_block->id; + (*vars)->version = var.symver; + } +} + SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value) { load(p, value); @@ -104,6 +139,7 @@ SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value) Symbol* sym = symbol_getbyid(p, node->dest.symid); sym->version++; node->dest.symver = sym->version; + phi_add(p, node->dest); ssa_block_add(p->curr_block, node); node->loaded = 1; @@ -439,6 +475,23 @@ void ssa_print(Parser* p, SsaNode* expr) void ssa_print_block(Parser* p, SsaBlock* block) { printf("L%lu:\n", block->id); + for (SsaPhi* phi = block->phis; phi; phi = phi->next) + { + Symbol* s = symbol_getbyid(p, phi->symid); + s->version++; + 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(")"); + } + + for (SsaNode* node = block->head; node; node = node->next) { printf(" ");