Răsfoiți Sursa

Fix calculation of vector type sizes

Ginger Bill 8 ani în urmă
părinte
comite
51ea59d76a
4 a modificat fișierele cu 22 adăugiri și 20 ștergeri
  1. 2 2
      src/check_expr.c
  2. 6 2
      src/ir.c
  3. 1 9
      src/ir_print.c
  4. 13 7
      src/types.c

+ 2 - 2
src/check_expr.c

@@ -5380,7 +5380,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
 						fields_visited[sel.index.e[0]] = true;
 						check_expr(c, o, fv->value);
 
-						if (base_type(field->type) == t_any) {
+						if (is_type_any(field->type) || is_type_union(field->type) || is_type_raw_union(field->type)) {
 							is_constant = false;
 						}
 						if (is_constant) {
@@ -5418,7 +5418,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
 							continue;
 						}
 
-						if (base_type(field->type) == t_any) {
+						if (is_type_any(field->type) || is_type_union(field->type) || is_type_raw_union(field->type)) {
 							is_constant = false;
 						}
 						if (is_constant) {

+ 6 - 2
src/ir.c

@@ -5203,7 +5203,9 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 					}
 
 					field = st->fields[index];
-					if (!is_union && ir_is_elem_const(proc->module, elem, field->type)) {
+					Type *ft = field->type;
+					if (!is_union && !is_type_union(ft) &&
+					    ir_is_elem_const(proc->module, elem, ft)) {
 						continue;
 					}
 
@@ -5211,7 +5213,9 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 
 					GB_ASSERT(ir_type(field_expr)->kind != Type_Tuple);
 
-					Type *ft = field->type;
+					if (is_type_union(ft)) {
+						// gb_printf_err("HERE! %s\n", type_to_string(ft));
+					}
 					irValue *fv = ir_emit_conv(proc, field_expr, ft);
 					irValue *gep = ir_emit_struct_ep(proc, v, index);
 					ir_emit_store(proc, gep, fv);

+ 1 - 9
src/ir_print.c

@@ -259,15 +259,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 			i64 align = type_align_of(heap_allocator(), t);
 			i64 total_size = type_size_of(heap_allocator(), t);
 		#if 1
-			i64 fields_size = 0;
-			if (t->Record.field_count > 0) {
-				type_set_offsets(m->allocator, t);
-				isize end_index = t->Record.field_count-1;
-				i64 end_offset = t->Record.offsets[end_index];
-				isize end_size = type_size_of(m->allocator, t->Record.fields[end_index]->type);
-				fields_size = align_formula(end_offset + end_size, build_context.word_size);
-			}
-			i64 block_size = total_size - fields_size -  build_context.word_size;
+			i64 block_size =  t->Record.variant_block_size;
 
 			ir_fprintf(f, "{[0 x <%lld x i8>], ", align);
 			for (isize i = 0; i < t->Record.field_count; i++) {

+ 13 - 7
src/types.c

@@ -93,6 +93,7 @@ typedef struct TypeRecord {
 	Entity **variants;
 	i32      variant_count;
 	Entity * union__tag;
+	i64      variant_block_size; // NOTE(bill): Internal use only
 
 
 	i64 *    offsets;
@@ -1817,18 +1818,18 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
 		total_size = (total_size_in_bits+7)/8;
 		return total_size;
 #else
-		i64 count, align, size, alignment;
-		count = t->Vector.count;
+		i64 count = t->Vector.count;
 		if (count == 0) {
 			return 0;
 		}
-		align = type_align_of_internal(allocator, t->Vector.elem, path);
+		i64 elem_align = type_align_of_internal(allocator, t->Vector.elem, path);
 		if (path->failure) {
 			return FAILURE_SIZE;
 		}
-		size  = type_size_of_internal( allocator, t->Vector.elem, path);
-		alignment = align_formula(size, align);
-		return alignment*(count-1) + size;
+		i64 vector_align = type_align_of_internal(allocator, t, path);
+		i64 elem_size = type_size_of_internal(allocator, t->Vector.elem, path);
+		i64 alignment = align_formula(elem_size, elem_align);
+		return align_formula(alignment*(count-1) + elem_size, vector_align);
 #endif
 	} break;
 
@@ -1904,6 +1905,7 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
 				i64 end_size = type_size_of_internal(allocator, end_type, path);
 				max = end_offset + end_size ;
 			}
+			i64 field_size = max;
 
 			for (isize i = 1; i < variant_count; i++) {
 				Type *variant_type = t->Record.variants[i]->type;
@@ -1912,9 +1914,13 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
 					max = size;
 				}
 			}
+
 			// NOTE(bill): Align to int
 			i64 size = align_formula(max, build_context.word_size);
-			size += type_size_of_internal(allocator, t_int, path);
+			// NOTE(bill): Calculate the padding between the common fields and the tag
+			t->Record.variant_block_size = size - field_size;
+
+			size += type_size_of(allocator, t_int);
 			size = align_formula(size, align);
 			return size;
 		} break;