diff options
Diffstat (limited to 'src/codegen/codegen.cpp')
| -rw-r--r-- | src/codegen/codegen.cpp | 137 |
1 files changed, 116 insertions, 21 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 9c71ea917..54ec5f2ba 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -67,16 +67,6 @@ String ssa_mangle_name(ssaGen *s, String path, String name) { } void ssa_gen_tree(ssaGen *s) { - if (v_zero == NULL) { - v_zero = ssa_make_const_int (gb_heap_allocator(), 0); - v_one = ssa_make_const_int (gb_heap_allocator(), 1); - v_zero32 = ssa_make_const_i32 (gb_heap_allocator(), 0); - v_one32 = ssa_make_const_i32 (gb_heap_allocator(), 1); - v_two32 = ssa_make_const_i32 (gb_heap_allocator(), 2); - v_false = ssa_make_const_bool(gb_heap_allocator(), false); - v_true = ssa_make_const_bool(gb_heap_allocator(), true); - } - struct ssaGlobalVariable { ssaValue *var, *init; DeclInfo *decl; @@ -85,9 +75,35 @@ void ssa_gen_tree(ssaGen *s) { ssaModule *m = &s->module; CheckerInfo *info = m->info; gbAllocator a = m->allocator; + + if (v_zero == NULL) { + v_zero = ssa_make_const_int (m->allocator, 0); + v_one = ssa_make_const_int (m->allocator, 1); + v_zero32 = ssa_make_const_i32 (m->allocator, 0); + v_one32 = ssa_make_const_i32 (m->allocator, 1); + v_two32 = ssa_make_const_i32 (m->allocator, 2); + v_false = ssa_make_const_bool(m->allocator, false); + v_true = ssa_make_const_bool(m->allocator, true); + } + + isize global_variable_max_count = 0; + + gb_for_array(i, info->entities.entries) { + auto *entry = &info->entities.entries[i]; + Entity *e = cast(Entity *)cast(uintptr)entry->key.key; + if (e->kind == Entity_Variable) { + global_variable_max_count++; + } + } + + + gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena); + defer (gb_temp_arena_memory_end(tmp)); + gbArray(ssaGlobalVariable) global_variables; - gb_array_init(global_variables, gb_heap_allocator()); - defer (gb_array_free(global_variables)); + gb_array_init_reserve(global_variables, m->tmp_allocator, global_variable_max_count); + + gb_for_array(i, info->entities.entries) { auto *entry = &info->entities.entries[i]; @@ -123,7 +139,7 @@ void ssa_gen_tree(ssaGen *s) { ExactValue v = tav->value; if (v.kind == ExactValue_String) { // NOTE(bill): The printer will fix the value correctly - g->Global.value = ssa_add_global_string_array(m, v.value_string); + // g->Global.value = ssa_add_global_string_array(m, v.value_string); } else { g->Global.value = ssa_make_value_constant(a, tav->type, v); } @@ -147,6 +163,8 @@ void ssa_gen_tree(ssaGen *s) { } if (pd->foreign_name.len > 0) { name = pd->foreign_name; + } else if (pd->link_name.len > 0) { + name = pd->link_name; } ssaValue *p = ssa_make_value_procedure(a, m, e, e->type, decl->type_expr, body, name); @@ -171,7 +189,18 @@ void ssa_gen_tree(ssaGen *s) { ssaDebugInfo *compile_unit = m->debug_info.entries[0].value; GB_ASSERT(compile_unit->kind == ssaDebugInfo_CompileUnit); ssaDebugInfo *all_procs = ssa_alloc_debug_info(m->allocator, ssaDebugInfo_AllProcs); - gb_array_init(all_procs->AllProcs.procs, gb_heap_allocator()); + + isize all_proc_max_count = 0; + gb_for_array(i, m->debug_info.entries) { + auto *entry = &m->debug_info.entries[i]; + ssaDebugInfo *di = entry->value; + di->id = i; + if (di->kind == ssaDebugInfo_Proc) { + all_proc_max_count++; + } + } + + gb_array_init_reserve(all_procs->AllProcs.procs, m->allocator, all_proc_max_count); map_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped compile_unit->CompileUnit.all_procs = all_procs; @@ -250,10 +279,12 @@ void ssa_gen_tree(ssaGen *s) { // Useful types Type *t_int_ptr = make_type_pointer(a, t_int); + Type *t_i64_ptr = make_type_pointer(a, t_i64); Type *t_bool_ptr = make_type_pointer(a, t_bool); Type *t_string_ptr = make_type_pointer(a, t_string); Type *t_type_info_ptr_ptr = make_type_pointer(a, t_type_info_ptr); - + Type *t_i64_slice_ptr = make_type_pointer(a, make_type_slice(a, t_i64)); + Type *t_string_slice_ptr = make_type_pointer(a, make_type_slice(a, t_string)); auto get_type_info_ptr = [](ssaProcedure *proc, ssaValue *type_info_data, Type *type) -> ssaValue * { return ssa_emit_struct_gep(proc, type_info_data, @@ -302,12 +333,12 @@ void ssa_gen_tree(ssaGen *s) { case Basic_i16: case Basic_i32: case Basic_i64: - case Basic_i128: + // case Basic_i128: case Basic_u8: case Basic_u16: case Basic_u32: case Basic_u64: - case Basic_u128: + // case Basic_u128: case Basic_int: case Basic_uint: { tag = ssa_add_local_generated(proc, t_type_info_integer); @@ -467,8 +498,72 @@ void ssa_gen_tree(ssaGen *s) { if (enum_base == NULL) { enum_base = t_int; } - ssaValue *gep = get_type_info_ptr(proc, type_info_data, enum_base); - ssa_emit_store(proc, ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr), gep); + ssaValue *base = ssa_emit_struct_gep(proc, tag, v_zero32, t_type_info_ptr_ptr); + ssa_emit_store(proc, base, get_type_info_ptr(proc, type_info_data, enum_base)); + + if (t->Record.other_field_count > 0) { + Entity **fields = t->Record.other_fields; + isize count = t->Record.other_field_count; + ssaValue *value_array = NULL; + ssaValue *name_array = NULL; + + + { + Token token = {Token_Identifier}; + i32 id = cast(i32)entry_index; + char name_base[] = "__$enum_values"; + isize name_len = gb_size_of(name_base) + 10; + token.string.text = gb_alloc_array(a, u8, name_len); + token.string.len = gb_snprintf(cast(char *)token.string.text, name_len, + "%s-%d", name_base, id)-1; + Entity *e = make_entity_variable(a, NULL, token, make_type_array(a, t_i64, count)); + value_array = ssa_make_value_global(a, e, NULL); + value_array->Global.is_private = true; + ssa_module_add_value(m, e, value_array); + map_set(&m->members, hash_string(token.string), value_array); + } + { + Token token = {Token_Identifier}; + i32 id = cast(i32)entry_index; + char name_base[] = "__$enum_names"; + isize name_len = gb_size_of(name_base) + 10; + token.string.text = gb_alloc_array(a, u8, name_len); + token.string.len = gb_snprintf(cast(char *)token.string.text, name_len, + "%s-%d", name_base, id)-1; + Entity *e = make_entity_variable(a, NULL, token, make_type_array(a, t_string, count)); + name_array = ssa_make_value_global(a, e, NULL); + name_array->Global.is_private = true; + ssa_module_add_value(m, e, name_array); + map_set(&m->members, hash_string(token.string), name_array); + } + + for (isize i = 0; i < count; i++) { + ssaValue *value_gep = ssa_emit_struct_gep(proc, value_array, i, t_i64_ptr); + ssaValue *name_gep = ssa_emit_struct_gep(proc, name_array, i, t_string_ptr); + + ssa_emit_store(proc, value_gep, ssa_make_const_i64(a, fields[i]->Constant.value.value_integer)); + ssa_emit_store(proc, name_gep, ssa_emit_global_string(proc, fields[i]->token.string)); + } + + ssaValue *v_count = ssa_make_const_int(a, count); + + + ssaValue *values = ssa_emit_struct_gep(proc, tag, v_one32, t_i64_slice_ptr); + ssaValue *names = ssa_emit_struct_gep(proc, tag, v_two32, t_string_slice_ptr); + ssaValue *value_slice = ssa_add_local_generated(proc, type_deref(t_i64_slice_ptr)); + ssaValue *name_slice = ssa_add_local_generated(proc, type_deref(t_string_slice_ptr)); + + ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, v_zero32, t_i64_ptr), ssa_array_elem(proc, value_array)); + ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, v_one32, t_int_ptr), v_count); + ssa_emit_store(proc, ssa_emit_struct_gep(proc, value_slice, v_two32, t_int_ptr), v_count); + + ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, v_zero32, t_string_ptr), ssa_array_elem(proc, name_array)); + ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, v_one32, t_int_ptr), v_count); + ssa_emit_store(proc, ssa_emit_struct_gep(proc, name_slice, v_two32, t_int_ptr), v_count); + + ssa_emit_store(proc, values, ssa_emit_load(proc, value_slice)); + ssa_emit_store(proc, names, ssa_emit_load(proc, name_slice)); + } } break; } } break; @@ -515,10 +610,10 @@ void ssa_gen_tree(ssaGen *s) { ssaValue *variadic = ssa_emit_struct_gep(proc, tag, v_two32, t_bool_ptr); if (t->Proc.params) { - ssa_emit_store(proc, params, get_type_info_ptr(proc, type_info_data, 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, 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)); |