Browse Source

Fix `soa_zip` and `soa_unzip`

gingerBill 1 year ago
parent
commit
c9b1c99a40
3 changed files with 23 additions and 5 deletions
  1. 2 2
      src/check_builtin.cpp
  2. 11 3
      src/llvm_backend_utility.cpp
  3. 10 0
      src/types.cpp

+ 2 - 2
src/check_builtin.cpp

@@ -3428,8 +3428,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 		auto types = slice_make<Type *>(permanent_allocator(), t->Struct.fields.count-1);
 		for_array(i, types) {
 			Entity *f = t->Struct.fields[i];
-			GB_ASSERT(f->type->kind == Type_Pointer);
-			types[i] = alloc_type_slice(f->type->Pointer.elem);
+			GB_ASSERT(f->type->kind == Type_MultiPointer);
+			types[i] = alloc_type_slice(f->type->MultiPointer.elem);
 		}
 
 		operand->type = alloc_type_tuple_from_field_types(types.data, types.count, false, false);

+ 11 - 3
src/llvm_backend_utility.cpp

@@ -328,6 +328,7 @@ gb_internal lbValue lb_soa_zip(lbProcedure *p, AstCallExpr *ce, TypeAndValue con
 	lbAddr res = lb_add_local_generated(p, tv.type, true);
 	for_array(i, slices) {
 		lbValue src = lb_slice_elem(p, slices[i]);
+		src = lb_emit_conv(p, src, alloc_type_pointer_to_multi_pointer(src.type));
 		lbValue dst = lb_emit_struct_ep(p, res.addr, cast(i32)i);
 		lb_emit_store(p, dst, src);
 	}
@@ -1559,19 +1560,26 @@ gb_internal lbValue lb_emit_matrix_ev(lbProcedure *p, lbValue s, isize row, isiz
 	return lb_emit_load(p, ptr);
 }
 
-
 gb_internal void lb_fill_slice(lbProcedure *p, lbAddr const &slice, lbValue base_elem, lbValue len) {
 	Type *t = lb_addr_type(slice);
 	GB_ASSERT(is_type_slice(t));
 	lbValue ptr = lb_addr_get_ptr(p, slice);
-	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 0), base_elem);
+	lbValue data = lb_emit_struct_ep(p, ptr, 0);
+	if (are_types_identical(type_deref(base_elem.type, true), type_deref(type_deref(data.type), true))) {
+		base_elem = lb_emit_conv(p, base_elem, type_deref(data.type));
+	}
+	lb_emit_store(p, data, base_elem);
 	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
 }
 gb_internal void lb_fill_string(lbProcedure *p, lbAddr const &string, lbValue base_elem, lbValue len) {
 	Type *t = lb_addr_type(string);
 	GB_ASSERT(is_type_string(t));
 	lbValue ptr = lb_addr_get_ptr(p, string);
-	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 0), base_elem);
+	lbValue data = lb_emit_struct_ep(p, ptr, 0);
+	if (are_types_identical(type_deref(base_elem.type, true), type_deref(type_deref(data.type), true))) {
+		base_elem = lb_emit_conv(p, base_elem, type_deref(data.type));
+	}
+	lb_emit_store(p, data, base_elem);
 	lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
 }
 

+ 10 - 0
src/types.cpp

@@ -988,6 +988,16 @@ gb_internal Type *alloc_type_soa_pointer(Type *elem) {
 	return t;
 }
 
+gb_internal Type *alloc_type_pointer_to_multi_pointer(Type *ptr) {
+	Type *original_type = ptr;
+	ptr = base_type(ptr);
+	if (ptr->kind == Type_Pointer) {
+		return alloc_type_multi_pointer(ptr->Pointer.elem);
+	} else if (ptr->kind != Type_MultiPointer) {
+		GB_PANIC("Invalid type: %s", type_to_string(original_type));
+	}
+	return original_type;
+}
 
 gb_internal Type *alloc_type_array(Type *elem, i64 count, Type *generic_count = nullptr) {
 	if (generic_count != nullptr) {