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
This commit is contained in:
Andrew Kelley
2023-09-23 23:06:08 -07:00
parent 8eff0a0a66
commit a7088fd9a3
9 changed files with 74 additions and 61 deletions

View File

@@ -6649,26 +6649,3 @@ pub fn structFieldAlignmentExtern(mod: *Module, field_ty: Type) Alignment {
return ty_abi_align;
}
/// TODO: avoid linear search by storing these in trailing data of packed struct types
/// then packedStructFieldByteOffset can be expressed in terms of bits / 8, fixing
/// that one too.
/// https://github.com/ziglang/zig/issues/17178
pub fn structPackedFieldBitOffset(
mod: *Module,
struct_type: InternPool.Key.StructType,
field_index: u32,
) u16 {
const ip = &mod.intern_pool;
assert(struct_type.layout == .Packed);
assert(struct_type.haveLayout(ip));
var bit_sum: u64 = 0;
for (0..struct_type.field_types.len) |i| {
if (i == field_index) {
return @intCast(bit_sum);
}
const field_ty = struct_type.field_types.get(ip)[i].toType();
bit_sum += field_ty.bitSize(mod);
}
unreachable; // index out of bounds
}