authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-26 23:31:38-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-27 00:54:14-04:00
log2dfb1ebee2bc215271e5416b723d746af319621b
tree9b859eebd0926cb82c7370362baafec617e763dc
parentd6b01931ef8a04777ae198af323c2b6ba998f7b1

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

8 files changed, 160 insertions(+), 84 deletions(-)

src/all_types.hpp+7-2
...@@ -210,11 +210,15 @@ struct ConstFn {...@@ -210,11 +210,15 @@ struct ConstFn {
210 FnTableEntry *fn_entry;210 FnTableEntry *fn_entry;
211};211};
212212
213struct ConstGlobalRefs {
214 LLVMValueRef llvm_value;
215 LLVMValueRef llvm_global;
216};
217
213struct ConstExprValue {218struct ConstExprValue {
214 TypeTableEntry *type;219 TypeTableEntry *type;
215 ConstValSpecial special;220 ConstValSpecial special;
216 LLVMValueRef llvm_value;221 ConstGlobalRefs *global_refs;
217 LLVMValueRef llvm_global;
218222
219 union {223 union {
220 // populated if special == ConstValSpecialStatic224 // populated if special == ConstValSpecialStatic
...@@ -527,6 +531,7 @@ enum CastOp {...@@ -527,6 +531,7 @@ enum CastOp {
527 CastOpBoolToInt,531 CastOpBoolToInt,
528 CastOpResizeSlice,532 CastOpResizeSlice,
529 CastOpBytesToSlice,533 CastOpBytesToSlice,
534 CastOpNumLitToConcrete,
530};535};
531536
532struct AstNodeFnCallExpr {537struct AstNodeFnCallExpr {
src/analyze.cpp+39-22
...@@ -3457,7 +3457,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {...@@ -3457,7 +3457,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
3457void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {3457void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
3458 const_val->special = ConstValSpecialStatic;3458 const_val->special = ConstValSpecialStatic;
3459 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));3459 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));
3460 const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(buf_len(str));3460 const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str));
34613461
3462 for (size_t i = 0; i < buf_len(str); i += 1) {3462 for (size_t i = 0; i < buf_len(str); i += 1) {
3463 ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i];3463 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) {...@@ -3468,7 +3468,7 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
3468}3468}
34693469
3470ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {3470ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {
3471 ConstExprValue *const_val = allocate<ConstExprValue>(1);3471 ConstExprValue *const_val = create_const_vals(1);
3472 init_const_str_lit(g, const_val, str);3472 init_const_str_lit(g, const_val, str);
3473 return const_val;3473 return const_val;
3474}3474}
...@@ -3476,10 +3476,10 @@ ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {...@@ -3476,10 +3476,10 @@ ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {
3476void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {3476void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
3477 // first we build the underlying array3477 // first we build the underlying array
3478 size_t len_with_null = buf_len(str) + 1;3478 size_t len_with_null = buf_len(str) + 1;
3479 ConstExprValue *array_val = allocate<ConstExprValue>(1);3479 ConstExprValue *array_val = create_const_vals(1);
3480 array_val->special = ConstValSpecialStatic;3480 array_val->special = ConstValSpecialStatic;
3481 array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);3481 array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);
3482 array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(len_with_null);3482 array_val->data.x_array.s_none.elements = create_const_vals(len_with_null);
3483 for (size_t i = 0; i < buf_len(str); i += 1) {3483 for (size_t i = 0; i < buf_len(str); i += 1) {
3484 ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i];3484 ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i];
3485 this_char->special = ConstValSpecialStatic;3485 this_char->special = ConstValSpecialStatic;
...@@ -3500,7 +3500,7 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {...@@ -3500,7 +3500,7 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
3500 const_val->data.x_ptr.data.base_array.is_cstr = true;3500 const_val->data.x_ptr.data.base_array.is_cstr = true;
3501}3501}
3502ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) {3502ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) {
3503 ConstExprValue *const_val = allocate<ConstExprValue>(1);3503 ConstExprValue *const_val = create_const_vals(1);
3504 init_const_c_str_lit(g, const_val, str);3504 init_const_c_str_lit(g, const_val, str);
3505 return const_val;3505 return const_val;
3506}3506}
...@@ -3513,7 +3513,7 @@ void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *typ...@@ -3513,7 +3513,7 @@ void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *typ
3513}3513}
35143514
3515ConstExprValue *create_const_unsigned_negative(TypeTableEntry *type, uint64_t x, bool negative) {3515ConstExprValue *create_const_unsigned_negative(TypeTableEntry *type, uint64_t x, bool negative) {
3516 ConstExprValue *const_val = allocate<ConstExprValue>(1);3516 ConstExprValue *const_val = create_const_vals(1);
3517 init_const_unsigned_negative(const_val, type, x, negative);3517 init_const_unsigned_negative(const_val, type, x, negative);
3518 return const_val;3518 return const_val;
3519}3519}
...@@ -3533,7 +3533,7 @@ void init_const_signed(ConstExprValue *const_val, TypeTableEntry *type, int64_t...@@ -3533,7 +3533,7 @@ void init_const_signed(ConstExprValue *const_val, TypeTableEntry *type, int64_t
3533}3533}
35343534
3535ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) {3535ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) {
3536 ConstExprValue *const_val = allocate<ConstExprValue>(1);3536 ConstExprValue *const_val = create_const_vals(1);
3537 init_const_signed(const_val, type, x);3537 init_const_signed(const_val, type, x);
3538 return const_val;3538 return const_val;
3539}3539}
...@@ -3545,7 +3545,7 @@ void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double va...@@ -3545,7 +3545,7 @@ void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double va
3545}3545}
35463546
3547ConstExprValue *create_const_float(TypeTableEntry *type, double value) {3547ConstExprValue *create_const_float(TypeTableEntry *type, double value) {
3548 ConstExprValue *const_val = allocate<ConstExprValue>(1);3548 ConstExprValue *const_val = create_const_vals(1);
3549 init_const_float(const_val, type, value);3549 init_const_float(const_val, type, value);
3550 return const_val;3550 return const_val;
3551}3551}
...@@ -3557,7 +3557,7 @@ void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, uint64...@@ -3557,7 +3557,7 @@ void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, uint64
3557}3557}
35583558
3559ConstExprValue *create_const_enum_tag(TypeTableEntry *type, uint64_t tag) {3559ConstExprValue *create_const_enum_tag(TypeTableEntry *type, uint64_t tag) {
3560 ConstExprValue *const_val = allocate<ConstExprValue>(1);3560 ConstExprValue *const_val = create_const_vals(1);
3561 init_const_enum_tag(const_val, type, tag);3561 init_const_enum_tag(const_val, type, tag);
3562 return const_val;3562 return const_val;
3563}3563}
...@@ -3569,7 +3569,7 @@ void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) {...@@ -3569,7 +3569,7 @@ void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) {
3569}3569}
35703570
3571ConstExprValue *create_const_bool(CodeGen *g, bool value) {3571ConstExprValue *create_const_bool(CodeGen *g, bool value) {
3572 ConstExprValue *const_val = allocate<ConstExprValue>(1);3572 ConstExprValue *const_val = create_const_vals(1);
3573 init_const_bool(g, const_val, value);3573 init_const_bool(g, const_val, value);
3574 return const_val;3574 return const_val;
3575}3575}
...@@ -3580,7 +3580,7 @@ void init_const_runtime(ConstExprValue *const_val, TypeTableEntry *type) {...@@ -3580,7 +3580,7 @@ void init_const_runtime(ConstExprValue *const_val, TypeTableEntry *type) {
3580}3580}
35813581
3582ConstExprValue *create_const_runtime(TypeTableEntry *type) {3582ConstExprValue *create_const_runtime(TypeTableEntry *type) {
3583 ConstExprValue *const_val = allocate<ConstExprValue>(1);3583 ConstExprValue *const_val = create_const_vals(1);
3584 init_const_runtime(const_val, type);3584 init_const_runtime(const_val, type);
3585 return const_val;3585 return const_val;
3586}3586}
...@@ -3592,7 +3592,7 @@ void init_const_type(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *type...@@ -3592,7 +3592,7 @@ void init_const_type(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *type
3592}3592}
35933593
3594ConstExprValue *create_const_type(CodeGen *g, TypeTableEntry *type_value) {3594ConstExprValue *create_const_type(CodeGen *g, TypeTableEntry *type_value) {
3595 ConstExprValue *const_val = allocate<ConstExprValue>(1);3595 ConstExprValue *const_val = create_const_vals(1);
3596 init_const_type(g, const_val, type_value);3596 init_const_type(g, const_val, type_value);
3597 return const_val;3597 return const_val;
3598}3598}
...@@ -3604,14 +3604,14 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr...@@ -3604,14 +3604,14 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr
36043604
3605 const_val->special = ConstValSpecialStatic;3605 const_val->special = ConstValSpecialStatic;
3606 const_val->type = get_slice_type(g, array_val->type->data.array.child_type, is_const);3606 const_val->type = get_slice_type(g, array_val->type->data.array.child_type, is_const);
3607 const_val->data.x_struct.fields = allocate<ConstExprValue>(2);3607 const_val->data.x_struct.fields = create_const_vals(2);
36083608
3609 init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const);3609 init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const);
3610 init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len);3610 init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len);
3611}3611}
36123612
3613ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) {3613ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) {
3614 ConstExprValue *const_val = allocate<ConstExprValue>(1);3614 ConstExprValue *const_val = create_const_vals(1);
3615 init_const_slice(g, const_val, array_val, start, len, is_const);3615 init_const_slice(g, const_val, array_val, start, len, is_const);
3616 return const_val;3616 return const_val;
3617}3617}
...@@ -3630,7 +3630,7 @@ void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue...@@ -3630,7 +3630,7 @@ void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue
3630}3630}
36313631
3632ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const) {3632ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const) {
3633 ConstExprValue *const_val = allocate<ConstExprValue>(1);3633 ConstExprValue *const_val = create_const_vals(1);
3634 init_const_ptr_array(g, const_val, array_val, elem_index, is_const);3634 init_const_ptr_array(g, const_val, array_val, elem_index, is_const);
3635 return const_val;3635 return const_val;
3636}3636}
...@@ -3643,7 +3643,7 @@ void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *p...@@ -3643,7 +3643,7 @@ void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *p
3643}3643}
36443644
3645ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const) {3645ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const) {
3646 ConstExprValue *const_val = allocate<ConstExprValue>(1);3646 ConstExprValue *const_val = create_const_vals(1);
3647 init_const_ptr_ref(g, const_val, pointee_val, is_const);3647 init_const_ptr_ref(g, const_val, pointee_val, is_const);
3648 return const_val;3648 return const_val;
3649}3649}
...@@ -3660,7 +3660,7 @@ void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeT...@@ -3660,7 +3660,7 @@ void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeT
3660ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type,3660ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type,
3661 size_t addr, bool is_const)3661 size_t addr, bool is_const)
3662{3662{
3663 ConstExprValue *const_val = allocate<ConstExprValue>(1);3663 ConstExprValue *const_val = create_const_vals(1);
3664 init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const);3664 init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const);
3665 return const_val;3665 return const_val;
3666}3666}
...@@ -3673,7 +3673,7 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde...@@ -3673,7 +3673,7 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde
3673}3673}
36743674
3675ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) {3675ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) {
3676 ConstExprValue *const_val = allocate<ConstExprValue>(1);3676 ConstExprValue *const_val = create_const_vals(1);
3677 init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end);3677 init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end);
3678 return const_val;3678 return const_val;
3679}3679}
...@@ -3689,7 +3689,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {...@@ -3689,7 +3689,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
36893689
3690 const_val->special = ConstValSpecialStatic;3690 const_val->special = ConstValSpecialStatic;
3691 size_t field_count = wanted_type->data.structure.src_field_count;3691 size_t field_count = wanted_type->data.structure.src_field_count;
3692 const_val->data.x_struct.fields = allocate<ConstExprValue>(field_count);3692 const_val->data.x_struct.fields = create_const_vals(field_count);
3693 for (size_t i = 0; i < field_count; i += 1) {3693 for (size_t i = 0; i < field_count; i += 1) {
3694 ConstExprValue *field_val = &const_val->data.x_struct.fields[i];3694 ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
3695 field_val->type = wanted_type->data.structure.fields[i].type_entry;3695 field_val->type = wanted_type->data.structure.fields[i].type_entry;
...@@ -3707,6 +3707,15 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {...@@ -3707,6 +3707,15 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
3707 }3707 }
3708}3708}
37093709
3710ConstExprValue *create_const_vals(size_t count) {
3711 ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count);
3712 ConstExprValue *vals = allocate<ConstExprValue>(count);
3713 for (size_t i = 0; i < count; i += 1) {
3714 vals[i].global_refs = &global_refs[i];
3715 }
3716 return vals;
3717}
3718
3710void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) {3719void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) {
3711 if (type_entry->id == TypeTableEntryIdStruct) {3720 if (type_entry->id == TypeTableEntryIdStruct) {
3712 if (!type_entry->data.structure.complete)3721 if (!type_entry->data.structure.complete)
...@@ -3788,16 +3797,24 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -3788,16 +3797,24 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
3788 return false;3797 return false;
3789 return true;3798 return true;
3790 case ConstPtrSpecialBaseArray:3799 case ConstPtrSpecialBaseArray:
3791 if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val)3800 if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val &&
3801 a->data.x_ptr.data.base_array.array_val->global_refs !=
3802 b->data.x_ptr.data.base_array.array_val->global_refs)
3803 {
3792 return false;3804 return false;
3805 }
3793 if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index)3806 if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index)
3794 return false;3807 return false;
3795 if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr)3808 if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr)
3796 return false;3809 return false;
3797 return true;3810 return true;
3798 case ConstPtrSpecialBaseStruct:3811 case ConstPtrSpecialBaseStruct:
3799 if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val)3812 if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val &&
3813 a->data.x_ptr.data.base_struct.struct_val->global_refs !=
3814 b->data.x_ptr.data.base_struct.struct_val->global_refs)
3815 {
3800 return false;3816 return false;
3817 }
3801 if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index)3818 if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index)
3802 return false;3819 return false;
3803 return true;3820 return true;
...@@ -4293,7 +4310,7 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {...@@ -4293,7 +4310,7 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
4293 if (const_val->data.x_array.special == ConstArraySpecialUndef) {4310 if (const_val->data.x_array.special == ConstArraySpecialUndef) {
4294 const_val->data.x_array.special = ConstArraySpecialNone;4311 const_val->data.x_array.special = ConstArraySpecialNone;
4295 size_t elem_count = const_val->type->data.array.len;4312 size_t elem_count = const_val->type->data.array.len;
4296 const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count);4313 const_val->data.x_array.s_none.elements = create_const_vals(elem_count);
4297 for (size_t i = 0; i < elem_count; i += 1) {4314 for (size_t i = 0; i < elem_count; i += 1) {
4298 ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i];4315 ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i];
4299 element_val->type = const_val->type->data.array.child_type;4316 element_val->type = const_val->type->data.array.child_type;
src/analyze.hpp+2
...@@ -153,6 +153,8 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_...@@ -153,6 +153,8 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
153153
154void init_const_undefined(CodeGen *g, ConstExprValue *const_val);154void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
155155
156ConstExprValue *create_const_vals(size_t count);
157
156TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);158TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
157ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);159ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
158FnTableEntry *get_extern_panic_fn(CodeGen *g);160FnTableEntry *get_extern_panic_fn(CodeGen *g);
src/codegen.cpp+47-32
...@@ -682,8 +682,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {...@@ -682,8 +682,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
682682
683static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {683static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {
684 ConstExprValue *val = &g->panic_msg_vals[msg_id];684 ConstExprValue *val = &g->panic_msg_vals[msg_id];
685 if (val->llvm_global)685 if (val->global_refs->llvm_global)
686 return val->llvm_global;686 return val->global_refs->llvm_global;
687687
688 Buf *buf_msg = panic_msg_buf(msg_id);688 Buf *buf_msg = panic_msg_buf(msg_id);
689 ConstExprValue *array_val = create_const_str_lit(g, buf_msg);689 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) {...@@ -692,8 +692,8 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {
692 render_const_val_global(g, val, "");692 render_const_val_global(g, val, "");
693 render_const_val(g, val);693 render_const_val(g, val);
694694
695 assert(val->llvm_global);695 assert(val->global_refs->llvm_global);
696 return val->llvm_global;696 return val->global_refs->llvm_global;
697}697}
698698
699static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len) {699static 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) {...@@ -1086,11 +1086,11 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
1086 if (handle_is_ptr(instruction->value.type)) {1086 if (handle_is_ptr(instruction->value.type)) {
1087 render_const_val_global(g, &instruction->value, "");1087 render_const_val_global(g, &instruction->value, "");
1088 TypeTableEntry *ptr_type = get_pointer_to_type(g, instruction->value.type, true);1088 TypeTableEntry *ptr_type = get_pointer_to_type(g, instruction->value.type, true);
1089 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_global, ptr_type->type_ref, "");1089 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, ptr_type->type_ref, "");
1090 } else if (instruction->value.type->id == TypeTableEntryIdPointer) {1090 } else if (instruction->value.type->id == TypeTableEntryIdPointer) {
1091 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_value, instruction->value.type->type_ref, "");1091 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value, instruction->value.type->type_ref, "");
1092 } else {1092 } else {
1093 instruction->llvm_value = instruction->value.llvm_value;1093 instruction->llvm_value = instruction->value.global_refs->llvm_value;
1094 }1094 }
1095 assert(instruction->llvm_value);1095 assert(instruction->llvm_value);
1096 }1096 }
...@@ -1535,6 +1535,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -1535,6 +1535,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
15351535
1536 switch (cast_instruction->cast_op) {1536 switch (cast_instruction->cast_op) {
1537 case CastOpNoCast:1537 case CastOpNoCast:
1538 case CastOpNumLitToConcrete:
1538 zig_unreachable();1539 zig_unreachable();
1539 case CastOpNoop:1540 case CastOpNoop:
1540 return expr_val;1541 return expr_val;
...@@ -3197,7 +3198,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent...@@ -3197,7 +3198,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent
3197 case ConstParentIdNone:3198 case ConstParentIdNone:
3198 render_const_val(g, val);3199 render_const_val(g, val);
3199 render_const_val_global(g, val, "");3200 render_const_val_global(g, val, "");
3200 return val->llvm_global;3201 return val->global_refs->llvm_global;
3201 case ConstParentIdStruct:3202 case ConstParentIdStruct:
3202 return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val,3203 return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val,
3203 parent->data.p_struct.field_index);3204 parent->data.p_struct.field_index);
...@@ -3506,9 +3507,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3506,9 +3507,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3506 render_const_val(g, pointee);3507 render_const_val(g, pointee);
3507 render_const_val_global(g, pointee, "");3508 render_const_val_global(g, pointee, "");
3508 ConstExprValue *other_val = pointee;3509 ConstExprValue *other_val = pointee;
3509 const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref);3510 const_val->global_refs->llvm_value = LLVMConstBitCast(other_val->global_refs->llvm_global, const_val->type->type_ref);
3510 render_const_val_global(g, const_val, "");3511 render_const_val_global(g, const_val, "");
3511 return const_val->llvm_value;3512 return const_val->global_refs->llvm_value;
3512 }3513 }
3513 case ConstPtrSpecialBaseArray:3514 case ConstPtrSpecialBaseArray:
3514 {3515 {
...@@ -3518,15 +3519,15 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3518,15 +3519,15 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3518 if (array_const_val->type->zero_bits) {3519 if (array_const_val->type->zero_bits) {
3519 // make this a null pointer3520 // make this a null pointer
3520 TypeTableEntry *usize = g->builtin_types.entry_usize;3521 TypeTableEntry *usize = g->builtin_types.entry_usize;
3521 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),3522 const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
3522 const_val->type->type_ref);3523 const_val->type->type_ref);
3523 render_const_val_global(g, const_val, "");3524 render_const_val_global(g, const_val, "");
3524 return const_val->llvm_value;3525 return const_val->global_refs->llvm_value;
3525 }3526 }
3526 LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val,3527 LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val,
3527 elem_index);3528 elem_index);
3528 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);3529 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
3529 const_val->llvm_value = ptr_val;3530 const_val->global_refs->llvm_value = ptr_val;
3530 render_const_val_global(g, const_val, "");3531 render_const_val_global(g, const_val, "");
3531 return ptr_val;3532 return ptr_val;
3532 }3533 }
...@@ -3537,10 +3538,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3537,10 +3538,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3537 if (struct_const_val->type->zero_bits) {3538 if (struct_const_val->type->zero_bits) {
3538 // make this a null pointer3539 // make this a null pointer
3539 TypeTableEntry *usize = g->builtin_types.entry_usize;3540 TypeTableEntry *usize = g->builtin_types.entry_usize;
3540 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),3541 const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
3541 const_val->type->type_ref);3542 const_val->type->type_ref);
3542 render_const_val_global(g, const_val, "");3543 render_const_val_global(g, const_val, "");
3543 return const_val->llvm_value;3544 return const_val->global_refs->llvm_value;
3544 }3545 }
3545 size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index;3546 size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index;
3546 size_t gen_field_index =3547 size_t gen_field_index =
...@@ -3548,7 +3549,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3548,7 +3549,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3548 LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val,3549 LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val,
3549 gen_field_index);3550 gen_field_index);
3550 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);3551 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
3551 const_val->llvm_value = ptr_val;3552 const_val->global_refs->llvm_value = ptr_val;
3552 render_const_val_global(g, const_val, "");3553 render_const_val_global(g, const_val, "");
3553 return ptr_val;3554 return ptr_val;
3554 }3555 }
...@@ -3556,10 +3557,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3556,10 +3557,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3556 {3557 {
3557 uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr;3558 uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr;
3558 TypeTableEntry *usize = g->builtin_types.entry_usize;3559 TypeTableEntry *usize = g->builtin_types.entry_usize;
3559 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false),3560 const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false),
3560 const_val->type->type_ref);3561 const_val->type->type_ref);
3561 render_const_val_global(g, const_val, "");3562 render_const_val_global(g, const_val, "");
3562 return const_val->llvm_value;3563 return const_val->global_refs->llvm_value;
3563 }3564 }
3564 }3565 }
3565 }3566 }
...@@ -3608,27 +3609,32 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3608,27 +3609,32 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3608}3609}
36093610
3610static void render_const_val(CodeGen *g, ConstExprValue *const_val) {3611static void render_const_val(CodeGen *g, ConstExprValue *const_val) {
3611 if (!const_val->llvm_value)3612 if (!const_val->global_refs)
3612 const_val->llvm_value = gen_const_val(g, const_val);3613 const_val->global_refs = allocate<ConstGlobalRefs>(1);
3614 if (!const_val->global_refs->llvm_value)
3615 const_val->global_refs->llvm_value = gen_const_val(g, const_val);
36133616
3614 if (const_val->llvm_global)3617 if (const_val->global_refs->llvm_global)
3615 LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value);3618 LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value);
3616}3619}
36173620
3618static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const char *name) {3621static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const char *name) {
3619 if (!const_val->llvm_global) {3622 if (!const_val->global_refs)
3620 LLVMTypeRef type_ref = const_val->llvm_value ? LLVMTypeOf(const_val->llvm_value) : const_val->type->type_ref;3623 const_val->global_refs = allocate<ConstGlobalRefs>(1);
3624
3625 if (!const_val->global_refs->llvm_global) {
3626 LLVMTypeRef type_ref = const_val->global_refs->llvm_value ? LLVMTypeOf(const_val->global_refs->llvm_value) : const_val->type->type_ref;
3621 LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, name);3627 LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, name);
3622 LLVMSetLinkage(global_value, LLVMInternalLinkage);3628 LLVMSetLinkage(global_value, LLVMInternalLinkage);
3623 LLVMSetGlobalConstant(global_value, true);3629 LLVMSetGlobalConstant(global_value, true);
3624 LLVMSetUnnamedAddr(global_value, true);3630 LLVMSetUnnamedAddr(global_value, true);
3625 LLVMSetAlignment(global_value, get_type_alignment(g, const_val->type));3631 LLVMSetAlignment(global_value, get_type_alignment(g, const_val->type));
36263632
3627 const_val->llvm_global = global_value;3633 const_val->global_refs->llvm_global = global_value;
3628 }3634 }
36293635
3630 if (const_val->llvm_value)3636 if (const_val->global_refs->llvm_value)
3631 LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value);3637 LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value);
3632}3638}
36333639
3634static void delete_unused_builtin_fns(CodeGen *g) {3640static void delete_unused_builtin_fns(CodeGen *g) {
...@@ -3849,7 +3855,7 @@ static void do_code_gen(CodeGen *g) {...@@ -3849,7 +3855,7 @@ static void do_code_gen(CodeGen *g) {
3849 bool exported = (var->linkage == VarLinkageExport);3855 bool exported = (var->linkage == VarLinkageExport);
3850 render_const_val(g, var->value);3856 render_const_val(g, var->value);
3851 render_const_val_global(g, var->value, buf_ptr(get_mangled_name(g, &var->name, exported)));3857 render_const_val_global(g, var->value, buf_ptr(get_mangled_name(g, &var->name, exported)));
3852 global_value = var->value->llvm_global;3858 global_value = var->value->global_refs->llvm_global;
38533859
3854 if (exported) {3860 if (exported) {
3855 LLVMSetLinkage(global_value, LLVMExternalLinkage);3861 LLVMSetLinkage(global_value, LLVMExternalLinkage);
...@@ -3862,7 +3868,7 @@ static void do_code_gen(CodeGen *g) {...@@ -3862,7 +3868,7 @@ static void do_code_gen(CodeGen *g) {
38623868
3863 // TODO debug info for function pointers3869 // TODO debug info for function pointers
3864 if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) {3870 if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) {
3865 gen_global_var(g, var, var->value->llvm_value, var->value->type);3871 gen_global_var(g, var, var->value->global_refs->llvm_value, var->value->type);
3866 }3872 }
3867 }3873 }
38683874
...@@ -4737,9 +4743,18 @@ static void init(CodeGen *g) {...@@ -4737,9 +4743,18 @@ static void init(CodeGen *g) {
47374743
4738 g->invalid_instruction = allocate<IrInstruction>(1);4744 g->invalid_instruction = allocate<IrInstruction>(1);
4739 g->invalid_instruction->value.type = g->builtin_types.entry_invalid;4745 g->invalid_instruction->value.type = g->builtin_types.entry_invalid;
4746 g->invalid_instruction->value.global_refs = allocate<ConstGlobalRefs>(1);
47404747
4741 g->const_void_val.special = ConstValSpecialStatic;4748 g->const_void_val.special = ConstValSpecialStatic;
4742 g->const_void_val.type = g->builtin_types.entry_void;4749 g->const_void_val.type = g->builtin_types.entry_void;
4750 g->const_void_val.global_refs = allocate<ConstGlobalRefs>(1);
4751
4752 {
4753 ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(PanicMsgIdCount);
4754 for (size_t i = 0; i < PanicMsgIdCount; i += 1) {
4755 g->panic_msg_vals[i].global_refs = &global_refs[i];
4756 }
4757 }
47434758
4744 define_builtin_fns(g);4759 define_builtin_fns(g);
4745 define_builtin_compile_vars(g);4760 define_builtin_compile_vars(g);
...@@ -4826,10 +4841,10 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {...@@ -4826,10 +4841,10 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
4826 TypeTableEntry *field_types[] = { str_type, fn_type, };4841 TypeTableEntry *field_types[] = { str_type, fn_type, };
4827 TypeTableEntry *struct_type = get_struct_type(g, "ZigTestFn", field_names, field_types, 2);4842 TypeTableEntry *struct_type = get_struct_type(g, "ZigTestFn", field_names, field_types, 2);
48284843
4829 ConstExprValue *test_fn_array = allocate<ConstExprValue>(1);4844 ConstExprValue *test_fn_array = create_const_vals(1);
4830 test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length);4845 test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length);
4831 test_fn_array->special = ConstValSpecialStatic;4846 test_fn_array->special = ConstValSpecialStatic;
4832 test_fn_array->data.x_array.s_none.elements = allocate<ConstExprValue>(g->test_fns.length);4847 test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length);
48334848
4834 for (size_t i = 0; i < g->test_fns.length; i += 1) {4849 for (size_t i = 0; i < g->test_fns.length; i += 1) {
4835 FnTableEntry *test_fn_entry = g->test_fns.at(i);4850 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) {...@@ -4840,7 +4855,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
4840 this_val->data.x_struct.parent.id = ConstParentIdArray;4855 this_val->data.x_struct.parent.id = ConstParentIdArray;
4841 this_val->data.x_struct.parent.data.p_array.array_val = test_fn_array;4856 this_val->data.x_struct.parent.data.p_array.array_val = test_fn_array;
4842 this_val->data.x_struct.parent.data.p_array.elem_index = i;4857 this_val->data.x_struct.parent.data.p_array.elem_index = i;
4843 this_val->data.x_struct.fields = allocate<ConstExprValue>(2);4858 this_val->data.x_struct.fields = create_const_vals(2);
48444859
4845 ConstExprValue *name_field = &this_val->data.x_struct.fields[0];4860 ConstExprValue *name_field = &this_val->data.x_struct.fields[0];
4846 ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name);4861 ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name);
src/ir.cpp+39-24
...@@ -553,6 +553,7 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no...@@ -553,6 +553,7 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no
553 special_instruction->base.source_node = source_node;553 special_instruction->base.source_node = source_node;
554 special_instruction->base.debug_id = exec_next_debug_id(irb->exec);554 special_instruction->base.debug_id = exec_next_debug_id(irb->exec);
555 special_instruction->base.owner_bb = irb->current_basic_block;555 special_instruction->base.owner_bb = irb->current_basic_block;
556 special_instruction->base.value.global_refs = allocate<ConstGlobalRefs>(1);
556 return special_instruction;557 return special_instruction;
557}558}
558559
...@@ -3210,7 +3211,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco...@@ -3210,7 +3211,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
3210 variable_entry->mem_slot_index = SIZE_MAX;3211 variable_entry->mem_slot_index = SIZE_MAX;
3211 variable_entry->is_comptime = is_comptime;3212 variable_entry->is_comptime = is_comptime;
3212 variable_entry->src_arg_index = SIZE_MAX;3213 variable_entry->src_arg_index = SIZE_MAX;
3213 variable_entry->value = allocate<ConstExprValue>(1);3214 variable_entry->value = create_const_vals(1);
32143215
3215 if (name) {3216 if (name) {
3216 buf_init_from_buf(&variable_entry->name, name);3217 buf_init_from_buf(&variable_entry->name, name);
...@@ -6565,6 +6566,14 @@ static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableE...@@ -6565,6 +6566,14 @@ static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableE
6565 }6566 }
6566}6567}
65676568
6569static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) {
6570 ConstGlobalRefs *global_refs = dest->global_refs;
6571 *dest = *src;
6572 if (!same_global_refs) {
6573 dest->global_refs = global_refs;
6574 }
6575}
6576
6568static void eval_const_expr_implicit_cast(CastOp cast_op,6577static void eval_const_expr_implicit_cast(CastOp cast_op,
6569 ConstExprValue *other_val, TypeTableEntry *other_type,6578 ConstExprValue *other_val, TypeTableEntry *other_type,
6570 ConstExprValue *const_val, TypeTableEntry *new_type)6579 ConstExprValue *const_val, TypeTableEntry *new_type)
...@@ -6576,7 +6585,13 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -6576,7 +6585,13 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
6576 case CastOpNoCast:6585 case CastOpNoCast:
6577 zig_unreachable();6586 zig_unreachable();
6578 case CastOpNoop:6587 case CastOpNoop:
6579 *const_val = *other_val;6588 {
6589 copy_const_val(const_val, other_val, other_val->special == ConstValSpecialStatic);
6590 const_val->type = new_type;
6591 break;
6592 }
6593 case CastOpNumLitToConcrete:
6594 const_val->data.x_bignum = other_val->data.x_bignum;
6580 const_val->type = new_type;6595 const_val->type = new_type;
6581 break;6596 break;
6582 case CastOpResizeSlice:6597 case CastOpResizeSlice:
...@@ -7188,7 +7203,7 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction...@@ -7188,7 +7203,7 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction
7188 }7203 }
7189 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,7204 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
7190 source_instr->source_node, wanted_type);7205 source_instr->source_node, wanted_type);
7191 result->value = *val;7206 result->value.data.x_bignum = val->data.x_bignum;
7192 result->value.type = wanted_type;7207 result->value.type = wanted_type;
7193 return result;7208 return result;
7194 }7209 }
...@@ -7613,7 +7628,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -7613,7 +7628,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
7613 (actual_type->id == TypeTableEntryIdNumLitInt &&7628 (actual_type->id == TypeTableEntryIdNumLitInt &&
7614 wanted_type->id == TypeTableEntryIdInt))7629 wanted_type->id == TypeTableEntryIdInt))
7615 {7630 {
7616 op = CastOpNoop;7631 op = CastOpNumLitToConcrete;
7617 } else if (wanted_type->id == TypeTableEntryIdInt) {7632 } else if (wanted_type->id == TypeTableEntryIdInt) {
7618 op = CastOpFloatToInt;7633 op = CastOpFloatToInt;
7619 } else if (wanted_type->id == TypeTableEntryIdFloat) {7634 } else if (wanted_type->id == TypeTableEntryIdFloat) {
...@@ -7741,7 +7756,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc...@@ -7741,7 +7756,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
7741 if (pointee->special != ConstValSpecialRuntime) {7756 if (pointee->special != ConstValSpecialRuntime) {
7742 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,7757 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,
7743 source_instruction->source_node, child_type);7758 source_instruction->source_node, child_type);
7744 result->value = *pointee;7759 copy_const_val(&result->value, pointee, ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst);
7745 return result;7760 return result;
7746 }7761 }
7747 }7762 }
...@@ -8584,7 +8599,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *...@@ -8584,7 +8599,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *
85848599
8585 result_type = get_pointer_to_type(ira->codegen, child_type, true);8600 result_type = get_pointer_to_type(ira->codegen, child_type, true);
85868601
8587 out_array_val = allocate<ConstExprValue>(1);8602 out_array_val = create_const_vals(1);
8588 out_array_val->special = ConstValSpecialStatic;8603 out_array_val->special = ConstValSpecialStatic;
8589 out_array_val->type = get_array_type(ira->codegen, child_type, new_len);8604 out_array_val->type = get_array_type(ira->codegen, child_type, new_len);
8590 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;8605 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
...@@ -8592,7 +8607,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *...@@ -8592,7 +8607,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *
8592 out_val->data.x_ptr.data.base_array.array_val = out_array_val;8607 out_val->data.x_ptr.data.base_array.array_val = out_array_val;
8593 out_val->data.x_ptr.data.base_array.elem_index = 0;8608 out_val->data.x_ptr.data.base_array.elem_index = 0;
8594 }8609 }
8595 out_array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(new_len);8610 out_array_val->data.x_array.s_none.elements = create_const_vals(new_len);
85968611
8597 expand_undef_array(ira->codegen, op1_array_val);8612 expand_undef_array(ira->codegen, op1_array_val);
85988613
...@@ -8648,7 +8663,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp...@@ -8648,7 +8663,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp
8648 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);8663 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
86498664
8650 uint64_t new_array_len = array_len.data.x_uint;8665 uint64_t new_array_len = array_len.data.x_uint;
8651 out_val->data.x_array.s_none.elements = allocate<ConstExprValue>(new_array_len);8666 out_val->data.x_array.s_none.elements = create_const_vals(new_array_len);
86528667
8653 expand_undef_array(ira->codegen, array_val);8668 expand_undef_array(ira->codegen, array_val);
86548669
...@@ -9139,7 +9154,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -9139,7 +9154,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
9139 GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1);9154 GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1);
9140 generic_id->fn_entry = fn_entry;9155 generic_id->fn_entry = fn_entry;
9141 generic_id->param_count = 0;9156 generic_id->param_count = 0;
9142 generic_id->params = allocate<ConstExprValue>(new_fn_arg_count);9157 generic_id->params = create_const_vals(new_fn_arg_count);
9143 size_t next_proto_i = 0;9158 size_t next_proto_i = 0;
91449159
9145 if (first_arg_ptr) {9160 if (first_arg_ptr) {
...@@ -9451,7 +9466,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp...@@ -9451,7 +9466,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp
9451 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value);9466 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value);
9452 if (pointee->type == child_type) {9467 if (pointee->type == child_type) {
9453 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);9468 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
9454 *out_val = *pointee;9469 copy_const_val(out_val, pointee, value->value.data.x_ptr.mut == ConstPtrMutComptimeConst);
9455 return child_type;9470 return child_type;
9456 }9471 }
9457 }9472 }
...@@ -10118,7 +10133,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source...@@ -10118,7 +10133,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
1011810133
10119 // TODO instead of allocating this every time, put it in the tld value and we can reference10134 // TODO instead of allocating this every time, put it in the tld value and we can reference
10120 // the same one every time10135 // the same one every time
10121 ConstExprValue *const_val = allocate<ConstExprValue>(1);10136 ConstExprValue *const_val = create_const_vals(1);
10122 const_val->special = ConstValSpecialStatic;10137 const_val->special = ConstValSpecialStatic;
10123 const_val->type = fn_entry->type_entry;10138 const_val->type = fn_entry->type_entry;
10124 const_val->data.x_fn.fn_entry = fn_entry;10139 const_val->data.x_fn.fn_entry = fn_entry;
...@@ -10162,7 +10177,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -10162,7 +10177,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
10162 }10177 }
10163 } else if (container_type->id == TypeTableEntryIdArray) {10178 } else if (container_type->id == TypeTableEntryIdArray) {
10164 if (buf_eql_str(field_name, "len")) {10179 if (buf_eql_str(field_name, "len")) {
10165 ConstExprValue *len_val = allocate<ConstExprValue>(1);10180 ConstExprValue *len_val = create_const_vals(1);
10166 init_const_usize(ira->codegen, len_val, container_type->data.array.len);10181 init_const_usize(ira->codegen, len_val, container_type->data.array.len);
1016710182
10168 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;10183 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
...@@ -10185,7 +10200,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -10185,7 +10200,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
10185 ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val);10200 ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val);
1018610201
10187 if (buf_eql_str(field_name, "len")) {10202 if (buf_eql_str(field_name, "len")) {
10188 ConstExprValue *len_val = allocate<ConstExprValue>(1);10203 ConstExprValue *len_val = create_const_vals(1);
10189 size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index;10204 size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index;
10190 init_const_usize(ira->codegen, len_val, len);10205 init_const_usize(ira->codegen, len_val, len);
1019110206
...@@ -10258,7 +10273,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -10258,7 +10273,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
10258 } else if (child_type->id == TypeTableEntryIdPureError) {10273 } else if (child_type->id == TypeTableEntryIdPureError) {
10259 auto err_table_entry = ira->codegen->error_table.maybe_get(field_name);10274 auto err_table_entry = ira->codegen->error_table.maybe_get(field_name);
10260 if (err_table_entry) {10275 if (err_table_entry) {
10261 ConstExprValue *const_val = allocate<ConstExprValue>(1);10276 ConstExprValue *const_val = create_const_vals(1);
10262 const_val->special = ConstValSpecialStatic;10277 const_val->special = ConstValSpecialStatic;
10263 const_val->type = child_type;10278 const_val->type = child_type;
10264 const_val->data.x_pure_err = err_table_entry->value;10279 const_val->data.x_pure_err = err_table_entry->value;
...@@ -11346,7 +11361,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -11346,7 +11361,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
11346 case TypeTableEntryIdPureError:11361 case TypeTableEntryIdPureError:
11347 if (pointee_val) {11362 if (pointee_val) {
11348 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);11363 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
11349 *out_val = *pointee_val;11364 copy_const_val(out_val, pointee_val, true);
11350 out_val->type = target_type;11365 out_val->type = target_type;
11351 return target_type;11366 return target_type;
11352 }11367 }
...@@ -11583,7 +11598,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru...@@ -11583,7 +11598,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
11583 ConstExprValue const_val = {};11598 ConstExprValue const_val = {};
11584 const_val.special = ConstValSpecialStatic;11599 const_val.special = ConstValSpecialStatic;
11585 const_val.type = container_type;11600 const_val.type = container_type;
11586 const_val.data.x_struct.fields = allocate<ConstExprValue>(actual_field_count);11601 const_val.data.x_struct.fields = create_const_vals(actual_field_count);
11587 for (size_t i = 0; i < instr_field_count; i += 1) {11602 for (size_t i = 0; i < instr_field_count; i += 1) {
11588 IrInstructionContainerInitFieldsField *field = &fields[i];11603 IrInstructionContainerInitFieldsField *field = &fields[i];
1158911604
...@@ -11624,7 +11639,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru...@@ -11624,7 +11639,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
11624 if (!field_val)11639 if (!field_val)
11625 return ira->codegen->builtin_types.entry_invalid;11640 return ira->codegen->builtin_types.entry_invalid;
1162611641
11627 const_val.data.x_struct.fields[field_index] = *field_val;11642 copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true);
11628 } else {11643 } else {
11629 first_non_const_instruction = casted_field_value;11644 first_non_const_instruction = casted_field_value;
11630 const_val.special = ConstValSpecialRuntime;11645 const_val.special = ConstValSpecialRuntime;
...@@ -11698,7 +11713,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -11698,7 +11713,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
11698 ConstExprValue const_val = {};11713 ConstExprValue const_val = {};
11699 const_val.special = ConstValSpecialStatic;11714 const_val.special = ConstValSpecialStatic;
11700 const_val.type = fixed_size_array_type;11715 const_val.type = fixed_size_array_type;
11701 const_val.data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count);11716 const_val.data.x_array.s_none.elements = create_const_vals(elem_count);
1170211717
11703 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);11718 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
1170411719
...@@ -11723,7 +11738,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -11723,7 +11738,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
11723 if (!elem_val)11738 if (!elem_val)
11724 return ira->codegen->builtin_types.entry_invalid;11739 return ira->codegen->builtin_types.entry_invalid;
1172511740
11726 const_val.data.x_array.s_none.elements[i] = *elem_val;11741 copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true);
11727 } else {11742 } else {
11728 first_non_const_instruction = casted_arg;11743 first_non_const_instruction = casted_arg;
11729 const_val.special = ConstValSpecialRuntime;11744 const_val.special = ConstValSpecialRuntime;
...@@ -11950,7 +11965,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc...@@ -11950,7 +11965,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc
11950 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true);11965 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true);
11951 }11966 }
11952 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);11967 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
11953 *out_val = *err->cached_error_name_val;11968 copy_const_val(out_val, err->cached_error_name_val, true);
11954 return str_type;11969 return str_type;
11955 }11970 }
1195611971
...@@ -12133,7 +12148,7 @@ static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstru...@@ -12133,7 +12148,7 @@ static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstru
12133 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, &type_entry->name);12148 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, &type_entry->name);
12134 }12149 }
12135 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);12150 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
12136 *out_val = *type_entry->cached_const_name_val;12151 copy_const_val(out_val, type_entry->cached_const_name_val, true);
12137 return out_val->type;12152 return out_val->type;
12138}12153}
1213912154
...@@ -12809,7 +12824,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -12809,7 +12824,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
12809 }12824 }
1281012825
12811 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);12826 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
12812 out_val->data.x_struct.fields = allocate<ConstExprValue>(2);12827 out_val->data.x_struct.fields = create_const_vals(2);
1281312828
12814 ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index];12829 ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index];
1281512830
...@@ -13370,7 +13385,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc...@@ -13370,7 +13385,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc
13370 return ira->codegen->builtin_types.entry_invalid;13385 return ira->codegen->builtin_types.entry_invalid;
1337113386
13372 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);13387 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
13373 *out_val = *val;13388 copy_const_val(out_val, val, false);
13374 out_val->type = dest_type;13389 out_val->type = dest_type;
13375 return dest_type;13390 return dest_type;
13376 }13391 }
...@@ -13696,7 +13711,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl...@@ -13696,7 +13711,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl
13696 ira->new_irb.exec = new_exec;13711 ira->new_irb.exec = new_exec;
1369713712
13698 ira->exec_context.mem_slot_count = ira->old_irb.exec->mem_slot_count;13713 ira->exec_context.mem_slot_count = ira->old_irb.exec->mem_slot_count;
13699 ira->exec_context.mem_slot_list = allocate<ConstExprValue>(ira->exec_context.mem_slot_count);13714 ira->exec_context.mem_slot_list = create_const_vals(ira->exec_context.mem_slot_count);
1370013715
13701 IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0);13716 IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0);
13702 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr);13717 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr);
test/cases/eval.zig+10
...@@ -332,3 +332,13 @@ test "compile-time downcast when the bits fit" {...@@ -332,3 +332,13 @@ test "compile-time downcast when the bits fit" {
332 assert(byte == 255);332 assert(byte == 255);
333 }333 }
334}334}
335
336const hi1 = "hi";
337const hi2 = hi1;
338test "const global shares pointer with other same one" {
339 assertEqualPtrs(&hi1[0], &hi2[0]);
340 comptime assert(&hi1[0] == &hi2[0]);
341}
342fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) {
343 assert(ptr1 == ptr2);
344}
test/cases/var_args.zig+14
...@@ -65,3 +65,17 @@ test "array of var args functions" {...@@ -65,3 +65,17 @@ test "array of var args functions" {
65 assert(foos[0]());65 assert(foos[0]());
66 assert(!foos[1]());66 assert(!foos[1]());
67}67}
68
69
70test "pass array and slice of same array to var args should have same pointers" {
71 const array = "hi";
72 const slice: []const u8 = array;
73 return assertSlicePtrsEql(array, slice);
74}
75
76fn assertSlicePtrsEql(args: ...) {
77 const s1 = ([]const u8)(args[0]);
78 const s2 = args[1];
79 assert(s1.ptr == s2.ptr);
80}
81
test/tests.zig+2-4
...@@ -591,8 +591,7 @@ pub const CompileErrorContext = struct {...@@ -591,8 +591,7 @@ pub const CompileErrorContext = struct {
591 tc.addSourceFile(".tmp_source.zig", source);591 tc.addSourceFile(".tmp_source.zig", source);
592 comptime var arg_i = 0;592 comptime var arg_i = 0;
593 inline while (arg_i < expected_lines.len) : (arg_i += 1) {593 inline while (arg_i < expected_lines.len) : (arg_i += 1) {
594 // TODO mem.dupe is because of issue #336594 tc.addExpectedError(expected_lines[arg_i]);
595 tc.addExpectedError(%%mem.dupe(self.b.allocator, u8, expected_lines[arg_i]));
596 }595 }
597 return tc;596 return tc;
598 }597 }
...@@ -854,8 +853,7 @@ pub const ParseHContext = struct {...@@ -854,8 +853,7 @@ pub const ParseHContext = struct {
854 tc.addSourceFile("source.h", source);853 tc.addSourceFile("source.h", source);
855 comptime var arg_i = 0;854 comptime var arg_i = 0;
856 inline while (arg_i < expected_lines.len) : (arg_i += 1) {855 inline while (arg_i < expected_lines.len) : (arg_i += 1) {
857 // TODO mem.dupe is because of issue #336856 tc.addExpectedError(expected_lines[arg_i]);
858 tc.addExpectedError(%%mem.dupe(self.b.allocator, u8, expected_lines[arg_i]));
859 }857 }
860 return tc;858 return tc;
861 }859 }