authorgravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2023-08-15 00:44:58+02:00
committergravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2024-02-21 16:24:59+01:00
log1d94e9ef83835c3549ec294c1b63d4230f9fcc10
tree85cbb026bf697a805d381392b4364c927042eb78
parent8feae5d2d5fa8b82922f6dbb45b1aae7a4d6a93f

LLVM: Make sure child types get added first

The LLVM bitcode requires all type references in structs to be to earlier defined types. We make sure types are ordered in the builder itself in order to avoid having to iterate the types multiple times and changing the values of type indicies.

1 files changed, 14 insertions(+), 11 deletions(-)

src/codegen/llvm.zig+14-11
...@@ -3406,20 +3406,17 @@ pub const Object = struct {...@@ -3406,20 +3406,17 @@ pub const Object = struct {
3406 },3406 },
3407 .simple_type => unreachable,3407 .simple_type => unreachable,
3408 .struct_type => |struct_type| {3408 .struct_type => |struct_type| {
3409 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());3409 if (o.type_map.get(t.toIntern())) |value| return value;
3410 if (gop.found_existing) return gop.value_ptr.*;
34113410
3412 if (struct_type.layout == .Packed) {3411 if (struct_type.layout == .Packed) {
3413 const int_ty = try o.lowerType(Type.fromInterned(struct_type.backingIntType(ip).*));3412 const int_ty = try o.lowerType(Type.fromInterned(struct_type.backingIntType(ip).*));
3414 gop.value_ptr.* = int_ty;3413 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
3415 return int_ty;3414 return int_ty;
3416 }3415 }
34173416
3418 const name = try o.builder.string(ip.stringToSlice(3417 const name = try o.builder.string(ip.stringToSlice(
3419 try mod.declPtr(struct_type.decl.unwrap().?).getFullyQualifiedName(mod),3418 try mod.declPtr(struct_type.decl.unwrap().?).getFullyQualifiedName(mod),
3420 ));3419 ));
3421 const ty = try o.builder.opaqueType(name);
3422 gop.value_ptr.* = ty; // must be done before any recursive calls
34233420
3424 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};3421 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
3425 defer llvm_field_types.deinit(o.gpa);3422 defer llvm_field_types.deinit(o.gpa);
...@@ -3484,6 +3481,9 @@ pub const Object = struct {...@@ -3484,6 +3481,9 @@ pub const Object = struct {
3484 );3481 );
3485 }3482 }
34863483
3484 const ty = try o.builder.opaqueType(name);
3485 try o.type_map.put(o.gpa, t.toIntern(), ty);
3486
3487 try o.builder.namedTypeSetBody(3487 try o.builder.namedTypeSetBody(
3488 ty,3488 ty,
3489 try o.builder.structType(struct_kind, llvm_field_types.items),3489 try o.builder.structType(struct_kind, llvm_field_types.items),
...@@ -3553,29 +3553,26 @@ pub const Object = struct {...@@ -3553,29 +3553,26 @@ pub const Object = struct {
3553 return o.builder.structType(.normal, llvm_field_types.items);3553 return o.builder.structType(.normal, llvm_field_types.items);
3554 },3554 },
3555 .union_type => |union_type| {3555 .union_type => |union_type| {
3556 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());3556 if (o.type_map.get(t.toIntern())) |value| return value;
3557 if (gop.found_existing) return gop.value_ptr.*;
35583557
3559 const union_obj = ip.loadUnionType(union_type);3558 const union_obj = ip.loadUnionType(union_type);
3560 const layout = mod.getUnionLayout(union_obj);3559 const layout = mod.getUnionLayout(union_obj);
35613560
3562 if (union_obj.flagsPtr(ip).layout == .Packed) {3561 if (union_obj.flagsPtr(ip).layout == .Packed) {
3563 const int_ty = try o.builder.intType(@intCast(t.bitSize(mod)));3562 const int_ty = try o.builder.intType(@intCast(t.bitSize(mod)));
3564 gop.value_ptr.* = int_ty;3563 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
3565 return int_ty;3564 return int_ty;
3566 }3565 }
35673566
3568 if (layout.payload_size == 0) {3567 if (layout.payload_size == 0) {
3569 const enum_tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty));3568 const enum_tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty));
3570 gop.value_ptr.* = enum_tag_ty;3569 try o.type_map.put(o.gpa, t.toIntern(), enum_tag_ty);
3571 return enum_tag_ty;3570 return enum_tag_ty;
3572 }3571 }
35733572
3574 const name = try o.builder.string(ip.stringToSlice(3573 const name = try o.builder.string(ip.stringToSlice(
3575 try mod.declPtr(union_obj.decl).getFullyQualifiedName(mod),3574 try mod.declPtr(union_obj.decl).getFullyQualifiedName(mod),
3576 ));3575 ));
3577 const ty = try o.builder.opaqueType(name);
3578 gop.value_ptr.* = ty; // must be done before any recursive calls
35793576
3580 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);3577 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
3581 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);3578 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
...@@ -3595,6 +3592,9 @@ pub const Object = struct {...@@ -3595,6 +3592,9 @@ pub const Object = struct {
3595 };3592 };
35963593
3597 if (layout.tag_size == 0) {3594 if (layout.tag_size == 0) {
3595 const ty = try o.builder.opaqueType(name);
3596 try o.type_map.put(o.gpa, t.toIntern(), ty);
3597
3598 try o.builder.namedTypeSetBody(3598 try o.builder.namedTypeSetBody(
3599 ty,3599 ty,
3600 try o.builder.structType(.normal, &.{payload_ty}),3600 try o.builder.structType(.normal, &.{payload_ty}),
...@@ -3620,6 +3620,9 @@ pub const Object = struct {...@@ -3620,6 +3620,9 @@ pub const Object = struct {
3620 llvm_fields_len += 1;3620 llvm_fields_len += 1;
3621 }3621 }
36223622
3623 const ty = try o.builder.opaqueType(name);
3624 try o.type_map.put(o.gpa, t.toIntern(), ty);
3625
3623 try o.builder.namedTypeSetBody(3626 try o.builder.namedTypeSetBody(
3624 ty,3627 ty,
3625 try o.builder.structType(.normal, llvm_fields[0..llvm_fields_len]),3628 try o.builder.structType(.normal, llvm_fields[0..llvm_fields_len]),