authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-16 10:06:58-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-16 10:06:58-05:00
logf12d36641f67564d2103f75ed7a5445219197db5
tree63f967ea88d81475466fbc00929e05d8fe1ec2a3
parent018cbff438cedc19d0ad18021619ec7ede997307

union secret field is the tag index instead of distinct type index

See #144

4 files changed, 15 insertions(+), 17 deletions(-)

src/all_types.hpp+3-3
...@@ -105,7 +105,8 @@ struct ConstStructValue {...@@ -105,7 +105,8 @@ struct ConstStructValue {
105};105};
106106
107struct ConstUnionValue {107struct ConstUnionValue {
108 ConstExprValue *value;108 uint64_t tag;
109 ConstExprValue *payload;
109 ConstParent parent;110 ConstParent parent;
110};111};
111112
...@@ -349,6 +350,7 @@ struct TypeEnumField {...@@ -349,6 +350,7 @@ struct TypeEnumField {
349struct TypeUnionField {350struct TypeUnionField {
350 Buf *name;351 Buf *name;
351 TypeTableEntry *type_entry;352 TypeTableEntry *type_entry;
353 uint32_t value;
352 uint32_t gen_index;354 uint32_t gen_index;
353};355};
354356
...@@ -1067,8 +1069,6 @@ struct TypeTableEntryUnion {...@@ -1067,8 +1069,6 @@ struct TypeTableEntryUnion {
10671069
1068 uint32_t union_size_bytes;1070 uint32_t union_size_bytes;
1069 TypeTableEntry *most_aligned_union_member;1071 TypeTableEntry *most_aligned_union_member;
1070
1071 HashMap<const TypeTableEntry *, uint32_t, type_ptr_hash, type_ptr_eql> distinct_types = {};
1072};1072};
10731073
1074struct FnGenParamInfo {1074struct FnGenParamInfo {
src/analyze.cpp+8-10
...@@ -1872,8 +1872,6 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {...@@ -1872,8 +1872,6 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
18721872
1873 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);1873 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
1874 ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);1874 ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
1875 auto distinct_types = &union_type->data.unionation.distinct_types;
1876 distinct_types->init(4);
18771875
1878 Scope *scope = &union_type->data.unionation.decls_scope->base;1876 Scope *scope = &union_type->data.unionation.decls_scope->base;
1879 ImportTableEntry *import = get_scope_import(scope);1877 ImportTableEntry *import = get_scope_import(scope);
...@@ -1895,10 +1893,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {...@@ -1895,10 +1893,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
1895 if (!type_has_bits(field_type))1893 if (!type_has_bits(field_type))
1896 continue;1894 continue;
18971895
1898 size_t distinct_type_index = distinct_types->size();1896 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_union_field->name), i);
1899 if (distinct_types->put_unique(field_type, distinct_type_index) == nullptr) {
1900 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(&field_type->name), distinct_type_index);
1901 }
19021897
1903 uint64_t store_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);1898 uint64_t store_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
1904 uint64_t abi_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);1899 uint64_t abi_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);
...@@ -1954,7 +1949,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {...@@ -1954,7 +1949,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
19541949
1955 assert(most_aligned_union_member != nullptr);1950 assert(most_aligned_union_member != nullptr);
19561951
1957 bool want_safety = (distinct_types->size() > 1) && auto_layout;1952 bool want_safety = auto_layout && (field_count >= 2);
1958 uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;1953 uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
19591954
19601955
...@@ -2007,7 +2002,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {...@@ -2007,7 +2002,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
2007 assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits);2002 assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits);
20082003
2009 // create llvm type for root struct2004 // create llvm type for root struct
2010 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, distinct_types->size() - 1);2005 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
2011 TypeTableEntry *tag_type_entry = tag_int_type;2006 TypeTableEntry *tag_type_entry = tag_int_type;
2012 union_type->data.unionation.tag_type = tag_type_entry;2007 union_type->data.unionation.tag_type = tag_type_entry;
2013 uint64_t align_of_tag_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);2008 uint64_t align_of_tag_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
...@@ -2034,7 +2029,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {...@@ -2034,7 +2029,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
2034 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,2029 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
2035 ZigLLVMTypeToScope(union_type->di_type), "AnonEnum",2030 ZigLLVMTypeToScope(union_type->di_type), "AnonEnum",
2036 import->di_file, (unsigned)(decl_node->line + 1),2031 import->di_file, (unsigned)(decl_node->line + 1),
2037 tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, distinct_types->size(),2032 tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, field_count,
2038 tag_type_entry->di_type, "");2033 tag_type_entry->di_type, "");
20392034
2040 // create debug type for union2035 // create debug type for union
...@@ -2257,6 +2252,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2257,6 +2252,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2257 type_union_field->name = field_node->data.struct_field.name;2252 type_union_field->name = field_node->data.struct_field.name;
2258 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);2253 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
2259 type_union_field->type_entry = field_type;2254 type_union_field->type_entry = field_type;
2255 type_union_field->value = i;
22602256
2261 type_ensure_zero_bits_known(g, field_type);2257 type_ensure_zero_bits_known(g, field_type);
2262 if (type_is_invalid(field_type)) {2258 if (type_is_invalid(field_type)) {
...@@ -2276,9 +2272,11 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2276,9 +2272,11 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2276 }2272 }
2277 }2273 }
22782274
2275 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
2276
2279 union_type->data.unionation.zero_bits_loop_flag = false;2277 union_type->data.unionation.zero_bits_loop_flag = false;
2280 union_type->data.unionation.gen_field_count = gen_field_index;2278 union_type->data.unionation.gen_field_count = gen_field_index;
2281 union_type->zero_bits = (gen_field_index == 0);2279 union_type->zero_bits = (gen_field_index == 0 && (field_count < 2 || !auto_layout));
2282 union_type->data.unionation.zero_bits_known = true;2280 union_type->data.unionation.zero_bits_known = true;
22832281
2284 // also compute abi_alignment2282 // also compute abi_alignment
src/codegen.cpp+2-3
...@@ -3962,7 +3962,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3962,7 +3962,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3962 case TypeTableEntryIdUnion:3962 case TypeTableEntryIdUnion:
3963 {3963 {
3964 LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref;3964 LLVMTypeRef union_type_ref = type_entry->data.unionation.union_type_ref;
3965 ConstExprValue *payload_value = const_val->data.x_union.value;3965 ConstExprValue *payload_value = const_val->data.x_union.payload;
3966 assert(payload_value != nullptr);3966 assert(payload_value != nullptr);
39673967
3968 if (!type_has_bits(payload_value->type)) {3968 if (!type_has_bits(payload_value->type)) {
...@@ -3999,8 +3999,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3999,8 +3999,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3999 return union_value_ref;3999 return union_value_ref;
4000 }4000 }
40014001
4002 size_t distinct_type_index = type_entry->data.unionation.distinct_types.get(const_val->data.x_union.value->type);4002 LLVMValueRef tag_value = LLVMConstInt(type_entry->data.unionation.tag_type->type_ref, const_val->data.x_union.tag, false);
4003 LLVMValueRef tag_value = LLVMConstInt(type_entry->data.unionation.tag_type->type_ref, distinct_type_index, false);
40044003
4005 LLVMValueRef fields[2];4004 LLVMValueRef fields[2];
4006 fields[type_entry->data.unionation.gen_union_index] = union_value_ref;4005 fields[type_entry->data.unionation.gen_union_index] = union_value_ref;
src/ir.cpp+2-1
...@@ -13158,7 +13158,8 @@ static TypeTableEntry *ir_analyze_container_init_fields_union(IrAnalyze *ira, Ir...@@ -13158,7 +13158,8 @@ static TypeTableEntry *ir_analyze_container_init_fields_union(IrAnalyze *ira, Ir
13158 return ira->codegen->builtin_types.entry_invalid;13158 return ira->codegen->builtin_types.entry_invalid;
1315913159
13160 ConstExprValue *out_val = ir_build_const_from(ira, instruction);13160 ConstExprValue *out_val = ir_build_const_from(ira, instruction);
13161 out_val->data.x_union.value = field_val;13161 out_val->data.x_union.payload = field_val;
13162 out_val->data.x_union.tag = type_field->value;
1316213163
13163 ConstParent *parent = get_const_val_parent(ira->codegen, field_val);13164 ConstParent *parent = get_const_val_parent(ira->codegen, field_val);
13164 if (parent != nullptr) {13165 if (parent != nullptr) {