diff options
Diffstat (limited to 'src/codegen/codegen.cpp')
| -rw-r--r-- | src/codegen/codegen.cpp | 687 |
1 files changed, 0 insertions, 687 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp deleted file mode 100644 index a6d6b404c..000000000 --- a/src/codegen/codegen.cpp +++ /dev/null @@ -1,687 +0,0 @@ -#include "ssa.cpp" -#include "print_llvm.cpp" - -struct ssaGen { - ssaModule module; - gbFile output_file; -}; - -b32 ssa_gen_init(ssaGen *s, Checker *c) { - if (global_error_collector.count != 0) { - return false; - } - - isize tc = c->parser->total_token_count; - if (tc < 2) { - return false; - } - - ssa_init_module(&s->module, c); - s->module.generate_debug_info = false; - - // TODO(bill): generate appropriate output name - int pos = cast(int)string_extension_position(c->parser->init_fullpath); - gbFileError err = gb_file_create(&s->output_file, gb_bprintf("%.*s.ll", pos, c->parser->init_fullpath.text)); - if (err != gbFileError_None) { - return false; - } - - return true; -} - -void ssa_gen_destroy(ssaGen *s) { - ssa_destroy_module(&s->module); - gb_file_close(&s->output_file); -} - -String ssa_mangle_name(ssaGen *s, String path, String name) { - // NOTE(bill): prefix names not in the init scope - // TODO(bill): make robust and not just rely on the file's name - - ssaModule *m = &s->module; - CheckerInfo *info = m->info; - gbAllocator a = m->allocator; - AstFile *file = *map_get(&info->files, hash_string(path)); - - char *str = gb_alloc_array(a, char, path.len+1); - gb_memmove(str, path.text, path.len); - str[path.len] = 0; - for (isize i = 0; i < path.len; i++) { - if (str[i] == '\\') { - str[i] = '/'; - } - } - - char const *base = gb_path_base_name(str); - char const *ext = gb_path_extension(base); - isize base_len = ext-1-base; - - isize max_len = base_len + 1 + 10 + 1 + name.len; - u8 *new_name = gb_alloc_array(a, u8, max_len); - isize new_name_len = gb_snprintf( - cast(char *)new_name, max_len, - "%.*s-%u.%.*s", - cast(int)base_len, base, - file->id, - LIT(name)); - - return make_string(new_name, new_name_len-1); -} - - -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; - Entity *entry_point = NULL; - - for_array(i, info->entities.entries) { - auto *entry = &info->entities.entries[i]; - Entity *e = cast(Entity *)cast(uintptr)entry->key.key; - String name = e->token.string; - if (e->kind == Entity_Variable) { - global_variable_max_count++; - } else if (e->kind == Entity_Procedure) { - if (e->scope->is_init && name == "main") { - entry_point = e; - } - } - } - - struct ssaGlobalVariable { - ssaValue *var, *init; - DeclInfo *decl; - }; - Array<ssaGlobalVariable> global_variables; - array_init(&global_variables, m->tmp_allocator, global_variable_max_count); - - auto min_dep_map = generate_minimum_dependency_map(info, entry_point); - defer (map_destroy(&min_dep_map)); - - for_array(i, info->entities.entries) { - auto *entry = &info->entities.entries[i]; - Entity *e = cast(Entity *)cast(uintptr)entry->key.key; - String name = e->token.string; - DeclInfo *decl = entry->value; - Scope *scope = e->scope; - - if (!scope->is_file) { - continue; - } - - if (map_get(&min_dep_map, hash_pointer(e)) == NULL) { - // NOTE(bill): Nothing depends upon it so doesn't need to be built - continue; - } - - if (!scope->is_global && !scope->is_init) { - name = ssa_mangle_name(s, e->token.pos.file, name); - } - - - switch (e->kind) { - case Entity_TypeName: - GB_ASSERT(e->type->kind == Type_Named); - map_set(&m->type_names, hash_pointer(e->type), name); - ssa_gen_global_type_name(m, e, name); - break; - - case Entity_Variable: { - ssaValue *g = ssa_make_value_global(a, e, NULL); - if (decl->var_decl_tags & VarDeclTag_thread_local) { - g->Global.is_thread_local = true; - } - ssaGlobalVariable var = {}; - var.var = g; - var.decl = decl; - - if (decl->init_expr != NULL) { - TypeAndValue *tav = map_get(&info->types, hash_pointer(decl->init_expr)); - if (tav != NULL) { - if (tav->value.kind != ExactValue_Invalid) { - ExactValue v = tav->value; - if (v.kind != ExactValue_String) { - g->Global.value = ssa_add_module_constant(m, tav->type, v); - } - } - } - } - - if (g->Global.value == NULL) { - array_add(&global_variables, var); - } - - map_set(&m->values, hash_pointer(e), g); - map_set(&m->members, hash_string(name), g); - } break; - - case Entity_Procedure: { - auto *pd = &decl->proc_decl->ProcDecl; - String original_name = name; - AstNode *body = pd->body; - if (pd->tags & ProcTag_foreign) { - name = pd->name->Ident.string; - } - 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); - p->Proc.tags = pd->tags; - - map_set(&m->values, hash_pointer(e), p); - HashKey hash_name = hash_string(name); - if (map_get(&m->members, hash_name) == NULL) { - map_set(&m->members, hash_name, p); - } - } break; - } - } - - for_array(i, m->members.entries) { - auto *entry = &m->members.entries[i]; - ssaValue *v = entry->value; - if (v->kind == ssaValue_Proc) - ssa_build_proc(v, NULL); - } - - 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); - - isize all_proc_max_count = 0; - 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++; - } - } - - array_init(&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; - - - 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) { - array_add(&all_procs->AllProcs.procs, di); - } - } - - - { // Startup Runtime - // Cleanup(bill): probably better way of doing code insertion - String name = make_string(SSA_STARTUP_RUNTIME_PROC_NAME); - Type *proc_type = make_type_proc(a, gb_alloc_item(a, Scope), - NULL, 0, - NULL, 0, false); - AstNode *body = gb_alloc_item(a, AstNode); - ssaValue *p = ssa_make_value_procedure(a, m, NULL, proc_type, NULL, body, name); - Token token = {}; - token.string = name; - Entity *e = make_entity_procedure(a, NULL, token, proc_type); - - map_set(&m->values, hash_pointer(e), p); - map_set(&m->members, hash_string(name), p); - - ssaProcedure *proc = &p->Proc; - proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea? - - ssa_begin_procedure_body(proc); - - // TODO(bill): Should do a dependency graph do check which order to initialize them in? - for_array(i, global_variables) { - ssaGlobalVariable *var = &global_variables[i]; - if (var->decl->init_expr != NULL) { - var->init = ssa_build_expr(proc, var->decl->init_expr); - } - } - - // NOTE(bill): Initialize constants first - for_array(i, global_variables) { - ssaGlobalVariable *var = &global_variables[i]; - if (var->init != NULL) { - if (var->init->kind == ssaValue_Constant) { - ssa_emit_store(proc, var->var, var->init); - } - } - } - - for_array(i, global_variables) { - ssaGlobalVariable *var = &global_variables[i]; - if (var->init != NULL) { - if (var->init->kind != ssaValue_Constant) { - ssa_emit_store(proc, var->var, var->init); - } - } - } - - { // NOTE(bill): Setup type_info data - // TODO(bill): Try and make a lot of this constant aggregate literals in LLVM IR - ssaValue *type_info_data = NULL; - ssaValue *type_info_member_data = NULL; - - ssaValue **found = NULL; - found = map_get(&proc->module->members, hash_string(make_string(SSA_TYPE_INFO_DATA_NAME))); - GB_ASSERT(found != NULL); - type_info_data = *found; - - found = map_get(&proc->module->members, hash_string(make_string(SSA_TYPE_INFO_DATA_MEMBER_NAME))); - GB_ASSERT(found != NULL); - type_info_member_data = *found; - - CheckerInfo *info = proc->module->info; - - // Useful types - 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_array_ep(proc, type_info_data, cast(i32)ssa_type_info_index(proc->module->info, type)); - }; - - i32 type_info_member_index = 0; - - auto type_info_member_offset = [](ssaProcedure *proc, ssaValue *data, isize count, i32 *index) -> ssaValue * { - ssaValue *offset = ssa_emit_array_ep(proc, data, *index); - *index += count; - return offset; - }; - - - - for_array(type_info_map_index, info->type_info_map.entries) { - auto *entry = &info->type_info_map.entries[type_info_map_index]; - Type *t = cast(Type *)cast(uintptr)entry->key.key; - t = default_type(t); - isize entry_index = entry->value; - - ssaValue *tag = NULL; - - switch (t->kind) { - case Type_Named: { - tag = ssa_add_local_generated(proc, t_type_info_named); - - // TODO(bill): Which is better? The mangled name or actual name? - // ssaValue *gsa = ssa_add_global_string_array(proc, make_exact_value_string(t->Named.name)); - ssaValue *gsa = ssa_add_global_string_array(m, t->Named.type_name->token.string); - ssaValue *elem = ssa_array_elem(proc, gsa); - ssaValue *len = ssa_array_len(proc, ssa_emit_load(proc, gsa)); - ssaValue *name = ssa_emit_string(proc, elem, len); - - ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Named.base); - - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 0), name); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 1), gep); - } break; - - case Type_Basic: - switch (t->Basic.kind) { - case Basic_bool: - tag = ssa_add_local_generated(proc, t_type_info_boolean); - break; - case Basic_i8: - case Basic_i16: - case Basic_i32: - case Basic_i64: - case Basic_u8: - case Basic_u16: - case Basic_u32: - case Basic_u64: - case Basic_int: - case Basic_uint: { - tag = ssa_add_local_generated(proc, t_type_info_integer); - b32 is_unsigned = (t->Basic.flags & BasicFlag_Unsigned) != 0; - ssaValue *bits = ssa_make_const_int(a, type_size_of(m->sizes, a, t)); - ssaValue *is_signed = ssa_make_const_bool(a, !is_unsigned); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 0), bits); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 1), is_signed); - } break; - - case Basic_f32: - case Basic_f64: { - tag = ssa_add_local_generated(proc, t_type_info_float); - ssaValue *bits = ssa_make_const_int(a, type_size_of(m->sizes, a, t)); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 0), bits); - } break; - - case Basic_rawptr: - tag = ssa_add_local_generated(proc, t_type_info_pointer); - break; - - case Basic_string: - tag = ssa_add_local_generated(proc, t_type_info_string); - break; - - case Basic_any: - tag = ssa_add_local_generated(proc, t_type_info_any); - break; - } - break; - - case Type_Pointer: { - tag = ssa_add_local_generated(proc, t_type_info_pointer); - ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Pointer.elem); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 0), gep); - } break; - case Type_Maybe: { - tag = ssa_add_local_generated(proc, t_type_info_maybe); - ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Maybe.elem); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 0), gep); - } break; - case Type_Array: { - tag = ssa_add_local_generated(proc, t_type_info_array); - ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Array.elem); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 0), gep); - - isize ez = type_size_of(m->sizes, a, t->Array.elem); - ssaValue *elem_size = ssa_emit_struct_ep(proc, tag, 1); - ssa_emit_store(proc, elem_size, ssa_make_const_int(a, ez)); - - ssaValue *count = ssa_emit_struct_ep(proc, tag, 2); - ssa_emit_store(proc, count, ssa_make_const_int(a, t->Array.count)); - - } break; - case Type_Slice: { - tag = ssa_add_local_generated(proc, t_type_info_slice); - ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Slice.elem); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 0), gep); - - isize ez = type_size_of(m->sizes, a, t->Slice.elem); - ssaValue *elem_size = ssa_emit_struct_ep(proc, tag, 1); - ssa_emit_store(proc, elem_size, ssa_make_const_int(a, ez)); - - } break; - case Type_Vector: { - tag = ssa_add_local_generated(proc, t_type_info_vector); - ssaValue *gep = get_type_info_ptr(proc, type_info_data, t->Vector.elem); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 0), gep); - - isize ez = type_size_of(m->sizes, a, t->Vector.elem); - ssaValue *elem_size = ssa_emit_struct_ep(proc, tag, 1); - ssa_emit_store(proc, elem_size, ssa_make_const_int(a, ez)); - - ssaValue *count = ssa_emit_struct_ep(proc, tag, 2); - ssa_emit_store(proc, count, ssa_make_const_int(a, t->Vector.count)); - - } break; - case Type_Record: { - switch (t->Record.kind) { - 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); - ssaValue *size = ssa_make_const_int(a, type_size_of(m->sizes, a, t)); - ssaValue *align = ssa_make_const_int(a, type_align_of(m->sizes, a, t)); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 1), size); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 2), align); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 3), packed); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 4), 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 - for (isize source_index = 0; source_index < t->Record.field_count; source_index++) { - // TODO(bill): Order fields in source order not layout order - Entity *f = t->Record.fields_in_src_order[source_index]; - ssaValue *tip = get_type_info_ptr(proc, type_info_data, f->type); - i64 foffset = t->Record.struct_offsets[f->Variable.field_index]; - GB_ASSERT(f->kind == Entity_Variable && f->Variable.field); - - ssaValue *field = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, source_index)); - ssaValue *name = ssa_emit_struct_ep(proc, field, 0); - ssaValue *type_info = ssa_emit_struct_ep(proc, field, 1); - ssaValue *offset = ssa_emit_struct_ep(proc, field, 2); - - if (f->token.string.len > 0) { - ssa_emit_store(proc, name, ssa_emit_global_string(proc, f->token.string)); - } - ssa_emit_store(proc, type_info, tip); - ssa_emit_store(proc, offset, ssa_make_const_int(a, foffset)); - } - - Type *slice_type = make_type_slice(a, t_type_info_member); - Type *slice_type_ptr = make_type_pointer(a, slice_type); - ssaValue *slice = ssa_emit_struct_ep(proc, tag, 0); - ssaValue *field_count = ssa_make_const_int(a, t->Record.field_count); - - ssaValue *elem = ssa_emit_struct_ep(proc, slice, 0); - ssaValue *len = ssa_emit_struct_ep(proc, slice, 1); - ssaValue *cap = ssa_emit_struct_ep(proc, slice, 2); - - ssa_emit_store(proc, elem, memory); - ssa_emit_store(proc, len, field_count); - ssa_emit_store(proc, cap, field_count); - } break; - case TypeRecord_Union: - tag = ssa_add_local_generated(proc, t_type_info_union); - { - ssaValue *size = ssa_make_const_int(a, type_size_of(m->sizes, a, t)); - ssaValue *align = ssa_make_const_int(a, type_align_of(m->sizes, a, t)); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 1), size); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 2), align); - } - break; - case TypeRecord_RawUnion: { - tag = ssa_add_local_generated(proc, t_type_info_raw_union); - { - ssaValue *size = ssa_make_const_int(a, type_size_of(m->sizes, a, t)); - ssaValue *align = ssa_make_const_int(a, type_align_of(m->sizes, a, t)); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 1), size); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 2), align); - } - - ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Record.field_count, &type_info_member_index); - - for (isize i = 0; i < t->Record.field_count; i++) { - ssaValue *field = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, i)); - ssaValue *name = ssa_emit_struct_ep(proc, field, 0); - ssaValue *type_info = ssa_emit_struct_ep(proc, field, 1); - ssaValue *offset = ssa_emit_struct_ep(proc, field, 2); - - Entity *f = t->Record.fields[i]; - ssaValue *tip = get_type_info_ptr(proc, type_info_data, f->type); - - if (f->token.string.len > 0) { - ssa_emit_store(proc, name, ssa_emit_global_string(proc, f->token.string)); - } - ssa_emit_store(proc, type_info, tip); - ssa_emit_store(proc, offset, ssa_make_const_int(a, 0)); - } - - Type *slice_type = make_type_slice(a, t_type_info_member); - Type *slice_type_ptr = make_type_pointer(a, slice_type); - ssaValue *slice = ssa_emit_struct_ep(proc, tag, 0); - ssaValue *field_count = ssa_make_const_int(a, t->Record.field_count); - - ssaValue *elem = ssa_emit_struct_ep(proc, slice, 0); - ssaValue *len = ssa_emit_struct_ep(proc, slice, 1); - ssaValue *cap = ssa_emit_struct_ep(proc, slice, 2); - - ssa_emit_store(proc, elem, memory); - ssa_emit_store(proc, len, field_count); - ssa_emit_store(proc, cap, field_count); - } break; - case TypeRecord_Enum: { - tag = ssa_add_local_generated(proc, t_type_info_enum); - Type *enum_base = t->Record.enum_base; - if (enum_base == NULL) { - enum_base = t_int; - } - ssaValue *base = ssa_emit_struct_ep(proc, tag, 0); - 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_ep(proc, value_array, i); - ssaValue *name_gep = ssa_emit_struct_ep(proc, name_array, i); - - 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_ep(proc, tag, 1); - ssaValue *names = ssa_emit_struct_ep(proc, tag, 2); - 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_ep(proc, value_slice, 0), ssa_array_elem(proc, value_array)); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, value_slice, 1), v_count); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, value_slice, 2), v_count); - - ssa_emit_store(proc, ssa_emit_struct_ep(proc, name_slice, 0), ssa_array_elem(proc, name_array)); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, name_slice, 1), v_count); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, name_slice, 2), 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; - - case Type_Tuple: { - tag = ssa_add_local_generated(proc, t_type_info_tuple); - - { - ssaValue *align = ssa_make_const_int(a, type_align_of(m->sizes, a, t)); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 2), align); - } - - ssaValue *memory = type_info_member_offset(proc, type_info_member_data, t->Tuple.variable_count, &type_info_member_index); - - for (isize i = 0; i < t->Tuple.variable_count; i++) { - ssaValue *field = ssa_emit_ptr_offset(proc, memory, ssa_make_const_int(a, i)); - ssaValue *name = ssa_emit_struct_ep(proc, field, 0); - ssaValue *type_info = ssa_emit_struct_ep(proc, field, 1); - // NOTE(bill): offset is not used for tuples - - Entity *f = t->Tuple.variables[i]; - ssaValue *tip = get_type_info_ptr(proc, type_info_data, f->type); - - if (f->token.string.len > 0) { - ssa_emit_store(proc, name, ssa_emit_global_string(proc, f->token.string)); - } - ssa_emit_store(proc, type_info, tip); - } - - Type *slice_type = make_type_slice(a, t_type_info_member); - Type *slice_type_ptr = make_type_pointer(a, slice_type); - ssaValue *slice = ssa_emit_struct_ep(proc, tag, 0); - ssaValue *variable_count = ssa_make_const_int(a, t->Tuple.variable_count); - - ssaValue *elem = ssa_emit_struct_ep(proc, slice, 0); - ssaValue *len = ssa_emit_struct_ep(proc, slice, 1); - ssaValue *cap = ssa_emit_struct_ep(proc, slice, 2); - - ssa_emit_store(proc, elem, memory); - ssa_emit_store(proc, len, variable_count); - ssa_emit_store(proc, cap, variable_count); - } break; - - case Type_Proc: { - tag = ssa_add_local_generated(proc, t_type_info_procedure); - - ssaValue *params = ssa_emit_struct_ep(proc, tag, 0); - ssaValue *results = ssa_emit_struct_ep(proc, tag, 1); - ssaValue *variadic = ssa_emit_struct_ep(proc, tag, 2); - - 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 - } break; - } - - if (tag != NULL) { - ssaValue *gep = ssa_emit_array_ep(proc, type_info_data, entry_index); - ssaValue *val = ssa_emit_conv(proc, ssa_emit_load(proc, tag), t_type_info); - ssa_emit_store(proc, gep, val); - } - } - } - - ssa_end_procedure_body(proc); - } - - for_array(i, m->procs) { - 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"); -} - - -void ssa_gen_ir(ssaGen *s) { - ssaFileBuffer buf = {}; - ssa_file_buffer_init(&buf, &s->output_file); - defer (ssa_file_buffer_destroy(&buf)); - - ssa_print_llvm_ir(&buf, &s->module); -} |