char* binop_name(SsaNode* node)
{
char* name = NULL;
- if (node->left_type->form == FORM_INT)
+ if (SSA_LTYPE(node)->form == FORM_INT)
{
switch(node->code)
{
default: assert(!"unknown"); break;
}
}
- else if (node->left_type->form == FORM_REAL)
+ else if (SSA_LTYPE(node)->form == FORM_REAL)
{
switch(node->code)
{
{
if (is_const)
{
- print_const(expr->left_type, value);
+ print_const(SSA_LTYPE(expr), value);
}
else
{
if (expr->code == LOAD)
{
printf(" ");
- print_ident(p, &(expr->dest));
+ print_ident(p, &(SSA_VAR(expr)));
printf(" = load ");
- emit_type(expr->ret_type);
+ emit_type(SSA_TYPE(expr));
printf(", ");
- emit_type(expr->ret_type);
+ emit_type(SSA_TYPE(expr));
printf("* ");
- print_ident(p, &(expr->left.var));
+ print_ident(p, &(SSA_LVAR(expr)));
puts("");
}
else if (expr->code == STORE)
{
printf(" store ");
- emit_type(expr->left_type);
- print_operand(p, expr, expr->lconst, &(expr->left));
+ emit_type(SSA_LTYPE(expr));
+ print_operand(p, expr, SSA_LCONST(expr), &(expr->left->value));
printf(", ");
- emit_type(expr->ret_type);
+ emit_type(SSA_TYPE(expr));
printf("* ");
- print_ident(p, &(expr->dest));
+ print_ident(p, &(SSA_VAR(expr)));
puts("");
}
else if (expr->code == '[')
{
printf(" ");
- print_ident(p, &(expr->dest));
+ print_ident(p, &(SSA_VAR(expr)));
printf(" = getelementptr ");
- emit_type(expr->left_type);
+ emit_type(SSA_LTYPE(expr));
printf(", ");
- emit_type(expr->left_type);
+ emit_type(SSA_LTYPE(expr));
printf("* ");
- print_ident(p, &(expr->left.var));
+ print_ident(p, &(SSA_LVAR(expr)));
printf(", ");
- emit_type(expr->left_type->base);
+ emit_type(SSA_LTYPE(expr)->base);
printf(" 0, ");
- emit_type(expr->left_type->base);
+ emit_type(SSA_LTYPE(expr)->base);
printf(" ");
- print_operand(p, expr, expr->rconst, &(expr->right));
+ print_operand(p, expr, SSA_RCONST(expr), &(expr->right->value));
puts("");
}
else
if (expr->code == RETURN)
{
printf(" ret ");
- emit_type(expr->ret_type);
- if (expr->ret_type->form != FORM_VOID)
+ emit_type(SSA_TYPE(expr));
+ if (SSA_TYPE(expr)->form != FORM_VOID)
{
printf(" ");
if (expr->mode == MODE_CTRL)
{
- print_ident(p, &(expr->dest));
+ print_ident(p, &(SSA_VAR(expr)));
}
else
{
- print_const(expr->ret_type, &(expr->left));
+ print_const(SSA_TYPE(expr), &(expr->value));
}
}
puts("");
else if (expr->code == IF)
{
printf(" br %%Bool ");
- print_ident(p, &(expr->dest));
+ print_ident(p, &(SSA_VAR(expr)));
printf(", label %%L%ld, label %%L%ld\n",
- expr->left.block->id,
- expr->right.block->id
+ SSA_LBLK(expr)->id,
+ SSA_RBLK(expr)->id
);
}
else if (expr->code == BRANCH)
{
- printf(" br label %%L%ld\n", expr->left.block->id);
+ printf(" br label %%L%ld\n", SSA_LBLK(expr)->id);
}
break;
case MODE_UNOP:
printf(" ");
- print_ident(p, &(expr->dest));
+ print_ident(p, &(SSA_VAR(expr)));
printf(" = \n");
break;
case MODE_BINOP:
printf(" ");
- print_ident(p, &(expr->dest));
+ print_ident(p, &(SSA_VAR(expr)));
printf(" = %s ", binop_name(expr));
- emit_type(expr->left_type);
+ emit_type(SSA_LTYPE(expr));
printf(" ");
- print_operand(p, expr, expr->lconst, &(expr->left));
+ print_operand(p, expr, SSA_LCONST(expr), &(expr->left->value));
printf(", ");
- print_operand(p, expr, expr->rconst, &(expr->right));
+ print_operand(p, expr, SSA_RCONST(expr), &(expr->right->value));
printf("\n");
break;
bool ssa_asbool(SsaNode* node)
{
assert(node->code == BOOL);
- return (bool)(node->left.val.i);
+ return (bool)(SSA_VAL(node).i);
}
long long ssa_asint(SsaNode* node)
{
assert(node->code == INT);
- return (node->left.val.i);
+ return (SSA_VAL(node).i);
}
double ssa_asreal(SsaNode* node)
{
assert(node->code == REAL);
- return (node->left.val.f);
+ return (SSA_VAL(node).f);
}
/*
SsaNode* node = calloc(1, sizeof(SsaNode));
node->code = code;
node->mode = mode;
- node->dest.symid = 0;
- node->dest.symver = 0;
+ SSA_VAR(node).symid = 0;
+ SSA_VAR(node).symver = 0;
return node;
}
else
{
node = ssa_node(IDENT, MODE_VAR);
- node->ret_type = sym->type;
- node->left_type = sym->type;
- node->right_type = sym->type;
+ node->type = sym->type;
node->loaded = !sym->global;
- node->dest.symid = index;
- node->dest.symver = sym->version;
- node->left.var.symid = index;
- node->left.var.symver = sym->version;
+ SSA_VAR(node).symid = index;
+ SSA_VAR(node).symver = sym->version;
}
return node;
}
{
(void)p;
SsaNode* node = ssa_node(BOOL, MODE_CONST);
- node->ret_type = &BoolType;
- node->left_type = &BoolType;
- node->left.val.i = val;
+ node->type = &BoolType;
+ SSA_VAL(node).i = val;
return node;
}
{
(void)p;
SsaNode* node = ssa_node(INT, MODE_CONST);
- node->ret_type = &IntType;
- node->left_type = &IntType;
- node->left.val.i = val;
+ node->type = &IntType;
+ SSA_VAL(node).i = val;
return node;
}
{
(void)p;
SsaNode* node = ssa_node(REAL, MODE_CONST);
- node->ret_type = &RealType;
- node->left_type = &RealType;
- node->left.val.f = val;
+ node->type = &RealType;
+ SSA_VAL(node).f = val;
return node;
}
{
load(p, value);
SsaNode* node = ssa_node(STORE, MODE_MEMORY);
- node->ret_type = dest->ret_type;
- node->left_type = dest->ret_type;
- node->dest = dest->left.var;
+ node->type = dest->type;
+ node->left = value;
+ SSA_VAR(node) = SSA_VAR(dest);
- if (value->mode == MODE_CONST)
+ if (!symbol_getbyid(p, SSA_VAR(node).symid)->global)
{
- node->lconst = 1;
- node->left = value->left;
- }
- else
- {
- node->left.var = value->dest;
- }
-
- if (!symbol_getbyid(p, node->dest.symid)->global)
- {
- node->dest.symver = phi_add(p, node->dest);
+ SSA_VAR(node).symver = phi_add(p, SSA_VAR(node));
}
ssa_block_add(p->curr_block, node);
node->loaded = 1;
SsaNode* ssa_index(Parser* p, SsaNode* array, SsaNode* index)
{
-// load(p, array);
load(p, index);
SsaNode* node = ssa_node('[', MODE_MEMORY);
- node->ret_type = array->ret_type->base;
- node->left_type = array->ret_type;
- node->left = array->left;
-
-// if (index->mode == MODE_CONST)
-// {
-// node->rconst = 1;
-// node->right = index->left;
-// }
-// else
- {
- node->right.var = index->dest;
- }
-
+ node->type = array->type->base;
+ node->left = array;
+ node->right = index;
return node;
}
{
cond = load(p, cond);
SsaNode* node = ssa_node(IF, MODE_CTRL);
- node->ret_type = &VoidType;
- node->left_type = &BoolType;
- node->left.block = br1;
- node->right.block = br2;
+ node->left = cond;
+ SSA_LBLK(node) = br1;
+ SSA_RBLK(node) = br2;
node = load(p, node);
- node->dest = cond->dest;
+ SSA_VAR(node) = SSA_VAR(cond); // TODO: unnecessary?
return node;
}
{
load(p, expr);
}
- node->ret_type = expr->ret_type;
- node->left_type = expr->ret_type;
+ node->type = expr->type;
node = load(p, node);
- node->dest = expr->dest;
+ SSA_VAR(node) = SSA_VAR(expr);
}
else
{
- node->ret_type = &VoidType;
- node->left_type = &VoidType;
+ node->type = &VoidType;
node = load(p, node);
}
return node;
SsaNode* ssa_branch(Parser* p, SsaBlock* br)
{
SsaNode* node = ssa_node(BRANCH, MODE_CTRL);
- node->left.block = br;
+ SSA_LBLK(node) = br;
ssa_block_add(p->curr_block, node);
node->loaded = 1;
return node;
left = load(p, left);
right = load(p, right);
node = ssa_node(op, MODE_BINOP);
-
- if (left->mode == MODE_CONST)
- {
- node->lconst = 1;
- node->left = left->left;
- node->right.var = right->dest;
- }
- else if (right->mode == MODE_CONST)
- {
- node->rconst = 1;
- node->left.var = left->dest;
- node->right = right->left;
- }
- else
- {
- node->left.var = left->dest;
- node->right.var = right->dest;
- }
+ node->left = load(p, left);
+ node->right = load(p, right);
/* set the result type appropriately */
- node->ret_type = left->ret_type;
- node->left_type = left->ret_type;
+ node->type = left->type;
/* comparison ops are handled specially */
switch (op)
case LTEQ:
case '>':
case GTEQ:
- node->ret_type = &BoolType;
+ node->type = &BoolType;
break;
}
}
{
operand = load(p, operand);
node = ssa_node(op, MODE_UNOP);
- node->ret_type = operand->ret_type;
- node->left_type = operand->ret_type;
- node->left.var = operand->dest;
+ node->type = operand->type;
+ node->left = operand;
}
return node;
}
static SsaNode* const_binop(int op, SsaNode* a, SsaNode* b)
{
- if (a->ret_type->form == FORM_INT || a->ret_type->form == FORM_BOOL)
+ if (a->type->form == FORM_INT || a->type->form == FORM_BOOL)
{
switch (op)
{
- case '+': a->left.val.i = a->left.val.i + b->left.val.i; break;
- case '-': a->left.val.i = a->left.val.i - b->left.val.i; break;
- case '*': a->left.val.i = a->left.val.i * b->left.val.i; break;
- case '/': a->left.val.i = a->left.val.i / b->left.val.i; break;
- case '%': a->left.val.i = a->left.val.i % b->left.val.i; break;
- case AND: a->left.val.i = a->left.val.i && b->left.val.i; break;
- case OR: a->left.val.i = a->left.val.i || b->left.val.i; break;
+ case '+': SSA_LVAL(a).i = SSA_LVAL(a).i + SSA_LVAL(b).i; break;
+ case '-': SSA_LVAL(a).i = SSA_LVAL(a).i - SSA_LVAL(b).i; break;
+ case '*': SSA_LVAL(a).i = SSA_LVAL(a).i * SSA_LVAL(b).i; break;
+ case '/': SSA_LVAL(a).i = SSA_LVAL(a).i / SSA_LVAL(b).i; break;
+ case '%': SSA_LVAL(a).i = SSA_LVAL(a).i % SSA_LVAL(b).i; break;
+ case AND: SSA_LVAL(a).i = SSA_LVAL(a).i && SSA_LVAL(b).i; break;
+ case OR: SSA_LVAL(a).i = SSA_LVAL(a).i || SSA_LVAL(b).i; break;
case EQ:
puts("EQ");
- a->left.val.i = a->left.val.i == b->left.val.i;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).i = SSA_LVAL(a).i == SSA_LVAL(b).i;
+ a->type = &BoolType;
break;
case NEQ:
- a->left.val.i = a->left.val.i != b->left.val.i;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).i = SSA_LVAL(a).i != SSA_LVAL(b).i;
+ a->type = &BoolType;
break;
case '<':
- a->left.val.i = a->left.val.i < b->left.val.i;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).i = SSA_LVAL(a).i < SSA_LVAL(b).i;
+ a->type = &BoolType;
break;
case LTEQ:
- a->left.val.i = a->left.val.i <= b->left.val.i;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).i = SSA_LVAL(a).i <= SSA_LVAL(b).i;
+ a->type = &BoolType;
break;
case '>':
- a->left.val.i = a->left.val.i > b->left.val.i;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).i = SSA_LVAL(a).i > SSA_LVAL(b).i;
+ a->type = &BoolType;
break;
case GTEQ:
- a->left.val.i = a->left.val.i >= b->left.val.i;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).i = SSA_LVAL(a).i >= SSA_LVAL(b).i;
+ a->type = &BoolType;
break;
default:
break;
}
}
- else if (a->ret_type->form == FORM_REAL)
+ else if (a->type->form == FORM_REAL)
{
switch (op)
{
- case '+': a->left.val.f = a->left.val.f + b->left.val.f; break;
- case '-': a->left.val.f = a->left.val.f - b->left.val.f; break;
- case '*': a->left.val.f = a->left.val.f * b->left.val.f; break;
- case '/': a->left.val.f = a->left.val.f / b->left.val.f; break;
+ case '+': SSA_LVAL(a).f = SSA_LVAL(a).f + SSA_LVAL(b).f; break;
+ case '-': SSA_LVAL(a).f = SSA_LVAL(a).f - SSA_LVAL(b).f; break;
+ case '*': SSA_LVAL(a).f = SSA_LVAL(a).f * SSA_LVAL(b).f; break;
+ case '/': SSA_LVAL(a).f = SSA_LVAL(a).f / SSA_LVAL(b).f; break;
case EQ:
- a->left.val.f = a->left.val.f == b->left.val.f;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).f = SSA_LVAL(a).f == SSA_LVAL(b).f;
+ a->type = &BoolType;
break;
case NEQ:
- a->left.val.f = a->left.val.f != b->left.val.f;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).f = SSA_LVAL(a).f != SSA_LVAL(b).f;
+ a->type = &BoolType;
break;
case '<':
- a->left.val.f = a->left.val.f < b->left.val.f;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).f = SSA_LVAL(a).f < SSA_LVAL(b).f;
+ a->type = &BoolType;
break;
case LTEQ:
- a->left.val.f = a->left.val.f <= b->left.val.f;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).f = SSA_LVAL(a).f <= SSA_LVAL(b).f;
+ a->type = &BoolType;
break;
case '>':
- a->left.val.f = a->left.val.f > b->left.val.f;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).f = SSA_LVAL(a).f > SSA_LVAL(b).f;
+ a->type = &BoolType;
break;
case GTEQ:
- a->left.val.f = a->left.val.f >= b->left.val.f;
- a->ret_type = &BoolType;
+ SSA_LVAL(a).f = SSA_LVAL(a).f >= SSA_LVAL(b).f;
+ a->type = &BoolType;
break;
default:
{
assert(!"not a left.valid form");
}
-
- a->left_type = a->ret_type;
return a;
}
static SsaNode* const_unop(int op, SsaNode* a)
{
- if (a->ret_type->form == FORM_INT)
+ if (a->type->form == FORM_INT)
{
switch (op)
{
- case '+': a->left.val.i = +a->left.val.i; break;
- case '-': a->left.val.i = -a->left.val.i; break;
+ case '+': SSA_LVAL(a).i = +SSA_LVAL(a).i; break;
+ case '-': SSA_LVAL(a).i = -SSA_LVAL(a).i; break;
default: assert(!"not a valid op"); break;
}
}
- else if (a->ret_type->form == FORM_REAL)
+ else if (a->type->form == FORM_REAL)
{
switch (op)
{
- case '+': a->left.val.f = +a->left.val.f; break;
- case '-': a->left.val.f = -a->left.val.f; break;
+ case '+': SSA_LVAL(a).f = +SSA_LVAL(a).f; break;
+ case '-': SSA_LVAL(a).f = -SSA_LVAL(a).f; break;
default: assert(!"not a valid op"); break;
}
}
- else if (a->ret_type->form == FORM_BOOL)
+ else if (a->type->form == FORM_BOOL)
{
switch (op)
{
- case NOT: a->left.val.i = !a->left.val.i; break;
+ case NOT: SSA_LVAL(a).i = !SSA_LVAL(a).i; break;
default: assert(!"not a valid op"); break;
}
}
// else
if (node->mode == MODE_VAR)
{
- node->left.var = node->dest;
- node->dest.symid = 0;
+ node->left = ssa_ident(p, 0);
+ SSA_LVAR(node) = SSA_VAR(node);
+ SSA_VAR(node).symid = 0;
node->mode = MODE_MEMORY;
node->code = LOAD;
}
- if (node->dest.symid == 0)
+ if (SSA_VAR(node).symid == 0)
{
Symbol* sym = symbol_getbyid(p, 0);
sym->version++;
- node->dest.symver = sym->version;
+ SSA_VAR(node).symver = sym->version;
}
ssa_block_add(p->curr_block, node);
node->loaded = 1;