/* parse the private declarations */
if (accept(p, CONST))
{
- p->curr_block = ssa_block(p);
const_decl(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);
: 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);
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;
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(" ");