aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/codegen.cpp6
-rw-r--r--src/codegen/print_llvm.cpp50
-rw-r--r--src/codegen/ssa.cpp345
3 files changed, 259 insertions, 142 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp
index 95727e519..377a4eaee 100644
--- a/src/codegen/codegen.cpp
+++ b/src/codegen/codegen.cpp
@@ -69,7 +69,6 @@ String ssa_mangle_name(ssaGen *s, String path, String name) {
void ssa_gen_tree(ssaGen *s) {
-
ssaModule *m = &s->module;
CheckerInfo *info = m->info;
gbAllocator a = m->allocator;
@@ -677,12 +676,7 @@ void ssa_gen_tree(ssaGen *s) {
ssa_build_proc(m->procs[i], m->procs[i]->Proc.parent);
}
-
-
-
// m->layout = make_string("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64");
-
-
}
diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp
index 0d8a5e51f..cef4e8559 100644
--- a/src/codegen/print_llvm.cpp
+++ b/src/codegen/print_llvm.cpp
@@ -500,8 +500,12 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
}
void ssa_print_block_name(ssaFileBuffer *f, ssaBlock *b) {
- ssa_print_escape_string(f, b->label, false);
- ssa_fprintf(f, "-%d", b->id);
+ if (b != NULL) {
+ ssa_print_escape_string(f, b->label, false);
+ ssa_fprintf(f, "-%td", b->index);
+ } else {
+ ssa_fprintf(f, "<INVALID-BLOCK>");
+ }
}
void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type_hint) {
@@ -648,6 +652,32 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
ssa_fprintf(f, "\n");
} break;
+ case ssaInstr_Phi: {
+ ssa_fprintf(f, "%%%d = phi ", value->id);
+ ssa_print_type(f, m, instr->Phi.type);
+ ssa_fprintf(f, " ", value->id);
+
+ for (isize i = 0; i < instr->Phi.edges.count; i++) {
+ ssaValue *edge = instr->Phi.edges[i];
+ if (i > 0) {
+ ssa_fprintf(f, ", ");
+ }
+
+ ssaBlock *block = NULL;
+ if (instr->parent != NULL &&
+ i < instr->parent->preds.count) {
+ block = instr->parent->preds[i];
+ }
+
+ ssa_fprintf(f, "[ ");
+ ssa_print_value(f, m, edge, instr->Phi.type);
+ ssa_fprintf(f, ", %%");
+ ssa_print_block_name(f, block);
+ ssa_fprintf(f, " ]");
+ }
+ ssa_fprintf(f, "\n");
+ } break;
+
case ssaInstr_ExtractValue: {
Type *et = instr->ExtractValue.elem_type;
ssa_fprintf(f, "%%%d = extractvalue ", value->id);
@@ -721,12 +751,12 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
ssa_fprintf(f, "%%%d = ", value->id);
- if (gb_is_between(bo->op.kind, Token__ComparisonBegin+1, Token__ComparisonEnd-1)) {
+ if (gb_is_between(bo->op, Token__ComparisonBegin+1, Token__ComparisonEnd-1)) {
if (is_type_string(elem_type)) {
ssa_fprintf(f, "call ");
ssa_print_type(f, m, t_bool);
char *runtime_proc = "";
- switch (bo->op.kind) {
+ switch (bo->op) {
case Token_CmpEq: runtime_proc = "__string_eq"; break;
case Token_NotEq: runtime_proc = "__string_ne"; break;
case Token_Lt: runtime_proc = "__string_lt"; break;
@@ -750,7 +780,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
} else if (is_type_float(elem_type)) {
ssa_fprintf(f, "fcmp ");
- switch (bo->op.kind) {
+ switch (bo->op) {
case Token_CmpEq: ssa_fprintf(f, "oeq"); break;
case Token_NotEq: ssa_fprintf(f, "one"); break;
case Token_Lt: ssa_fprintf(f, "olt"); break;
@@ -760,15 +790,15 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
}
} else {
ssa_fprintf(f, "icmp ");
- if (bo->op.kind != Token_CmpEq &&
- bo->op.kind != Token_NotEq) {
+ if (bo->op != Token_CmpEq &&
+ bo->op != Token_NotEq) {
if (is_type_unsigned(elem_type)) {
ssa_fprintf(f, "u");
} else {
ssa_fprintf(f, "s");
}
}
- switch (bo->op.kind) {
+ switch (bo->op) {
case Token_CmpEq: ssa_fprintf(f, "eq"); break;
case Token_NotEq: ssa_fprintf(f, "ne"); break;
case Token_Lt: ssa_fprintf(f, "lt"); break;
@@ -781,7 +811,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
if (is_type_float(elem_type))
ssa_fprintf(f, "f");
- switch (bo->op.kind) {
+ switch (bo->op) {
case Token_Add: ssa_fprintf(f, "add"); break;
case Token_Sub: ssa_fprintf(f, "sub"); break;
case Token_And: ssa_fprintf(f, "and"); break;
@@ -800,7 +830,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
else ssa_fprintf(f, "s");
}
- switch (bo->op.kind) {
+ switch (bo->op) {
case Token_Quo: ssa_fprintf(f, "div"); break;
case Token_Mod: ssa_fprintf(f, "rem"); break;
}
diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp
index 5875c4b35..7f0f18f79 100644
--- a/src/codegen/ssa.cpp
+++ b/src/codegen/ssa.cpp
@@ -69,7 +69,7 @@ struct ssaModule {
struct ssaBlock {
- i32 id;
+ isize index;
AstNode *node;
Scope *scope;
isize scope_index;
@@ -266,12 +266,12 @@ struct ssaInstr {
ssaValue *false_value;
} Select;
struct {
- String comment;
Array<ssaValue *> edges;
+ Type *type;
} Phi;
struct {
Type *type;
- Token op;
+ TokenKind op;
ssaValue *left, *right;
} BinaryOp;
struct {
@@ -513,6 +513,8 @@ Type *ssa_type(ssaInstr *instr) {
return instr->Load.type;
case ssaInstr_GetElementPtr:
return instr->GetElementPtr.result_type;
+ case ssaInstr_Phi:
+ return instr->Phi.type;
case ssaInstr_ExtractValue:
return instr->ExtractValue.result_type;
case ssaInstr_InsertValue:
@@ -742,7 +744,7 @@ ssaValue *ssa_make_instr_insert_value(ssaProcedure *p, ssaValue *value, ssaValue
}
-ssaValue *ssa_make_instr_binary_op(ssaProcedure *p, Token op, ssaValue *left, ssaValue *right, Type *type) {
+ssaValue *ssa_make_instr_binary_op(ssaProcedure *p, TokenKind op, ssaValue *left, ssaValue *right, Type *type) {
ssaValue *v = ssa_alloc_instr(p, ssaInstr_BinaryOp);
ssaInstr *i = &v->Instr;
i->BinaryOp.op = op;
@@ -761,6 +763,14 @@ ssaValue *ssa_make_instr_br(ssaProcedure *p, ssaValue *cond, ssaBlock *true_bloc
return v;
}
+ssaValue *ssa_make_instr_phi(ssaProcedure *p, Array<ssaValue *> edges, Type *type) {
+ ssaValue *v = ssa_alloc_instr(p, ssaInstr_Phi);
+ ssaInstr *i = &v->Instr;
+ i->Phi.edges = edges;
+ i->Phi.type = type;
+ return v;
+}
+
ssaValue *ssa_make_instr_unreachable(ssaProcedure *p) {
ssaValue *v = ssa_alloc_instr(p, ssaInstr_Unreachable);
return v;
@@ -1065,7 +1075,7 @@ Type *ssa_addr_type(ssaAddr lval) {
return NULL;
}
-ssaBlock *ssa__make_block(ssaProcedure *proc, AstNode *node, String label) {
+ssaBlock *ssa_add_block(ssaProcedure *proc, AstNode *node, char *label) {
Scope *scope = NULL;
if (node != NULL) {
Scope **found = map_get(&proc->module->info->scopes, hash_pointer(node));
@@ -1076,12 +1086,8 @@ ssaBlock *ssa__make_block(ssaProcedure *proc, AstNode *node, String label) {
}
}
- ssaValue *block = ssa_make_value_block(proc, node, scope, label);
- return &block->Block;
-}
-
-ssaBlock *ssa_add_block(ssaProcedure *proc, AstNode *node, String label) {
- ssaBlock *block = ssa__make_block(proc, node, label);
+ ssaValue *value = ssa_make_value_block(proc, node, scope, make_string(label));
+ ssaBlock *block = &value->Block;
array_add(&proc->blocks, block);
return block;
}
@@ -1091,13 +1097,12 @@ void ssa_emit_no_op(ssaProcedure *proc);
void ssa_emit_jump(ssaProcedure *proc, ssaBlock *block);
void ssa_build_defer_stmt(ssaProcedure *proc, ssaDefer d) {
- ssaBlock *b = ssa__make_block(proc, NULL, make_string("defer"));
+ ssaBlock *b = ssa_add_block(proc, NULL, "defer");
// NOTE(bill): The prev block may defer injection before it's terminator
ssaInstr *last_instr = ssa_get_last_instr(proc->curr_block);
if (last_instr == NULL || !ssa_is_instr_terminating(last_instr)) {
ssa_emit_jump(proc, b);
}
- array_add(&proc->blocks, b);
proc->curr_block = b;
ssa_emit_comment(proc, make_string("defer"));
if (d.kind == ssaDefer_Node) {
@@ -1228,8 +1233,8 @@ void ssa_begin_procedure_body(ssaProcedure *proc) {
array_init(&proc->defer_stmts, gb_heap_allocator());
array_init(&proc->children, gb_heap_allocator());
- proc->decl_block = ssa_add_block(proc, proc->type_expr, make_string("decls"));
- proc->entry_block = ssa_add_block(proc, proc->type_expr, make_string("entry"));
+ proc->decl_block = ssa_add_block(proc, proc->type_expr, "decls");
+ proc->entry_block = ssa_add_block(proc, proc->type_expr, "entry");
proc->curr_block = proc->entry_block;
if (proc->type->Proc.params != NULL) {
@@ -1241,6 +1246,92 @@ void ssa_begin_procedure_body(ssaProcedure *proc) {
}
}
+void ssa_remove_pred(ssaBlock *a, ssaBlock *b) {
+
+}
+
+void ssa_remove_dead_blocks(ssaProcedure *proc) {
+ isize j = 0;
+ for_array(i, proc->blocks) {
+ ssaBlock *b = proc->blocks[i];
+ if (b != NULL) {
+ // NOTE(bill): Swap order
+ b->index = j;
+ proc->blocks[j] = b;
+ j++;
+ }
+ }
+
+ proc->blocks.count = j;
+}
+
+void ssa_mark_reachable(ssaBlock *b) {
+ isize const WHITE = 0;
+ isize const BLACK = -1;
+ b->index = BLACK;
+ for_array(i, b->succs) {
+ ssaBlock *succ = b->succs[i];
+ if (succ->index == WHITE) {
+ ssa_mark_reachable(succ);
+ }
+ }
+}
+
+void ssa_remove_unreachable_blocks(ssaProcedure *proc) {
+ isize const WHITE = 0;
+ isize const BLACK = -1;
+ for_array(i, proc->blocks) {
+ proc->blocks[i]->index = WHITE;
+ }
+
+ ssa_mark_reachable(proc->blocks[0]);
+
+ for_array(i, proc->blocks) {
+ ssaBlock *b = proc->blocks[i];
+ if (b->index == WHITE) {
+ for_array(j, b->succs) {
+ ssaBlock *c = b->succs[j];
+ if (c->index == BLACK) {
+ // ssa_remove_pred(c, b);
+ }
+ }
+ // NOTE(bill): Mark as empty but don't actually free it
+ // As it's been allocated with an arena
+ proc->blocks[i] = NULL;
+ }
+ }
+ ssa_remove_dead_blocks(proc);
+}
+
+
+void ssa_optimize_blocks(ssaProcedure *proc) {
+ ssa_remove_unreachable_blocks(proc);
+
+#if 0
+ b32 changed = false;
+ do {
+ for_array(i, proc->blocks) {
+ ssaBlock *b = proc->blocks[i];
+ if (b == NULL) {
+ continue;
+ }
+
+ // if (ssa_fuse_blocks(proc, b)) {
+ // changed = true;
+ // }
+
+ if (ssa_jump_threading(proc, b)) {
+ // x -> y -> z becomes x -> z if y is just a jump
+ changed = true;
+ continue;
+ }
+ }
+ } while (changed);
+#endif
+
+ ssa_remove_dead_blocks(proc);
+}
+
void ssa_end_procedure_body(ssaProcedure *proc) {
if (proc->type->Proc.result_count == 0) {
ssa_emit_ret(proc, NULL);
@@ -1253,12 +1344,13 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
proc->curr_block = proc->decl_block;
ssa_emit_jump(proc, proc->entry_block);
+ ssa_optimize_blocks(proc);
+
// Number blocks and registers
i32 reg_id = 0;
for_array(i, proc->blocks) {
ssaBlock *b = proc->blocks[i];
- b->id = i;
for_array(j, b->instrs) {
ssaValue *value = b->instrs[j];
GB_ASSERT(value->kind == ssaValue_Instr);
@@ -1300,17 +1392,17 @@ void ssa_pop_target_list(ssaProcedure *proc) {
-ssaValue *ssa_emit_arith(ssaProcedure *proc, Token op, ssaValue *left, ssaValue *right, Type *type) {
- switch (op.kind) {
+ssaValue *ssa_emit_arith(ssaProcedure *proc, TokenKind op, ssaValue *left, ssaValue *right, Type *type) {
+ switch (op) {
case Token_AndNot: {
// NOTE(bill): x &~ y == x & (~y) == x & (y ~ -1)
// NOTE(bill): "not" `x` == `x` "xor" `-1`
ssaValue *neg = ssa_add_module_constant(proc->module, type, make_exact_value_integer(-1));
- op.kind = Token_Xor;
+ op = Token_Xor;
right = ssa_emit_arith(proc, op, right, neg, type);
GB_ASSERT(right->Instr.kind == ssaInstr_BinaryOp);
right->Instr.BinaryOp.type = type;
- op.kind = Token_And;
+ op = Token_And;
} /* fallthrough */
case Token_Add:
case Token_Sub:
@@ -1328,7 +1420,7 @@ ssaValue *ssa_emit_arith(ssaProcedure *proc, Token op, ssaValue *left, ssaValue
return ssa_emit(proc, ssa_make_instr_binary_op(proc, op, left, right, type));
}
-ssaValue *ssa_emit_comp(ssaProcedure *proc, Token op, ssaValue *left, ssaValue *right) {
+ssaValue *ssa_emit_comp(ssaProcedure *proc, TokenKind op_kind, ssaValue *left, ssaValue *right) {
Type *a = base_type(ssa_type(left));
Type *b = base_type(ssa_type(right));
@@ -1344,7 +1436,7 @@ ssaValue *ssa_emit_comp(ssaProcedure *proc, Token op, ssaValue *left, ssaValue *
if (is_type_vector(a)) {
result = make_type_vector(proc->module->allocator, t_bool, a->Vector.count);
}
- return ssa_emit(proc, ssa_make_instr_binary_op(proc, op, left, right, result));
+ return ssa_emit(proc, ssa_make_instr_binary_op(proc, op_kind, left, right, result));
}
ssaValue *ssa_emit_ptr_offset(ssaProcedure *proc, ssaValue *ptr, ssaValue *offset) {
@@ -1601,9 +1693,8 @@ ssaValue *ssa_add_local_slice(ssaProcedure *proc, Type *slice_type, ssaValue *ba
}
GB_ASSERT(max != NULL);
- Token op_sub = {Token_Sub};
- ssaValue *len = ssa_emit_arith(proc, op_sub, high, low, t_int);
- ssaValue *cap = ssa_emit_arith(proc, op_sub, max, low, t_int);
+ ssaValue *len = ssa_emit_arith(proc, Token_Sub, high, low, t_int);
+ ssaValue *cap = ssa_emit_arith(proc, Token_Sub, max, low, t_int);
ssaValue *elem = NULL;
switch (bt->kind) {
@@ -1779,8 +1870,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
// integer -> boolean
if (is_type_integer(src) && is_type_boolean(dst)) {
- Token op = {Token_NotEq};
- return ssa_emit_comp(proc, op, value, v_zero);
+ return ssa_emit_comp(proc, Token_NotEq, value, v_zero);
}
@@ -2013,9 +2103,10 @@ void ssa_build_cond(ssaProcedure *proc, AstNode *cond, ssaBlock *true_block, ssa
ssaValue *ssa_emit_logical_binary_expr(ssaProcedure *proc, AstNode *expr) {
ast_node(be, BinaryExpr, expr);
- ssaBlock *true_ = ssa_add_block(proc, NULL, make_string("logical.cmp.true"));
- ssaBlock *false_ = ssa_add_block(proc, NULL, make_string("logical.cmp.false"));
- ssaBlock *done = ssa__make_block(proc, NULL, make_string("logical.cmp.done"));
+#if 0
+ ssaBlock *true_ = ssa_add_block(proc, NULL, "logical.cmp.true");
+ ssaBlock *false_ = ssa_add_block(proc, NULL, "logical.cmp.false");
+ ssaBlock *done = ssa_add_block(proc, NULL, "logical.cmp.done");
ssaValue *result = ssa_add_local_generated(proc, t_bool);
ssa_build_cond(proc, expr, true_, false_);
@@ -2028,10 +2119,48 @@ ssaValue *ssa_emit_logical_binary_expr(ssaProcedure *proc, AstNode *expr) {
ssa_emit_store(proc, result, v_false);
ssa_emit_jump(proc, done);
- array_add(&proc->blocks, done);
proc->curr_block = done;
return ssa_emit_load(proc, result);
+#else
+ ssaBlock *rhs = ssa_add_block(proc, NULL, "logical.cmp.rhs");
+ ssaBlock *done = ssa_add_block(proc, NULL, "logical.cmp.done");
+
+ Type *type = type_of_expr(proc->module->info, expr);
+ type = default_type(type);
+
+ ssaValue *short_circuit = NULL;
+ if (be->op.kind == Token_CmpAnd) {
+ ssa_build_cond(proc, be->left, rhs, done);
+ short_circuit = v_false;
+ } else if (be->op.kind == Token_CmpOr) {
+ ssa_build_cond(proc, be->left, done, rhs);
+ short_circuit = v_true;
+ }
+
+ if (rhs->preds.count == 0) {
+ proc->curr_block = done;
+ return short_circuit;
+ }
+
+ if (done->preds.count == 0) {
+ proc->curr_block = rhs;
+ return ssa_build_expr(proc, be->right);
+ }
+
+ Array<ssaValue *> edges = {};
+ array_init(&edges, proc->module->allocator, done->preds.count+1);
+ for_array(i, done->preds) {
+ array_add(&edges, short_circuit);
+ }
+
+ proc->curr_block = rhs;
+ array_add(&edges, ssa_build_expr(proc, be->right));
+ ssa_emit_jump(proc, done);
+ proc->curr_block = done;
+
+ return ssa_emit(proc, ssa_make_instr_phi(proc, edges, type));
+#endif
}
@@ -2125,14 +2254,14 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
return ssa_build_expr(proc, ue->expr);
case Token_Sub: // NOTE(bill): -`x` == 0 - `x`
- return ssa_emit_arith(proc, ue->op, v_zero, ssa_build_expr(proc, ue->expr), tv->type);
+ return ssa_emit_arith(proc, ue->op.kind, v_zero, ssa_build_expr(proc, ue->expr), tv->type);
case Token_Not: // Boolean not
case Token_Xor: { // Bitwise not
// NOTE(bill): "not" `x` == `x` "xor" `-1`
ssaValue *left = ssa_build_expr(proc, ue->expr);
ssaValue *right = ssa_add_module_constant(proc->module, tv->type, make_exact_value_integer(-1));
- return ssa_emit_arith(proc, ue->op,
+ return ssa_emit_arith(proc, ue->op.kind,
left, right,
tv->type);
} break;
@@ -2152,7 +2281,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
case Token_AndNot:
case Token_Shl:
case Token_Shr:
- return ssa_emit_arith(proc, be->op,
+ return ssa_emit_arith(proc, be->op.kind,
ssa_build_expr(proc, be->left),
ssa_build_expr(proc, be->right),
tv->type);
@@ -2167,7 +2296,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssaValue *left = ssa_build_expr(proc, be->left);
ssaValue *right = ssa_build_expr(proc, be->right);
- ssaValue *cmp = ssa_emit_comp(proc, be->op, left, right);
+ ssaValue *cmp = ssa_emit_comp(proc, be->op.kind, left, right);
return ssa_emit_conv(proc, cmp, default_type(tv->type));
} break;
@@ -2420,8 +2549,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssa_slice_bounds_check(proc, ast_node_token(ce->args[1]), v_zero, len, cap, false);
- Token mul = {Token_Mul};
- ssaValue *slice_size = ssa_emit_arith(proc, mul, elem_size, cap, t_int);
+ ssaValue *slice_size = ssa_emit_arith(proc, Token_Mul, elem_size, cap, t_int);
ssaValue **args = gb_alloc_array(allocator, ssaValue *, 2);
args[0] = slice_size;
@@ -2445,10 +2573,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssaValue *cond = ssa_build_expr(proc, ce->args[0]);
GB_ASSERT(is_type_boolean(ssa_type(cond)));
- Token eq = {Token_CmpEq};
- cond = ssa_emit_comp(proc, eq, cond, v_false);
- ssaBlock *err = ssa_add_block(proc, NULL, make_string("builtin.assert.err"));
- ssaBlock *done = ssa__make_block(proc, NULL, make_string("builtin.assert.done"));
+ cond = ssa_emit_comp(proc, Token_CmpEq, cond, v_false);
+ ssaBlock *err = ssa_add_block(proc, NULL, "builtin.assert.err");
+ ssaBlock *done = ssa_add_block(proc, NULL, "builtin.assert.done");
ssa_emit_if(proc, cond, err, done);
proc->curr_block = err;
@@ -2471,7 +2598,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssa_emit_global_call(proc, "__assert", args, 4);
ssa_emit_jump(proc, done);
- array_add(&proc->blocks, done);
proc->curr_block = done;
return NULL;
@@ -2515,12 +2641,11 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssaValue *len_dst = ssa_slice_len(proc, dst_slice);
ssaValue *len_src = ssa_slice_len(proc, src_slice);
- Token lt = {Token_Lt};
- ssaValue *cond = ssa_emit_comp(proc, lt, len_dst, len_src);
+ ssaValue *cond = ssa_emit_comp(proc, Token_Lt, len_dst, len_src);
ssaValue *len = ssa_emit_select(proc, cond, len_dst, len_src);
- Token mul = {Token_Mul};
+
ssaValue *elem_size = ssa_make_const_int(proc->module->allocator, size_of_elem);
- ssaValue *byte_count = ssa_emit_arith(proc, mul, len, elem_size, t_int);
+ ssaValue *byte_count = ssa_emit_arith(proc, Token_Mul, len, elem_size, t_int);
ssaValue **args = gb_alloc_array(proc->module->allocator, ssaValue *, 3);
args[0] = dst;
@@ -2553,10 +2678,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
// NOTE(bill): Check if can append is possible
- Token lt = {Token_Lt};
- ssaValue *cond = ssa_emit_comp(proc, lt, len, cap);
- ssaBlock *able = ssa_add_block(proc, NULL, make_string("builtin.append.able"));
- ssaBlock *done = ssa__make_block(proc, NULL, make_string("builtin.append.done"));
+ ssaValue *cond = ssa_emit_comp(proc, Token_Lt, len, cap);
+ ssaBlock *able = ssa_add_block(proc, NULL, "builtin.append.able");
+ ssaBlock *done = ssa_add_block(proc, NULL, "builtin.append.done");
ssa_emit_if(proc, cond, able, done);
proc->curr_block = able;
@@ -2579,13 +2703,11 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssa_emit_global_call(proc, "__mem_copy", args, 3);
// Increment slice length
- Token add = {Token_Add};
- ssaValue *new_len = ssa_emit_arith(proc, add, len, v_one, t_int);
+ ssaValue *new_len = ssa_emit_arith(proc, Token_Add, len, v_one, t_int);
ssaValue *gep = ssa_emit_struct_gep(proc, slice_ptr, v_one32, t_int);
ssa_emit_store(proc, gep, new_len);
ssa_emit_jump(proc, done);
- array_add(&proc->blocks, done);
proc->curr_block = done;
return ssa_emit_conv(proc, cond, t_bool, true);
@@ -2627,12 +2749,11 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
Type *ptr_type = base_type(ssa_type(ptr_a));
GB_ASSERT(ptr_type->kind == Type_Pointer);
isize elem_size = type_size_of(proc->module->sizes, proc->module->allocator, ptr_type->Pointer.elem);
- Token sub = {Token_Sub};
- ssaValue *v = ssa_emit_arith(proc, sub, ptr_a, ptr_b, t_int);
+
+ ssaValue *v = ssa_emit_arith(proc, Token_Sub, ptr_a, ptr_b, t_int);
if (elem_size > 1) {
- Token quo = {Token_Quo};
ssaValue *ez = ssa_make_const_int(proc->module->allocator, elem_size);
- v = ssa_emit_arith(proc, quo, v, ez, t_int);
+ v = ssa_emit_arith(proc, Token_Quo, v, ez, t_int);
}
return v;
@@ -2665,8 +2786,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssaValue *x = ssa_build_expr(proc, ce->args[0]);
ssaValue *y = ssa_build_expr(proc, ce->args[1]);
Type *t = base_type(ssa_type(x));
- Token lt = {Token_Lt};
- ssaValue *cond = ssa_emit_comp(proc, lt, x, y);
+ ssaValue *cond = ssa_emit_comp(proc, Token_Lt, x, y);
return ssa_emit_select(proc, cond, x, y);
} break;
@@ -2675,21 +2795,18 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssaValue *x = ssa_build_expr(proc, ce->args[0]);
ssaValue *y = ssa_build_expr(proc, ce->args[1]);
Type *t = base_type(ssa_type(x));
- Token gt = {Token_Gt};
- ssaValue *cond = ssa_emit_comp(proc, gt, x, y);
+ ssaValue *cond = ssa_emit_comp(proc, Token_Gt, x, y);
return ssa_emit_select(proc, cond, x, y);
} break;
case BuiltinProc_abs: {
ssa_emit_comment(proc, make_string("abs"));
- Token lt = {Token_Lt};
- Token sub = {Token_Sub};
ssaValue *x = ssa_build_expr(proc, ce->args[0]);
Type *t = ssa_type(x);
- ssaValue *neg_x = ssa_emit_arith(proc, sub, v_zero, x, t);
- ssaValue *cond = ssa_emit_comp(proc, lt, x, v_zero);
+ ssaValue *neg_x = ssa_emit_arith(proc, Token_Sub, v_zero, x, t);
+ ssaValue *cond = ssa_emit_comp(proc, Token_Lt, x, v_zero);
return ssa_emit_select(proc, cond, neg_x, x);
} break;
@@ -3117,10 +3234,9 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
ssa_slice_bounds_check(proc, se->open, low, high, max, false);
- Token op_sub = {Token_Sub};
ssaValue *elem = ssa_slice_elem(proc, base);
- ssaValue *len = ssa_emit_arith(proc, op_sub, high, low, t_int);
- ssaValue *cap = ssa_emit_arith(proc, op_sub, max, low, t_int);
+ ssaValue *len = ssa_emit_arith(proc, Token_Sub, high, low, t_int);
+ ssaValue *cap = ssa_emit_arith(proc, Token_Sub, max, low, t_int);
ssaValue *slice = ssa_add_local_generated(proc, slice_type);
ssaValue *gep0 = ssa_emit_struct_gep(proc, slice, v_zero32, ssa_type(elem));
@@ -3142,10 +3258,9 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
ssa_slice_bounds_check(proc, se->open, low, high, max, false);
- Token op_sub = {Token_Sub};
ssaValue *elem = ssa_array_elem(proc, addr);
- ssaValue *len = ssa_emit_arith(proc, op_sub, high, low, t_int);
- ssaValue *cap = ssa_emit_arith(proc, op_sub, max, low, t_int);
+ ssaValue *len = ssa_emit_arith(proc, Token_Sub, high, low, t_int);
+ ssaValue *cap = ssa_emit_arith(proc, Token_Sub, max, low, t_int);
ssaValue *slice = ssa_add_local_generated(proc, slice_type);
ssaValue *gep0 = ssa_emit_struct_gep(proc, slice, v_zero32, ssa_type(elem));
@@ -3166,9 +3281,8 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
ssa_slice_bounds_check(proc, se->open, low, high, high, true);
- Token op_sub = {Token_Sub};
ssaValue *elem, *len;
- len = ssa_emit_arith(proc, op_sub, high, low, t_int);
+ len = ssa_emit_arith(proc, Token_Sub, high, low, t_int);
elem = ssa_string_elem(proc, base);
elem = ssa_emit_ptr_offset(proc, elem, low);
@@ -3231,7 +3345,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
return ssa_make_addr(NULL, NULL);
}
-void ssa_build_assign_op(ssaProcedure *proc, ssaAddr lhs, ssaValue *value, Token op) {
+void ssa_build_assign_op(ssaProcedure *proc, ssaAddr lhs, ssaValue *value, TokenKind op) {
ssaValue *old_value = ssa_lvalue_load(proc, lhs);
Type *type = ssa_type(old_value);
ssaValue *change = ssa_emit_conv(proc, value, type);
@@ -3255,13 +3369,13 @@ void ssa_build_cond(ssaProcedure *proc, AstNode *cond, ssaBlock *true_block, ssa
case_ast_node(be, BinaryExpr, cond);
if (be->op.kind == Token_CmpAnd) {
- ssaBlock *block = ssa_add_block(proc, NULL, make_string("cmp.and"));
+ ssaBlock *block = ssa_add_block(proc, NULL, "cmp.and");
ssa_build_cond(proc, be->left, block, false_block);
proc->curr_block = block;
ssa_build_cond(proc, be->right, true_block, false_block);
return;
} else if (be->op.kind == Token_CmpOr) {
- ssaBlock *block = ssa_add_block(proc, NULL, make_string("cmp.or"));
+ ssaBlock *block = ssa_add_block(proc, NULL, "cmp.or");
ssa_build_cond(proc, be->left, true_block, block);
proc->curr_block = block;
ssa_build_cond(proc, be->right, true_block, false_block);
@@ -3497,11 +3611,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_ast_node(ids, IncDecStmt, node);
ssa_emit_comment(proc, make_string("IncDecStmt"));
- Token op = ids->op;
- if (op.kind == Token_Increment) {
- op.kind = Token_Add;
- } else if (op.kind == Token_Decrement) {
- op.kind = Token_Sub;
+ TokenKind op = ids->op.kind;
+ if (op == Token_Increment) {
+ op = Token_Add;
+ } else if (op == Token_Decrement) {
+ op = Token_Sub;
}
ssaAddr lval = ssa_build_addr(proc, ids->expr);
ssaValue *one = ssa_emit_conv(proc, v_one, ssa_addr_type(lval));
@@ -3577,13 +3691,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
default: {
// NOTE(bill): Only 1 += 1 is allowed, no tuples
// +=, -=, etc
- Token op = as->op;
- i32 kind = op.kind;
- kind += Token_Add - Token_AddEq; // Convert += to +
- op.kind = cast(TokenKind)kind;
+ i32 op = cast(i32)as->op.kind;
+ op += Token_Add - Token_AddEq; // Convert += to +
ssaAddr lhs = ssa_build_addr(proc, as->lhs[0]);
ssaValue *value = ssa_build_expr(proc, as->rhs[0]);
- ssa_build_assign_op(proc, lhs, value, op);
+ ssa_build_assign_op(proc, lhs, value, cast(TokenKind)op);
} break;
}
case_end;
@@ -3658,16 +3770,16 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_ast_node(is, IfStmt, node);
ssa_emit_comment(proc, make_string("IfStmt"));
if (is->init != NULL) {
- ssaBlock *init = ssa_add_block(proc, node, make_string("if.init"));
+ ssaBlock *init = ssa_add_block(proc, node, "if.init");
ssa_emit_jump(proc, init);
proc->curr_block = init;
ssa_build_stmt(proc, is->init);
}
- ssaBlock *then = ssa_add_block(proc, node, make_string("if.then"));
- ssaBlock *done = ssa__make_block(proc, node, make_string("if.done")); // NOTE(bill): Append later
+ ssaBlock *then = ssa_add_block(proc, node, "if.then");
+ ssaBlock *done = ssa_add_block(proc, node, "if.done"); // NOTE(bill): Append later
ssaBlock *else_ = done;
if (is->else_stmt != NULL) {
- else_ = ssa_add_block(proc, is->else_stmt, make_string("if.else"));
+ else_ = ssa_add_block(proc, is->else_stmt, "if.else");
}
ssa_build_cond(proc, is->cond, then, else_);
@@ -3688,29 +3800,28 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssa_emit_jump(proc, done);
}
- array_add(&proc->blocks, done);
proc->curr_block = done;
case_end;
case_ast_node(fs, ForStmt, node);
ssa_emit_comment(proc, make_string("ForStmt"));
if (fs->init != NULL) {
- ssaBlock *init = ssa_add_block(proc, node, make_string("for.init"));
+ ssaBlock *init = ssa_add_block(proc, node, "for.init");
ssa_emit_jump(proc, init);
proc->curr_block = init;
ssa_build_stmt(proc, fs->init);
}
- ssaBlock *body = ssa_add_block(proc, node, make_string("for.body"));
- ssaBlock *done = ssa__make_block(proc, node, make_string("for.done")); // NOTE(bill): Append later
+ ssaBlock *body = ssa_add_block(proc, node, "for.body");
+ ssaBlock *done = ssa_add_block(proc, node, "for.done"); // NOTE(bill): Append later
ssaBlock *loop = body;
if (fs->cond != NULL) {
- loop = ssa_add_block(proc, node, make_string("for.loop"));
+ loop = ssa_add_block(proc, node, "for.loop");
}
ssaBlock *cont = loop;
if (fs->post != NULL) {
- cont = ssa_add_block(proc, node, make_string("for.post"));
+ cont = ssa_add_block(proc, node, "for.post");
}
ssa_emit_jump(proc, loop);
@@ -3736,7 +3847,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
}
- array_add(&proc->blocks, done);
proc->curr_block = done;
case_end;
@@ -3750,11 +3860,10 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
if (ms->tag != NULL) {
tag = ssa_build_expr(proc, ms->tag);
}
- ssaBlock *done = ssa__make_block(proc, node, make_string("match.done")); // NOTE(bill): Append later
+ ssaBlock *done = ssa_add_block(proc, node, "match.done"); // NOTE(bill): Append later
ast_node(body, BlockStmt, ms->body);
-
AstNodeArray default_stmts = {};
ssaBlock *default_fall = NULL;
ssaBlock *default_block = NULL;
@@ -3766,28 +3875,24 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
for_array(i, body->stmts) {
AstNode *clause = body->stmts[i];
ssaBlock *body = fall;
- b32 append_body = false;
-
ast_node(cc, CaseClause, clause);
if (body == NULL) {
- append_body = true;
if (cc->list.count == 0) {
- body = ssa__make_block(proc, clause, make_string("match.dflt.body"));
+ body = ssa_add_block(proc, clause, "match.dflt.body");
} else {
- body = ssa__make_block(proc, clause, make_string("match.case.body"));
+ body = ssa_add_block(proc, clause, "match.case.body");
}
}
if (append_fall && body == fall) {
append_fall = false;
- append_body = true;
}
fall = done;
if (i+1 < case_count) {
append_fall = true;
- fall = ssa__make_block(proc, clause, make_string("match.fall.body"));
+ fall = ssa_add_block(proc, clause, "match.fall.body");
}
if (cc->list.count == 0) {
@@ -3799,19 +3904,14 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
}
ssaBlock *next_cond = NULL;
- Token eq = {Token_CmpEq};
for_array(j, cc->list) {
AstNode *expr = cc->list[j];
- next_cond = ssa__make_block(proc, clause, make_string("match.case.next"));
+ next_cond = ssa_add_block(proc, clause, "match.case.next");
- ssaValue *cond = ssa_emit_comp(proc, eq, tag, ssa_build_expr(proc, expr));
+ ssaValue *cond = ssa_emit_comp(proc, Token_CmpEq, tag, ssa_build_expr(proc, expr));
ssa_emit_if(proc, cond, body, next_cond);
- array_add(&proc->blocks, next_cond);
proc->curr_block = next_cond;
}
- if (append_body) {
- array_add(&proc->blocks, body);
- }
proc->curr_block = body;
ssa_push_target_list(proc, done, NULL, fall);
@@ -3826,7 +3926,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
if (default_block != NULL) {
ssa_emit_jump(proc, default_block);
- array_add(&proc->blocks, default_block);
proc->curr_block = default_block;
ssa_push_target_list(proc, done, NULL, default_fall);
@@ -3837,7 +3936,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
}
ssa_emit_jump(proc, done);
- array_add(&proc->blocks, done);
proc->curr_block = done;
case_end;
@@ -3856,11 +3954,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssaValue *data = ssa_emit_conv(proc, parent, t_rawptr);
- ssaBlock *start_block = ssa_add_block(proc, node, make_string("type-match.case.first"));
+ ssaBlock *start_block = ssa_add_block(proc, node, "type-match.case.first");
ssa_emit_jump(proc, start_block);
proc->curr_block = start_block;
- ssaBlock *done = ssa__make_block(proc, node, make_string("type-match.done")); // NOTE(bill): Append later
+ ssaBlock *done = ssa_add_block(proc, node, "type-match.done"); // NOTE(bill): Append later
ast_node(body, BlockStmt, ms->body);
@@ -3878,12 +3976,12 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
if (cc->list.count == 0) {
// default case
default_stmts = cc->stmts;
- default_block = ssa__make_block(proc, clause, make_string("type-match.dflt.body"));
+ default_block = ssa_add_block(proc, clause, "type-match.dflt.body");
continue;
}
- ssaBlock *body = ssa__make_block(proc, clause, make_string("type-match.case.body"));
+ ssaBlock *body = ssa_add_block(proc, clause, "type-match.case.body");
Scope *scope = *map_get(&proc->module->info->scopes, hash_pointer(clause));
Entity *tag_var_entity = current_scope_lookup_entity(scope, tag_var_name);
@@ -3907,14 +4005,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
}
GB_ASSERT(index != NULL);
- ssaBlock *next_cond = ssa__make_block(proc, clause, make_string("type-match.case.next"));
- Token eq = {Token_CmpEq};
- ssaValue *cond = ssa_emit_comp(proc, eq, tag_index, index);
+ ssaBlock *next_cond = ssa_add_block(proc, clause, "type-match.case.next");
+ ssaValue *cond = ssa_emit_comp(proc, Token_CmpEq, tag_index, index);
ssa_emit_if(proc, cond, body, next_cond);
- array_add(&proc->blocks, next_cond);
proc->curr_block = next_cond;
- array_add(&proc->blocks, body);
proc->curr_block = body;
ssa_push_target_list(proc, done, NULL, NULL);
@@ -3929,7 +4024,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
if (default_block != NULL) {
ssa_emit_jump(proc, default_block);
- array_add(&proc->blocks, default_block);
proc->curr_block = default_block;
ssa_push_target_list(proc, done, NULL, NULL);
@@ -3940,7 +4034,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
}
ssa_emit_jump(proc, done);
- array_add(&proc->blocks, done);
proc->curr_block = done;
case_end;