authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-25 15:53:28-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-02-25 15:53:28-05:00
log81a47dc874d8468db7120e1733acd122f90d8eab
tree97921a5f1f37300756e7dcbce9dbfad347574d3e
parent26196be344e971c26ed044a39b68d0420cd94b90
parent477be90c0c18a473c5b0c84c0fbcc9ce41e47738
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14725 from jacobly0/more-ctype

CBE: more `CType` improvements

3 files changed, 156 insertions(+), 140 deletions(-)

src/codegen/c.zig+95-64
......@@ -82,15 +82,20 @@ pub const LazyFnMap = std.AutoArrayHashMapUnmanaged(LazyFnKey, LazyFnValue);
8282
8383const LoopDepth = u16;
8484const Local = struct {
85 ty: Type,
86 alignment: u32,
85 cty_idx: CType.Index,
8786 /// How many loops the last definition was nested in.
8887 loop_depth: LoopDepth,
88 alignas: CType.AlignAs,
89
90 pub fn getType(local: Local) LocalType {
91 return .{ .cty_idx = local.cty_idx, .alignas = local.alignas };
92 }
8993};
9094
9195const LocalIndex = u16;
92const LocalsList = std.ArrayListUnmanaged(LocalIndex);
93const LocalsMap = std.ArrayHashMapUnmanaged(Type, LocalsList, Type.HashContext32, true);
96const LocalType = struct { cty_idx: CType.Index, alignas: CType.AlignAs };
97const LocalsList = std.AutoArrayHashMapUnmanaged(LocalIndex, void);
98const LocalsMap = std.AutoArrayHashMapUnmanaged(LocalType, LocalsList);
9499const LocalsStack = std.ArrayListUnmanaged(LocalsMap);
95100
96101const ValueRenderLocation = enum {
......@@ -296,10 +301,6 @@ pub const Function = struct {
296301 /// Needed for memory used by the keys of free_locals_stack entries.
297302 arena: std.heap.ArenaAllocator,
298303
299 fn tyHashCtx(f: Function) Type.HashContext32 {
300 return .{ .mod = f.object.dg.module };
301 }
302
303304 fn resolveInst(f: *Function, inst: Air.Inst.Ref) !CValue {
304305 const gop = try f.value_map.getOrPut(inst);
305306 if (gop.found_existing) return gop.value_ptr.*;
......@@ -339,10 +340,11 @@ pub const Function = struct {
339340 /// Skips the reuse logic.
340341 fn allocLocalValue(f: *Function, ty: Type, alignment: u32) !CValue {
341342 const gpa = f.object.dg.gpa;
343 const target = f.object.dg.module.getTarget();
342344 try f.locals.append(gpa, .{
343 .ty = ty,
344 .alignment = alignment,
345 .cty_idx = try f.typeToIndex(ty, .complete),
345346 .loop_depth = @intCast(LoopDepth, f.free_locals_stack.items.len - 1),
347 .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target)),
346348 });
347349 return .{ .new_local = @intCast(LocalIndex, f.locals.items.len - 1) };
348350 }
......@@ -355,14 +357,15 @@ pub const Function = struct {
355357
356358 /// Only allocates the local; does not print anything.
357359 fn allocAlignedLocal(f: *Function, ty: Type, _: CQualifiers, alignment: u32) !CValue {
358 if (f.getFreeLocals().getPtrContext(ty, f.tyHashCtx())) |locals_list| {
359 for (locals_list.items, 0..) |local_index, i| {
360 const local = &f.locals.items[local_index];
361 if (local.alignment >= alignment) {
362 local.loop_depth = @intCast(LoopDepth, f.free_locals_stack.items.len - 1);
363 _ = locals_list.swapRemove(i);
364 return .{ .new_local = local_index };
365 }
360 const target = f.object.dg.module.getTarget();
361 if (f.getFreeLocals().getPtr(.{
362 .cty_idx = try f.typeToIndex(ty, .complete),
363 .alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target)),
364 })) |locals_list| {
365 if (locals_list.popOrNull()) |local_entry| {
366 const local = &f.locals.items[local_entry.key];
367 local.loop_depth = @intCast(LoopDepth, f.free_locals_stack.items.len - 1);
368 return .{ .new_local = local_entry.key };
366369 }
367370 }
368371
......@@ -1695,22 +1698,34 @@ pub const DeclGen = struct {
16951698 qualifiers: CQualifiers,
16961699 alignment: u32,
16971700 kind: CType.Kind,
1701 ) error{ OutOfMemory, AnalysisFail }!void {
1702 const target = dg.module.getTarget();
1703 const alignas = CType.AlignAs.init(alignment, ty.abiAlignment(target));
1704 try dg.renderCTypeAndName(w, try dg.typeToIndex(ty, kind), name, qualifiers, alignas);
1705 }
1706
1707 fn renderCTypeAndName(
1708 dg: *DeclGen,
1709 w: anytype,
1710 cty_idx: CType.Index,
1711 name: CValue,
1712 qualifiers: CQualifiers,
1713 alignas: CType.AlignAs,
16981714 ) error{ OutOfMemory, AnalysisFail }!void {
16991715 const store = &dg.ctypes.set;
17001716 const module = dg.module;
17011717
1702 if (alignment != 0) switch (std.math.order(alignment, ty.abiAlignment(dg.module.getTarget()))) {
1703 .lt => try w.print("zig_under_align({}) ", .{alignment}),
1718 switch (std.math.order(alignas.@"align", alignas.abi)) {
1719 .lt => try w.print("zig_under_align({}) ", .{alignas.getAlign()}),
17041720 .eq => {},
1705 .gt => try w.print("zig_align({}) ", .{alignment}),
1706 };
1721 .gt => try w.print("zig_align({}) ", .{alignas.getAlign()}),
1722 }
17071723
1708 const idx = try dg.typeToIndex(ty, kind);
17091724 const trailing =
1710 try renderTypePrefix(dg.decl_index, store.*, module, w, idx, .suffix, qualifiers);
1725 try renderTypePrefix(dg.decl_index, store.*, module, w, cty_idx, .suffix, qualifiers);
17111726 try w.print("{}", .{trailing});
17121727 try dg.writeCValue(w, name);
1713 try renderTypeSuffix(dg.decl_index, store.*, module, w, idx, .suffix, .{});
1728 try renderTypeSuffix(dg.decl_index, store.*, module, w, cty_idx, .suffix, .{});
17141729 }
17151730
17161731 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
......@@ -2589,36 +2604,27 @@ pub fn genFunc(f: *Function) !void {
25892604 if (value) continue; // static
25902605 const local = f.locals.items[local_index];
25912606 log.debug("inserting local {d} into free_locals", .{local_index});
2592 const gop = try free_locals.getOrPutContext(gpa, local.ty, f.tyHashCtx());
2607 const gop = try free_locals.getOrPut(gpa, local.getType());
25932608 if (!gop.found_existing) gop.value_ptr.* = .{};
2594 try gop.value_ptr.append(gpa, local_index);
2609 try gop.value_ptr.putNoClobber(gpa, local_index, {});
25952610 }
25962611
25972612 const SortContext = struct {
2598 target: std.Target,
2599 keys: []const Type,
2613 keys: []const LocalType,
26002614
2601 pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool {
2602 const a_ty = ctx.keys[a_index];
2603 const b_ty = ctx.keys[b_index];
2604 return b_ty.abiAlignment(ctx.target) < a_ty.abiAlignment(ctx.target);
2615 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
2616 const lhs_ty = ctx.keys[lhs_index];
2617 const rhs_ty = ctx.keys[rhs_index];
2618 return lhs_ty.alignas.getAlign() > rhs_ty.alignas.getAlign();
26052619 }
26062620 };
2607 const target = o.dg.module.getTarget();
2608 free_locals.sort(SortContext{ .target = target, .keys = free_locals.keys() });
2621 free_locals.sort(SortContext{ .keys = free_locals.keys() });
26092622
26102623 const w = o.code_header.writer();
26112624 for (free_locals.values()) |list| {
2612 for (list.items) |local_index| {
2625 for (list.keys()) |local_index| {
26132626 const local = f.locals.items[local_index];
2614 try o.dg.renderTypeAndName(
2615 w,
2616 local.ty,
2617 .{ .local = local_index },
2618 .{},
2619 local.alignment,
2620 .complete,
2621 );
2627 try o.dg.renderCTypeAndName(w, local.cty_idx, .{ .local = local_index }, .{}, local.alignas);
26222628 try w.writeAll(";\n ");
26232629 }
26242630 }
......@@ -4486,13 +4492,13 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {
44864492 const new_free_locals = f.getFreeLocals();
44874493 var it = new_free_locals.iterator();
44884494 while (it.next()) |entry| {
4489 const gop = try old_free_locals.getOrPutContext(gpa, entry.key_ptr.*, f.tyHashCtx());
4495 const gop = try old_free_locals.getOrPut(gpa, entry.key_ptr.*);
44904496 if (gop.found_existing) {
4491 try gop.value_ptr.appendSlice(gpa, entry.value_ptr.items);
4492 } else {
4493 gop.value_ptr.* = entry.value_ptr.*;
4494 entry.value_ptr.* = .{};
4495 }
4497 try gop.value_ptr.ensureUnusedCapacity(gpa, entry.value_ptr.count());
4498 for (entry.value_ptr.keys()) |local_index| {
4499 gop.value_ptr.putAssumeCapacityNoClobber(local_index, {});
4500 }
4501 } else gop.value_ptr.* = entry.value_ptr.move();
44964502 }
44974503 deinitFreeLocalsMap(gpa, new_free_locals);
44984504 new_free_locals.* = old_free_locals.move();
......@@ -4522,6 +4528,10 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
45224528 // that we can notice and use them in the else branch. Any new locals must
45234529 // necessarily be free already after the then branch is complete.
45244530 const pre_locals_len = @intCast(LocalIndex, f.locals.items.len);
4531 // Remember how many allocs there were before entering the then branch so
4532 // that we can notice and make sure not to use them in the else branch.
4533 // Any new allocs must be removed from the free list.
4534 const pre_allocs_len = @intCast(LocalIndex, f.allocs.count());
45254535 const pre_clone_depth = f.free_locals_clone_depth;
45264536 f.free_locals_clone_depth = @intCast(LoopDepth, f.free_locals_stack.items.len);
45274537
......@@ -4552,7 +4562,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
45524562 try die(f, inst, Air.indexToRef(operand));
45534563 }
45544564
4555 try noticeBranchFrees(f, pre_locals_len, inst);
4565 try noticeBranchFrees(f, pre_locals_len, pre_allocs_len, inst);
45564566
45574567 if (needs_else) {
45584568 try genBody(f, else_body);
......@@ -4627,6 +4637,10 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
46274637 // we can notice and use them in subsequent branches. Any new locals must
46284638 // necessarily be free already after the previous branch is complete.
46294639 const pre_locals_len = @intCast(LocalIndex, f.locals.items.len);
4640 // Remember how many allocs there were before entering each branch so that
4641 // we can notice and make sure not to use them in subsequent branches.
4642 // Any new allocs must be removed from the free list.
4643 const pre_allocs_len = @intCast(LocalIndex, f.allocs.count());
46304644 const pre_clone_depth = f.free_locals_clone_depth;
46314645 f.free_locals_clone_depth = @intCast(LoopDepth, f.free_locals_stack.items.len);
46324646
......@@ -4647,7 +4661,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
46474661 try genBody(f, case_body);
46484662 }
46494663
4650 try noticeBranchFrees(f, pre_locals_len, inst);
4664 try noticeBranchFrees(f, pre_locals_len, pre_allocs_len, inst);
46514665 } else {
46524666 for (liveness.deaths[case_i]) |operand| {
46534667 try die(f, inst, Air.indexToRef(operand));
......@@ -7441,21 +7455,16 @@ fn freeLocal(f: *Function, inst: Air.Inst.Index, local_index: LocalIndex, ref_in
74417455 const local = &f.locals.items[local_index];
74427456 log.debug("%{d}: freeing t{d} (operand %{d})", .{ inst, local_index, ref_inst });
74437457 if (local.loop_depth < f.free_locals_clone_depth) return;
7444 const gop = try f.free_locals_stack.items[local.loop_depth].getOrPutContext(
7445 gpa,
7446 local.ty,
7447 f.tyHashCtx(),
7448 );
7458 const gop = try f.free_locals_stack.items[local.loop_depth].getOrPut(gpa, local.getType());
74497459 if (!gop.found_existing) gop.value_ptr.* = .{};
74507460 if (std.debug.runtime_safety) {
7451 // If this trips, it means a local is being inserted into the
7452 // free_locals map while it already exists in the map, which is not
7453 // allowed.
7454 assert(mem.indexOfScalar(LocalIndex, gop.value_ptr.items, local_index) == null);
74557461 // If this trips, an unfreeable allocation was attempted to be freed.
74567462 assert(!f.allocs.contains(local_index));
74577463 }
7458 try gop.value_ptr.append(gpa, local_index);
7464 // If this trips, it means a local is being inserted into the
7465 // free_locals map while it already exists in the map, which is not
7466 // allowed.
7467 try gop.value_ptr.putNoClobber(gpa, local_index, {});
74597468}
74607469
74617470const BigTomb = struct {
......@@ -7504,14 +7513,36 @@ fn deinitFreeLocalsMap(gpa: mem.Allocator, map: *LocalsMap) void {
75047513 map.deinit(gpa);
75057514}
75067515
7507fn noticeBranchFrees(f: *Function, pre_locals_len: LocalIndex, inst: Air.Inst.Index) !void {
7516fn noticeBranchFrees(
7517 f: *Function,
7518 pre_locals_len: LocalIndex,
7519 pre_allocs_len: LocalIndex,
7520 inst: Air.Inst.Index,
7521) !void {
7522 const free_locals = f.getFreeLocals();
7523
75087524 for (f.locals.items[pre_locals_len..], pre_locals_len..) |*local, local_i| {
75097525 const local_index = @intCast(LocalIndex, local_i);
7510 if (f.allocs.contains(local_index)) continue; // allocs are not freeable
7526 if (f.allocs.contains(local_index)) {
7527 if (std.debug.runtime_safety) {
7528 // new allocs are no longer freeable, so make sure they aren't in the free list
7529 if (free_locals.getPtr(local.getType())) |locals_list| {
7530 assert(!locals_list.contains(local_index));
7531 }
7532 }
7533 continue;
7534 }
75117535
75127536 // free more deeply nested locals from other branches at current depth
75137537 assert(local.loop_depth >= f.free_locals_stack.items.len - 1);
75147538 local.loop_depth = @intCast(LoopDepth, f.free_locals_stack.items.len - 1);
75157539 try freeLocal(f, inst, local_index, 0);
75167540 }
7541
7542 for (f.allocs.keys()[pre_allocs_len..]) |local_i| {
7543 const local_index = @intCast(LocalIndex, local_i);
7544 const local = &f.locals.items[local_index];
7545 // new allocs are no longer freeable, so remove them from the free list
7546 if (free_locals.getPtr(local.getType())) |locals_list| _ = locals_list.swapRemove(local_index);
7547 }
75177548}
src/codegen/c/type.zig+59-76
......@@ -251,38 +251,6 @@ pub const CType = extern union {
251251 type: Index,
252252 alignas: AlignAs,
253253 };
254 pub const AlignAs = struct {
255 @"align": std.math.Log2Int(u32),
256 abi: std.math.Log2Int(u32),
257
258 pub fn init(alignment: u32, abi_alignment: u32) AlignAs {
259 assert(std.math.isPowerOfTwo(alignment));
260 assert(std.math.isPowerOfTwo(abi_alignment));
261 return .{
262 .@"align" = std.math.log2_int(u32, alignment),
263 .abi = std.math.log2_int(u32, abi_alignment),
264 };
265 }
266 pub fn abiAlign(ty: Type, target: Target) AlignAs {
267 const abi_align = ty.abiAlignment(target);
268 return init(abi_align, abi_align);
269 }
270 pub fn fieldAlign(struct_ty: Type, field_i: usize, target: Target) AlignAs {
271 return init(
272 struct_ty.structFieldAlign(field_i, target),
273 struct_ty.structFieldType(field_i).abiAlignment(target),
274 );
275 }
276 pub fn unionPayloadAlign(union_ty: Type, target: Target) AlignAs {
277 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
278 const union_payload_align = union_obj.abiAlignment(target, false);
279 return init(union_payload_align, union_payload_align);
280 }
281
282 pub fn getAlign(self: AlignAs) u32 {
283 return @as(u32, 1) << self.@"align";
284 }
285 };
286254 };
287255
288256 pub const Unnamed = struct {
......@@ -311,13 +279,57 @@ pub const CType = extern union {
311279 };
312280 };
313281
282 pub const AlignAs = struct {
283 @"align": std.math.Log2Int(u32),
284 abi: std.math.Log2Int(u32),
285
286 pub fn init(alignment: u32, abi_alignment: u32) AlignAs {
287 const actual_align = if (alignment != 0) alignment else abi_alignment;
288 assert(std.math.isPowerOfTwo(actual_align));
289 assert(std.math.isPowerOfTwo(abi_alignment));
290 return .{
291 .@"align" = std.math.log2_int(u32, actual_align),
292 .abi = std.math.log2_int(u32, abi_alignment),
293 };
294 }
295 pub fn abiAlign(ty: Type, target: Target) AlignAs {
296 const abi_align = ty.abiAlignment(target);
297 return init(abi_align, abi_align);
298 }
299 pub fn fieldAlign(struct_ty: Type, field_i: usize, target: Target) AlignAs {
300 return init(
301 struct_ty.structFieldAlign(field_i, target),
302 struct_ty.structFieldType(field_i).abiAlignment(target),
303 );
304 }
305 pub fn unionPayloadAlign(union_ty: Type, target: Target) AlignAs {
306 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
307 const union_payload_align = union_obj.abiAlignment(target, false);
308 return init(union_payload_align, union_payload_align);
309 }
310
311 pub fn getAlign(self: AlignAs) u32 {
312 return @as(u32, 1) << self.@"align";
313 }
314 };
315
314316 pub const Index = u32;
315317 pub const Store = struct {
316318 arena: std.heap.ArenaAllocator.State = .{},
317319 set: Set = .{},
318320
319321 pub const Set = struct {
320 pub const Map = std.ArrayHashMapUnmanaged(CType, void, HashContext32, true);
322 pub const Map = std.ArrayHashMapUnmanaged(CType, void, HashContext, true);
323 const HashContext = struct {
324 store: *const Set,
325
326 pub fn hash(self: @This(), cty: CType) Map.Hash {
327 return @truncate(Map.Hash, cty.hash(self.store.*));
328 }
329 pub fn eql(_: @This(), lhs: CType, rhs: CType, _: usize) bool {
330 return lhs.eql(rhs);
331 }
332 };
321333
322334 map: Map = .{},
323335
......@@ -328,7 +340,7 @@ pub const CType = extern union {
328340
329341 pub fn indexToHash(self: Set, index: Index) Map.Hash {
330342 if (index < Tag.no_payload_count)
331 return (HashContext32{ .store = &self }).hash(self.indexToCType(index));
343 return (HashContext{ .store = &self }).hash(self.indexToCType(index));
332344 return self.map.entries.items(.hash)[index - Tag.no_payload_count];
333345 }
334346
......@@ -905,7 +917,7 @@ pub const CType = extern union {
905917 self.storage.anon.fields[0] = .{
906918 .name = "array",
907919 .type = array_idx,
908 .alignas = Payload.Fields.AlignAs.abiAlign(ty, lookup.getTarget()),
920 .alignas = AlignAs.abiAlign(ty, lookup.getTarget()),
909921 };
910922 self.initAnon(kind, fwd_idx, 1);
911923 } else self.init(switch (kind) {
......@@ -1004,12 +1016,12 @@ pub const CType = extern union {
10041016 self.storage.anon.fields[0] = .{
10051017 .name = "ptr",
10061018 .type = ptr_idx,
1007 .alignas = Payload.Fields.AlignAs.abiAlign(ptr_ty, target),
1019 .alignas = AlignAs.abiAlign(ptr_ty, target),
10081020 };
10091021 self.storage.anon.fields[1] = .{
10101022 .name = "len",
10111023 .type = Tag.uintptr_t.toIndex(),
1012 .alignas = Payload.Fields.AlignAs.abiAlign(Type.usize, target),
1024 .alignas = AlignAs.abiAlign(Type.usize, target),
10131025 };
10141026 self.initAnon(kind, fwd_idx, 2);
10151027 } else self.init(switch (kind) {
......@@ -1125,7 +1137,7 @@ pub const CType = extern union {
11251137 self.storage.anon.fields[field_count] = .{
11261138 .name = "payload",
11271139 .type = payload_idx.?,
1128 .alignas = Payload.Fields.AlignAs.unionPayloadAlign(ty, target),
1140 .alignas = AlignAs.unionPayloadAlign(ty, target),
11291141 };
11301142 field_count += 1;
11311143 }
......@@ -1133,7 +1145,7 @@ pub const CType = extern union {
11331145 self.storage.anon.fields[field_count] = .{
11341146 .name = "tag",
11351147 .type = tag_idx.?,
1136 .alignas = Payload.Fields.AlignAs.abiAlign(tag_ty.?, target),
1148 .alignas = AlignAs.abiAlign(tag_ty.?, target),
11371149 };
11381150 field_count += 1;
11391151 }
......@@ -1158,11 +1170,7 @@ pub const CType = extern union {
11581170 const field_ty = ty.structFieldType(field_i);
11591171 if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue;
11601172
1161 const field_align = Payload.Fields.AlignAs.fieldAlign(
1162 ty,
1163 field_i,
1164 target,
1165 );
1173 const field_align = AlignAs.fieldAlign(ty, field_i, target);
11661174 if (field_align.@"align" < field_align.abi) {
11671175 is_packed = true;
11681176 if (!lookup.isMutable()) break;
......@@ -1235,12 +1243,12 @@ pub const CType = extern union {
12351243 self.storage.anon.fields[0] = .{
12361244 .name = "payload",
12371245 .type = payload_idx,
1238 .alignas = Payload.Fields.AlignAs.abiAlign(payload_ty, target),
1246 .alignas = AlignAs.abiAlign(payload_ty, target),
12391247 };
12401248 self.storage.anon.fields[1] = .{
12411249 .name = "is_null",
12421250 .type = Tag.bool.toIndex(),
1243 .alignas = Payload.Fields.AlignAs.abiAlign(Type.bool, target),
1251 .alignas = AlignAs.abiAlign(Type.bool, target),
12441252 };
12451253 self.initAnon(kind, fwd_idx, 2);
12461254 } else self.init(switch (kind) {
......@@ -1273,12 +1281,12 @@ pub const CType = extern union {
12731281 self.storage.anon.fields[0] = .{
12741282 .name = "payload",
12751283 .type = payload_idx,
1276 .alignas = Payload.Fields.AlignAs.abiAlign(payload_ty, target),
1284 .alignas = AlignAs.abiAlign(payload_ty, target),
12771285 };
12781286 self.storage.anon.fields[1] = .{
12791287 .name = "error",
12801288 .type = error_idx,
1281 .alignas = Payload.Fields.AlignAs.abiAlign(error_ty, target),
1289 .alignas = AlignAs.abiAlign(error_ty, target),
12821290 };
12831291 self.initAnon(kind, fwd_idx, 2);
12841292 } else self.init(switch (kind) {
......@@ -1551,7 +1559,7 @@ pub const CType = extern union {
15511559 .complete, .parameter, .payload => .complete,
15521560 .global => .global,
15531561 }).?,
1554 .alignas = Payload.Fields.AlignAs.fieldAlign(ty, field_i, target),
1562 .alignas = AlignAs.fieldAlign(ty, field_i, target),
15551563 };
15561564 }
15571565
......@@ -1635,28 +1643,6 @@ pub const CType = extern union {
16351643 }
16361644 }
16371645
1638 pub const HashContext64 = struct {
1639 store: *const Store.Set,
1640
1641 pub fn hash(self: @This(), cty: CType) u64 {
1642 return cty.hash(self.store.*);
1643 }
1644 pub fn eql(_: @This(), lhs: CType, rhs: CType) bool {
1645 return lhs.eql(rhs);
1646 }
1647 };
1648
1649 pub const HashContext32 = struct {
1650 store: *const Store.Set,
1651
1652 pub fn hash(self: @This(), cty: CType) u32 {
1653 return @truncate(u32, cty.hash(self.store.*));
1654 }
1655 pub fn eql(_: @This(), lhs: CType, rhs: CType, _: usize) bool {
1656 return lhs.eql(rhs);
1657 }
1658 };
1659
16601646 pub const TypeAdapter64 = struct {
16611647 kind: Kind,
16621648 lookup: Convert.Lookup,
......@@ -1719,7 +1705,7 @@ pub const CType = extern union {
17191705 else => unreachable,
17201706 },
17211707 mem.span(c_field.name),
1722 ) or Payload.Fields.AlignAs.fieldAlign(ty, field_i, target).@"align" !=
1708 ) or AlignAs.fieldAlign(ty, field_i, target).@"align" !=
17231709 c_field.alignas.@"align") return false;
17241710 }
17251711 return true;
......@@ -1840,10 +1826,7 @@ pub const CType = extern union {
18401826 .Union => ty.unionFields().keys()[field_i],
18411827 else => unreachable,
18421828 });
1843 autoHash(
1844 hasher,
1845 Payload.Fields.AlignAs.fieldAlign(ty, field_i, target).@"align",
1846 );
1829 autoHash(hasher, AlignAs.fieldAlign(ty, field_i, target).@"align");
18471830 }
18481831 },
18491832
test/behavior/vector.zig+2
......@@ -1247,6 +1247,7 @@ test "load packed vector element" {
12471247 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12481248 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
12491249 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1250 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
12501251
12511252 var x: @Vector(2, u15) = .{ 1, 4 };
12521253 try expect((&x[0]).* == 1);
......@@ -1259,6 +1260,7 @@ test "store packed vector element" {
12591260 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12601261 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
12611262 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1263 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
12621264
12631265 var v = @Vector(4, u1){ 1, 1, 1, 1 };
12641266 try expectEqual(@Vector(4, u1){ 1, 1, 1, 1 }, v);