diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2021-06-26 13:40:22 +0200 |
|---|---|---|
| committer | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2021-06-26 13:40:22 +0200 |
| commit | c3697193629ac4e87972d009b0a2789aaeff4356 (patch) | |
| tree | 121b241bcc4242f44a52bb3627ddbd874837246a /src/llvm_backend.cpp | |
| parent | 40a12cca53dcecd73740bb4cb704cee25189cfc1 (diff) | |
| parent | d8940f5fd712873a79cce27aea6f0e05e58ae09a (diff) | |
Merge branch 'master' into zlib_optimize
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 79364b0eb..a9a9ad0ac 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3601,7 +3601,7 @@ void lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len lb_type(p->module, t_int) }; unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); - GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2])); + GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1])); LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); LLVMValueRef args[4] = {}; @@ -6839,6 +6839,10 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc return lb_const_nil(m, original_type); } + if (is_type_raw_union(type)) { + return lb_const_nil(m, original_type); + } + isize offset = 0; if (type->Struct.custom_align > 0) { offset = 1; @@ -11141,26 +11145,27 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) { return res; } } else if (is_type_slice(t)) { - lbValue len = lb_emit_struct_ev(p, x, 1); + lbValue data = lb_emit_struct_ev(p, x, 0); if (op_kind == Token_CmpEq) { - res.value = LLVMBuildIsNull(p->builder, len.value, ""); + res.value = LLVMBuildIsNull(p->builder, data.value, ""); return res; } else if (op_kind == Token_NotEq) { - res.value = LLVMBuildIsNotNull(p->builder, len.value, ""); + res.value = LLVMBuildIsNotNull(p->builder, data.value, ""); return res; } } else if (is_type_dynamic_array(t)) { - lbValue cap = lb_emit_struct_ev(p, x, 2); + lbValue data = lb_emit_struct_ev(p, x, 0); if (op_kind == Token_CmpEq) { - res.value = LLVMBuildIsNull(p->builder, cap.value, ""); + res.value = LLVMBuildIsNull(p->builder, data.value, ""); return res; } else if (op_kind == Token_NotEq) { - res.value = LLVMBuildIsNotNull(p->builder, cap.value, ""); + res.value = LLVMBuildIsNotNull(p->builder, data.value, ""); return res; } } else if (is_type_map(t)) { - lbValue cap = lb_map_cap(p, x); - return lb_emit_comp(p, op_kind, cap, lb_zero(p->module, cap.type)); + lbValue hashes = lb_emit_struct_ev(p, x, 0); + lbValue data = lb_emit_struct_ev(p, hashes, 0); + return lb_emit_comp(p, op_kind, data, lb_zero(p->module, data.type)); } else if (is_type_union(t)) { if (type_size_of(t) == 0) { if (op_kind == Token_CmpEq) { @@ -11181,21 +11186,35 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) { } else if (is_type_soa_struct(t)) { Type *bt = base_type(t); if (bt->Struct.soa_kind == StructSoa_Slice) { - lbValue len = lb_soa_struct_len(p, x); + LLVMValueRef the_value = {}; + if (bt->Struct.fields.count == 0) { + lbValue len = lb_soa_struct_len(p, x); + the_value = len.value; + } else { + lbValue first_field = lb_emit_struct_ev(p, x, 0); + the_value = first_field.value; + } if (op_kind == Token_CmpEq) { - res.value = LLVMBuildIsNull(p->builder, len.value, ""); + res.value = LLVMBuildIsNull(p->builder, the_value, ""); return res; } else if (op_kind == Token_NotEq) { - res.value = LLVMBuildIsNotNull(p->builder, len.value, ""); + res.value = LLVMBuildIsNotNull(p->builder, the_value, ""); return res; } } else if (bt->Struct.soa_kind == StructSoa_Dynamic) { - lbValue cap = lb_soa_struct_cap(p, x); + LLVMValueRef the_value = {}; + if (bt->Struct.fields.count == 0) { + lbValue cap = lb_soa_struct_cap(p, x); + the_value = cap.value; + } else { + lbValue first_field = lb_emit_struct_ev(p, x, 0); + the_value = first_field.value; + } if (op_kind == Token_CmpEq) { - res.value = LLVMBuildIsNull(p->builder, cap.value, ""); + res.value = LLVMBuildIsNull(p->builder, the_value, ""); return res; } else if (op_kind == Token_NotEq) { - res.value = LLVMBuildIsNotNull(p->builder, cap.value, ""); + res.value = LLVMBuildIsNotNull(p->builder, the_value, ""); return res; } } @@ -13449,6 +13468,8 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { TypeStruct *st = &bt->Struct; if (cl->elems.count > 0) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); + lbValue comp_lit_ptr = lb_addr_get_ptr(p, v); + for_array(field_index, cl->elems) { Ast *elem = cl->elems[field_index]; @@ -13477,6 +13498,12 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { field_expr = lb_build_expr(p, elem); + lbValue gep = {}; + if (is_raw_union) { + gep = lb_emit_conv(p, comp_lit_ptr, alloc_type_pointer(ft)); + } else { + gep = lb_emit_struct_ep(p, comp_lit_ptr, cast(i32)index); + } Type *fet = field_expr.type; GB_ASSERT(fet->kind != Type_Tuple); @@ -13485,11 +13512,9 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (is_type_union(ft) && !are_types_identical(fet, ft) && !is_type_untyped(fet)) { GB_ASSERT_MSG(union_variant_index(ft, fet) > 0, "%s", type_to_string(fet)); - lbValue gep = lb_emit_struct_ep(p, lb_addr_get_ptr(p, v), cast(i32)index); lb_emit_store_union_variant(p, gep, field_expr, fet); } else { lbValue fv = lb_emit_conv(p, field_expr, ft); - lbValue gep = lb_emit_struct_ep(p, lb_addr_get_ptr(p, v), cast(i32)index); lb_emit_store(p, gep, fv); } } |