zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 1d94e9ef83835c3549ec294c1b63d4230f9fcc10 (tree)
parent 8feae5d2d5fa8b82922f6dbb45b1aae7a4d6a93f
Author: antlilja <liljaanton2001@gmail.com>
Date:   Tue, 15 Aug 2023 00:44:58 +0200

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.

Diffstat:
Msrc/codegen/llvm.zig | 25++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig @@ -3406,20 +3406,17 @@ pub const Object = struct { }, .simple_type => unreachable, .struct_type => |struct_type| { - const gop = try o.type_map.getOrPut(o.gpa, t.toIntern()); - if (gop.found_existing) return gop.value_ptr.*; + if (o.type_map.get(t.toIntern())) |value| return value; if (struct_type.layout == .Packed) { const int_ty = try o.lowerType(Type.fromInterned(struct_type.backingIntType(ip).*)); - gop.value_ptr.* = int_ty; + try o.type_map.put(o.gpa, t.toIntern(), int_ty); return int_ty; } const name = try o.builder.string(ip.stringToSlice( try mod.declPtr(struct_type.decl.unwrap().?).getFullyQualifiedName(mod), )); - const ty = try o.builder.opaqueType(name); - gop.value_ptr.* = ty; // must be done before any recursive calls var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){}; defer llvm_field_types.deinit(o.gpa); @@ -3484,6 +3481,9 @@ pub const Object = struct { ); } + const ty = try o.builder.opaqueType(name); + try o.type_map.put(o.gpa, t.toIntern(), ty); + try o.builder.namedTypeSetBody( ty, try o.builder.structType(struct_kind, llvm_field_types.items), @@ -3553,29 +3553,26 @@ pub const Object = struct { return o.builder.structType(.normal, llvm_field_types.items); }, .union_type => |union_type| { - const gop = try o.type_map.getOrPut(o.gpa, t.toIntern()); - if (gop.found_existing) return gop.value_ptr.*; + if (o.type_map.get(t.toIntern())) |value| return value; const union_obj = ip.loadUnionType(union_type); const layout = mod.getUnionLayout(union_obj); if (union_obj.flagsPtr(ip).layout == .Packed) { const int_ty = try o.builder.intType(@intCast(t.bitSize(mod))); - gop.value_ptr.* = int_ty; + try o.type_map.put(o.gpa, t.toIntern(), int_ty); return int_ty; } if (layout.payload_size == 0) { const enum_tag_ty = try o.lowerType(Type.fromInterned(union_obj.enum_tag_ty)); - gop.value_ptr.* = enum_tag_ty; + try o.type_map.put(o.gpa, t.toIntern(), enum_tag_ty); return enum_tag_ty; } const name = try o.builder.string(ip.stringToSlice( try mod.declPtr(union_obj.decl).getFullyQualifiedName(mod), )); - const ty = try o.builder.opaqueType(name); - gop.value_ptr.* = ty; // must be done before any recursive calls const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]); const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty); @@ -3595,6 +3592,9 @@ pub const Object = struct { }; if (layout.tag_size == 0) { + const ty = try o.builder.opaqueType(name); + try o.type_map.put(o.gpa, t.toIntern(), ty); + try o.builder.namedTypeSetBody( ty, try o.builder.structType(.normal, &.{payload_ty}), @@ -3620,6 +3620,9 @@ pub const Object = struct { llvm_fields_len += 1; } + const ty = try o.builder.opaqueType(name); + try o.type_map.put(o.gpa, t.toIntern(), ty); + try o.builder.namedTypeSetBody( ty, try o.builder.structType(.normal, llvm_fields[0..llvm_fields_len]),