diff options
| author | David Rubin <daviru007@icloud.com> | 2024-08-11 03:14:12 -0700 |
|---|---|---|
| committer | David Rubin <daviru007@icloud.com> | 2024-08-25 15:16:42 -0700 |
| commit | b4bb64ce78bf2dee9437f366a362ef4d8c77b204 (patch) | |
| tree | 218658e59522e59a432b6e9adea9f1993c0fb51d /src/Zcu/PerThread.zig | |
| parent | 849c31a6cc3d1e554f97c2ccf7aaa886070cfadd (diff) | |
| download | zig-b4bb64ce78bf2dee9437f366a362ef4d8c77b204.tar.gz zig-b4bb64ce78bf2dee9437f366a362ef4d8c77b204.zip | |
sema: rework type resolution to use Zcu when possible
Diffstat (limited to 'src/Zcu/PerThread.zig')
| -rw-r--r-- | src/Zcu/PerThread.zig | 162 |
1 files changed, 27 insertions, 135 deletions
diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index 01063ab2ce..ab9e6bbabb 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -2756,7 +2756,7 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error! // pointee type needs to be resolved more, that needs to be done before calling // this ptr() function. if (info.flags.alignment != .none and - info.flags.alignment == Type.fromInterned(info.child).abiAlignment(pt)) + info.flags.alignment == Type.fromInterned(info.child).abiAlignment(pt.zcu)) { canon_info.flags.alignment = .none; } @@ -2766,7 +2766,7 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error! // we change it to 0 here. If this causes an assertion trip, the pointee type // needs to be resolved before calling this ptr() function. .none => if (info.packed_offset.host_size != 0) { - const elem_bit_size = Type.fromInterned(info.child).bitSize(pt); + const elem_bit_size = Type.fromInterned(info.child).bitSize(pt.zcu); assert(info.packed_offset.bit_offset + elem_bit_size <= info.packed_offset.host_size * 8); if (info.packed_offset.host_size * 8 == elem_bit_size) { canon_info.packed_offset.host_size = 0; @@ -2784,7 +2784,7 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error! /// In general, prefer this function during semantic analysis. pub fn ptrTypeSema(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Zcu.SemaError!Type { if (info.flags.alignment != .none) { - _ = try Type.fromInterned(info.child).abiAlignmentAdvanced(pt, .sema); + _ = try Type.fromInterned(info.child).abiAlignmentSema(pt); } return pt.ptrType(info); } @@ -2984,15 +2984,15 @@ pub fn smallestUnsignedInt(pt: Zcu.PerThread, max: u64) Allocator.Error!Type { /// `max`. Asserts that neither value is undef. /// TODO: if #3806 is implemented, this becomes trivial pub fn intFittingRange(pt: Zcu.PerThread, min: Value, max: Value) !Type { - const mod = pt.zcu; - assert(!min.isUndef(mod)); - assert(!max.isUndef(mod)); + const zcu = pt.zcu; + assert(!min.isUndef(zcu)); + assert(!max.isUndef(zcu)); if (std.debug.runtime_safety) { - assert(Value.order(min, max, pt).compare(.lte)); + assert(Value.order(min, max, zcu).compare(.lte)); } - const sign = min.orderAgainstZero(pt) == .lt; + const sign = min.orderAgainstZero(zcu) == .lt; const min_val_bits = pt.intBitsForValue(min, sign); const max_val_bits = pt.intBitsForValue(max, sign); @@ -3032,120 +3032,30 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 { return @as(u16, @intCast(big.bitCountTwosComp())); }, .lazy_align => |lazy_ty| { - return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(pt).toByteUnits() orelse 0) + @intFromBool(sign); + return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(pt.zcu).toByteUnits() orelse 0) + @intFromBool(sign); }, .lazy_size => |lazy_ty| { - return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(pt)) + @intFromBool(sign); + return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(pt.zcu)) + @intFromBool(sign); }, } } -pub fn getUnionLayout(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) Zcu.UnionLayout { - const mod = pt.zcu; - const ip = &mod.intern_pool; - assert(loaded_union.haveLayout(ip)); - var most_aligned_field: u32 = undefined; - var most_aligned_field_size: u64 = undefined; - var biggest_field: u32 = undefined; - var payload_size: u64 = 0; - var payload_align: InternPool.Alignment = .@"1"; - for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| { - if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(pt)) continue; - - const explicit_align = loaded_union.fieldAlign(ip, field_index); - const field_align = if (explicit_align != .none) - explicit_align - else - Type.fromInterned(field_ty).abiAlignment(pt); - const field_size = Type.fromInterned(field_ty).abiSize(pt); - if (field_size > payload_size) { - payload_size = field_size; - biggest_field = @intCast(field_index); - } - if (field_align.compare(.gte, payload_align)) { - payload_align = field_align; - most_aligned_field = @intCast(field_index); - most_aligned_field_size = field_size; - } - } - const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag(); - if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(pt)) { - return .{ - .abi_size = payload_align.forward(payload_size), - .abi_align = payload_align, - .most_aligned_field = most_aligned_field, - .most_aligned_field_size = most_aligned_field_size, - .biggest_field = biggest_field, - .payload_size = payload_size, - .payload_align = payload_align, - .tag_align = .none, - .tag_size = 0, - .padding = 0, - }; - } - - const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(pt); - const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt).max(.@"1"); - return .{ - .abi_size = loaded_union.sizeUnordered(ip), - .abi_align = tag_align.max(payload_align), - .most_aligned_field = most_aligned_field, - .most_aligned_field_size = most_aligned_field_size, - .biggest_field = biggest_field, - .payload_size = payload_size, - .payload_align = payload_align, - .tag_align = tag_align, - .tag_size = tag_size, - .padding = loaded_union.paddingUnordered(ip), - }; -} - -pub fn unionAbiSize(mod: *Module, loaded_union: InternPool.LoadedUnionType) u64 { - return mod.getUnionLayout(loaded_union).abi_size; -} - /// Returns 0 if the union is represented with 0 bits at runtime. pub fn unionAbiAlignment(pt: Zcu.PerThread, loaded_union: InternPool.LoadedUnionType) InternPool.Alignment { - const mod = pt.zcu; - const ip = &mod.intern_pool; + const zcu = pt.zcu; + const ip = &zcu.intern_pool; const have_tag = loaded_union.flagsPtr(ip).runtime_tag.hasTag(); var max_align: InternPool.Alignment = .none; - if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(pt); + if (have_tag) max_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(zcu); for (loaded_union.field_types.get(ip), 0..) |field_ty, field_index| { - if (!Type.fromInterned(field_ty).hasRuntimeBits(pt)) continue; + if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; - const field_align = mod.unionFieldNormalAlignment(loaded_union, @intCast(field_index)); + const field_align = zcu.unionFieldNormalAlignment(loaded_union, @intCast(field_index)); max_align = max_align.max(field_align); } return max_align; } -/// Returns the field alignment of a non-packed union. Asserts the layout is not packed. -pub fn unionFieldNormalAlignment( - pt: Zcu.PerThread, - loaded_union: InternPool.LoadedUnionType, - field_index: u32, -) InternPool.Alignment { - return pt.unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal) catch unreachable; -} - -/// Returns the field alignment of a non-packed union. Asserts the layout is not packed. -/// If `strat` is `.sema`, may perform type resolution. -pub fn unionFieldNormalAlignmentAdvanced( - pt: Zcu.PerThread, - loaded_union: InternPool.LoadedUnionType, - field_index: u32, - comptime strat: Type.ResolveStrat, -) Zcu.SemaError!InternPool.Alignment { - const ip = &pt.zcu.intern_pool; - assert(loaded_union.flagsUnordered(ip).layout != .@"packed"); - const field_align = loaded_union.fieldAlign(ip, field_index); - if (field_align != .none) return field_align; - const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); - if (field_ty.isNoReturn(pt.zcu)) return .none; - return (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar; -} - /// Returns the field alignment of a non-packed struct. Asserts the layout is not packed. pub fn structFieldAlignment( pt: Zcu.PerThread, @@ -3153,31 +3063,13 @@ pub fn structFieldAlignment( field_ty: Type, layout: std.builtin.Type.ContainerLayout, ) InternPool.Alignment { - return pt.structFieldAlignmentAdvanced(explicit_alignment, field_ty, layout, .normal) catch unreachable; -} - -/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed. -/// If `strat` is `.sema`, may perform type resolution. -pub fn structFieldAlignmentAdvanced( - pt: Zcu.PerThread, - explicit_alignment: InternPool.Alignment, - field_ty: Type, - layout: std.builtin.Type.ContainerLayout, - comptime strat: Type.ResolveStrat, -) Zcu.SemaError!InternPool.Alignment { - assert(layout != .@"packed"); - if (explicit_alignment != .none) return explicit_alignment; - const ty_abi_align = (try field_ty.abiAlignmentAdvanced(pt, strat.toLazy())).scalar; - switch (layout) { - .@"packed" => unreachable, - .auto => if (pt.zcu.getTarget().ofmt != .c) return ty_abi_align, - .@"extern" => {}, - } - // extern - if (field_ty.isAbiInt(pt.zcu) and field_ty.intInfo(pt.zcu).bits >= 128) { - return ty_abi_align.maxStrict(.@"16"); - } - return ty_abi_align; + return field_ty.structFieldAlignmentAdvanced( + explicit_alignment, + layout, + .normal, + pt.zcu, + {}, + ) catch unreachable; } /// https://github.com/ziglang/zig/issues/17178 explored storing these bit offsets @@ -3189,8 +3081,8 @@ pub fn structPackedFieldBitOffset( struct_type: InternPool.LoadedStructType, field_index: u32, ) u16 { - const mod = pt.zcu; - const ip = &mod.intern_pool; + const zcu = pt.zcu; + const ip = &zcu.intern_pool; assert(struct_type.layout == .@"packed"); assert(struct_type.haveLayout(ip)); var bit_sum: u64 = 0; @@ -3199,7 +3091,7 @@ pub fn structPackedFieldBitOffset( return @intCast(bit_sum); } const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); - bit_sum += field_ty.bitSize(pt); + bit_sum += field_ty.bitSize(zcu); } unreachable; // index out of bounds } @@ -3244,7 +3136,7 @@ pub fn navPtrType(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Allocator. return pt.ptrType(.{ .child = ty.toIntern(), .flags = .{ - .alignment = if (r.alignment == ty.abiAlignment(pt)) + .alignment = if (r.alignment == ty.abiAlignment(zcu)) .none else r.alignment, @@ -3274,7 +3166,7 @@ pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPo const zcu = pt.zcu; const r = zcu.intern_pool.getNav(nav_index).status.resolved; if (r.alignment != .none) return r.alignment; - return Value.fromInterned(r.val).typeOf(zcu).abiAlignment(pt); + return Value.fromInterned(r.val).typeOf(zcu).abiAlignment(zcu); } /// Given a container type requiring resolution, ensures that it is up-to-date. |
