authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-05 19:13:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:29-07:00
log31aee50c1a96b7e72b42ee885636b27fbcac8eb4
treeddd17a80a48fa620a6d4cea9d8f6a970eb90845d
parent08e97639513f09e2797bd7afcdfdfecdad6c6fd8

InternPool: add a slice encoding

This uses the data field to reference its pointer field type, which allows for efficient and infallible access of a slice type's pointer type.

15 files changed, 120 insertions(+), 65 deletions(-)

src/InternPool.zig+38
...@@ -668,6 +668,9 @@ pub const Tag = enum(u8) {...@@ -668,6 +668,9 @@ pub const Tag = enum(u8) {
668 /// A fully explicitly specified pointer type.668 /// A fully explicitly specified pointer type.
669 /// data is payload to Pointer.669 /// data is payload to Pointer.
670 type_pointer,670 type_pointer,
671 /// A slice type.
672 /// data is Index of underlying pointer type.
673 type_slice,
671 /// An optional type.674 /// An optional type.
672 /// data is the child type.675 /// data is the child type.
673 type_optional,676 type_optional,
...@@ -984,6 +987,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {...@@ -984,6 +987,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
984 } };987 } };
985 },988 },
986989
990 .type_slice => {
991 const ptr_ty_index = @intToEnum(Index, data);
992 var result = indexToKey(ip, ptr_ty_index);
993 result.ptr_type.size = .Slice;
994 return result;
995 },
996
987 .type_optional => .{ .opt_type = @intToEnum(Index, data) },997 .type_optional => .{ .opt_type = @intToEnum(Index, data) },
988998
989 .type_error_union => @panic("TODO"),999 .type_error_union => @panic("TODO"),
...@@ -1041,6 +1051,19 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -1041,6 +1051,19 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
1041 },1051 },
1042 .ptr_type => |ptr_type| {1052 .ptr_type => |ptr_type| {
1043 assert(ptr_type.elem_type != .none);1053 assert(ptr_type.elem_type != .none);
1054
1055 if (ptr_type.size == .Slice) {
1056 var new_key = key;
1057 new_key.ptr_type.size = .Many;
1058 const ptr_ty_index = try get(ip, gpa, new_key);
1059 try ip.items.ensureUnusedCapacity(gpa, 1);
1060 ip.items.appendAssumeCapacity(.{
1061 .tag = .type_slice,
1062 .data = @enumToInt(ptr_ty_index),
1063 });
1064 return @intToEnum(Index, ip.items.len - 1);
1065 }
1066
1044 // TODO introduce more pointer encodings1067 // TODO introduce more pointer encodings
1045 ip.items.appendAssumeCapacity(.{1068 ip.items.appendAssumeCapacity(.{
1046 .tag = .type_pointer,1069 .tag = .type_pointer,
...@@ -1401,6 +1424,20 @@ pub fn childType(ip: InternPool, i: Index) Index {...@@ -1401,6 +1424,20 @@ pub fn childType(ip: InternPool, i: Index) Index {
1401 };1424 };
1402}1425}
14031426
1427/// Given a slice type, returns the type of the pointer field.
1428pub fn slicePtrType(ip: InternPool, i: Index) Index {
1429 switch (i) {
1430 .const_slice_u8_type => return .manyptr_const_u8_type,
1431 .const_slice_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
1432 else => {},
1433 }
1434 const item = ip.items.get(@enumToInt(i));
1435 switch (item.tag) {
1436 .type_slice => return @intToEnum(Index, item.data),
1437 else => unreachable, // not a slice type
1438 }
1439}
1440
1404pub fn dump(ip: InternPool) void {1441pub fn dump(ip: InternPool) void {
1405 dumpFallible(ip, std.heap.page_allocator) catch return;1442 dumpFallible(ip, std.heap.page_allocator) catch return;
1406}1443}
...@@ -1438,6 +1475,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {...@@ -1438,6 +1475,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
1438 .type_array => @sizeOf(Vector),1475 .type_array => @sizeOf(Vector),
1439 .type_vector => @sizeOf(Vector),1476 .type_vector => @sizeOf(Vector),
1440 .type_pointer => @sizeOf(Pointer),1477 .type_pointer => @sizeOf(Pointer),
1478 .type_slice => 0,
1441 .type_optional => 0,1479 .type_optional => 0,
1442 .type_error_union => @sizeOf(ErrorUnion),1480 .type_error_union => @sizeOf(ErrorUnion),
1443 .type_enum_simple => @sizeOf(EnumSimple),1481 .type_enum_simple => @sizeOf(EnumSimple),
src/Module.zig+1-1
...@@ -6553,7 +6553,7 @@ pub fn populateTestFunctions(...@@ -6553,7 +6553,7 @@ pub fn populateTestFunctions(
6553 }6553 }
6554 const decl = mod.declPtr(decl_index);6554 const decl = mod.declPtr(decl_index);
6555 var buf: Type.SlicePtrFieldTypeBuffer = undefined;6555 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
6556 const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).childType(mod);6556 const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf, mod).childType(mod);
65576557
6558 const array_decl_index = d: {6558 const array_decl_index = d: {
6559 // Add mod.test_functions to an array decl then make the test_functions6559 // Add mod.test_functions to an array decl then make the test_functions
src/Sema.zig+6-5
...@@ -24201,7 +24201,7 @@ fn fieldPtr(...@@ -24201,7 +24201,7 @@ fn fieldPtr(
2420124201
24202 if (mem.eql(u8, field_name, "ptr")) {24202 if (mem.eql(u8, field_name, "ptr")) {
24203 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);24203 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
24204 const slice_ptr_ty = inner_ty.slicePtrFieldType(buf);24204 const slice_ptr_ty = inner_ty.slicePtrFieldType(buf, mod);
2420524205
24206 const result_ty = try Type.ptr(sema.arena, sema.mod, .{24206 const result_ty = try Type.ptr(sema.arena, sema.mod, .{
24207 .pointee_type = slice_ptr_ty,24207 .pointee_type = slice_ptr_ty,
...@@ -27804,7 +27804,7 @@ fn beginComptimePtrMutation(...@@ -27804,7 +27804,7 @@ fn beginComptimePtrMutation(
27804 sema,27804 sema,
27805 block,27805 block,
27806 src,27806 src,
27807 parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)),27807 parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),
27808 &val_ptr.castTag(.slice).?.data.ptr,27808 &val_ptr.castTag(.slice).?.data.ptr,
27809 ptr_elem_ty,27809 ptr_elem_ty,
27810 parent.decl_ref_mut,27810 parent.decl_ref_mut,
...@@ -27859,7 +27859,7 @@ fn beginComptimePtrMutation(...@@ -27859,7 +27859,7 @@ fn beginComptimePtrMutation(
27859 sema,27859 sema,
27860 block,27860 block,
27861 src,27861 src,
27862 parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)),27862 parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),
27863 &val_ptr.castTag(.slice).?.data.ptr,27863 &val_ptr.castTag(.slice).?.data.ptr,
27864 ptr_elem_ty,27864 ptr_elem_ty,
27865 parent.decl_ref_mut,27865 parent.decl_ref_mut,
...@@ -28256,7 +28256,7 @@ fn beginComptimePtrLoad(...@@ -28256,7 +28256,7 @@ fn beginComptimePtrLoad(
28256 const slice_val = tv.val.castTag(.slice).?.data;28256 const slice_val = tv.val.castTag(.slice).?.data;
28257 deref.pointee = switch (field_index) {28257 deref.pointee = switch (field_index) {
28258 Value.Payload.Slice.ptr_index => TypedValue{28258 Value.Payload.Slice.ptr_index => TypedValue{
28259 .ty = field_ptr.container_ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)),28259 .ty = field_ptr.container_ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),
28260 .val = slice_val.ptr,28260 .val = slice_val.ptr,
28261 },28261 },
28262 Value.Payload.Slice.len_index => TypedValue{28262 Value.Payload.Slice.len_index => TypedValue{
...@@ -29339,8 +29339,9 @@ fn analyzeSlicePtr(...@@ -29339,8 +29339,9 @@ fn analyzeSlicePtr(
29339 slice: Air.Inst.Ref,29339 slice: Air.Inst.Ref,
29340 slice_ty: Type,29340 slice_ty: Type,
29341) CompileError!Air.Inst.Ref {29341) CompileError!Air.Inst.Ref {
29342 const mod = sema.mod;
29342 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);29343 const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
29343 const result_ty = slice_ty.slicePtrFieldType(buf);29344 const result_ty = slice_ty.slicePtrFieldType(buf, mod);
29344 if (try sema.resolveMaybeUndefVal(slice)) |val| {29345 if (try sema.resolveMaybeUndefVal(slice)) |val| {
29345 if (val.isUndef()) return sema.addConstUndef(result_ty);29346 if (val.isUndef()) return sema.addConstUndef(result_ty);
29346 return sema.addConstant(result_ty, val.slicePtr());29347 return sema.addConstant(result_ty, val.slicePtr());
src/arch/aarch64/CodeGen.zig+1-1
...@@ -3435,7 +3435,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -3435,7 +3435,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
3435 const slice_ty = self.typeOf(bin_op.lhs);3435 const slice_ty = self.typeOf(bin_op.lhs);
3436 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {3436 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
3437 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3437 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3438 const ptr_ty = slice_ty.slicePtrFieldType(&buf);3438 const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod);
34393439
3440 const slice_mcv = try self.resolveInst(bin_op.lhs);3440 const slice_mcv = try self.resolveInst(bin_op.lhs);
3441 const base_mcv = slicePtr(slice_mcv);3441 const base_mcv = slicePtr(slice_mcv);
src/arch/arm/CodeGen.zig+1-1
...@@ -2433,7 +2433,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2433,7 +2433,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2433 const slice_ty = self.typeOf(bin_op.lhs);2433 const slice_ty = self.typeOf(bin_op.lhs);
2434 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {2434 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
2435 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2435 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
2436 const ptr_ty = slice_ty.slicePtrFieldType(&buf);2436 const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod);
24372437
2438 const slice_mcv = try self.resolveInst(bin_op.lhs);2438 const slice_mcv = try self.resolveInst(bin_op.lhs);
2439 const base_mcv = slicePtr(slice_mcv);2439 const base_mcv = slicePtr(slice_mcv);
src/arch/sparc64/CodeGen.zig+1-1
...@@ -2462,7 +2462,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2462,7 +2462,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2462 const elem_size = elem_ty.abiSize(mod);2462 const elem_size = elem_ty.abiSize(mod);
24632463
2464 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2464 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
2465 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);2465 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
24662466
2467 const index_lock: ?RegisterLock = if (index_mcv == .register)2467 const index_lock: ?RegisterLock = if (index_mcv == .register)
2468 self.register_manager.lockRegAssumeUnused(index_mcv.register)2468 self.register_manager.lockRegAssumeUnused(index_mcv.register)
src/arch/x86_64/CodeGen.zig+6-5
...@@ -4056,7 +4056,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {...@@ -4056,7 +4056,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
4056 const elem_ty = slice_ty.childType(mod);4056 const elem_ty = slice_ty.childType(mod);
4057 const elem_size = elem_ty.abiSize(mod);4057 const elem_size = elem_ty.abiSize(mod);
4058 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4058 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4059 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);4059 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
40604060
4061 const index_ty = self.typeOf(rhs);4061 const index_ty = self.typeOf(rhs);
4062 const index_mcv = try self.resolveInst(rhs);4062 const index_mcv = try self.resolveInst(rhs);
...@@ -4081,11 +4081,12 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {...@@ -4081,11 +4081,12 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
4081}4081}
40824082
4083fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {4083fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
4084 const mod = self.bin_file.options.module.?;
4084 const bin_op = self.air.instructions.items(.data)[inst].bin_op;4085 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4085 const slice_ty = self.typeOf(bin_op.lhs);4086 const slice_ty = self.typeOf(bin_op.lhs);
40864087
4087 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4088 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4088 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);4089 const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
4089 const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs);4090 const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs);
4090 const dst_mcv = try self.allocRegOrMem(inst, false);4091 const dst_mcv = try self.allocRegOrMem(inst, false);
4091 try self.load(dst_mcv, slice_ptr_field_type, elem_ptr);4092 try self.load(dst_mcv, slice_ptr_field_type, elem_ptr);
...@@ -8682,7 +8683,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -8682,7 +8683,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
86828683
8683 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;8684 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
8684 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))8685 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
8685 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }8686 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty }
8686 else8687 else
8687 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };8688 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
86888689
...@@ -8774,7 +8775,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)...@@ -8774,7 +8775,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
87748775
8775 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;8776 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
8776 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))8777 const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
8777 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }8778 .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty }
8778 else8779 else
8779 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };8780 .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
87808781
...@@ -10813,7 +10814,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {...@@ -10813,7 +10814,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
10813 switch (dst_ptr_ty.ptrSize(mod)) {10814 switch (dst_ptr_ty.ptrSize(mod)) {
10814 .Slice => {10815 .Slice => {
10815 var buf: Type.SlicePtrFieldTypeBuffer = undefined;10816 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
10816 const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf);10817 const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf, mod);
1081710818
10818 // TODO: this only handles slices stored in the stack10819 // TODO: this only handles slices stored in the stack
10819 const ptr = dst_ptr;10820 const ptr = dst_ptr;
src/codegen.zig+3-3
...@@ -361,7 +361,7 @@ pub fn generateSymbol(...@@ -361,7 +361,7 @@ pub fn generateSymbol(
361361
362 // generate ptr362 // generate ptr
363 var buf: Type.SlicePtrFieldTypeBuffer = undefined;363 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
364 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);364 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod);
365 switch (try generateSymbol(bin_file, src_loc, .{365 switch (try generateSymbol(bin_file, src_loc, .{
366 .ty = slice_ptr_field_type,366 .ty = slice_ptr_field_type,
367 .val = slice.ptr,367 .val = slice.ptr,
...@@ -851,7 +851,7 @@ fn lowerParentPtr(...@@ -851,7 +851,7 @@ fn lowerParentPtr(
851 var buf: Type.SlicePtrFieldTypeBuffer = undefined;851 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
852 break :offset switch (field_ptr.field_index) {852 break :offset switch (field_ptr.field_index) {
853 0 => 0,853 0 => 0,
854 1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(mod),854 1 => field_ptr.container_ty.slicePtrFieldType(&buf, mod).abiSize(mod),
855 else => unreachable,855 else => unreachable,
856 };856 };
857 },857 },
...@@ -951,7 +951,7 @@ fn lowerDeclRef(...@@ -951,7 +951,7 @@ fn lowerDeclRef(
951 if (typed_value.ty.isSlice(mod)) {951 if (typed_value.ty.isSlice(mod)) {
952 // generate ptr952 // generate ptr
953 var buf: Type.SlicePtrFieldTypeBuffer = undefined;953 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
954 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);954 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod);
955 switch (try generateSymbol(bin_file, src_loc, .{955 switch (try generateSymbol(bin_file, src_loc, .{
956 .ty = slice_ptr_field_type,956 .ty = slice_ptr_field_type,
957 .val = typed_value.val,957 .val = typed_value.val,
src/codegen/c.zig+7-6
...@@ -566,7 +566,7 @@ pub const DeclGen = struct {...@@ -566,7 +566,7 @@ pub const DeclGen = struct {
566 }566 }
567567
568 var buf: Type.SlicePtrFieldTypeBuffer = undefined;568 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
569 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Initializer);569 try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), val.slicePtr(), .Initializer);
570570
571 var len_pl: Value.Payload.U64 = .{571 var len_pl: Value.Payload.U64 = .{
572 .base = .{ .tag = .int_u64 },572 .base = .{ .tag = .int_u64 },
...@@ -787,7 +787,7 @@ pub const DeclGen = struct {...@@ -787,7 +787,7 @@ pub const DeclGen = struct {
787787
788 try writer.writeAll("{(");788 try writer.writeAll("{(");
789 var buf: Type.SlicePtrFieldTypeBuffer = undefined;789 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
790 const ptr_ty = ty.slicePtrFieldType(&buf);790 const ptr_ty = ty.slicePtrFieldType(&buf, mod);
791 try dg.renderType(writer, ptr_ty);791 try dg.renderType(writer, ptr_ty);
792 return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});792 return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});
793 } else {793 } else {
...@@ -1088,7 +1088,7 @@ pub const DeclGen = struct {...@@ -1088,7 +1088,7 @@ pub const DeclGen = struct {
1088 var buf: Type.SlicePtrFieldTypeBuffer = undefined;1088 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
10891089
1090 try writer.writeByte('{');1090 try writer.writeByte('{');
1091 try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, initializer_type);1091 try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), slice.ptr, initializer_type);
1092 try writer.writeAll(", ");1092 try writer.writeAll(", ");
1093 try dg.renderValue(writer, Type.usize, slice.len, initializer_type);1093 try dg.renderValue(writer, Type.usize, slice.len, initializer_type);
1094 try writer.writeByte('}');1094 try writer.writeByte('}');
...@@ -4107,6 +4107,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons...@@ -4107,6 +4107,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
4107}4107}
41084108
4109fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {4109fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4110 const mod = f.object.dg.module;
4110 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;4111 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
4111 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;4112 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
41124113
...@@ -4116,7 +4117,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4116,7 +4117,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
41164117
4117 const inst_ty = f.typeOfIndex(inst);4118 const inst_ty = f.typeOfIndex(inst);
4118 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4119 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4119 const ptr_ty = inst_ty.slicePtrFieldType(&buf);4120 const ptr_ty = inst_ty.slicePtrFieldType(&buf, mod);
41204121
4121 const writer = f.object.writer();4122 const writer = f.object.writer();
4122 const local = try f.allocLocal(inst, inst_ty);4123 const local = try f.allocLocal(inst, inst_ty);
...@@ -5112,7 +5113,7 @@ fn airIsNull(...@@ -5112,7 +5113,7 @@ fn airIsNull(
5112 TypedValue{ .ty = payload_ty, .val = Value.zero }5113 TypedValue{ .ty = payload_ty, .val = Value.zero }
5113 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {5114 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
5114 try writer.writeAll(".ptr");5115 try writer.writeAll(".ptr");
5115 const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf);5116 const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf, mod);
5116 break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };5117 break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };
5117 } else rhs: {5118 } else rhs: {
5118 try writer.writeAll(".is_null");5119 try writer.writeAll(".is_null");
...@@ -5845,7 +5846,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5845,7 +5846,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
5845 // &(*(void *)p)[0], although LLVM does via GetElementPtr5846 // &(*(void *)p)[0], although LLVM does via GetElementPtr
5846 if (operand == .undef) {5847 if (operand == .undef) {
5847 var buf: Type.SlicePtrFieldTypeBuffer = undefined;5848 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
5848 try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf) }, .Initializer);5849 try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf, mod) }, .Initializer);
5849 } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {5850 } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5850 try writer.writeAll("&(");5851 try writer.writeAll("&(");
5851 try f.writeCValueDeref(writer, operand);5852 try f.writeCValueDeref(writer, operand);
src/codegen/c/type.zig+1-1
...@@ -1432,7 +1432,7 @@ pub const CType = extern union {...@@ -1432,7 +1432,7 @@ pub const CType = extern union {
1432 .payload => unreachable,1432 .payload => unreachable,
1433 }) |fwd_idx| {1433 }) |fwd_idx| {
1434 var buf: Type.SlicePtrFieldTypeBuffer = undefined;1434 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
1435 const ptr_ty = ty.slicePtrFieldType(&buf);1435 const ptr_ty = ty.slicePtrFieldType(&buf, mod);
1436 if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| {1436 if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| {
1437 self.storage = .{ .anon = undefined };1437 self.storage = .{ .anon = undefined };
1438 self.storage.anon.fields[0] = .{1438 self.storage.anon.fields[0] = .{
src/codegen/llvm.zig+7-7
...@@ -1638,7 +1638,7 @@ pub const Object = struct {...@@ -1638,7 +1638,7 @@ pub const Object = struct {
16381638
1639 if (ty.isSlice(mod)) {1639 if (ty.isSlice(mod)) {
1640 var buf: Type.SlicePtrFieldTypeBuffer = undefined;1640 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
1641 const ptr_ty = ty.slicePtrFieldType(&buf);1641 const ptr_ty = ty.slicePtrFieldType(&buf, mod);
1642 const len_ty = Type.usize;1642 const len_ty = Type.usize;
16431643
1644 const name = try ty.nameAlloc(gpa, o.module);1644 const name = try ty.nameAlloc(gpa, o.module);
...@@ -2822,7 +2822,7 @@ pub const DeclGen = struct {...@@ -2822,7 +2822,7 @@ pub const DeclGen = struct {
2822 .Pointer => {2822 .Pointer => {
2823 if (t.isSlice(mod)) {2823 if (t.isSlice(mod)) {
2824 var buf: Type.SlicePtrFieldTypeBuffer = undefined;2824 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
2825 const ptr_type = t.slicePtrFieldType(&buf);2825 const ptr_type = t.slicePtrFieldType(&buf, mod);
28262826
2827 const fields: [2]*llvm.Type = .{2827 const fields: [2]*llvm.Type = .{
2828 try dg.lowerType(ptr_type),2828 try dg.lowerType(ptr_type),
...@@ -3182,9 +3182,9 @@ pub const DeclGen = struct {...@@ -3182,9 +3182,9 @@ pub const DeclGen = struct {
3182 const param_ty = fn_info.param_types[it.zig_index - 1];3182 const param_ty = fn_info.param_types[it.zig_index - 1];
3183 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3183 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3184 const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional)3184 const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional)
3185 param_ty.optionalChild(mod).slicePtrFieldType(&buf)3185 param_ty.optionalChild(mod).slicePtrFieldType(&buf, mod)
3186 else3186 else
3187 param_ty.slicePtrFieldType(&buf);3187 param_ty.slicePtrFieldType(&buf, mod);
3188 const ptr_llvm_ty = try dg.lowerType(ptr_ty);3188 const ptr_llvm_ty = try dg.lowerType(ptr_ty);
3189 const len_llvm_ty = try dg.lowerType(Type.usize);3189 const len_llvm_ty = try dg.lowerType(Type.usize);
31903190
...@@ -3387,7 +3387,7 @@ pub const DeclGen = struct {...@@ -3387,7 +3387,7 @@ pub const DeclGen = struct {
3387 var buf: Type.SlicePtrFieldTypeBuffer = undefined;3387 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
3388 const fields: [2]*llvm.Value = .{3388 const fields: [2]*llvm.Value = .{
3389 try dg.lowerValue(.{3389 try dg.lowerValue(.{
3390 .ty = tv.ty.slicePtrFieldType(&buf),3390 .ty = tv.ty.slicePtrFieldType(&buf, mod),
3391 .val = slice.ptr,3391 .val = slice.ptr,
3392 }),3392 }),
3393 try dg.lowerValue(.{3393 try dg.lowerValue(.{
...@@ -4169,7 +4169,7 @@ pub const DeclGen = struct {...@@ -4169,7 +4169,7 @@ pub const DeclGen = struct {
4169 const mod = self.module;4169 const mod = self.module;
4170 if (tv.ty.isSlice(mod)) {4170 if (tv.ty.isSlice(mod)) {
4171 var buf: Type.SlicePtrFieldTypeBuffer = undefined;4171 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
4172 const ptr_ty = tv.ty.slicePtrFieldType(&buf);4172 const ptr_ty = tv.ty.slicePtrFieldType(&buf, mod);
4173 var slice_len: Value.Payload.U64 = .{4173 var slice_len: Value.Payload.U64 = .{
4174 .base = .{ .tag = .int_u64 },4174 .base = .{ .tag = .int_u64 },
4175 .data = tv.val.sliceLen(mod),4175 .data = tv.val.sliceLen(mod),
...@@ -6654,7 +6654,7 @@ pub const FuncGen = struct {...@@ -6654,7 +6654,7 @@ pub const FuncGen = struct {
6654 if (payload_ty.isSlice(mod)) {6654 if (payload_ty.isSlice(mod)) {
6655 const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");6655 const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");
6656 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;6656 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
6657 const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf));6657 const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf, mod));
6658 return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");6658 return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");
6659 }6659 }
6660 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");6660 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
src/codegen/spirv.zig+3-3
...@@ -669,7 +669,7 @@ pub const DeclGen = struct {...@@ -669,7 +669,7 @@ pub const DeclGen = struct {
669 const slice = val.castTag(.slice).?.data;669 const slice = val.castTag(.slice).?.data;
670670
671 var buf: Type.SlicePtrFieldTypeBuffer = undefined;671 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
672 const ptr_ty = ty.slicePtrFieldType(&buf);672 const ptr_ty = ty.slicePtrFieldType(&buf, mod);
673673
674 try self.lower(ptr_ty, slice.ptr);674 try self.lower(ptr_ty, slice.ptr);
675 try self.addInt(Type.usize, slice.len);675 try self.addInt(Type.usize, slice.len);
...@@ -2489,7 +2489,7 @@ pub const DeclGen = struct {...@@ -2489,7 +2489,7 @@ pub const DeclGen = struct {
2489 const index_id = try self.resolve(bin_op.rhs);2489 const index_id = try self.resolve(bin_op.rhs);
24902490
2491 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;2491 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2492 const ptr_ty = slice_ty.slicePtrFieldType(&slice_buf);2492 const ptr_ty = slice_ty.slicePtrFieldType(&slice_buf, mod);
2493 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);2493 const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
24942494
2495 const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);2495 const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);
...@@ -2987,7 +2987,7 @@ pub const DeclGen = struct {...@@ -2987,7 +2987,7 @@ pub const DeclGen = struct {
29872987
2988 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2988 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2989 const ptr_ty = if (payload_ty.isSlice(mod))2989 const ptr_ty = if (payload_ty.isSlice(mod))
2990 payload_ty.slicePtrFieldType(&ptr_buf)2990 payload_ty.slicePtrFieldType(&ptr_buf, mod)
2991 else2991 else
2992 payload_ty;2992 payload_ty;
29932993
src/link/Dwarf.zig+1-1
...@@ -278,7 +278,7 @@ pub const DeclState = struct {...@@ -278,7 +278,7 @@ pub const DeclState = struct {
278 var index = dbg_info_buffer.items.len;278 var index = dbg_info_buffer.items.len;
279 try dbg_info_buffer.resize(index + 4);279 try dbg_info_buffer.resize(index + 4);
280 var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);280 var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);
281 const ptr_ty = ty.slicePtrFieldType(buf);281 const ptr_ty = ty.slicePtrFieldType(buf, mod);
282 try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index));282 try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index));
283 // DW.AT.data_member_location, DW.FORM.udata283 // DW.AT.data_member_location, DW.FORM.udata
284 try dbg_info_buffer.ensureUnusedCapacity(6);284 try dbg_info_buffer.ensureUnusedCapacity(6);
src/type.zig+40-26
...@@ -2042,7 +2042,18 @@ pub const Type = struct {...@@ -2042,7 +2042,18 @@ pub const Type = struct {
2042 else => unreachable,2042 else => unreachable,
2043 },2043 },
2044 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {2044 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
2045 else => @panic("TODO"),2045 .ptr_type => |ptr_type| {
2046 if (ptr_type.alignment != 0) {
2047 return @intCast(u32, ptr_type.alignment);
2048 } else if (opt_sema) |sema| {
2049 const res = try ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .{ .sema = sema });
2050 return res.scalar;
2051 } else {
2052 return (ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
2053 }
2054 },
2055 .opt_type => |child| return child.toType().ptrAlignmentAdvanced(mod, opt_sema),
2056 else => unreachable,
2046 },2057 },
2047 }2058 }
2048 }2059 }
...@@ -3060,33 +3071,36 @@ pub const Type = struct {...@@ -3060,33 +3071,36 @@ pub const Type = struct {
3060 pointer: Payload.Pointer,3071 pointer: Payload.Pointer,
3061 };3072 };
30623073
3063 pub fn slicePtrFieldType(self: Type, buffer: *SlicePtrFieldTypeBuffer) Type {3074 pub fn slicePtrFieldType(ty: Type, buffer: *SlicePtrFieldTypeBuffer, mod: *const Module) Type {
3064 switch (self.tag()) {3075 switch (ty.ip_index) {
3065 .pointer => {3076 .none => switch (ty.tag()) {
3066 const payload = self.castTag(.pointer).?.data;3077 .pointer => {
3067 assert(payload.size == .Slice);3078 const payload = ty.castTag(.pointer).?.data;
30683079 assert(payload.size == .Slice);
3069 buffer.* = .{3080
3070 .pointer = .{3081 buffer.* = .{
3071 .data = .{3082 .pointer = .{
3072 .pointee_type = payload.pointee_type,3083 .data = .{
3073 .sentinel = payload.sentinel,3084 .pointee_type = payload.pointee_type,
3074 .@"align" = payload.@"align",3085 .sentinel = payload.sentinel,
3075 .@"addrspace" = payload.@"addrspace",3086 .@"align" = payload.@"align",
3076 .bit_offset = payload.bit_offset,3087 .@"addrspace" = payload.@"addrspace",
3077 .host_size = payload.host_size,3088 .bit_offset = payload.bit_offset,
3078 .vector_index = payload.vector_index,3089 .host_size = payload.host_size,
3079 .@"allowzero" = payload.@"allowzero",3090 .vector_index = payload.vector_index,
3080 .mutable = payload.mutable,3091 .@"allowzero" = payload.@"allowzero",
3081 .@"volatile" = payload.@"volatile",3092 .mutable = payload.mutable,
3082 .size = .Many,3093 .@"volatile" = payload.@"volatile",
3094 .size = .Many,
3095 },
3083 },3096 },
3084 },3097 };
3085 };3098 return Type.initPayload(&buffer.pointer.base);
3086 return Type.initPayload(&buffer.pointer.base);3099 },
3087 },
30883100
3089 else => unreachable,3101 else => unreachable,
3102 },
3103 else => return mod.intern_pool.slicePtrType(ty.ip_index).toType(),
3090 }3104 }
3091 }3105 }
30923106
src/value.zig+4-4
...@@ -2078,7 +2078,7 @@ pub const Value = struct {...@@ -2078,7 +2078,7 @@ pub const Value = struct {
2078 }2078 }
20792079
2080 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2080 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2081 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2081 const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
20822082
2083 return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, opt_sema);2083 return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, opt_sema);
2084 },2084 },
...@@ -2237,7 +2237,7 @@ pub const Value = struct {...@@ -2237,7 +2237,7 @@ pub const Value = struct {
2237 }2237 }
22382238
2239 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2239 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2240 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2240 const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
2241 const a_ptr = switch (a_ty.ptrSize(mod)) {2241 const a_ptr = switch (a_ty.ptrSize(mod)) {
2242 .Slice => a.slicePtr(),2242 .Slice => a.slicePtr(),
2243 .One => a,2243 .One => a,
...@@ -2376,7 +2376,7 @@ pub const Value = struct {...@@ -2376,7 +2376,7 @@ pub const Value = struct {
2376 .slice => {2376 .slice => {
2377 const slice = val.castTag(.slice).?.data;2377 const slice = val.castTag(.slice).?.data;
2378 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2378 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2379 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2379 const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
2380 hash(slice.ptr, ptr_ty, hasher, mod);2380 hash(slice.ptr, ptr_ty, hasher, mod);
2381 hash(slice.len, Type.usize, hasher, mod);2381 hash(slice.len, Type.usize, hasher, mod);
2382 },2382 },
...@@ -2499,7 +2499,7 @@ pub const Value = struct {...@@ -2499,7 +2499,7 @@ pub const Value = struct {
2499 .slice => {2499 .slice => {
2500 const slice = val.castTag(.slice).?.data;2500 const slice = val.castTag(.slice).?.data;
2501 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;2501 var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2502 const ptr_ty = ty.slicePtrFieldType(&ptr_buf);2502 const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
2503 slice.ptr.hashUncoerced(ptr_ty, hasher, mod);2503 slice.ptr.hashUncoerced(ptr_ty, hasher, mod);
2504 },2504 },
2505 else => val.hashPtr(hasher, mod),2505 else => val.hashPtr(hasher, mod),