| author | |
| committer | |
| log | eb072fa52846c6583b856c8c88d50d65f46b3667 |
| tree | f1c1f213685f476200562bcc870bc774bd81fa2f |
| parent | df5f0517b33b5f7bc2a508cf6a0ee62246f02d21 |
| parent | c08c0fc6eddf601785abfbc5e5a9ab5c89d7cfbf |
| signature |
compiler: packed structs cache bit offsets4 files changed, 17 insertions(+), 19 deletions(-)
src/InternPool.zig+1-1| ... | @@ -4195,7 +4195,7 @@ fn extraPackedStructType(ip: *const InternPool, extra_index: u32, inits: bool) K | ... | @@ -4195,7 +4195,7 @@ fn extraPackedStructType(ip: *const InternPool, extra_index: u32, inits: bool) K |
| 4195 | .len = fields_len, | 4195 | .len = fields_len, |
| 4196 | }, | 4196 | }, |
| 4197 | .field_inits = if (inits) .{ | 4197 | .field_inits = if (inits) .{ |
| 4198 | .start = type_struct_packed.end + fields_len + fields_len, | 4198 | .start = type_struct_packed.end + fields_len * 2, |
| 4199 | .len = fields_len, | 4199 | .len = fields_len, |
| 4200 | } else .{ | 4200 | } else .{ |
| 4201 | .start = 0, | 4201 | .start = 0, |
src/Module.zig+4-4| ... | @@ -6650,10 +6650,10 @@ pub fn structFieldAlignmentExtern(mod: *Module, field_ty: Type) Alignment { | ... | @@ -6650,10 +6650,10 @@ pub fn structFieldAlignmentExtern(mod: *Module, field_ty: Type) Alignment { |
| 6650 | return ty_abi_align; | 6650 | return ty_abi_align; |
| 6651 | } | 6651 | } |
| 6652 | 6652 | ||
| 6653 | /// TODO: avoid linear search by storing these in trailing data of packed struct types | 6653 | /// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets |
| 6654 | /// then packedStructFieldByteOffset can be expressed in terms of bits / 8, fixing | 6654 | /// into the packed struct InternPool data rather than computing this on the |
| 6655 | /// that one too. | 6655 | /// fly, however it was found to perform worse when measured on real world |
| 6656 | /// https://github.com/ziglang/zig/issues/17178 | 6656 | /// projects. |
| 6657 | pub fn structPackedFieldBitOffset( | 6657 | pub fn structPackedFieldBitOffset( |
| 6658 | mod: *Module, | 6658 | mod: *Module, |
| 6659 | struct_type: InternPool.Key.StructType, | 6659 | struct_type: InternPool.Key.StructType, |
src/Sema.zig+3-2| ... | @@ -21377,8 +21377,9 @@ fn reifyStruct( | ... | @@ -21377,8 +21377,9 @@ fn reifyStruct( |
| 21377 | } | 21377 | } |
| 21378 | 21378 | ||
| 21379 | var fields_bit_sum: u64 = 0; | 21379 | var fields_bit_sum: u64 = 0; |
| 21380 | for (struct_type.field_types.get(ip)) |field_ty| { | 21380 | for (0..struct_type.field_types.len) |i| { |
| 21381 | fields_bit_sum += field_ty.toType().bitSize(mod); | 21381 | const field_ty = struct_type.field_types.get(ip)[i].toType(); |
| 21382 | fields_bit_sum += field_ty.bitSize(mod); | ||
| 21382 | } | 21383 | } |
| 21383 | 21384 | ||
| 21384 | if (backing_int_val.optionalValue(mod)) |backing_int_ty_val| { | 21385 | if (backing_int_val.optionalValue(mod)) |backing_int_ty_val| { |
src/type.zig+9-12| ... | @@ -3021,27 +3021,24 @@ pub const Type = struct { | ... | @@ -3021,27 +3021,24 @@ pub const Type = struct { |
| 3021 | }; | 3021 | }; |
| 3022 | } | 3022 | } |
| 3023 | 3023 | ||
| 3024 | pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, mod: *Module) u32 { | 3024 | pub fn packedStructFieldBitOffset(ty: Type, field_index: usize, mod: *Module) u32 { |
| 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 | comptime assert(Type.packed_struct_layout_version == 2); | 3028 | comptime assert(Type.packed_struct_layout_version == 2); |
| 3029 | 3029 | ||
| 3030 | var bit_offset: u16 = undefined; | 3030 | var running_bits: u32 = 0; |
| 3031 | var elem_size_bits: u16 = undefined; | ||
| 3032 | var running_bits: u16 = 0; | ||
| 3033 | for (struct_type.field_types.get(ip), 0..) |field_ty, i| { | 3031 | for (struct_type.field_types.get(ip), 0..) |field_ty, i| { |
| 3032 | if (i == field_index) break; | ||
| 3034 | if (!field_ty.toType().hasRuntimeBits(mod)) continue; | 3033 | if (!field_ty.toType().hasRuntimeBits(mod)) continue; |
| 3035 | 3034 | const field_bits: u32 = @intCast(field_ty.toType().bitSize(mod)); | |
| 3036 | const field_bits: u16 = @intCast(field_ty.toType().bitSize(mod)); | ||
| 3037 | if (i == field_index) { | ||
| 3038 | bit_offset = running_bits; | ||
| 3039 | elem_size_bits = field_bits; | ||
| 3040 | } | ||
| 3041 | running_bits += field_bits; | 3035 | running_bits += field_bits; |
| 3042 | } | 3036 | } |
| 3043 | const byte_offset = bit_offset / 8; | 3037 | return running_bits; |
| 3044 | return byte_offset; | 3038 | } |
| 3039 | |||
| 3040 | pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, mod: *Module) u32 { | ||
| 3041 | return packedStructFieldBitOffset(ty, field_index, mod) / 8; | ||
| 3045 | } | 3042 | } |
| 3046 | 3043 | ||
| 3047 | pub const FieldOffset = struct { | 3044 | pub const FieldOffset = struct { |