aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorMatthew Lugg <mlugg@mlugg.co.uk>2024-11-01 01:43:08 +0000
committerGitHub <noreply@github.com>2024-11-01 01:43:08 +0000
commit3f7fac5fff9beed535a7674679a5e2c1f3cd74d2 (patch)
treec5f7affd52d47632874da1f533c888ef648e8304 /src/codegen
parenta916bc7fdd3975a9e2ef13c44f814c71ce017193 (diff)
parent24babde746621492c5111ffcd8edf575cb176d65 (diff)
downloadzig-3f7fac5fff9beed535a7674679a5e2c1f3cd74d2.tar.gz
zig-3f7fac5fff9beed535a7674679a5e2c1f3cd74d2.zip
Merge pull request #21817 from mlugg/no-anon-structs
compiler: remove anonymous struct types, unify all tuples
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig41
-rw-r--r--src/codegen/c/Type.zig20
-rw-r--r--src/codegen/llvm.zig31
-rw-r--r--src/codegen/spirv.zig63
4 files changed, 70 insertions, 85 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index be8d2ad2a5..4d55637f27 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -891,7 +891,7 @@ pub const DeclGen = struct {
.error_union_type,
.simple_type,
.struct_type,
- .anon_struct_type,
+ .tuple_type,
.union_type,
.opaque_type,
.enum_type,
@@ -908,7 +908,7 @@ pub const DeclGen = struct {
.undefined => unreachable,
.void => unreachable,
.null => unreachable,
- .empty_struct => unreachable,
+ .empty_tuple => unreachable,
.@"unreachable" => unreachable,
.generic_poison => unreachable,
@@ -1194,7 +1194,7 @@ pub const DeclGen = struct {
try writer.writeByte('}');
}
},
- .anon_struct_type => |tuple| {
+ .tuple_type => |tuple| {
if (!location.isInitializer()) {
try writer.writeByte('(');
try dg.renderCType(writer, ctype);
@@ -1605,7 +1605,7 @@ pub const DeclGen = struct {
}),
}
},
- .anon_struct_type => |anon_struct_info| {
+ .tuple_type => |tuple_info| {
if (!location.isInitializer()) {
try writer.writeByte('(');
try dg.renderCType(writer, ctype);
@@ -1614,9 +1614,9 @@ pub const DeclGen = struct {
try writer.writeByte('{');
var need_comma = false;
- for (0..anon_struct_info.types.len) |field_index| {
- if (anon_struct_info.values.get(ip)[field_index] != .none) continue;
- const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);
+ for (0..tuple_info.types.len) |field_index| {
+ if (tuple_info.values.get(ip)[field_index] != .none) continue;
+ const field_ty = Type.fromInterned(tuple_info.types.get(ip)[field_index]);
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
if (need_comma) try writer.writeByte(',');
@@ -5411,9 +5411,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
const input_val = try f.resolveInst(input);
try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});
try f.writeCValue(writer, if (asmInputNeedsLocal(f, constraint, input_val)) local: {
- const input_local = .{ .local = locals_index };
+ const input_local_idx = locals_index;
locals_index += 1;
- break :local input_local;
+ break :local .{ .local = input_local_idx };
} else input_val, .Other);
try writer.writeByte(')');
}
@@ -5651,15 +5651,12 @@ fn fieldLocation(
.begin,
};
},
- .anon_struct_type => |anon_struct_info| return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))
+ .tuple_type => return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))
.begin
else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))
.{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) }
else
- .{ .field = if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|
- .{ .identifier = field_name.toSlice(ip) }
- else
- .{ .field = field_index } },
+ .{ .field = .{ .field = field_index } },
.union_type => {
const loaded_union = ip.loadUnionType(container_ty.toIntern());
switch (loaded_union.flagsUnordered(ip).layout) {
@@ -5892,10 +5889,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
},
}
},
- .anon_struct_type => |anon_struct_info| if (anon_struct_info.fieldName(ip, extra.field_index).unwrap()) |field_name|
- .{ .identifier = field_name.toSlice(ip) }
- else
- .{ .field = extra.field_index },
+ .tuple_type => .{ .field = extra.field_index },
.union_type => field_name: {
const loaded_union = ip.loadUnionType(struct_ty.toIntern());
switch (loaded_union.flagsUnordered(ip).layout) {
@@ -7366,16 +7360,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
},
}
},
- .anon_struct_type => |anon_struct_info| for (0..anon_struct_info.types.len) |field_index| {
- if (anon_struct_info.values.get(ip)[field_index] != .none) continue;
- const field_ty = Type.fromInterned(anon_struct_info.types.get(ip)[field_index]);
+ .tuple_type => |tuple_info| for (0..tuple_info.types.len) |field_index| {
+ if (tuple_info.values.get(ip)[field_index] != .none) continue;
+ const field_ty = Type.fromInterned(tuple_info.types.get(ip)[field_index]);
if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));
- try f.writeCValueMember(writer, local, if (anon_struct_info.fieldName(ip, field_index).unwrap()) |field_name|
- .{ .identifier = field_name.toSlice(ip) }
- else
- .{ .field = field_index });
+ try f.writeCValueMember(writer, local, .{ .field = field_index });
try a.assign(f, writer);
try f.writeCValue(writer, resolved_elements[field_index], .Other);
try a.end(f, writer);
diff --git a/src/codegen/c/Type.zig b/src/codegen/c/Type.zig
index 1e0c23a96b..31daa75a13 100644
--- a/src/codegen/c/Type.zig
+++ b/src/codegen/c/Type.zig
@@ -1350,7 +1350,7 @@ pub const Pool = struct {
.i0_type,
.anyopaque_type,
.void_type,
- .empty_struct_type,
+ .empty_tuple_type,
.type_type,
.comptime_int_type,
.comptime_float_type,
@@ -1450,7 +1450,7 @@ pub const Pool = struct {
.null_value,
.bool_true,
.bool_false,
- .empty_struct,
+ .empty_tuple,
.generic_poison,
.none,
=> unreachable,
@@ -1730,16 +1730,16 @@ pub const Pool = struct {
),
}
},
- .anon_struct_type => |anon_struct_info| {
+ .tuple_type => |tuple_info| {
const scratch_top = scratch.items.len;
defer scratch.shrinkRetainingCapacity(scratch_top);
- try scratch.ensureUnusedCapacity(allocator, anon_struct_info.types.len *
+ try scratch.ensureUnusedCapacity(allocator, tuple_info.types.len *
@typeInfo(Field).@"struct".fields.len);
var hasher = Hasher.init;
- for (0..anon_struct_info.types.len) |field_index| {
- if (anon_struct_info.values.get(ip)[field_index] != .none) continue;
+ for (0..tuple_info.types.len) |field_index| {
+ if (tuple_info.values.get(ip)[field_index] != .none) continue;
const field_type = Type.fromInterned(
- anon_struct_info.types.get(ip)[field_index],
+ tuple_info.types.get(ip)[field_index],
);
const field_ctype = try pool.fromType(
allocator,
@@ -1750,11 +1750,7 @@ pub const Pool = struct {
kind.noParameter(),
);
if (field_ctype.index == .void) continue;
- const field_name = if (anon_struct_info.fieldName(ip, @intCast(field_index))
- .unwrap()) |field_name|
- try pool.string(allocator, field_name.toSlice(ip))
- else
- try pool.fmt(allocator, "f{d}", .{field_index});
+ const field_name = try pool.fmt(allocator, "f{d}", .{field_index});
pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
.name = field_name.index,
.ctype = field_ctype.index,
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index ec294ecd37..cec888fba9 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -2563,7 +2563,7 @@ pub const Object = struct {
}
switch (ip.indexToKey(ty.toIntern())) {
- .anon_struct_type => |tuple| {
+ .tuple_type => |tuple| {
var fields: std.ArrayListUnmanaged(Builder.Metadata) = .empty;
defer fields.deinit(gpa);
@@ -2582,11 +2582,8 @@ pub const Object = struct {
const field_offset = field_align.forward(offset);
offset = field_offset + field_size;
- const field_name = if (tuple.names.len != 0)
- tuple.names.get(ip)[i].toSlice(ip)
- else
- try std.fmt.allocPrintZ(gpa, "{d}", .{i});
- defer if (tuple.names.len == 0) gpa.free(field_name);
+ var name_buf: [32]u8 = undefined;
+ const field_name = std.fmt.bufPrint(&name_buf, "{d}", .{i}) catch unreachable;
fields.appendAssumeCapacity(try o.builder.debugMemberType(
try o.builder.metadataString(field_name),
@@ -3426,7 +3423,7 @@ pub const Object = struct {
.adhoc_inferred_error_set_type,
=> try o.errorIntType(),
.generic_poison_type,
- .empty_struct_type,
+ .empty_tuple_type,
=> unreachable,
// values, not types
.undef,
@@ -3443,7 +3440,7 @@ pub const Object = struct {
.null_value,
.bool_true,
.bool_false,
- .empty_struct,
+ .empty_tuple,
.generic_poison,
.none,
=> unreachable,
@@ -3610,13 +3607,13 @@ pub const Object = struct {
);
return ty;
},
- .anon_struct_type => |anon_struct_type| {
+ .tuple_type => |tuple_type| {
var llvm_field_types: std.ArrayListUnmanaged(Builder.Type) = .empty;
defer llvm_field_types.deinit(o.gpa);
// Although we can estimate how much capacity to add, these cannot be
// relied upon because of the recursive calls to lowerType below.
- try llvm_field_types.ensureUnusedCapacity(o.gpa, anon_struct_type.types.len);
- try o.struct_field_map.ensureUnusedCapacity(o.gpa, anon_struct_type.types.len);
+ try llvm_field_types.ensureUnusedCapacity(o.gpa, tuple_type.types.len);
+ try o.struct_field_map.ensureUnusedCapacity(o.gpa, tuple_type.types.len);
comptime assert(struct_layout_version == 2);
var offset: u64 = 0;
@@ -3625,8 +3622,8 @@ pub const Object = struct {
const struct_size = t.abiSize(zcu);
for (
- anon_struct_type.types.get(ip),
- anon_struct_type.values.get(ip),
+ tuple_type.types.get(ip),
+ tuple_type.values.get(ip),
0..,
) |field_ty, field_val, field_index| {
if (field_val != .none) continue;
@@ -3979,7 +3976,7 @@ pub const Object = struct {
.error_union_type,
.simple_type,
.struct_type,
- .anon_struct_type,
+ .tuple_type,
.union_type,
.opaque_type,
.enum_type,
@@ -3993,7 +3990,7 @@ pub const Object = struct {
.undefined => unreachable, // non-runtime value
.void => unreachable, // non-runtime value
.null => unreachable, // non-runtime value
- .empty_struct => unreachable, // non-runtime value
+ .empty_tuple => unreachable, // non-runtime value
.@"unreachable" => unreachable, // non-runtime value
.generic_poison => unreachable, // non-runtime value
@@ -4232,7 +4229,7 @@ pub const Object = struct {
),
}
},
- .anon_struct_type => |tuple| {
+ .tuple_type => |tuple| {
const struct_ty = try o.lowerType(ty);
const llvm_len = struct_ty.aggregateLen(&o.builder);
@@ -12516,7 +12513,7 @@ fn isByRef(ty: Type, zcu: *Zcu) bool {
.array, .frame => return ty.hasRuntimeBits(zcu),
.@"struct" => {
const struct_type = switch (ip.indexToKey(ty.toIntern())) {
- .anon_struct_type => |tuple| {
+ .tuple_type => |tuple| {
var count: usize = 0;
for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index 46c23d7d53..997771a940 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -731,13 +731,15 @@ const NavGen = struct {
.direct => {
const result_ty_id = try self.resolveType(Type.bool, .direct);
const result_id = self.spv.allocId();
- const operands = .{
- .id_result_type = result_ty_id,
- .id_result = result_id,
- };
switch (value) {
- true => try section.emit(self.spv.gpa, .OpConstantTrue, operands),
- false => try section.emit(self.spv.gpa, .OpConstantFalse, operands),
+ inline else => |val_ct| try section.emit(
+ self.spv.gpa,
+ if (val_ct) .OpConstantTrue else .OpConstantFalse,
+ .{
+ .id_result_type = result_ty_id,
+ .id_result = result_id,
+ },
+ ),
}
return result_id;
},
@@ -915,7 +917,7 @@ const NavGen = struct {
.error_union_type,
.simple_type,
.struct_type,
- .anon_struct_type,
+ .tuple_type,
.union_type,
.opaque_type,
.enum_type,
@@ -937,7 +939,7 @@ const NavGen = struct {
.undefined,
.void,
.null,
- .empty_struct,
+ .empty_tuple,
.@"unreachable",
.generic_poison,
=> unreachable, // non-runtime values
@@ -1125,7 +1127,7 @@ const NavGen = struct {
return try self.constructStruct(ty, types.items, constituents.items);
},
- .anon_struct_type => unreachable, // TODO
+ .tuple_type => unreachable, // TODO
else => unreachable,
},
.un => |un| {
@@ -1718,7 +1720,7 @@ const NavGen = struct {
},
.@"struct" => {
const struct_type = switch (ip.indexToKey(ty.toIntern())) {
- .anon_struct_type => |tuple| {
+ .tuple_type => |tuple| {
const member_types = try self.gpa.alloc(IdRef, tuple.values.len);
defer self.gpa.free(member_types);
@@ -2831,18 +2833,12 @@ const NavGen = struct {
}
},
.vulkan => {
- const op_result_ty = blk: {
- // Operations return a struct{T, T}
- // where T is maybe vectorized.
- const types = [2]InternPool.Index{ arith_op_ty.toIntern(), arith_op_ty.toIntern() };
- const values = [2]InternPool.Index{ .none, .none };
- const index = try ip.getAnonStructType(zcu.gpa, pt.tid, .{
- .types = &types,
- .values = &values,
- .names = &.{},
- });
- break :blk Type.fromInterned(index);
- };
+ // Operations return a struct{T, T}
+ // where T is maybe vectorized.
+ const op_result_ty: Type = .fromInterned(try ip.getTupleType(zcu.gpa, pt.tid, .{
+ .types = &.{ arith_op_ty.toIntern(), arith_op_ty.toIntern() },
+ .values = &.{ .none, .none },
+ }));
const op_result_ty_id = try self.resolveType(op_result_ty, .direct);
const opcode: Opcode = switch (op) {
@@ -4867,7 +4863,7 @@ const NavGen = struct {
var index: usize = 0;
switch (ip.indexToKey(result_ty.toIntern())) {
- .anon_struct_type => |tuple| {
+ .tuple_type => |tuple| {
for (tuple.types.get(ip), elements, 0..) |field_ty, element, i| {
if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
assert(Type.fromInterned(field_ty).hasRuntimeBits(zcu));
@@ -6216,15 +6212,20 @@ const NavGen = struct {
try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());
const result_id = self.spv.allocId();
- const operands = .{
- .id_result_type = bool_ty_id,
- .id_result = result_id,
- .operand_1 = error_id,
- .operand_2 = try self.constInt(Type.anyerror, 0, .direct),
- };
switch (pred) {
- .is_err => try self.func.body.emit(self.spv.gpa, .OpINotEqual, operands),
- .is_non_err => try self.func.body.emit(self.spv.gpa, .OpIEqual, operands),
+ inline else => |pred_ct| try self.func.body.emit(
+ self.spv.gpa,
+ switch (pred_ct) {
+ .is_err => .OpINotEqual,
+ .is_non_err => .OpIEqual,
+ },
+ .{
+ .id_result_type = bool_ty_id,
+ .id_result = result_id,
+ .operand_1 = error_id,
+ .operand_2 = try self.constInt(Type.anyerror, 0, .direct),
+ },
+ ),
}
return result_id;
}