diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-09-13 12:11:52 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-09-13 14:04:05 +0100 |
| commit | 817ae643c5a469bf2f237525086288a2632fa500 (patch) | |
| tree | 7d6e012b11bd76aeb62898f7311bd7bbeeaea256 /src/codegen | |
| parent | 59fb74d2a2706898cca60e35874ecd2477202e71 (diff) | |
Remove len(), cap() and replace with selectors; fix defer in match
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/codegen.cpp | 16 | ||||
| -rw-r--r-- | src/codegen/print_llvm.cpp | 2 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 156 |
3 files changed, 65 insertions, 109 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 4df5daccf..888df4a1a 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -330,6 +330,13 @@ void ssa_gen_tree(ssaGen *s) { case TypeRecord_Struct: { tag = ssa_add_local_generated(proc, t_type_info_struct); + { + ssaValue *packed = ssa_make_const_bool(a, t->Record.struct_is_packed); + ssaValue *ordered = ssa_make_const_bool(a, t->Record.struct_is_ordered); + ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_one32, t_bool_ptr), packed); + ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_two32, t_bool_ptr), ordered); + } + ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Record.field_count, &type_info_member_index); type_set_offsets(m->sizes, a, t); // NOTE(bill): Just incase the offsets have not been set yet @@ -456,9 +463,12 @@ void ssa_gen_tree(ssaGen *s) { ssaValue *results = ssa_emit_struct_gep(proc, tag, v_one32, t_type_info_ptr_ptr); ssaValue *variadic = ssa_emit_struct_gep(proc, tag, v_two32, t_bool_ptr); - - ssa_emit_store(proc, params, get_type_info_ptr(proc, type_info_data, t->Proc.params)); - ssa_emit_store(proc, results, get_type_info_ptr(proc, type_info_data, t->Proc.results)); + if (t->Proc.params) { + ssa_emit_store(proc, params, get_type_info_ptr(proc, type_info_data, t->Proc.params)); + } + if (t->Proc.results) { + ssa_emit_store(proc, results, get_type_info_ptr(proc, type_info_data, t->Proc.results)); + } ssa_emit_store(proc, variadic, ssa_make_const_bool(a, t->Proc.variadic)); // TODO(bill): Type_Info for procedures diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 0bff5b564..7ec3b369d 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -121,7 +121,7 @@ void ssa_print_encoded_local(ssaFileBuffer *f, String name) { void ssa_print_encoded_global(ssaFileBuffer *f, String name, b32 global_scope = false) { ssa_fprintf(f, "@"); - if (!global_scope) { + if (!global_scope && !are_strings_equal(name, make_string("main"))) { ssa_fprintf(f, "."); } ssa_print_escape_string(f, name, true); diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index ee4b33119..f1e992d7b 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -1116,10 +1116,16 @@ ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, S e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, type)); } break; + case Basic_string: + e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, sel.entity->type)); + break; + default: GB_PANIC("un-gep-able type"); break; } + } else if (type->kind == Type_Slice) { + e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, sel.entity->type)); } else { GB_PANIC("un-gep-able type"); } @@ -1159,10 +1165,16 @@ ssaValue *ssa_emit_deep_field_ev(ssaProcedure *proc, Type *type, ssaValue *e, Se e = ssa_emit_struct_ev(proc, e, index, type); } break; + case Basic_string: + e = ssa_emit_struct_ev(proc, e, index, sel.entity->type); + break; + default: GB_PANIC("un-ev-able type"); break; } + } else if (type->kind == Type_Slice) { + e = ssa_emit_struct_gep(proc, e, index, make_type_pointer(proc->module->allocator, sel.entity->type)); } else { GB_PANIC("un-ev-able type"); } @@ -1194,6 +1206,9 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) { } } } + if (entry_index < 0) { + gb_printf_err("%s\n", type_to_string(type)); + } GB_ASSERT(entry_index >= 0); return entry_index; } @@ -1599,7 +1614,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg ssaValue *result = ssa_add_local_generated(proc, t_any); ssaValue *data = NULL; - if (false && value->kind == ssaValue_Instr && + if (value->kind == ssaValue_Instr && value->Instr.kind == ssaInstr_Load) { // NOTE(bill): Addressable value data = value->Instr.Load.address; @@ -1704,37 +1719,16 @@ void ssa_array_bounds_check(ssaProcedure *proc, Token token, ssaValue *index, ss if ((proc->module->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) { return; } - ssa_emit_comment(proc, make_string("ArrayBoundsCheck")); - index = ssa_emit_conv(proc, index, t_int); - len = ssa_emit_conv(proc, len, t_int); - - Token le = {Token_LtEq}; - Token lt = {Token_Lt}; - Token cmp_and = {Token_And}; // NOTE(bill): Doesn't need to be logical - ssaValue *c0 = ssa_emit_comp(proc, le, v_zero, index); - ssaValue *c1 = ssa_emit_comp(proc, lt, index, len); - ssaValue *cond = ssa_emit_comp(proc, cmp_and, c0, c1); - - ssaBlock *then = ssa_add_block(proc, NULL, make_string("abc.then")); - ssaBlock *done = ssa__make_block(proc, NULL, make_string("abc.done")); - - ssa_emit_if(proc, cond, done, then); - proc->curr_block = then; - gbAllocator a = proc->module->allocator; ssaValue **args = gb_alloc_array(a, ssaValue *, 5); args[0] = ssa_emit_global_string(proc, token.pos.file); args[1] = ssa_make_const_int(a, token.pos.line); args[2] = ssa_make_const_int(a, token.pos.column); - args[3] = index; - args[4] = len; + args[3] = ssa_emit_conv(proc, index, t_int); + args[4] = ssa_emit_conv(proc, len, t_int); ssa_emit_global_call(proc, "__bounds_check_error", args, 5); - - ssa_emit_jump(proc, done); - gb_array_append(proc->blocks, done); - proc->curr_block = done; } void ssa_slice_bounds_check(ssaProcedure *proc, Token token, ssaValue *low, ssaValue *high, ssaValue *max, b32 is_substring) { @@ -1742,43 +1736,20 @@ void ssa_slice_bounds_check(ssaProcedure *proc, Token token, ssaValue *low, ssaV return; } - low = ssa_emit_conv(proc, low, t_int); - high = ssa_emit_conv(proc, high, t_int); - max = ssa_emit_conv(proc, max, t_int); - - Token le = {Token_LtEq}; - Token cmp_and = {Token_And}; // NOTE(bill): Doesn't need to be logical - ssaValue *c0 = ssa_emit_comp(proc, le, v_zero, low); - ssaValue *c1 = ssa_emit_comp(proc, le, low, high); - ssaValue *c2 = ssa_emit_comp(proc, le, high, max); - ssaValue *cond = NULL; - cond = ssa_emit_comp(proc, cmp_and, c0, c1); - cond = ssa_emit_comp(proc, cmp_and, cond, c2); - - ssaBlock *then = ssa_add_block(proc, NULL, make_string("seb.then")); - ssaBlock *done = ssa__make_block(proc, NULL, make_string("seb.done")); - - ssa_emit_if(proc, cond, done, then); - proc->curr_block = then; - gbAllocator a = proc->module->allocator; ssaValue **args = gb_alloc_array(a, ssaValue *, 6); args[0] = ssa_emit_global_string(proc, token.pos.file); args[1] = ssa_make_const_int(a, token.pos.line); args[2] = ssa_make_const_int(a, token.pos.column); - args[3] = low; - args[4] = high; - args[5] = max; + args[3] = ssa_emit_conv(proc, low, t_int); + args[4] = ssa_emit_conv(proc, high, t_int); + args[5] = ssa_emit_conv(proc, max, t_int); if (!is_substring) { ssa_emit_global_call(proc, "__slice_expr_error", args, 6); } else { ssa_emit_global_call(proc, "__substring_expr_error", args, 5); } - - ssa_emit_jump(proc, done); - gb_array_append(proc->blocks, done); - proc->curr_block = done; } @@ -2109,26 +2080,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue return ssa_emit_load(proc, slice); } break; - case BuiltinProc_delete: { - ssa_emit_comment(proc, make_string("delete")); - // delete :: proc(ptr: ^Type) - // delete :: proc(slice: []Type) - gbAllocator allocator = proc->module->allocator; - - ssaValue *value = ssa_build_expr(proc, ce->args[0]); - - if (is_type_slice(ssa_type(value))) { - Type *etp = get_base_type(ssa_type(value)); - etp = make_type_pointer(allocator, etp->Slice.elem); - value = ssa_emit(proc, ssa_make_instr_extract_value(proc, value, 0, etp)); - } - - ssaValue **args = gb_alloc_array(allocator, ssaValue *, 1); - args[0] = ssa_emit_conv(proc, value, t_rawptr, true); - return ssa_emit_global_call(proc, "dealloc", args, 1); - } break; - - case BuiltinProc_assert: { ssa_emit_comment(proc, make_string("assert")); ssaValue *cond = ssa_build_expr(proc, ce->args[0]); @@ -2174,25 +2125,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue return NULL; } break; - case BuiltinProc_len: { - ssa_emit_comment(proc, make_string("len")); - // len :: proc(v: Type) -> int - // NOTE(bill): len of an array is a constant expression - ssaValue *v = ssa_build_expr(proc, ce->args[0]); - Type *t = get_base_type(ssa_type(v)); - if (t == t_string) - return ssa_string_len(proc, v); - else if (t->kind == Type_Slice) - return ssa_slice_len(proc, v); - } break; - case BuiltinProc_cap: { - ssa_emit_comment(proc, make_string("cap")); - // cap :: proc(v: Type) -> int - // NOTE(bill): cap of an array is a constant expression - ssaValue *v = ssa_build_expr(proc, ce->args[0]); - Type *t = get_base_type(ssa_type(v)); - return ssa_slice_cap(proc, v); - } break; case BuiltinProc_copy: { ssa_emit_comment(proc, make_string("copy")); // copy :: proc(dst, src: []Type) -> int @@ -3393,9 +3325,15 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { gb_array_append(proc->blocks, body); } proc->curr_block = body; + + // TODO(bill): Handle fallthrough scope exit correctly + proc->scope_index++; ssa_push_target_list(proc, done, NULL, fall); ssa_build_stmt_list(proc, cc->stmts); + ssa_emit_defer_stmts(proc, ssaDefer_Default, body); ssa_pop_target_list(proc); + proc->scope_index--; + ssa_emit_jump(proc, done); proc->curr_block = next_cond; } @@ -3404,9 +3342,14 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { ssa_emit_jump(proc, default_block); gb_array_append(proc->blocks, default_block); proc->curr_block = default_block; + + // TODO(bill): Handle fallthrough scope exit correctly + proc->scope_index++; ssa_push_target_list(proc, done, NULL, default_fall); ssa_build_stmt_list(proc, default_stmts); + ssa_emit_defer_stmts(proc, ssaDefer_Default, default_block); ssa_pop_target_list(proc); + proc->scope_index--; } ssa_emit_jump(proc, done); @@ -3490,9 +3433,14 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { gb_array_append(proc->blocks, body); proc->curr_block = body; + + proc->scope_index++; ssa_push_target_list(proc, done, NULL, NULL); ssa_build_stmt_list(proc, cc->stmts); + ssa_emit_defer_stmts(proc, ssaDefer_Default, body); ssa_pop_target_list(proc); + proc->scope_index--; + ssa_emit_jump(proc, done); proc->curr_block = next_cond; } @@ -3501,9 +3449,13 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { ssa_emit_jump(proc, default_block); gb_array_append(proc->blocks, default_block); proc->curr_block = default_block; + + proc->scope_index++; ssa_push_target_list(proc, done, NULL, NULL); ssa_build_stmt_list(proc, default_stmts); + ssa_emit_defer_stmts(proc, ssaDefer_Default, default_block); ssa_pop_target_list(proc); + proc->scope_index--; } ssa_emit_jump(proc, done); @@ -3513,24 +3465,18 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { case_ast_node(bs, BranchStmt, node); ssaBlock *block = NULL; + #define branch_case(x) case GB_JOIN2(Token_, x): \ + for (ssaTargetList *t = proc->target_list; t != NULL && block == NULL; t = t->prev) { \ + block = GB_JOIN3(t->, x, _); \ + } break switch (bs->token.kind) { - case Token_break: { - for (ssaTargetList *t = proc->target_list; t != NULL && block == NULL; t = t->prev) { - block = t->break_; - } - } break; - case Token_continue: { - for (ssaTargetList *t = proc->target_list; t != NULL && block == NULL; t = t->prev) { - block = t->continue_; - } - } break; - case Token_fallthrough: { - for (ssaTargetList *t = proc->target_list; t != NULL && block == NULL; t = t->prev) { - block = t->fallthrough_; - } - } break; + branch_case(break); + branch_case(continue); + branch_case(fallthrough); } - if (block != NULL && bs->token.kind != Token_fallthrough) { + // TODO(bill): Handle fallthrough scope exit correctly + // if (block != NULL && bs->token.kind != Token_fallthrough) { + if (block != NULL) { ssa_emit_defer_stmts(proc, ssaDefer_Branch, block); } switch (bs->token.kind) { |