From 2dfb1ebee2bc215271e5416b723d746af319621b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 26 May 2017 23:31:38 -0400 Subject: const global values can reference each other Before, if you did something like: ``` const hi1 = "hi"; const hi2 = hi1; ``` This would create the "hi" data twice in the built object. But since the value is const we don't have to duplicate the data, now we take advantage of this fact. closes #336 --- src/all_types.hpp | 9 +++++-- src/analyze.cpp | 61 ++++++++++++++++++++++++++---------------- src/analyze.hpp | 2 ++ src/codegen.cpp | 79 +++++++++++++++++++++++++++++++++---------------------- src/ir.cpp | 63 +++++++++++++++++++++++++++----------------- 5 files changed, 134 insertions(+), 80 deletions(-) (limited to 'src') diff --git a/src/all_types.hpp b/src/all_types.hpp index 89f10aade6..52fe96fbf4 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -210,11 +210,15 @@ struct ConstFn { FnTableEntry *fn_entry; }; +struct ConstGlobalRefs { + LLVMValueRef llvm_value; + LLVMValueRef llvm_global; +}; + struct ConstExprValue { TypeTableEntry *type; ConstValSpecial special; - LLVMValueRef llvm_value; - LLVMValueRef llvm_global; + ConstGlobalRefs *global_refs; union { // populated if special == ConstValSpecialStatic @@ -527,6 +531,7 @@ enum CastOp { CastOpBoolToInt, CastOpResizeSlice, CastOpBytesToSlice, + CastOpNumLitToConcrete, }; struct AstNodeFnCallExpr { diff --git a/src/analyze.cpp b/src/analyze.cpp index b7069937d6..a2c847848c 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3457,7 +3457,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) { void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { const_val->special = ConstValSpecialStatic; const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str)); - const_val->data.x_array.s_none.elements = allocate(buf_len(str)); + const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str)); for (size_t i = 0; i < buf_len(str); i += 1) { ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i]; @@ -3468,7 +3468,7 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { } ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_str_lit(g, const_val, str); return const_val; } @@ -3476,10 +3476,10 @@ ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { // first we build the underlying array size_t len_with_null = buf_len(str) + 1; - ConstExprValue *array_val = allocate(1); + ConstExprValue *array_val = create_const_vals(1); array_val->special = ConstValSpecialStatic; array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null); - array_val->data.x_array.s_none.elements = allocate(len_with_null); + array_val->data.x_array.s_none.elements = create_const_vals(len_with_null); for (size_t i = 0; i < buf_len(str); i += 1) { ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i]; this_char->special = ConstValSpecialStatic; @@ -3500,7 +3500,7 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { const_val->data.x_ptr.data.base_array.is_cstr = true; } ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_c_str_lit(g, const_val, str); return const_val; } @@ -3513,7 +3513,7 @@ void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *typ } ConstExprValue *create_const_unsigned_negative(TypeTableEntry *type, uint64_t x, bool negative) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_unsigned_negative(const_val, type, x, negative); return const_val; } @@ -3533,7 +3533,7 @@ void init_const_signed(ConstExprValue *const_val, TypeTableEntry *type, int64_t } ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_signed(const_val, type, x); return const_val; } @@ -3545,7 +3545,7 @@ void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double va } ConstExprValue *create_const_float(TypeTableEntry *type, double value) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_float(const_val, type, value); return const_val; } @@ -3557,7 +3557,7 @@ void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, uint64 } ConstExprValue *create_const_enum_tag(TypeTableEntry *type, uint64_t tag) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_enum_tag(const_val, type, tag); return const_val; } @@ -3569,7 +3569,7 @@ void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) { } ConstExprValue *create_const_bool(CodeGen *g, bool value) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_bool(g, const_val, value); return const_val; } @@ -3580,7 +3580,7 @@ void init_const_runtime(ConstExprValue *const_val, TypeTableEntry *type) { } ConstExprValue *create_const_runtime(TypeTableEntry *type) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_runtime(const_val, type); return const_val; } @@ -3592,7 +3592,7 @@ void init_const_type(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *type } ConstExprValue *create_const_type(CodeGen *g, TypeTableEntry *type_value) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_type(g, const_val, type_value); return const_val; } @@ -3604,14 +3604,14 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr const_val->special = ConstValSpecialStatic; const_val->type = get_slice_type(g, array_val->type->data.array.child_type, is_const); - const_val->data.x_struct.fields = allocate(2); + const_val->data.x_struct.fields = create_const_vals(2); init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const); init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len); } ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_slice(g, const_val, array_val, start, len, is_const); return const_val; } @@ -3630,7 +3630,7 @@ void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue } ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_ptr_array(g, const_val, array_val, elem_index, is_const); return const_val; } @@ -3643,7 +3643,7 @@ void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *p } ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_ptr_ref(g, const_val, pointee_val, is_const); return const_val; } @@ -3660,7 +3660,7 @@ void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeT ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type, size_t addr, bool is_const) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const); return const_val; } @@ -3673,7 +3673,7 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde } ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end); return const_val; } @@ -3689,7 +3689,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { const_val->special = ConstValSpecialStatic; size_t field_count = wanted_type->data.structure.src_field_count; - const_val->data.x_struct.fields = allocate(field_count); + const_val->data.x_struct.fields = create_const_vals(field_count); for (size_t i = 0; i < field_count; i += 1) { ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; field_val->type = wanted_type->data.structure.fields[i].type_entry; @@ -3707,6 +3707,15 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { } } +ConstExprValue *create_const_vals(size_t count) { + ConstGlobalRefs *global_refs = allocate(count); + ConstExprValue *vals = allocate(count); + for (size_t i = 0; i < count; i += 1) { + vals[i].global_refs = &global_refs[i]; + } + return vals; +} + void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) { if (type_entry->id == TypeTableEntryIdStruct) { if (!type_entry->data.structure.complete) @@ -3788,16 +3797,24 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { return false; return true; case ConstPtrSpecialBaseArray: - if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val) + if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val && + a->data.x_ptr.data.base_array.array_val->global_refs != + b->data.x_ptr.data.base_array.array_val->global_refs) + { return false; + } if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index) return false; if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr) return false; return true; case ConstPtrSpecialBaseStruct: - if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val) + if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val && + a->data.x_ptr.data.base_struct.struct_val->global_refs != + b->data.x_ptr.data.base_struct.struct_val->global_refs) + { return false; + } if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index) return false; return true; @@ -4293,7 +4310,7 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { if (const_val->data.x_array.special == ConstArraySpecialUndef) { const_val->data.x_array.special = ConstArraySpecialNone; size_t elem_count = const_val->type->data.array.len; - const_val->data.x_array.s_none.elements = allocate(elem_count); + const_val->data.x_array.s_none.elements = create_const_vals(elem_count); for (size_t i = 0; i < elem_count; i += 1) { ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i]; element_val->type = const_val->type->data.array.child_type; diff --git a/src/analyze.hpp b/src/analyze.hpp index af5371a234..5666f203b2 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -153,6 +153,8 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_ void init_const_undefined(CodeGen *g, ConstExprValue *const_val); +ConstExprValue *create_const_vals(size_t count); + TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value); FnTableEntry *get_extern_panic_fn(CodeGen *g); diff --git a/src/codegen.cpp b/src/codegen.cpp index eae06df337..8221ce9e11 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -682,8 +682,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { ConstExprValue *val = &g->panic_msg_vals[msg_id]; - if (val->llvm_global) - return val->llvm_global; + if (val->global_refs->llvm_global) + return val->global_refs->llvm_global; Buf *buf_msg = panic_msg_buf(msg_id); ConstExprValue *array_val = create_const_str_lit(g, buf_msg); @@ -692,8 +692,8 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { render_const_val_global(g, val, ""); render_const_val(g, val); - assert(val->llvm_global); - return val->llvm_global; + assert(val->global_refs->llvm_global); + return val->global_refs->llvm_global; } static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len) { @@ -1086,11 +1086,11 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { if (handle_is_ptr(instruction->value.type)) { render_const_val_global(g, &instruction->value, ""); TypeTableEntry *ptr_type = get_pointer_to_type(g, instruction->value.type, true); - instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_global, ptr_type->type_ref, ""); + instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, ptr_type->type_ref, ""); } else if (instruction->value.type->id == TypeTableEntryIdPointer) { - instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_value, instruction->value.type->type_ref, ""); + instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value, instruction->value.type->type_ref, ""); } else { - instruction->llvm_value = instruction->value.llvm_value; + instruction->llvm_value = instruction->value.global_refs->llvm_value; } assert(instruction->llvm_value); } @@ -1535,6 +1535,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, switch (cast_instruction->cast_op) { case CastOpNoCast: + case CastOpNumLitToConcrete: zig_unreachable(); case CastOpNoop: return expr_val; @@ -3197,7 +3198,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent case ConstParentIdNone: render_const_val(g, val); render_const_val_global(g, val, ""); - return val->llvm_global; + return val->global_refs->llvm_global; case ConstParentIdStruct: return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val, parent->data.p_struct.field_index); @@ -3506,9 +3507,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { render_const_val(g, pointee); render_const_val_global(g, pointee, ""); ConstExprValue *other_val = pointee; - const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref); + const_val->global_refs->llvm_value = LLVMConstBitCast(other_val->global_refs->llvm_global, const_val->type->type_ref); render_const_val_global(g, const_val, ""); - return const_val->llvm_value; + return const_val->global_refs->llvm_value; } case ConstPtrSpecialBaseArray: { @@ -3518,15 +3519,15 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { if (array_const_val->type->zero_bits) { // make this a null pointer TypeTableEntry *usize = g->builtin_types.entry_usize; - const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), + const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), const_val->type->type_ref); render_const_val_global(g, const_val, ""); - return const_val->llvm_value; + return const_val->global_refs->llvm_value; } LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, elem_index); LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); - const_val->llvm_value = ptr_val; + const_val->global_refs->llvm_value = ptr_val; render_const_val_global(g, const_val, ""); return ptr_val; } @@ -3537,10 +3538,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { if (struct_const_val->type->zero_bits) { // make this a null pointer TypeTableEntry *usize = g->builtin_types.entry_usize; - const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), + const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref), const_val->type->type_ref); render_const_val_global(g, const_val, ""); - return const_val->llvm_value; + return const_val->global_refs->llvm_value; } size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index; size_t gen_field_index = @@ -3548,7 +3549,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val, gen_field_index); LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref); - const_val->llvm_value = ptr_val; + const_val->global_refs->llvm_value = ptr_val; render_const_val_global(g, const_val, ""); return ptr_val; } @@ -3556,10 +3557,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { { uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr; TypeTableEntry *usize = g->builtin_types.entry_usize; - const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false), + const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false), const_val->type->type_ref); render_const_val_global(g, const_val, ""); - return const_val->llvm_value; + return const_val->global_refs->llvm_value; } } } @@ -3608,27 +3609,32 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { } static void render_const_val(CodeGen *g, ConstExprValue *const_val) { - if (!const_val->llvm_value) - const_val->llvm_value = gen_const_val(g, const_val); + if (!const_val->global_refs) + const_val->global_refs = allocate(1); + if (!const_val->global_refs->llvm_value) + const_val->global_refs->llvm_value = gen_const_val(g, const_val); - if (const_val->llvm_global) - LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); + if (const_val->global_refs->llvm_global) + LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value); } static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const char *name) { - if (!const_val->llvm_global) { - LLVMTypeRef type_ref = const_val->llvm_value ? LLVMTypeOf(const_val->llvm_value) : const_val->type->type_ref; + if (!const_val->global_refs) + const_val->global_refs = allocate(1); + + if (!const_val->global_refs->llvm_global) { + LLVMTypeRef type_ref = const_val->global_refs->llvm_value ? LLVMTypeOf(const_val->global_refs->llvm_value) : const_val->type->type_ref; LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, name); LLVMSetLinkage(global_value, LLVMInternalLinkage); LLVMSetGlobalConstant(global_value, true); LLVMSetUnnamedAddr(global_value, true); LLVMSetAlignment(global_value, get_type_alignment(g, const_val->type)); - const_val->llvm_global = global_value; + const_val->global_refs->llvm_global = global_value; } - if (const_val->llvm_value) - LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); + if (const_val->global_refs->llvm_value) + LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value); } static void delete_unused_builtin_fns(CodeGen *g) { @@ -3849,7 +3855,7 @@ static void do_code_gen(CodeGen *g) { bool exported = (var->linkage == VarLinkageExport); render_const_val(g, var->value); render_const_val_global(g, var->value, buf_ptr(get_mangled_name(g, &var->name, exported))); - global_value = var->value->llvm_global; + global_value = var->value->global_refs->llvm_global; if (exported) { LLVMSetLinkage(global_value, LLVMExternalLinkage); @@ -3862,7 +3868,7 @@ static void do_code_gen(CodeGen *g) { // TODO debug info for function pointers if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) { - gen_global_var(g, var, var->value->llvm_value, var->value->type); + gen_global_var(g, var, var->value->global_refs->llvm_value, var->value->type); } } @@ -4737,9 +4743,18 @@ static void init(CodeGen *g) { g->invalid_instruction = allocate(1); g->invalid_instruction->value.type = g->builtin_types.entry_invalid; + g->invalid_instruction->value.global_refs = allocate(1); g->const_void_val.special = ConstValSpecialStatic; g->const_void_val.type = g->builtin_types.entry_void; + g->const_void_val.global_refs = allocate(1); + + { + ConstGlobalRefs *global_refs = allocate(PanicMsgIdCount); + for (size_t i = 0; i < PanicMsgIdCount; i += 1) { + g->panic_msg_vals[i].global_refs = &global_refs[i]; + } + } define_builtin_fns(g); define_builtin_compile_vars(g); @@ -4826,10 +4841,10 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { TypeTableEntry *field_types[] = { str_type, fn_type, }; TypeTableEntry *struct_type = get_struct_type(g, "ZigTestFn", field_names, field_types, 2); - ConstExprValue *test_fn_array = allocate(1); + ConstExprValue *test_fn_array = create_const_vals(1); test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length); test_fn_array->special = ConstValSpecialStatic; - test_fn_array->data.x_array.s_none.elements = allocate(g->test_fns.length); + test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length); for (size_t i = 0; i < g->test_fns.length; i += 1) { FnTableEntry *test_fn_entry = g->test_fns.at(i); @@ -4840,7 +4855,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { this_val->data.x_struct.parent.id = ConstParentIdArray; this_val->data.x_struct.parent.data.p_array.array_val = test_fn_array; this_val->data.x_struct.parent.data.p_array.elem_index = i; - this_val->data.x_struct.fields = allocate(2); + this_val->data.x_struct.fields = create_const_vals(2); ConstExprValue *name_field = &this_val->data.x_struct.fields[0]; ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name); diff --git a/src/ir.cpp b/src/ir.cpp index 82899fbf97..8e1a974359 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -553,6 +553,7 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no special_instruction->base.source_node = source_node; special_instruction->base.debug_id = exec_next_debug_id(irb->exec); special_instruction->base.owner_bb = irb->current_basic_block; + special_instruction->base.value.global_refs = allocate(1); return special_instruction; } @@ -3210,7 +3211,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco variable_entry->mem_slot_index = SIZE_MAX; variable_entry->is_comptime = is_comptime; variable_entry->src_arg_index = SIZE_MAX; - variable_entry->value = allocate(1); + variable_entry->value = create_const_vals(1); if (name) { buf_init_from_buf(&variable_entry->name, name); @@ -6565,6 +6566,14 @@ static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableE } } +static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { + ConstGlobalRefs *global_refs = dest->global_refs; + *dest = *src; + if (!same_global_refs) { + dest->global_refs = global_refs; + } +} + static void eval_const_expr_implicit_cast(CastOp cast_op, ConstExprValue *other_val, TypeTableEntry *other_type, ConstExprValue *const_val, TypeTableEntry *new_type) @@ -6576,7 +6585,13 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, case CastOpNoCast: zig_unreachable(); case CastOpNoop: - *const_val = *other_val; + { + copy_const_val(const_val, other_val, other_val->special == ConstValSpecialStatic); + const_val->type = new_type; + break; + } + case CastOpNumLitToConcrete: + const_val->data.x_bignum = other_val->data.x_bignum; const_val->type = new_type; break; case CastOpResizeSlice: @@ -7188,7 +7203,7 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction } IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type); - result->value = *val; + result->value.data.x_bignum = val->data.x_bignum; result->value.type = wanted_type; return result; } @@ -7613,7 +7628,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst (actual_type->id == TypeTableEntryIdNumLitInt && wanted_type->id == TypeTableEntryIdInt)) { - op = CastOpNoop; + op = CastOpNumLitToConcrete; } else if (wanted_type->id == TypeTableEntryIdInt) { op = CastOpFloatToInt; } else if (wanted_type->id == TypeTableEntryIdFloat) { @@ -7741,7 +7756,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc if (pointee->special != ConstValSpecialRuntime) { IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, source_instruction->source_node, child_type); - result->value = *pointee; + copy_const_val(&result->value, pointee, ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst); return result; } } @@ -8584,7 +8599,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * result_type = get_pointer_to_type(ira->codegen, child_type, true); - out_array_val = allocate(1); + out_array_val = create_const_vals(1); out_array_val->special = ConstValSpecialStatic; out_array_val->type = get_array_type(ira->codegen, child_type, new_len); out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; @@ -8592,7 +8607,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * out_val->data.x_ptr.data.base_array.array_val = out_array_val; out_val->data.x_ptr.data.base_array.elem_index = 0; } - out_array_val->data.x_array.s_none.elements = allocate(new_len); + out_array_val->data.x_array.s_none.elements = create_const_vals(new_len); expand_undef_array(ira->codegen, op1_array_val); @@ -8648,7 +8663,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); uint64_t new_array_len = array_len.data.x_uint; - out_val->data.x_array.s_none.elements = allocate(new_array_len); + out_val->data.x_array.s_none.elements = create_const_vals(new_array_len); expand_undef_array(ira->codegen, array_val); @@ -9139,7 +9154,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal GenericFnTypeId *generic_id = allocate(1); generic_id->fn_entry = fn_entry; generic_id->param_count = 0; - generic_id->params = allocate(new_fn_arg_count); + generic_id->params = create_const_vals(new_fn_arg_count); size_t next_proto_i = 0; if (first_arg_ptr) { @@ -9451,7 +9466,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); if (pointee->type == child_type) { ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); - *out_val = *pointee; + copy_const_val(out_val, pointee, value->value.data.x_ptr.mut == ConstPtrMutComptimeConst); return child_type; } } @@ -10118,7 +10133,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source // TODO instead of allocating this every time, put it in the tld value and we can reference // the same one every time - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); const_val->special = ConstValSpecialStatic; const_val->type = fn_entry->type_entry; const_val->data.x_fn.fn_entry = fn_entry; @@ -10162,7 +10177,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru } } else if (container_type->id == TypeTableEntryIdArray) { if (buf_eql_str(field_name, "len")) { - ConstExprValue *len_val = allocate(1); + ConstExprValue *len_val = create_const_vals(1); init_const_usize(ira->codegen, len_val, container_type->data.array.len); TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize; @@ -10185,7 +10200,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); if (buf_eql_str(field_name, "len")) { - ConstExprValue *len_val = allocate(1); + ConstExprValue *len_val = create_const_vals(1); size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index; init_const_usize(ira->codegen, len_val, len); @@ -10258,7 +10273,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru } else if (child_type->id == TypeTableEntryIdPureError) { auto err_table_entry = ira->codegen->error_table.maybe_get(field_name); if (err_table_entry) { - ConstExprValue *const_val = allocate(1); + ConstExprValue *const_val = create_const_vals(1); const_val->special = ConstValSpecialStatic; const_val->type = child_type; const_val->data.x_pure_err = err_table_entry->value; @@ -11346,7 +11361,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira, case TypeTableEntryIdPureError: if (pointee_val) { ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); - *out_val = *pointee_val; + copy_const_val(out_val, pointee_val, true); out_val->type = target_type; return target_type; } @@ -11583,7 +11598,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru ConstExprValue const_val = {}; const_val.special = ConstValSpecialStatic; const_val.type = container_type; - const_val.data.x_struct.fields = allocate(actual_field_count); + const_val.data.x_struct.fields = create_const_vals(actual_field_count); for (size_t i = 0; i < instr_field_count; i += 1) { IrInstructionContainerInitFieldsField *field = &fields[i]; @@ -11624,7 +11639,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru if (!field_val) return ira->codegen->builtin_types.entry_invalid; - const_val.data.x_struct.fields[field_index] = *field_val; + copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); } else { first_non_const_instruction = casted_field_value; const_val.special = ConstValSpecialRuntime; @@ -11698,7 +11713,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira ConstExprValue const_val = {}; const_val.special = ConstValSpecialStatic; const_val.type = fixed_size_array_type; - const_val.data.x_array.s_none.elements = allocate(elem_count); + const_val.data.x_array.s_none.elements = create_const_vals(elem_count); bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); @@ -11723,7 +11738,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira if (!elem_val) return ira->codegen->builtin_types.entry_invalid; - const_val.data.x_array.s_none.elements[i] = *elem_val; + copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true); } else { first_non_const_instruction = casted_arg; const_val.special = ConstValSpecialRuntime; @@ -11950,7 +11965,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); } ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - *out_val = *err->cached_error_name_val; + copy_const_val(out_val, err->cached_error_name_val, true); return str_type; } @@ -12133,7 +12148,7 @@ static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstru type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, &type_entry->name); } ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - *out_val = *type_entry->cached_const_name_val; + copy_const_val(out_val, type_entry->cached_const_name_val, true); return out_val->type; } @@ -12809,7 +12824,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio } ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - out_val->data.x_struct.fields = allocate(2); + out_val->data.x_struct.fields = create_const_vals(2); ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; @@ -13370,7 +13385,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc return ira->codegen->builtin_types.entry_invalid; ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - *out_val = *val; + copy_const_val(out_val, val, false); out_val->type = dest_type; return dest_type; } @@ -13696,7 +13711,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl ira->new_irb.exec = new_exec; ira->exec_context.mem_slot_count = ira->old_irb.exec->mem_slot_count; - ira->exec_context.mem_slot_list = allocate(ira->exec_context.mem_slot_count); + ira->exec_context.mem_slot_list = create_const_vals(ira->exec_context.mem_slot_count); IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); -- cgit v1.2.3