| author | |
| committer | |
| log | c08c0fc6eddf601785abfbc5e5a9ab5c89d7cfbf |
| tree | 65cabc6acd2db112c1fa9557c2f34dfd04659113 |
| parent | a7088fd9a3edb037f0f51bb402a3c557334634f3 |
This is mostly a revert of a7088fd9a3edb037f0f51bb402a3c557334634f3.
Measurement revealed the commit actually regressed performance.9 files changed, 52 insertions(+), 67 deletions(-)
src/InternPool.zig+6-46| ... | @@ -105,25 +105,6 @@ pub const MapIndex = enum(u32) { | ... | @@ -105,25 +105,6 @@ pub const MapIndex = enum(u32) { |
| 105 | } | 105 | } |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | pub const OptionalInt = enum(u32) { | ||
| 109 | none = std.math.maxInt(u32), | ||
| 110 | _, | ||
| 111 | |||
| 112 | pub fn init(x: u32) @This() { | ||
| 113 | const result: @This() = @enumFromInt(x); | ||
| 114 | assert(result != .none); | ||
| 115 | return result; | ||
| 116 | } | ||
| 117 | |||
| 118 | pub fn initOptional(opt_x: ?u32) @This() { | ||
| 119 | return @This().init(opt_x orelse return .none); | ||
| 120 | } | ||
| 121 | |||
| 122 | pub fn unwrap(this: @This()) ?u32 { | ||
| 123 | return if (this == .none) null else @intFromEnum(this); | ||
| 124 | } | ||
| 125 | }; | ||
| 126 | |||
| 127 | pub const RuntimeIndex = enum(u32) { | 108 | pub const RuntimeIndex = enum(u32) { |
| 128 | zero = 0, | 109 | zero = 0, |
| 129 | comptime_field_ptr = std.math.maxInt(u32), | 110 | comptime_field_ptr = std.math.maxInt(u32), |
| ... | @@ -396,8 +377,6 @@ pub const Key = union(enum) { | ... | @@ -396,8 +377,6 @@ pub const Key = union(enum) { |
| 396 | field_aligns: Alignment.Slice, | 377 | field_aligns: Alignment.Slice, |
| 397 | runtime_order: RuntimeOrder.Slice, | 378 | runtime_order: RuntimeOrder.Slice, |
| 398 | comptime_bits: ComptimeBits, | 379 | comptime_bits: ComptimeBits, |
| 399 | /// In the case of packed structs these are bit offsets; in the case of | ||
| 400 | /// non-packed structs these are byte offsets. | ||
| 401 | offsets: Offsets, | 380 | offsets: Offsets, |
| 402 | names_map: OptionalMapIndex, | 381 | names_map: OptionalMapIndex, |
| 403 | 382 | ||
| ... | @@ -496,15 +475,6 @@ pub const Key = union(enum) { | ... | @@ -496,15 +475,6 @@ pub const Key = union(enum) { |
| 496 | return s.field_names.get(ip)[i].toOptional(); | 475 | return s.field_names.get(ip)[i].toOptional(); |
| 497 | } | 476 | } |
| 498 | 477 | ||
| 499 | /// Asserts it is a packed struct. | ||
| 500 | /// Asserts the layout is resolved. | ||
| 501 | pub fn fieldBitOffset(s: @This(), ip: *InternPool, i: usize) u32 { | ||
| 502 | assert(s.layout == .Packed); | ||
| 503 | assert(s.haveLayout(ip)); | ||
| 504 | const result: OptionalInt = @enumFromInt(s.offsets.get(ip)[i]); | ||
| 505 | return result.unwrap().?; | ||
| 506 | } | ||
| 507 | |||
| 508 | pub fn fieldIsComptime(s: @This(), ip: *const InternPool, i: usize) bool { | 478 | pub fn fieldIsComptime(s: @This(), ip: *const InternPool, i: usize) bool { |
| 509 | return s.comptime_bits.getBit(ip, i); | 479 | return s.comptime_bits.getBit(ip, i); |
| 510 | } | 480 | } |
| ... | @@ -623,11 +593,7 @@ pub const Key = union(enum) { | ... | @@ -623,11 +593,7 @@ pub const Key = union(enum) { |
| 623 | 593 | ||
| 624 | pub fn haveLayout(s: @This(), ip: *InternPool) bool { | 594 | pub fn haveLayout(s: @This(), ip: *InternPool) bool { |
| 625 | return switch (s.layout) { | 595 | return switch (s.layout) { |
| 626 | .Packed => { | 596 | .Packed => s.backingIntType(ip).* != .none, |
| 627 | if (s.offsets.len == 0) return true; | ||
| 628 | const first_offset: OptionalInt = @enumFromInt(ip.extra.items[s.offsets.start]); | ||
| 629 | return first_offset != .none; | ||
| 630 | }, | ||
| 631 | .Auto, .Extern => s.flagsPtr(ip).layout_resolved, | 597 | .Auto, .Extern => s.flagsPtr(ip).layout_resolved, |
| 632 | }; | 598 | }; |
| 633 | } | 599 | } |
| ... | @@ -2970,8 +2936,7 @@ pub const Tag = enum(u8) { | ... | @@ -2970,8 +2936,7 @@ pub const Tag = enum(u8) { |
| 2970 | /// Trailing: | 2936 | /// Trailing: |
| 2971 | /// 0. type: Index for each fields_len | 2937 | /// 0. type: Index for each fields_len |
| 2972 | /// 1. name: NullTerminatedString for each fields_len | 2938 | /// 1. name: NullTerminatedString for each fields_len |
| 2973 | /// 2. bit_offset: OptionalInt for each fields_len // none until layout resolved | 2939 | /// 2. init: Index for each fields_len // if tag is type_struct_packed_inits |
| 2974 | /// 3. init: Index for each fields_len // if tag is type_struct_packed_inits | ||
| 2975 | pub const TypeStructPacked = struct { | 2940 | pub const TypeStructPacked = struct { |
| 2976 | decl: Module.Decl.Index, | 2941 | decl: Module.Decl.Index, |
| 2977 | zir_index: Zir.Inst.Index, | 2942 | zir_index: Zir.Inst.Index, |
| ... | @@ -4229,12 +4194,8 @@ fn extraPackedStructType(ip: *const InternPool, extra_index: u32, inits: bool) K | ... | @@ -4229,12 +4194,8 @@ fn extraPackedStructType(ip: *const InternPool, extra_index: u32, inits: bool) K |
| 4229 | .start = type_struct_packed.end + fields_len, | 4194 | .start = type_struct_packed.end + fields_len, |
| 4230 | .len = fields_len, | 4195 | .len = fields_len, |
| 4231 | }, | 4196 | }, |
| 4232 | .offsets = .{ | ||
| 4233 | .start = type_struct_packed.end + fields_len * 2, | ||
| 4234 | .len = fields_len, | ||
| 4235 | }, | ||
| 4236 | .field_inits = if (inits) .{ | 4197 | .field_inits = if (inits) .{ |
| 4237 | .start = type_struct_packed.end + fields_len * 3, | 4198 | .start = type_struct_packed.end + fields_len * 2, |
| 4238 | .len = fields_len, | 4199 | .len = fields_len, |
| 4239 | } else .{ | 4200 | } else .{ |
| 4240 | .start = 0, | 4201 | .start = 0, |
| ... | @@ -4243,6 +4204,7 @@ fn extraPackedStructType(ip: *const InternPool, extra_index: u32, inits: bool) K | ... | @@ -4243,6 +4204,7 @@ fn extraPackedStructType(ip: *const InternPool, extra_index: u32, inits: bool) K |
| 4243 | .field_aligns = .{ .start = 0, .len = 0 }, | 4204 | .field_aligns = .{ .start = 0, .len = 0 }, |
| 4244 | .runtime_order = .{ .start = 0, .len = 0 }, | 4205 | .runtime_order = .{ .start = 0, .len = 0 }, |
| 4245 | .comptime_bits = .{ .start = 0, .len = 0 }, | 4206 | .comptime_bits = .{ .start = 0, .len = 0 }, |
| 4207 | .offsets = .{ .start = 0, .len = 0 }, | ||
| 4246 | .names_map = type_struct_packed.data.names_map.toOptional(), | 4208 | .names_map = type_struct_packed.data.names_map.toOptional(), |
| 4247 | }; | 4209 | }; |
| 4248 | } | 4210 | } |
| ... | @@ -5317,7 +5279,6 @@ pub fn getStructType( | ... | @@ -5317,7 +5279,6 @@ pub fn getStructType( |
| 5317 | try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStructPacked).Struct.fields.len + | 5279 | try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStructPacked).Struct.fields.len + |
| 5318 | ini.fields_len + // types | 5280 | ini.fields_len + // types |
| 5319 | ini.fields_len + // names | 5281 | ini.fields_len + // names |
| 5320 | ini.fields_len + // offsets | ||
| 5321 | ini.fields_len); // inits | 5282 | ini.fields_len); // inits |
| 5322 | try ip.items.append(gpa, .{ | 5283 | try ip.items.append(gpa, .{ |
| 5323 | .tag = if (ini.any_default_inits) .type_struct_packed_inits else .type_struct_packed, | 5284 | .tag = if (ini.any_default_inits) .type_struct_packed_inits else .type_struct_packed, |
| ... | @@ -5332,7 +5293,6 @@ pub fn getStructType( | ... | @@ -5332,7 +5293,6 @@ pub fn getStructType( |
| 5332 | }); | 5293 | }); |
| 5333 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len); | 5294 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len); |
| 5334 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len); | 5295 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len); |
| 5335 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalInt.none), ini.fields_len); | ||
| 5336 | if (ini.any_default_inits) { | 5296 | if (ini.any_default_inits) { |
| 5337 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len); | 5297 | ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len); |
| 5338 | } | 5298 | } |
| ... | @@ -7153,12 +7113,12 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -7153,12 +7113,12 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 7153 | .type_struct_packed => b: { | 7113 | .type_struct_packed => b: { |
| 7154 | const info = ip.extraData(Tag.TypeStructPacked, data); | 7114 | const info = ip.extraData(Tag.TypeStructPacked, data); |
| 7155 | break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len + | 7115 | break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len + |
| 7156 | info.fields_len + info.fields_len + info.fields_len); | 7116 | info.fields_len + info.fields_len); |
| 7157 | }, | 7117 | }, |
| 7158 | .type_struct_packed_inits => b: { | 7118 | .type_struct_packed_inits => b: { |
| 7159 | const info = ip.extraData(Tag.TypeStructPacked, data); | 7119 | const info = ip.extraData(Tag.TypeStructPacked, data); |
| 7160 | break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len + | 7120 | break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len + |
| 7161 | info.fields_len + info.fields_len + info.fields_len + info.fields_len); | 7121 | info.fields_len + info.fields_len + info.fields_len); |
| 7162 | }, | 7122 | }, |
| 7163 | .type_tuple_anon => b: { | 7123 | .type_tuple_anon => b: { |
| 7164 | const info = ip.extraData(TypeStructAnon, data); | 7124 | const info = ip.extraData(TypeStructAnon, data); |
src/Module.zig+23| ... | @@ -6649,3 +6649,26 @@ pub fn structFieldAlignmentExtern(mod: *Module, field_ty: Type) Alignment { | ... | @@ -6649,3 +6649,26 @@ pub fn structFieldAlignmentExtern(mod: *Module, field_ty: Type) Alignment { |
| 6649 | 6649 | ||
| 6650 | return ty_abi_align; | 6650 | return ty_abi_align; |
| 6651 | } | 6651 | } |
| 6652 | |||
| 6653 | /// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets | ||
| 6654 | /// into the packed struct InternPool data rather than computing this on the | ||
| 6655 | /// fly, however it was found to perform worse when measured on real world | ||
| 6656 | /// projects. | ||
| 6657 | pub fn structPackedFieldBitOffset( | ||
| 6658 | mod: *Module, | ||
| 6659 | struct_type: InternPool.Key.StructType, | ||
| 6660 | field_index: u32, | ||
| 6661 | ) u16 { | ||
| 6662 | const ip = &mod.intern_pool; | ||
| 6663 | assert(struct_type.layout == .Packed); | ||
| 6664 | assert(struct_type.haveLayout(ip)); | ||
| 6665 | var bit_sum: u64 = 0; | ||
| 6666 | for (0..struct_type.field_types.len) |i| { | ||
| 6667 | if (i == field_index) { | ||
| 6668 | return @intCast(bit_sum); | ||
| 6669 | } | ||
| 6670 | const field_ty = struct_type.field_types.get(ip)[i].toType(); | ||
| 6671 | bit_sum += field_ty.bitSize(mod); | ||
| 6672 | } | ||
| 6673 | unreachable; // index out of bounds | ||
| 6674 | } |
src/Sema.zig-2| ... | @@ -21343,7 +21343,6 @@ fn reifyStruct( | ... | @@ -21343,7 +21343,6 @@ fn reifyStruct( |
| 21343 | 21343 | ||
| 21344 | var fields_bit_sum: u64 = 0; | 21344 | var fields_bit_sum: u64 = 0; |
| 21345 | for (0..struct_type.field_types.len) |i| { | 21345 | for (0..struct_type.field_types.len) |i| { |
| 21346 | struct_type.offsets.get(ip)[i] = @intCast(fields_bit_sum); | ||
| 21347 | const field_ty = struct_type.field_types.get(ip)[i].toType(); | 21346 | const field_ty = struct_type.field_types.get(ip)[i].toType(); |
| 21348 | fields_bit_sum += field_ty.bitSize(mod); | 21347 | fields_bit_sum += field_ty.bitSize(mod); |
| 21349 | } | 21348 | } |
| ... | @@ -34774,7 +34773,6 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp | ... | @@ -34774,7 +34773,6 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp |
| 34774 | var accumulator: u64 = 0; | 34773 | var accumulator: u64 = 0; |
| 34775 | for (0..struct_type.field_types.len) |i| { | 34774 | for (0..struct_type.field_types.len) |i| { |
| 34776 | const field_ty = struct_type.field_types.get(ip)[i].toType(); | 34775 | const field_ty = struct_type.field_types.get(ip)[i].toType(); |
| 34777 | struct_type.offsets.get(ip)[i] = @intCast(accumulator); | ||
| 34778 | accumulator += try field_ty.bitSizeAdvanced(mod, &sema); | 34776 | accumulator += try field_ty.bitSizeAdvanced(mod, &sema); |
| 34779 | } | 34777 | } |
| 34780 | break :blk accumulator; | 34778 | break :blk accumulator; |
src/arch/wasm/CodeGen.zig+1-1| ... | @@ -3779,7 +3779,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3779,7 +3779,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3779 | .Packed => switch (struct_ty.zigTypeTag(mod)) { | 3779 | .Packed => switch (struct_ty.zigTypeTag(mod)) { |
| 3780 | .Struct => result: { | 3780 | .Struct => result: { |
| 3781 | const packed_struct = mod.typeToPackedStruct(struct_ty).?; | 3781 | const packed_struct = mod.typeToPackedStruct(struct_ty).?; |
| 3782 | const offset = packed_struct.fieldBitOffset(ip, field_index); | 3782 | const offset = mod.structPackedFieldBitOffset(packed_struct, field_index); |
| 3783 | const backing_ty = packed_struct.backingIntType(ip).toType(); | 3783 | const backing_ty = packed_struct.backingIntType(ip).toType(); |
| 3784 | const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse { | 3784 | const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse { |
| 3785 | return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{}); | 3785 | return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{}); |
src/arch/x86_64/CodeGen.zig+2-4| ... | @@ -5593,7 +5593,6 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 | ... | @@ -5593,7 +5593,6 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 |
| 5593 | 5593 | ||
| 5594 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | 5594 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5595 | const mod = self.bin_file.options.module.?; | 5595 | const mod = self.bin_file.options.module.?; |
| 5596 | const ip = &mod.intern_pool; | ||
| 5597 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5596 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 5598 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | 5597 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 5599 | const result: MCValue = result: { | 5598 | const result: MCValue = result: { |
| ... | @@ -5611,7 +5610,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5611,7 +5610,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5611 | const field_off: u32 = switch (container_ty.containerLayout(mod)) { | 5610 | const field_off: u32 = switch (container_ty.containerLayout(mod)) { |
| 5612 | .Auto, .Extern => @intCast(container_ty.structFieldOffset(index, mod) * 8), | 5611 | .Auto, .Extern => @intCast(container_ty.structFieldOffset(index, mod) * 8), |
| 5613 | .Packed => if (mod.typeToStruct(container_ty)) |struct_type| | 5612 | .Packed => if (mod.typeToStruct(container_ty)) |struct_type| |
| 5614 | struct_type.fieldBitOffset(ip, index) | 5613 | mod.structPackedFieldBitOffset(struct_type, index) |
| 5615 | else | 5614 | else |
| 5616 | 0, | 5615 | 0, |
| 5617 | }; | 5616 | }; |
| ... | @@ -11411,7 +11410,6 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11411,7 +11410,6 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 11411 | 11410 | ||
| 11412 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | 11411 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 11413 | const mod = self.bin_file.options.module.?; | 11412 | const mod = self.bin_file.options.module.?; |
| 11414 | const ip = &mod.intern_pool; | ||
| 11415 | const result_ty = self.typeOfIndex(inst); | 11413 | const result_ty = self.typeOfIndex(inst); |
| 11416 | const len: usize = @intCast(result_ty.arrayLen(mod)); | 11414 | const len: usize = @intCast(result_ty.arrayLen(mod)); |
| 11417 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 11415 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -11442,7 +11440,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11442,7 +11440,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 11442 | } | 11440 | } |
| 11443 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod)); | 11441 | const elem_abi_size: u32 = @intCast(elem_ty.abiSize(mod)); |
| 11444 | const elem_abi_bits = elem_abi_size * 8; | 11442 | const elem_abi_bits = elem_abi_size * 8; |
| 11445 | const elem_off = struct_type.fieldBitOffset(ip, elem_i); | 11443 | const elem_off = mod.structPackedFieldBitOffset(struct_type, elem_i); |
| 11446 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); | 11444 | const elem_byte_off: i32 = @intCast(elem_off / elem_abi_bits * elem_abi_size); |
| 11447 | const elem_bit_off = elem_off % elem_abi_bits; | 11445 | const elem_bit_off = elem_off % elem_abi_bits; |
| 11448 | const elem_mcv = try self.resolveInst(elem); | 11446 | const elem_mcv = try self.resolveInst(elem); |
src/codegen.zig+8-9| ... | @@ -630,8 +630,7 @@ fn lowerParentPtr( | ... | @@ -630,8 +630,7 @@ fn lowerParentPtr( |
| 630 | reloc_info: RelocInfo, | 630 | reloc_info: RelocInfo, |
| 631 | ) CodeGenError!Result { | 631 | ) CodeGenError!Result { |
| 632 | const mod = bin_file.options.module.?; | 632 | const mod = bin_file.options.module.?; |
| 633 | const ip = &mod.intern_pool; | 633 | const ptr = mod.intern_pool.indexToKey(parent_ptr).ptr; |
| 634 | const ptr = ip.indexToKey(parent_ptr).ptr; | ||
| 635 | assert(ptr.len == .none); | 634 | assert(ptr.len == .none); |
| 636 | return switch (ptr.addr) { | 635 | return switch (ptr.addr) { |
| 637 | .decl, .mut_decl => try lowerDeclRef( | 636 | .decl, .mut_decl => try lowerDeclRef( |
| ... | @@ -657,7 +656,7 @@ fn lowerParentPtr( | ... | @@ -657,7 +656,7 @@ fn lowerParentPtr( |
| 657 | code, | 656 | code, |
| 658 | debug_output, | 657 | debug_output, |
| 659 | reloc_info.offset(@as(u32, @intCast(errUnionPayloadOffset( | 658 | reloc_info.offset(@as(u32, @intCast(errUnionPayloadOffset( |
| 660 | ip.typeOf(eu_payload).toType(), | 659 | mod.intern_pool.typeOf(eu_payload).toType(), |
| 661 | mod, | 660 | mod, |
| 662 | )))), | 661 | )))), |
| 663 | ), | 662 | ), |
| ... | @@ -676,17 +675,17 @@ fn lowerParentPtr( | ... | @@ -676,17 +675,17 @@ fn lowerParentPtr( |
| 676 | code, | 675 | code, |
| 677 | debug_output, | 676 | debug_output, |
| 678 | reloc_info.offset(@as(u32, @intCast(elem.index * | 677 | reloc_info.offset(@as(u32, @intCast(elem.index * |
| 679 | ip.typeOf(elem.base).toType().elemType2(mod).abiSize(mod)))), | 678 | mod.intern_pool.typeOf(elem.base).toType().elemType2(mod).abiSize(mod)))), |
| 680 | ), | 679 | ), |
| 681 | .field => |field| { | 680 | .field => |field| { |
| 682 | const base_type = ip.indexToKey(ip.typeOf(field.base)).ptr_type.child; | 681 | const base_type = mod.intern_pool.indexToKey(mod.intern_pool.typeOf(field.base)).ptr_type.child; |
| 683 | return lowerParentPtr( | 682 | return lowerParentPtr( |
| 684 | bin_file, | 683 | bin_file, |
| 685 | src_loc, | 684 | src_loc, |
| 686 | field.base, | 685 | field.base, |
| 687 | code, | 686 | code, |
| 688 | debug_output, | 687 | debug_output, |
| 689 | reloc_info.offset(switch (ip.indexToKey(base_type)) { | 688 | reloc_info.offset(switch (mod.intern_pool.indexToKey(base_type)) { |
| 690 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 689 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 691 | .One, .Many, .C => unreachable, | 690 | .One, .Many, .C => unreachable, |
| 692 | .Slice => switch (field.index) { | 691 | .Slice => switch (field.index) { |
| ... | @@ -704,9 +703,9 @@ fn lowerParentPtr( | ... | @@ -704,9 +703,9 @@ fn lowerParentPtr( |
| 704 | mod, | 703 | mod, |
| 705 | )), | 704 | )), |
| 706 | .Packed => if (mod.typeToStruct(base_type.toType())) |struct_type| | 705 | .Packed => if (mod.typeToStruct(base_type.toType())) |struct_type| |
| 707 | math.divExact(u32, struct_type.fieldBitOffset( | 706 | math.divExact(u16, mod.structPackedFieldBitOffset( |
| 708 | ip, | 707 | struct_type, |
| 709 | field.index, | 708 | @intCast(field.index), |
| 710 | ), 8) catch |err| switch (err) { | 709 | ), 8) catch |err| switch (err) { |
| 711 | error.UnexpectedRemainder => 0, | 710 | error.UnexpectedRemainder => 0, |
| 712 | error.DivisionByZero => unreachable, | 711 | error.DivisionByZero => unreachable, |
src/codegen/c.zig+1-1| ... | @@ -5429,7 +5429,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5429,7 +5429,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5429 | 5429 | ||
| 5430 | const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1)); | 5430 | const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1)); |
| 5431 | 5431 | ||
| 5432 | const bit_offset = struct_type.fieldBitOffset(ip, extra.field_index); | 5432 | const bit_offset = mod.structPackedFieldBitOffset(struct_type, extra.field_index); |
| 5433 | const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset); | 5433 | const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset); |
| 5434 | 5434 | ||
| 5435 | const field_int_signedness = if (inst_ty.isAbiInt(mod)) | 5435 | const field_int_signedness = if (inst_ty.isAbiInt(mod)) |
src/codegen/llvm.zig+1-2| ... | @@ -6192,7 +6192,6 @@ pub const FuncGen = struct { | ... | @@ -6192,7 +6192,6 @@ pub const FuncGen = struct { |
| 6192 | fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6192 | fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { |
| 6193 | const o = self.dg.object; | 6193 | const o = self.dg.object; |
| 6194 | const mod = o.module; | 6194 | const mod = o.module; |
| 6195 | const ip = &mod.intern_pool; | ||
| 6196 | const inst = body_tail[0]; | 6195 | const inst = body_tail[0]; |
| 6197 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 6196 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 6198 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; | 6197 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | @@ -6208,7 +6207,7 @@ pub const FuncGen = struct { | ... | @@ -6208,7 +6207,7 @@ pub const FuncGen = struct { |
| 6208 | .Struct => switch (struct_ty.containerLayout(mod)) { | 6207 | .Struct => switch (struct_ty.containerLayout(mod)) { |
| 6209 | .Packed => { | 6208 | .Packed => { |
| 6210 | const struct_type = mod.typeToStruct(struct_ty).?; | 6209 | const struct_type = mod.typeToStruct(struct_ty).?; |
| 6211 | const bit_offset = struct_type.fieldBitOffset(ip, field_index); | 6210 | const bit_offset = mod.structPackedFieldBitOffset(struct_type, field_index); |
| 6212 | const containing_int = struct_llvm_val; | 6211 | const containing_int = struct_llvm_val; |
| 6213 | const shift_amt = | 6212 | const shift_amt = |
| 6214 | try o.builder.intValue(containing_int.typeOfWip(&self.wip), bit_offset); | 6213 | try o.builder.intValue(containing_int.typeOfWip(&self.wip), bit_offset); |
src/type.zig+10-2| ... | @@ -3025,8 +3025,16 @@ pub const Type = struct { | ... | @@ -3025,8 +3025,16 @@ pub const Type = struct { |
| 3025 | const ip = &mod.intern_pool; | 3025 | const ip = &mod.intern_pool; |
| 3026 | const struct_type = ip.indexToKey(ty.toIntern()).struct_type; | 3026 | const struct_type = ip.indexToKey(ty.toIntern()).struct_type; |
| 3027 | assert(struct_type.layout == .Packed); | 3027 | assert(struct_type.layout == .Packed); |
| 3028 | assert(struct_type.haveLayout(ip)); | 3028 | comptime assert(Type.packed_struct_layout_version == 2); |
| 3029 | return struct_type.offsets.get(ip)[field_index]; | 3029 | |
| 3030 | var running_bits: u32 = 0; | ||
| 3031 | for (struct_type.field_types.get(ip), 0..) |field_ty, i| { | ||
| 3032 | if (i == field_index) break; | ||
| 3033 | if (!field_ty.toType().hasRuntimeBits(mod)) continue; | ||
| 3034 | const field_bits: u32 = @intCast(field_ty.toType().bitSize(mod)); | ||
| 3035 | running_bits += field_bits; | ||
| 3036 | } | ||
| 3037 | return running_bits; | ||
| 3030 | } | 3038 | } |
| 3031 | 3039 | ||
| 3032 | pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, mod: *Module) u32 { | 3040 | pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, mod: *Module) u32 { |