aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-09-23 23:06:08 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-09-23 23:06:08 -0700
commita7088fd9a3edb037f0f51bb402a3c557334634f3 (patch)
treedba5fd9f32b341d1cb64b9813033e1558c1e8d2b /src/type.zig
parent8eff0a0a669dbdacf9cebbc96fdf20536f3073ee (diff)
downloadzig-a7088fd9a3edb037f0f51bb402a3c557334634f3.tar.gz
zig-a7088fd9a3edb037f0f51bb402a3c557334634f3.zip
compiler: packed structs cache bit offsets
Instead of linear search every time a packed struct field's bit or byte offset is wanted, they are computed once during resolution of the packed struct's backing int type, and stored in InternPool for O(1) lookup. Closes #17178
Diffstat (limited to 'src/type.zig')
-rw-r--r--src/type.zig25
1 files changed, 7 insertions, 18 deletions
diff --git a/src/type.zig b/src/type.zig
index 0ed8c394fc..83a89b527b 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -3021,27 +3021,16 @@ pub const Type = struct {
};
}
- pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, mod: *Module) u32 {
+ pub fn packedStructFieldBitOffset(ty: Type, field_index: usize, mod: *Module) u32 {
const ip = &mod.intern_pool;
const struct_type = ip.indexToKey(ty.toIntern()).struct_type;
assert(struct_type.layout == .Packed);
- comptime assert(Type.packed_struct_layout_version == 2);
-
- var bit_offset: u16 = undefined;
- var elem_size_bits: u16 = undefined;
- var running_bits: u16 = 0;
- for (struct_type.field_types.get(ip), 0..) |field_ty, i| {
- if (!field_ty.toType().hasRuntimeBits(mod)) continue;
-
- const field_bits: u16 = @intCast(field_ty.toType().bitSize(mod));
- if (i == field_index) {
- bit_offset = running_bits;
- elem_size_bits = field_bits;
- }
- running_bits += field_bits;
- }
- const byte_offset = bit_offset / 8;
- return byte_offset;
+ assert(struct_type.haveLayout(ip));
+ return struct_type.offsets.get(ip)[field_index];
+ }
+
+ pub fn packedStructFieldByteOffset(ty: Type, field_index: usize, mod: *Module) u32 {
+ return packedStructFieldBitOffset(ty, field_index, mod) / 8;
}
pub const FieldOffset = struct {