From 4d044ee7e0b1ca61b8f2205f318449780ae23bd2 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Sat, 21 Oct 2023 12:03:36 -0400 Subject: sema: Add union alignment resolution - Add resolveUnionAlignment, to resolve a union's alignment only, without triggering layout resolution. - Update resolveUnionLayout to cache size, alignment, and padding. abiSizeAdvanced and abiAlignmentAdvanced now use this information instead of computing it each time. --- src/InternPool.zig | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'src/InternPool.zig') diff --git a/src/InternPool.zig b/src/InternPool.zig index 802c32545d..a4fefaba29 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -491,7 +491,7 @@ pub const Key = union(enum) { /// The returned pointer expires with any addition to the `InternPool`. /// Asserts the struct is not packed. - pub fn flagsPtr(self: @This(), ip: *InternPool) *Tag.TypeStruct.Flags { + pub fn flagsPtr(self: @This(), ip: *const InternPool) *Tag.TypeStruct.Flags { assert(self.layout != .Packed); const flags_field_index = std.meta.fieldIndex(Tag.TypeStruct, "flags").?; return @ptrCast(&ip.extra.items[self.extra_index + flags_field_index]); @@ -687,6 +687,18 @@ pub const Key = union(enum) { return @ptrCast(&ip.extra.items[self.extra_index + flags_field_index]); } + /// The returned pointer expires with any addition to the `InternPool`. + pub fn size(self: @This(), ip: *InternPool) *u32 { + const size_field_index = std.meta.fieldIndex(Tag.TypeUnion, "size").?; + return @ptrCast(&ip.extra.items[self.extra_index + size_field_index]); + } + + /// The returned pointer expires with any addition to the `InternPool`. + pub fn padding(self: @This(), ip: *InternPool) *u32 { + const padding_field_index = std.meta.fieldIndex(Tag.TypeUnion, "padding").?; + return @ptrCast(&ip.extra.items[self.extra_index + padding_field_index]); + } + pub fn haveFieldTypes(self: @This(), ip: *const InternPool) bool { return self.flagsPtr(ip).status.haveFieldTypes(); } @@ -1744,6 +1756,10 @@ pub const UnionType = struct { enum_tag_ty: Index, /// The integer tag type of the enum. int_tag_ty: Index, + /// ABI size of the union, including padding + size: u64, + /// Trailing padding bytes + padding: u32, /// List of field names in declaration order. field_names: NullTerminatedString.Slice, /// List of field types in declaration order. @@ -1830,6 +1846,10 @@ pub const UnionType = struct { return self.flagsPtr(ip).runtime_tag.hasTag(); } + pub fn haveFieldTypes(self: UnionType, ip: *const InternPool) bool { + return self.flagsPtr(ip).status.haveFieldTypes(); + } + pub fn haveLayout(self: UnionType, ip: *const InternPool) bool { return self.flagsPtr(ip).status.haveLayout(); } @@ -1867,6 +1887,8 @@ pub fn loadUnionType(ip: *InternPool, key: Key.UnionType) UnionType { .namespace = type_union.data.namespace, .enum_tag_ty = enum_ty, .int_tag_ty = enum_info.tag_ty, + .size = type_union.data.padding, + .padding = type_union.data.padding, .field_names = enum_info.names, .names_map = enum_info.names_map, .field_types = .{ @@ -2943,6 +2965,10 @@ pub const Tag = enum(u8) { /// 1. field align: Alignment for each field; declaration order pub const TypeUnion = struct { flags: Flags, + // Only valid after .have_layout + size: u32, + // Only valid after .have_layout + padding: u32, decl: Module.Decl.Index, namespace: Module.Namespace.Index, /// The enum that provides the list of field names and values. @@ -2957,7 +2983,8 @@ pub const Tag = enum(u8) { status: UnionType.Status, requires_comptime: RequiresComptime, assumed_runtime_bits: bool, - _: u21 = 0, + alignment: Alignment, + _: u15 = 0, }; }; @@ -3021,7 +3048,7 @@ pub const Tag = enum(u8) { any_comptime_fields: bool, any_default_inits: bool, any_aligned_fields: bool, - /// `undefined` until the layout_resolved + /// `.none` until layout_resolved alignment: Alignment, /// Dependency loop detection when resolving struct alignment. alignment_wip: bool, @@ -5262,6 +5289,8 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat const union_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeUnion{ .flags = ini.flags, + .size = std.math.maxInt(u32), + .padding = std.math.maxInt(u32), .decl = ini.decl, .namespace = ini.namespace, .tag_ty = ini.enum_tag_ty, -- cgit v1.2.3