From bb56360bfaa317809bd3c742a655b357bd5b6226 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Thu, 26 Apr 2018 14:03:19 +0300 Subject: Added TypeInfo cache --- src/all_types.hpp | 1 + src/codegen.cpp | 10 ++++- src/ir.cpp | 109 ++++++++++++++++++++++++++++++------------------------ 3 files changed, 70 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/all_types.hpp b/src/all_types.hpp index 332fc5204e..c1c6c9a1a5 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1507,6 +1507,7 @@ struct CodeGen { HashMap exported_symbol_names; HashMap external_prototypes; HashMap string_literals_table; + HashMap type_info_cache; ZigList import_queue; diff --git a/src/codegen.cpp b/src/codegen.cpp index 7d83a38bbf..71df7fcd65 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -88,6 +88,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out g->exported_symbol_names.init(8); g->external_prototypes.init(8); g->string_literals_table.init(16); + g->type_info_cache.init(32); g->is_test_build = false; g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib); buf_resize(&g->global_asm, 0); @@ -6347,7 +6348,8 @@ static void define_builtin_compile_vars(CodeGen *g) { buf_appendf(contents, "};\n\n"); } { - // TODO: Add method info where methods are supported. + // @TODO Add method info where methods are supported. + // @TODO Add Namespace info. buf_appendf(contents, "pub const TypeInfo = union(TypeId) {\n" " Type: void,\n" @@ -6403,6 +6405,11 @@ static void define_builtin_compile_vars(CodeGen *g) { " Packed,\n" " };\n" "\n" + " pub const Method = struct {\n" + " name: []const u8,\n" + " fn_info: Fn,\n" + " };\n" + "\n" " pub const StructField = struct {\n" " name: []const u8,\n" " offset: usize,\n" @@ -6412,6 +6419,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const Struct = struct {\n" " layout: ContainerLayout,\n" " fields: []StructField,\n" + " methods: []Method,\n" " };\n" "\n" " pub const Nullable = struct {\n" diff --git a/src/ir.cpp b/src/ir.cpp index cbd8d51b32..9229e4e89d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15810,6 +15810,15 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, ssize_t parent_field_index, TypeTableEntry *type_entry) { + // Lookup an available value in our cache. + auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); + if (entry != nullptr) + return entry->value; + + ConstExprValue *result = nullptr; + + // @TODO + // We should probably cache the values generated with a type_entry key. assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); @@ -15832,75 +15841,73 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p return nullptr; case TypeTableEntryIdInt: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Int"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Int"); ConstExprValue *fields = create_const_vals(2); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // is_signed: bool - ensure_field_index(payload->type, "is_signed", 0); + ensure_field_index(result->type, "is_signed", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_bool; fields[0].data.x_bool = type_entry->data.integral.is_signed; // bits: u8 - ensure_field_index(payload->type, "bits", 1); + ensure_field_index(result->type, "bits", 1); fields[1].special = ConstValSpecialStatic; fields[1].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); - - return payload; + break; } case TypeTableEntryIdFloat: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Float"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Float"); ConstExprValue *fields = create_const_vals(1); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // bits: u8 - ensure_field_index(payload->type, "bits", 0); + ensure_field_index(result->type, "bits", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); - - return payload; + break; } case TypeTableEntryIdPointer: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Pointer"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Pointer"); ConstExprValue *fields = create_const_vals(4); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // is_const: bool - ensure_field_index(payload->type, "is_const", 0); + ensure_field_index(result->type, "is_const", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_bool; fields[0].data.x_bool = type_entry->data.pointer.is_const; // is_volatile: bool - ensure_field_index(payload->type, "is_volatile", 1); + ensure_field_index(result->type, "is_volatile", 1); fields[1].special = ConstValSpecialStatic; fields[1].type = ira->codegen->builtin_types.entry_bool; fields[1].data.x_bool = type_entry->data.pointer.is_volatile; // alignment: u32 - ensure_field_index(payload->type, "alignment", 2); + ensure_field_index(result->type, "alignment", 2); fields[2].special = ConstValSpecialStatic; fields[2].type = ira->codegen->builtin_types.entry_u32; bigint_init_unsigned(&fields[2].data.x_bigint, type_entry->data.pointer.alignment); // child: &TypeInfo - ensure_field_index(payload->type, "child", 3); + ensure_field_index(result->type, "child", 3); TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); @@ -15917,26 +15924,26 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p type_entry->data.pointer.child_type); fields[3].data.x_ptr.data.ref.pointee = union_val; - return payload; + break; } case TypeTableEntryIdArray: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Array"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Array"); ConstExprValue *fields = create_const_vals(2); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // len: usize - ensure_field_index(payload->type, "len", 0); + ensure_field_index(result->type, "len", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_usize; bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); // child: &TypeInfo - ensure_field_index(payload->type, "child", 1); + ensure_field_index(result->type, "child", 1); TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); @@ -15953,21 +15960,21 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p type_entry->data.array.child_type); fields[1].data.x_ptr.data.ref.pointee = union_val; - return payload; + break; } case TypeTableEntryIdMaybe: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Nullable"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Nullable"); ConstExprValue *fields = create_const_vals(1); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // child: &TypeInfo - ensure_field_index(payload->type, "child", 0); + ensure_field_index(result->type, "child", 0); TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); @@ -15984,21 +15991,21 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p type_entry->data.maybe.child_type); fields[0].data.x_ptr.data.ref.pointee = union_val; - return payload; + break; } case TypeTableEntryIdPromise: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Promise"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Promise"); ConstExprValue *fields = create_const_vals(1); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // child: ?&TypeInfo - ensure_field_index(payload->type, "child", 0); + ensure_field_index(result->type, "child", 0); TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); TypeTableEntry *type_info_ptr_type = get_pointer_to_type(ira->codegen, type_info_type, false); @@ -16029,11 +16036,15 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p maybe_value->data.x_ptr.data.ref.pointee = union_val; fields[0].data.x_maybe = maybe_value; } - return payload; + break; } default: zig_unreachable(); } + + assert(result != nullptr); + ira->codegen->type_info_cache.put(type_entry, result); + return result; } static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, -- cgit v1.2.3