authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-20 01:48:27-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-20 01:48:50-04:00
loga1062c63cad1ad80ecd42f6c58403133a608cca2
tree3e90b061a0026c96cda7458825a9b4976ad54d48
parentea72fea1a4e2bc8309c211308f49f7f2c38507be

llvm: add Builder trailing extra interface


1 files changed, 194 insertions(+), 141 deletions(-)

src/codegen/llvm/Builder.zig+194-141
...@@ -311,8 +311,8 @@ pub const Type = enum(u32) {...@@ -311,8 +311,8 @@ pub const Type = enum(u32) {
311 .function,311 .function,
312 .vararg_function,312 .vararg_function,
313 => {313 => {
314 const extra = builder.typeExtraDataTrail(Type.Function, item.data);314 var extra = builder.typeExtraDataTrail(Type.Function, item.data);
315 return @ptrCast(builder.type_extra.items[extra.end..][0..extra.data.params_len]);315 return extra.trail.next(extra.data.params_len, Type, builder);
316 },316 },
317 else => unreachable,317 else => unreachable,
318 }318 }
...@@ -519,8 +519,8 @@ pub const Type = enum(u32) {...@@ -519,8 +519,8 @@ pub const Type = enum(u32) {
519 .structure,519 .structure,
520 .packed_structure,520 .packed_structure,
521 => {521 => {
522 const extra = builder.typeExtraDataTrail(Type.Structure, item.data);522 var extra = builder.typeExtraDataTrail(Type.Structure, item.data);
523 return @ptrCast(builder.type_extra.items[extra.end..][0..extra.data.fields_len]);523 return extra.trail.next(extra.data.fields_len, Type, builder);
524 },524 },
525 .named_structure => return builder.typeExtraData(Type.NamedStructure, item.data).body525 .named_structure => return builder.typeExtraData(Type.NamedStructure, item.data).body
526 .structFields(builder),526 .structFields(builder),
...@@ -539,9 +539,8 @@ pub const Type = enum(u32) {...@@ -539,9 +539,8 @@ pub const Type = enum(u32) {
539 .structure,539 .structure,
540 .packed_structure,540 .packed_structure,
541 => {541 => {
542 const extra = builder.typeExtraDataTrail(Type.Structure, item.data);542 var extra = builder.typeExtraDataTrail(Type.Structure, item.data);
543 const fields: []const Type =543 const fields = extra.trail.next(extra.data.fields_len, Type, builder);
544 @ptrCast(builder.type_extra.items[extra.end..][0..extra.data.fields_len]);
545 return fields[indices[0]].childTypeAt(indices[1..], builder);544 return fields[indices[0]].childTypeAt(indices[1..], builder);
546 },545 },
547 .named_structure => builder.typeExtraData(Type.NamedStructure, item.data).body546 .named_structure => builder.typeExtraData(Type.NamedStructure, item.data).body
...@@ -590,9 +589,8 @@ pub const Type = enum(u32) {...@@ -590,9 +589,8 @@ pub const Type = enum(u32) {
590 .metadata => "Metadata",589 .metadata => "Metadata",
591 }),590 }),
592 .function, .vararg_function => |kind| {591 .function, .vararg_function => |kind| {
593 const extra = data.builder.typeExtraDataTrail(Type.Function, item.data);592 var extra = data.builder.typeExtraDataTrail(Type.Function, item.data);
594 const params: []const Type =593 const params = extra.trail.next(extra.data.params_len, Type, data.builder);
595 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.params_len]);
596 try writer.print("f_{m}", .{extra.data.ret.fmt(data.builder)});594 try writer.print("f_{m}", .{extra.data.ret.fmt(data.builder)});
597 for (params) |param| try writer.print("{m}", .{param.fmt(data.builder)});595 for (params) |param| try writer.print("{m}", .{param.fmt(data.builder)});
598 switch (kind) {596 switch (kind) {
...@@ -605,11 +603,9 @@ pub const Type = enum(u32) {...@@ -605,11 +603,9 @@ pub const Type = enum(u32) {
605 .integer => try writer.print("i{d}", .{item.data}),603 .integer => try writer.print("i{d}", .{item.data}),
606 .pointer => try writer.print("p{d}", .{item.data}),604 .pointer => try writer.print("p{d}", .{item.data}),
607 .target => {605 .target => {
608 const extra = data.builder.typeExtraDataTrail(Type.Target, item.data);606 var extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
609 const types: []const Type =607 const types = extra.trail.next(extra.data.types_len, Type, data.builder);
610 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.types_len]);608 const ints = extra.trail.next(extra.data.ints_len, u32, data.builder);
611 const ints: []const u32 = @ptrCast(data.builder.type_extra.items[extra.end +
612 extra.data.types_len ..][0..extra.data.ints_len]);
613 try writer.print("t{s}", .{extra.data.name.toSlice(data.builder).?});609 try writer.print("t{s}", .{extra.data.name.toSlice(data.builder).?});
614 for (types) |ty| try writer.print("_{m}", .{ty.fmt(data.builder)});610 for (types) |ty| try writer.print("_{m}", .{ty.fmt(data.builder)});
615 for (ints) |int| try writer.print("_{d}", .{int});611 for (ints) |int| try writer.print("_{d}", .{int});
...@@ -636,9 +632,8 @@ pub const Type = enum(u32) {...@@ -636,9 +632,8 @@ pub const Type = enum(u32) {
636 try writer.print("a{d}{m}", .{ extra.length(), extra.child.fmt(data.builder) });632 try writer.print("a{d}{m}", .{ extra.length(), extra.child.fmt(data.builder) });
637 },633 },
638 .structure, .packed_structure => {634 .structure, .packed_structure => {
639 const extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);635 var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);
640 const fields: []const Type =636 const fields = extra.trail.next(extra.data.fields_len, Type, data.builder);
641 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.fields_len]);
642 try writer.writeAll("sl_");637 try writer.writeAll("sl_");
643 for (fields) |field| try writer.print("{m}", .{field.fmt(data.builder)});638 for (fields) |field| try writer.print("{m}", .{field.fmt(data.builder)});
644 try writer.writeByte('s');639 try writer.writeByte('s');
...@@ -656,9 +651,8 @@ pub const Type = enum(u32) {...@@ -656,9 +651,8 @@ pub const Type = enum(u32) {
656 switch (item.tag) {651 switch (item.tag) {
657 .simple => unreachable,652 .simple => unreachable,
658 .function, .vararg_function => |kind| {653 .function, .vararg_function => |kind| {
659 const extra = data.builder.typeExtraDataTrail(Type.Function, item.data);654 var extra = data.builder.typeExtraDataTrail(Type.Function, item.data);
660 const params: []const Type =655 const params = extra.trail.next(extra.data.params_len, Type, data.builder);
661 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.params_len]);
662 if (!comptime std.mem.eql(u8, fmt_str, ">"))656 if (!comptime std.mem.eql(u8, fmt_str, ">"))
663 try writer.print("{%} ", .{extra.data.ret.fmt(data.builder)});657 try writer.print("{%} ", .{extra.data.ret.fmt(data.builder)});
664 if (!comptime std.mem.eql(u8, fmt_str, "<")) {658 if (!comptime std.mem.eql(u8, fmt_str, "<")) {
...@@ -681,11 +675,9 @@ pub const Type = enum(u32) {...@@ -681,11 +675,9 @@ pub const Type = enum(u32) {
681 .integer => try writer.print("i{d}", .{item.data}),675 .integer => try writer.print("i{d}", .{item.data}),
682 .pointer => try writer.print("ptr{}", .{@as(AddrSpace, @enumFromInt(item.data))}),676 .pointer => try writer.print("ptr{}", .{@as(AddrSpace, @enumFromInt(item.data))}),
683 .target => {677 .target => {
684 const extra = data.builder.typeExtraDataTrail(Type.Target, item.data);678 var extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
685 const types: []const Type =679 const types = extra.trail.next(extra.data.types_len, Type, data.builder);
686 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.types_len]);680 const ints = extra.trail.next(extra.data.ints_len, u32, data.builder);
687 const ints: []const u32 = @ptrCast(data.builder.type_extra.items[extra.end +
688 extra.data.types_len ..][0..extra.data.ints_len]);
689 try writer.print(681 try writer.print(
690 \\target({"}682 \\target({"}
691 , .{extra.data.name.fmt(data.builder)});683 , .{extra.data.name.fmt(data.builder)});
...@@ -714,9 +706,8 @@ pub const Type = enum(u32) {...@@ -714,9 +706,8 @@ pub const Type = enum(u32) {
714 try writer.print("[{d} x {%}]", .{ extra.length(), extra.child.fmt(data.builder) });706 try writer.print("[{d} x {%}]", .{ extra.length(), extra.child.fmt(data.builder) });
715 },707 },
716 .structure, .packed_structure => |kind| {708 .structure, .packed_structure => |kind| {
717 const extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);709 var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);
718 const fields: []const Type =710 const fields = extra.trail.next(extra.data.fields_len, Type, data.builder);
719 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.fields_len]);
720 switch (kind) {711 switch (kind) {
721 .structure => {},712 .structure => {},
722 .packed_structure => try writer.writeByte('<'),713 .packed_structure => try writer.writeByte('<'),
...@@ -812,10 +803,8 @@ pub const Type = enum(u32) {...@@ -812,10 +803,8 @@ pub const Type = enum(u32) {
812 => {803 => {
813 if (try visited.fetchPut(builder.gpa, self, {})) |_| return false;804 if (try visited.fetchPut(builder.gpa, self, {})) |_| return false;
814805
815 const extra = builder.typeExtraDataTrail(Type.Structure, item.data);806 var extra = builder.typeExtraDataTrail(Type.Structure, item.data);
816 const fields: []const Type = @ptrCast(807 const fields = extra.trail.next(extra.data.fields_len, Type, builder);
817 builder.type_extra.items[extra.end..][0..extra.data.fields_len],
818 );
819 for (fields) |field| {808 for (fields) |field| {
820 if (field.isVector(builder) and field.vectorKind(builder) == .scalable)809 if (field.isVector(builder) and field.vectorKind(builder) == .scalable)
821 return false;810 return false;
...@@ -1639,9 +1628,8 @@ pub const Function = struct {...@@ -1639,9 +1628,8 @@ pub const Function = struct {
1639 .extractelement => wip.extraData(ExtractElement, instruction.data)1628 .extractelement => wip.extraData(ExtractElement, instruction.data)
1640 .val.typeOfWip(wip).childType(wip.builder),1629 .val.typeOfWip(wip).childType(wip.builder),
1641 .extractvalue => {1630 .extractvalue => {
1642 const extra = wip.extraDataTrail(ExtractValue, instruction.data);1631 var extra = wip.extraDataTrail(ExtractValue, instruction.data);
1643 const indices: []const u32 =1632 const indices = extra.trail.next(extra.data.indices_len, u32, wip);
1644 wip.extra.items[extra.end..][0..extra.data.indices_len];
1645 return extra.data.val.typeOfWip(wip).childTypeAt(indices, wip.builder);1633 return extra.data.val.typeOfWip(wip).childTypeAt(indices, wip.builder);
1646 },1634 },
1647 .@"fcmp false",1635 .@"fcmp false",
...@@ -1694,9 +1682,8 @@ pub const Function = struct {...@@ -1694,9 +1682,8 @@ pub const Function = struct {
1694 .getelementptr,1682 .getelementptr,
1695 .@"getelementptr inbounds",1683 .@"getelementptr inbounds",
1696 => {1684 => {
1697 const extra = wip.extraDataTrail(GetElementPtr, instruction.data);1685 var extra = wip.extraDataTrail(GetElementPtr, instruction.data);
1698 const indices: []const Value =1686 const indices = extra.trail.next(extra.data.indices_len, Value, wip);
1699 @ptrCast(wip.extra.items[extra.end..][0..extra.data.indices_len]);
1700 const base_ty = extra.data.base.typeOfWip(wip);1687 const base_ty = extra.data.base.typeOfWip(wip);
1701 if (!base_ty.isVector(wip.builder)) for (indices) |index| {1688 if (!base_ty.isVector(wip.builder)) for (indices) |index| {
1702 const index_ty = index.typeOfWip(wip);1689 const index_ty = index.typeOfWip(wip);
...@@ -1829,9 +1816,8 @@ pub const Function = struct {...@@ -1829,9 +1816,8 @@ pub const Function = struct {
1829 .extractelement => function.extraData(ExtractElement, instruction.data)1816 .extractelement => function.extraData(ExtractElement, instruction.data)
1830 .val.typeOf(function_index, builder).childType(builder),1817 .val.typeOf(function_index, builder).childType(builder),
1831 .extractvalue => {1818 .extractvalue => {
1832 const extra = function.extraDataTrail(ExtractValue, instruction.data);1819 var extra = function.extraDataTrail(ExtractValue, instruction.data);
1833 const indices: []const u32 =1820 const indices = extra.trail.next(extra.data.indices_len, u32, function);
1834 function.extra[extra.end..][0..extra.data.indices_len];
1835 return extra.data.val.typeOf(function_index, builder)1821 return extra.data.val.typeOf(function_index, builder)
1836 .childTypeAt(indices, builder);1822 .childTypeAt(indices, builder);
1837 },1823 },
...@@ -1885,9 +1871,8 @@ pub const Function = struct {...@@ -1885,9 +1871,8 @@ pub const Function = struct {
1885 .getelementptr,1871 .getelementptr,
1886 .@"getelementptr inbounds",1872 .@"getelementptr inbounds",
1887 => {1873 => {
1888 const extra = function.extraDataTrail(GetElementPtr, instruction.data);1874 var extra = function.extraDataTrail(GetElementPtr, instruction.data);
1889 const indices: []const Value =1875 const indices = extra.trail.next(extra.data.indices_len, Value, function);
1890 @ptrCast(function.extra[extra.end..][0..extra.data.indices_len]);
1891 const base_ty = extra.data.base.typeOf(function_index, builder);1876 const base_ty = extra.data.base.typeOf(function_index, builder);
1892 if (!base_ty.isVector(builder)) for (indices) |index| {1877 if (!base_ty.isVector(builder)) for (indices) |index| {
1893 const index_ty = index.typeOf(function_index, builder);1878 const index_ty = index.typeOf(function_index, builder);
...@@ -1908,10 +1893,9 @@ pub const Function = struct {...@@ -1908,10 +1893,9 @@ pub const Function = struct {
1908 .phi,1893 .phi,
1909 .@"phi fast",1894 .@"phi fast",
1910 => {1895 => {
1911 const extra = function.extraDataTrail(Phi, instruction.data);1896 var extra = function.extraDataTrail(Phi, instruction.data);
1912 const incoming_vals: []const Value =1897 const vals = extra.trail.next(extra.data.incoming_len, Value, function);
1913 @ptrCast(function.extra[extra.end..][0..extra.data.incoming_len]);1898 return vals[0].typeOf(function_index, builder);
1914 return incoming_vals[0].typeOf(function_index, builder);
1915 },1899 },
1916 .select,1900 .select,
1917 .@"select fast",1901 .@"select fast",
...@@ -2112,11 +2096,32 @@ pub const Function = struct {...@@ -2112,11 +2096,32 @@ pub const Function = struct {
2112 return argument_index.toValue();2096 return argument_index.toValue();
2113 }2097 }
21142098
2099 const ExtraDataTrail = struct {
2100 index: Instruction.ExtraIndex,
2101
2102 fn nextMut(self: *ExtraDataTrail, len: u32, comptime Item: type, function: *Function) []Item {
2103 const items: []Item = @ptrCast(function.extra[self.index..][0..len]);
2104 self.index += @intCast(len);
2105 return items;
2106 }
2107
2108 fn next(
2109 self: *ExtraDataTrail,
2110 len: u32,
2111 comptime Item: type,
2112 function: *const Function,
2113 ) []const Item {
2114 const items: []const Item = @ptrCast(function.extra[self.index..][0..len]);
2115 self.index += @intCast(len);
2116 return items;
2117 }
2118 };
2119
2115 fn extraDataTrail(2120 fn extraDataTrail(
2116 self: *const Function,2121 self: *const Function,
2117 comptime T: type,2122 comptime T: type,
2118 index: Instruction.ExtraIndex,2123 index: Instruction.ExtraIndex,
2119 ) struct { data: T, end: Instruction.ExtraIndex } {2124 ) struct { data: T, trail: ExtraDataTrail } {
2120 var result: T = undefined;2125 var result: T = undefined;
2121 const fields = @typeInfo(T).Struct.fields;2126 const fields = @typeInfo(T).Struct.fields;
2122 inline for (fields, self.extra[index..][0..fields.len]) |field, value|2127 inline for (fields, self.extra[index..][0..fields.len]) |field, value|
...@@ -2126,7 +2131,10 @@ pub const Function = struct {...@@ -2126,7 +2131,10 @@ pub const Function = struct {
2126 MemoryAccessInfo, Instruction.Alloca.Info => @bitCast(value),2131 MemoryAccessInfo, Instruction.Alloca.Info => @bitCast(value),
2127 else => @compileError("bad field type: " ++ @typeName(field.type)),2132 else => @compileError("bad field type: " ++ @typeName(field.type)),
2128 };2133 };
2129 return .{ .data = result, .end = index + @as(Type.Item.ExtraIndex, @intCast(fields.len)) };2134 return .{
2135 .data = result,
2136 .trail = .{ .index = index + @as(Type.Item.ExtraIndex, @intCast(fields.len)) },
2137 };
2130 }2138 }
21312139
2132 fn extraData(self: *const Function, comptime T: type, index: Instruction.ExtraIndex) T {2140 fn extraData(self: *const Function, comptime T: type, index: Instruction.ExtraIndex) T {
...@@ -2315,14 +2323,10 @@ pub const WipFunction = struct {...@@ -2315,14 +2323,10 @@ pub const WipFunction = struct {
2315 wip: *WipFunction,2323 wip: *WipFunction,
2316 ) Allocator.Error!void {2324 ) Allocator.Error!void {
2317 const instruction = wip.instructions.get(@intFromEnum(self.instruction));2325 const instruction = wip.instructions.get(@intFromEnum(self.instruction));
2318 const extra = wip.extraDataTrail(Instruction.Switch, instruction.data);2326 var extra = wip.extraDataTrail(Instruction.Switch, instruction.data);
2319 const case_vals: []Constant =
2320 @ptrCast(wip.extra.items[extra.end..][0..extra.data.cases_len]);
2321 const case_dests: []Block.Index =
2322 @ptrCast(wip.extra.items[extra.end + extra.data.cases_len ..][0..extra.data.cases_len]);
2323 assert(val.typeOf(wip.builder) == extra.data.val.typeOfWip(wip));2327 assert(val.typeOf(wip.builder) == extra.data.val.typeOfWip(wip));
2324 case_vals[self.index] = val;2328 extra.trail.nextMut(extra.data.cases_len, Constant, wip)[self.index] = val;
2325 case_dests[self.index] = dest;2329 extra.trail.nextMut(extra.data.cases_len, Block.Index, wip)[self.index] = dest;
2326 self.index += 1;2330 self.index += 1;
2327 dest.ptr(wip).branches += 1;2331 dest.ptr(wip).branches += 1;
2328 if (wip.builder.useLibLlvm())2332 if (wip.builder.useLibLlvm())
...@@ -3113,13 +3117,10 @@ pub const WipFunction = struct {...@@ -3113,13 +3117,10 @@ pub const WipFunction = struct {
3113 const incoming_len = self.block.ptrConst(wip).incoming;3117 const incoming_len = self.block.ptrConst(wip).incoming;
3114 assert(vals.len == incoming_len and blocks.len == incoming_len);3118 assert(vals.len == incoming_len and blocks.len == incoming_len);
3115 const instruction = wip.instructions.get(@intFromEnum(self.instruction));3119 const instruction = wip.instructions.get(@intFromEnum(self.instruction));
3116 const extra = wip.extraDataTrail(Instruction.WipPhi, instruction.data);3120 var extra = wip.extraDataTrail(Instruction.WipPhi, instruction.data);
3117 for (vals) |val| assert(val.typeOfWip(wip) == extra.data.type);3121 for (vals) |val| assert(val.typeOfWip(wip) == extra.data.type);
3118 const incoming_vals: []Value = @ptrCast(wip.extra.items[extra.end..][0..incoming_len]);3122 @memcpy(extra.trail.nextMut(incoming_len, Value, wip), vals);
3119 const incoming_blocks: []Block.Index =3123 @memcpy(extra.trail.nextMut(incoming_len, Block.Index, wip), blocks);
3120 @ptrCast(wip.extra.items[extra.end + incoming_len ..][0..incoming_len]);
3121 @memcpy(incoming_vals, vals);
3122 @memcpy(incoming_blocks, blocks);
3123 if (wip.builder.useLibLlvm()) {3124 if (wip.builder.useLibLlvm()) {
3124 const ExpectedContents = extern struct {3125 const ExpectedContents = extern struct {
3125 [expected_incoming_len]*llvm.Value,3126 [expected_incoming_len]*llvm.Value,
...@@ -3504,9 +3505,8 @@ pub const WipFunction = struct {...@@ -3504,9 +3505,8 @@ pub const WipFunction = struct {
3504 });3505 });
3505 },3506 },
3506 .extractvalue => {3507 .extractvalue => {
3507 const extra = self.extraDataTrail(Instruction.ExtractValue, instruction.data);3508 var extra = self.extraDataTrail(Instruction.ExtractValue, instruction.data);
3508 const indices: []const u32 =3509 const indices = extra.trail.next(extra.data.indices_len, u32, self);
3509 self.extra.items[extra.end..][0..extra.data.indices_len];
3510 instruction.data = wip_extra.addExtra(Instruction.ExtractValue{3510 instruction.data = wip_extra.addExtra(Instruction.ExtractValue{
3511 .val = instructions.map(extra.data.val),3511 .val = instructions.map(extra.data.val),
3512 .indices_len = extra.data.indices_len,3512 .indices_len = extra.data.indices_len,
...@@ -3520,9 +3520,8 @@ pub const WipFunction = struct {...@@ -3520,9 +3520,8 @@ pub const WipFunction = struct {
3520 .getelementptr,3520 .getelementptr,
3521 .@"getelementptr inbounds",3521 .@"getelementptr inbounds",
3522 => {3522 => {
3523 const extra = self.extraDataTrail(Instruction.GetElementPtr, instruction.data);3523 var extra = self.extraDataTrail(Instruction.GetElementPtr, instruction.data);
3524 const indices: []const Value =3524 const indices = extra.trail.next(extra.data.indices_len, Value, self);
3525 @ptrCast(self.extra.items[extra.end..][0..extra.data.indices_len]);
3526 instruction.data = wip_extra.addExtra(Instruction.GetElementPtr{3525 instruction.data = wip_extra.addExtra(Instruction.GetElementPtr{
3527 .type = extra.data.type,3526 .type = extra.data.type,
3528 .base = instructions.map(extra.data.base),3527 .base = instructions.map(extra.data.base),
...@@ -3539,9 +3538,8 @@ pub const WipFunction = struct {...@@ -3539,9 +3538,8 @@ pub const WipFunction = struct {
3539 });3538 });
3540 },3539 },
3541 .insertvalue => {3540 .insertvalue => {
3542 const extra = self.extraDataTrail(Instruction.InsertValue, instruction.data);3541 var extra = self.extraDataTrail(Instruction.InsertValue, instruction.data);
3543 const indices: []const u32 =3542 const indices = extra.trail.next(extra.data.indices_len, u32, self);
3544 self.extra.items[extra.end..][0..extra.data.indices_len];
3545 instruction.data = wip_extra.addExtra(Instruction.InsertValue{3543 instruction.data = wip_extra.addExtra(Instruction.InsertValue{
3546 .val = instructions.map(extra.data.val),3544 .val = instructions.map(extra.data.val),
3547 .elem = instructions.map(extra.data.elem),3545 .elem = instructions.map(extra.data.elem),
...@@ -3564,12 +3562,10 @@ pub const WipFunction = struct {...@@ -3564,12 +3562,10 @@ pub const WipFunction = struct {
3564 .phi,3562 .phi,
3565 .@"phi fast",3563 .@"phi fast",
3566 => {3564 => {
3567 const extra = self.extraDataTrail(Instruction.WipPhi, instruction.data);
3568 const incoming_len = current_block.incoming;3565 const incoming_len = current_block.incoming;
3569 const incoming_vals: []const Value =3566 var extra = self.extraDataTrail(Instruction.WipPhi, instruction.data);
3570 @ptrCast(self.extra.items[extra.end..][0..incoming_len]);3567 const incoming_vals = extra.trail.next(incoming_len, Value, self);
3571 const incoming_blocks: []const Block.Index =3568 const incoming_blocks = extra.trail.next(incoming_len, Block.Index, self);
3572 @ptrCast(self.extra.items[extra.end + incoming_len ..][0..incoming_len]);
3573 instruction.data = wip_extra.addExtra(Instruction.Phi{3569 instruction.data = wip_extra.addExtra(Instruction.Phi{
3574 .incoming_len = incoming_len,3570 .incoming_len = incoming_len,
3575 });3571 });
...@@ -3607,11 +3603,9 @@ pub const WipFunction = struct {...@@ -3607,11 +3603,9 @@ pub const WipFunction = struct {
3607 });3603 });
3608 },3604 },
3609 .@"switch" => {3605 .@"switch" => {
3610 const extra = self.extraDataTrail(Instruction.Switch, instruction.data);3606 var extra = self.extraDataTrail(Instruction.Switch, instruction.data);
3611 const case_vals: []const Constant =3607 const case_vals = extra.trail.next(extra.data.cases_len, Constant, self);
3612 @ptrCast(self.extra.items[extra.end..][0..extra.data.cases_len]);3608 const case_blocks = extra.trail.next(extra.data.cases_len, Block.Index, self);
3613 const case_blocks: []const Block.Index = @ptrCast(self.extra
3614 .items[extra.end + extra.data.cases_len ..][0..extra.data.cases_len]);
3615 instruction.data = wip_extra.addExtra(Instruction.Switch{3609 instruction.data = wip_extra.addExtra(Instruction.Switch{
3616 .val = instructions.map(extra.data.val),3610 .val = instructions.map(extra.data.val),
3617 .default = extra.data.default,3611 .default = extra.data.default,
...@@ -3956,11 +3950,32 @@ pub const WipFunction = struct {...@@ -3956,11 +3950,32 @@ pub const WipFunction = struct {
3956 return result;3950 return result;
3957 }3951 }
39583952
3953 const ExtraDataTrail = struct {
3954 index: Instruction.ExtraIndex,
3955
3956 fn nextMut(self: *ExtraDataTrail, len: u32, comptime Item: type, wip: *WipFunction) []Item {
3957 const items: []Item = @ptrCast(wip.extra.items[self.index..][0..len]);
3958 self.index += @intCast(len);
3959 return items;
3960 }
3961
3962 fn next(
3963 self: *ExtraDataTrail,
3964 len: u32,
3965 comptime Item: type,
3966 wip: *const WipFunction,
3967 ) []const Item {
3968 const items: []const Item = @ptrCast(wip.extra.items[self.index..][0..len]);
3969 self.index += @intCast(len);
3970 return items;
3971 }
3972 };
3973
3959 fn extraDataTrail(3974 fn extraDataTrail(
3960 self: *const WipFunction,3975 self: *const WipFunction,
3961 comptime T: type,3976 comptime T: type,
3962 index: Instruction.ExtraIndex,3977 index: Instruction.ExtraIndex,
3963 ) struct { data: T, end: Instruction.ExtraIndex } {3978 ) struct { data: T, trail: ExtraDataTrail } {
3964 var result: T = undefined;3979 var result: T = undefined;
3965 const fields = @typeInfo(T).Struct.fields;3980 const fields = @typeInfo(T).Struct.fields;
3966 inline for (fields, self.extra.items[index..][0..fields.len]) |field, value|3981 inline for (fields, self.extra.items[index..][0..fields.len]) |field, value|
...@@ -3970,7 +3985,10 @@ pub const WipFunction = struct {...@@ -3970,7 +3985,10 @@ pub const WipFunction = struct {
3970 MemoryAccessInfo, Instruction.Alloca.Info => @bitCast(value),3985 MemoryAccessInfo, Instruction.Alloca.Info => @bitCast(value),
3971 else => @compileError("bad field type: " ++ @typeName(field.type)),3986 else => @compileError("bad field type: " ++ @typeName(field.type)),
3972 };3987 };
3973 return .{ .data = result, .end = index + @as(Type.Item.ExtraIndex, @intCast(fields.len)) };3988 return .{
3989 .data = result,
3990 .trail = .{ .index = index + @as(Type.Item.ExtraIndex, @intCast(fields.len)) },
3991 };
3974 }3992 }
39753993
3976 fn extraData(self: *const WipFunction, comptime T: type, index: Instruction.ExtraIndex) T {3994 fn extraData(self: *const WipFunction, comptime T: type, index: Instruction.ExtraIndex) T {
...@@ -4315,9 +4333,9 @@ pub const Constant = enum(u32) {...@@ -4315,9 +4333,9 @@ pub const Constant = enum(u32) {
4315 .getelementptr,4333 .getelementptr,
4316 .@"getelementptr inbounds",4334 .@"getelementptr inbounds",
4317 => {4335 => {
4318 const extra = builder.constantExtraDataTrail(GetElementPtr, item.data);4336 var extra = builder.constantExtraDataTrail(GetElementPtr, item.data);
4319 const indices: []const Constant = @ptrCast(builder.constant_extra4337 const indices =
4320 .items[extra.end..][0..extra.data.info.indices_len]);4338 extra.trail.next(extra.data.info.indices_len, Constant, builder);
4321 const base_ty = extra.data.base.typeOf(builder);4339 const base_ty = extra.data.base.typeOf(builder);
4322 if (!base_ty.isVector(builder)) for (indices) |index| {4340 if (!base_ty.isVector(builder)) for (indices) |index| {
4323 const index_ty = index.typeOf(builder);4341 const index_ty = index.typeOf(builder);
...@@ -4392,10 +4410,9 @@ pub const Constant = enum(u32) {...@@ -4392,10 +4410,9 @@ pub const Constant = enum(u32) {
4392 return extra.lo_lo == 0 and extra.lo_hi == 0 and extra.hi == 0;4410 return extra.lo_lo == 0 and extra.lo_hi == 0 and extra.hi == 0;
4393 },4411 },
4394 .vector => {4412 .vector => {
4395 const extra = builder.constantExtraDataTrail(Aggregate, item.data);4413 var extra = builder.constantExtraDataTrail(Aggregate, item.data);
4396 const len = extra.data.type.aggregateLen(builder);4414 const len: u32 = @intCast(extra.data.type.aggregateLen(builder));
4397 const vals: []const Constant =4415 const vals = extra.trail.next(len, Constant, builder);
4398 @ptrCast(builder.constant_extra.items[extra.end..][0..len]);
4399 for (vals) |val| if (!val.isZeroInit(builder)) return false;4416 for (vals) |val| if (!val.isZeroInit(builder)) return false;
4400 return true;4417 return true;
4401 },4418 },
...@@ -4549,10 +4566,9 @@ pub const Constant = enum(u32) {...@@ -4549,10 +4566,9 @@ pub const Constant = enum(u32) {
4549 .array,4566 .array,
4550 .vector,4567 .vector,
4551 => |tag| {4568 => |tag| {
4552 const extra = data.builder.constantExtraDataTrail(Aggregate, item.data);4569 var extra = data.builder.constantExtraDataTrail(Aggregate, item.data);
4553 const len = extra.data.type.aggregateLen(data.builder);4570 const len: u32 = @intCast(extra.data.type.aggregateLen(data.builder));
4554 const vals: []const Constant =4571 const vals = extra.trail.next(len, Constant, data.builder);
4555 @ptrCast(data.builder.constant_extra.items[extra.end..][0..len]);
4556 try writer.writeAll(switch (tag) {4572 try writer.writeAll(switch (tag) {
4557 .structure => "{ ",4573 .structure => "{ ",
4558 .packed_structure => "<{ ",4574 .packed_structure => "<{ ",
...@@ -4631,9 +4647,9 @@ pub const Constant = enum(u32) {...@@ -4631,9 +4647,9 @@ pub const Constant = enum(u32) {
4631 .getelementptr,4647 .getelementptr,
4632 .@"getelementptr inbounds",4648 .@"getelementptr inbounds",
4633 => |tag| {4649 => |tag| {
4634 const extra = data.builder.constantExtraDataTrail(GetElementPtr, item.data);4650 var extra = data.builder.constantExtraDataTrail(GetElementPtr, item.data);
4635 const indices: []const Constant = @ptrCast(data.builder.constant_extra4651 const indices =
4636 .items[extra.end..][0..extra.data.info.indices_len]);4652 extra.trail.next(extra.data.info.indices_len, Constant, data.builder);
4637 try writer.print("{s} ({%}, {%}", .{4653 try writer.print("{s} ({%}, {%}", .{
4638 @tagName(tag),4654 @tagName(tag),
4639 extra.data.type.fmt(data.builder),4655 extra.data.type.fmt(data.builder),
...@@ -5243,9 +5259,8 @@ pub fn namedTypeSetBody(...@@ -5243,9 +5259,8 @@ pub fn namedTypeSetBody(
5243 @intFromEnum(body_type);5259 @intFromEnum(body_type);
5244 if (self.useLibLlvm()) {5260 if (self.useLibLlvm()) {
5245 const body_item = self.type_items.items[@intFromEnum(body_type)];5261 const body_item = self.type_items.items[@intFromEnum(body_type)];
5246 const body_extra = self.typeExtraDataTrail(Type.Structure, body_item.data);5262 var body_extra = self.typeExtraDataTrail(Type.Structure, body_item.data);
5247 const body_fields: []const Type =5263 const body_fields = body_extra.trail.next(body_extra.data.fields_len, Type, self);
5248 @ptrCast(self.type_extra.items[body_extra.end..][0..body_extra.data.fields_len]);
5249 const llvm_fields = try self.gpa.alloc(*llvm.Type, body_fields.len);5264 const llvm_fields = try self.gpa.alloc(*llvm.Type, body_fields.len);
5250 defer self.gpa.free(llvm_fields);5265 defer self.gpa.free(llvm_fields);
5251 for (llvm_fields, body_fields) |*llvm_field, body_field| llvm_field.* = body_field.toLlvm(self);5266 for (llvm_fields, body_fields) |*llvm_field, body_field| llvm_field.* = body_field.toLlvm(self);
...@@ -5947,10 +5962,9 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -5947,10 +5962,9 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
5947 });5962 });
5948 },5963 },
5949 .extractvalue => |tag| {5964 .extractvalue => |tag| {
5950 const extra =5965 var extra =
5951 function.extraDataTrail(Function.Instruction.ExtractValue, instruction.data);5966 function.extraDataTrail(Function.Instruction.ExtractValue, instruction.data);
5952 const indices: []const u32 =5967 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
5953 function.extra[extra.end..][0..extra.data.indices_len];
5954 try writer.print(" %{} = {s} {%}", .{5968 try writer.print(" %{} = {s} {%}", .{
5955 instruction_index.name(&function).fmt(self),5969 instruction_index.name(&function).fmt(self),
5956 @tagName(tag),5970 @tagName(tag),
...@@ -5976,12 +5990,11 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -5976,12 +5990,11 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
5976 .getelementptr,5990 .getelementptr,
5977 .@"getelementptr inbounds",5991 .@"getelementptr inbounds",
5978 => |tag| {5992 => |tag| {
5979 const extra = function.extraDataTrail(5993 var extra = function.extraDataTrail(
5980 Function.Instruction.GetElementPtr,5994 Function.Instruction.GetElementPtr,
5981 instruction.data,5995 instruction.data,
5982 );5996 );
5983 const indices: []const Value =5997 const indices = extra.trail.next(extra.data.indices_len, Value, &function);
5984 @ptrCast(function.extra[extra.end..][0..extra.data.indices_len]);
5985 try writer.print(" %{} = {s} {%}, {%}", .{5998 try writer.print(" %{} = {s} {%}, {%}", .{
5986 instruction_index.name(&function).fmt(self),5999 instruction_index.name(&function).fmt(self),
5987 @tagName(tag),6000 @tagName(tag),
...@@ -6005,10 +6018,9 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -6005,10 +6018,9 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
6005 });6018 });
6006 },6019 },
6007 .insertvalue => |tag| {6020 .insertvalue => |tag| {
6008 const extra =6021 var extra =
6009 function.extraDataTrail(Function.Instruction.InsertValue, instruction.data);6022 function.extraDataTrail(Function.Instruction.InsertValue, instruction.data);
6010 const indices: []const u32 =6023 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
6011 function.extra[extra.end..][0..extra.data.indices_len];
6012 try writer.print(" %{} = {s} {%}, {%}", .{6024 try writer.print(" %{} = {s} {%}, {%}", .{
6013 instruction_index.name(&function).fmt(self),6025 instruction_index.name(&function).fmt(self),
6014 @tagName(tag),6026 @tagName(tag),
...@@ -6063,12 +6075,10 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -6063,12 +6075,10 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
6063 .phi,6075 .phi,
6064 .@"phi fast",6076 .@"phi fast",
6065 => |tag| {6077 => |tag| {
6066 const extra =6078 var extra = function.extraDataTrail(Function.Instruction.Phi, instruction.data);
6067 function.extraDataTrail(Function.Instruction.Phi, instruction.data);6079 const vals = extra.trail.next(extra.data.incoming_len, Value, &function);
6068 const vals: []const Value =6080 const blocks =
6069 @ptrCast(function.extra[extra.end..][0..extra.data.incoming_len]);6081 extra.trail.next(extra.data.incoming_len, Function.Block.Index, &function);
6070 const blocks: []const Function.Block.Index = @ptrCast(function.extra[extra.end +
6071 extra.data.incoming_len ..][0..extra.data.incoming_len]);
6072 try writer.print(" %{} = {s} {%} ", .{6082 try writer.print(" %{} = {s} {%} ", .{
6073 instruction_index.name(&function).fmt(self),6083 instruction_index.name(&function).fmt(self),
6074 @tagName(tag),6084 @tagName(tag),
...@@ -6125,12 +6135,11 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator...@@ -6125,12 +6135,11 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
6125 });6135 });
6126 },6136 },
6127 .@"switch" => |tag| {6137 .@"switch" => |tag| {
6128 const extra =6138 var extra =
6129 function.extraDataTrail(Function.Instruction.Switch, instruction.data);6139 function.extraDataTrail(Function.Instruction.Switch, instruction.data);
6130 const vals: []const Constant =6140 const vals = extra.trail.next(extra.data.cases_len, Constant, &function);
6131 @ptrCast(function.extra[extra.end..][0..extra.data.cases_len]);6141 const blocks =
6132 const blocks: []const Function.Block.Index = @ptrCast(function.extra[extra.end +6142 extra.trail.next(extra.data.cases_len, Function.Block.Index, &function);
6133 extra.data.cases_len ..][0..extra.data.cases_len]);
6134 try writer.print(" {s} {%}, {%} [", .{6143 try writer.print(" {s} {%}, {%} [", .{
6135 @tagName(tag),6144 @tagName(tag),
6136 extra.data.val.fmt(function_index, self),6145 extra.data.val.fmt(function_index, self),
...@@ -6216,9 +6225,8 @@ fn fnTypeAssumeCapacity(...@@ -6216,9 +6225,8 @@ fn fnTypeAssumeCapacity(
6216 }6225 }
6217 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {6226 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
6218 const rhs_data = ctx.builder.type_items.items[rhs_index];6227 const rhs_data = ctx.builder.type_items.items[rhs_index];
6219 const rhs_extra = ctx.builder.typeExtraDataTrail(Type.Function, rhs_data.data);6228 var rhs_extra = ctx.builder.typeExtraDataTrail(Type.Function, rhs_data.data);
6220 const rhs_params: []const Type =6229 const rhs_params = rhs_extra.trail.next(rhs_extra.data.params_len, Type, ctx.builder);
6221 @ptrCast(ctx.builder.type_extra.items[rhs_extra.end..][0..rhs_extra.data.params_len]);
6222 return rhs_data.tag == tag and lhs_key.ret == rhs_extra.data.ret and6230 return rhs_data.tag == tag and lhs_key.ret == rhs_extra.data.ret and
6223 std.mem.eql(Type, lhs_key.params, rhs_params);6231 std.mem.eql(Type, lhs_key.params, rhs_params);
6224 }6232 }
...@@ -6400,9 +6408,8 @@ fn structTypeAssumeCapacity(...@@ -6400,9 +6408,8 @@ fn structTypeAssumeCapacity(
6400 }6408 }
6401 pub fn eql(ctx: @This(), lhs_key: []const Type, _: void, rhs_index: usize) bool {6409 pub fn eql(ctx: @This(), lhs_key: []const Type, _: void, rhs_index: usize) bool {
6402 const rhs_data = ctx.builder.type_items.items[rhs_index];6410 const rhs_data = ctx.builder.type_items.items[rhs_index];
6403 const rhs_extra = ctx.builder.typeExtraDataTrail(Type.Structure, rhs_data.data);6411 var rhs_extra = ctx.builder.typeExtraDataTrail(Type.Structure, rhs_data.data);
6404 const rhs_fields: []const Type =6412 const rhs_fields = rhs_extra.trail.next(rhs_extra.data.fields_len, Type, ctx.builder);
6405 @ptrCast(ctx.builder.type_extra.items[rhs_extra.end..][0..rhs_extra.data.fields_len]);
6406 return rhs_data.tag == tag and std.mem.eql(Type, lhs_key, rhs_fields);6413 return rhs_data.tag == tag and std.mem.eql(Type, lhs_key, rhs_fields);
6407 }6414 }
6408 };6415 };
...@@ -6542,11 +6549,32 @@ fn addTypeExtraAssumeCapacity(self: *Builder, extra: anytype) Type.Item.ExtraInd...@@ -6542,11 +6549,32 @@ fn addTypeExtraAssumeCapacity(self: *Builder, extra: anytype) Type.Item.ExtraInd
6542 return result;6549 return result;
6543}6550}
65446551
6552const TypeExtraDataTrail = struct {
6553 index: Type.Item.ExtraIndex,
6554
6555 fn nextMut(self: *TypeExtraDataTrail, len: u32, comptime Item: type, builder: *Builder) []Item {
6556 const items: []Item = @ptrCast(builder.type_extra.items[self.index..][0..len]);
6557 self.index += @intCast(len);
6558 return items;
6559 }
6560
6561 fn next(
6562 self: *TypeExtraDataTrail,
6563 len: u32,
6564 comptime Item: type,
6565 builder: *const Builder,
6566 ) []const Item {
6567 const items: []const Item = @ptrCast(builder.type_extra.items[self.index..][0..len]);
6568 self.index += @intCast(len);
6569 return items;
6570 }
6571};
6572
6545fn typeExtraDataTrail(6573fn typeExtraDataTrail(
6546 self: *const Builder,6574 self: *const Builder,
6547 comptime T: type,6575 comptime T: type,
6548 index: Type.Item.ExtraIndex,6576 index: Type.Item.ExtraIndex,
6549) struct { data: T, end: Type.Item.ExtraIndex } {6577) struct { data: T, trail: TypeExtraDataTrail } {
6550 var result: T = undefined;6578 var result: T = undefined;
6551 const fields = @typeInfo(T).Struct.fields;6579 const fields = @typeInfo(T).Struct.fields;
6552 inline for (fields, self.type_extra.items[index..][0..fields.len]) |field, value|6580 inline for (fields, self.type_extra.items[index..][0..fields.len]) |field, value|
...@@ -6555,7 +6583,10 @@ fn typeExtraDataTrail(...@@ -6555,7 +6583,10 @@ fn typeExtraDataTrail(
6555 String, Type => @enumFromInt(value),6583 String, Type => @enumFromInt(value),
6556 else => @compileError("bad field type: " ++ @typeName(field.type)),6584 else => @compileError("bad field type: " ++ @typeName(field.type)),
6557 };6585 };
6558 return .{ .data = result, .end = index + @as(Type.Item.ExtraIndex, @intCast(fields.len)) };6586 return .{
6587 .data = result,
6588 .trail = .{ .index = index + @as(Type.Item.ExtraIndex, @intCast(fields.len)) },
6589 };
6559}6590}
65606591
6561fn typeExtraData(self: *const Builder, comptime T: type, index: Type.Item.ExtraIndex) T {6592fn typeExtraData(self: *const Builder, comptime T: type, index: Type.Item.ExtraIndex) T {
...@@ -6914,7 +6945,7 @@ fn structConstAssumeCapacity(...@@ -6914,7 +6945,7 @@ fn structConstAssumeCapacity(
6914 vals: []const Constant,6945 vals: []const Constant,
6915) if (build_options.have_llvm) Allocator.Error!Constant else Constant {6946) if (build_options.have_llvm) Allocator.Error!Constant else Constant {
6916 const type_item = self.type_items.items[@intFromEnum(ty)];6947 const type_item = self.type_items.items[@intFromEnum(ty)];
6917 const extra = self.typeExtraDataTrail(Type.Structure, switch (type_item.tag) {6948 var extra = self.typeExtraDataTrail(Type.Structure, switch (type_item.tag) {
6918 .structure, .packed_structure => type_item.data,6949 .structure, .packed_structure => type_item.data,
6919 .named_structure => data: {6950 .named_structure => data: {
6920 const body_ty = self.typeExtraData(Type.NamedStructure, type_item.data).body;6951 const body_ty = self.typeExtraData(Type.NamedStructure, type_item.data).body;
...@@ -6926,8 +6957,7 @@ fn structConstAssumeCapacity(...@@ -6926,8 +6957,7 @@ fn structConstAssumeCapacity(
6926 },6957 },
6927 else => unreachable,6958 else => unreachable,
6928 });6959 });
6929 const fields: []const Type =6960 const fields = extra.trail.next(extra.data.fields_len, Type, self);
6930 @ptrCast(self.type_extra.items[extra.end..][0..extra.data.fields_len]);
6931 for (fields, vals) |field, val| assert(field == val.typeOf(self));6961 for (fields, vals) |field, val| assert(field == val.typeOf(self));
69326962
6933 for (vals) |val| {6963 for (vals) |val| {
...@@ -7405,9 +7435,9 @@ fn gepConstAssumeCapacity(...@@ -7405,9 +7435,9 @@ fn gepConstAssumeCapacity(
7405 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {7435 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
7406 if (ctx.builder.constant_items.items(.tag)[rhs_index] != tag) return false;7436 if (ctx.builder.constant_items.items(.tag)[rhs_index] != tag) return false;
7407 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];7437 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
7408 const rhs_extra = ctx.builder.constantExtraDataTrail(Constant.GetElementPtr, rhs_data);7438 var rhs_extra = ctx.builder.constantExtraDataTrail(Constant.GetElementPtr, rhs_data);
7409 const rhs_indices: []const Constant = @ptrCast(ctx.builder.constant_extra7439 const rhs_indices =
7410 .items[rhs_extra.end..][0..rhs_extra.data.info.indices_len]);7440 rhs_extra.trail.next(rhs_extra.data.info.indices_len, Constant, ctx.builder);
7411 return lhs_key.type == rhs_extra.data.type and lhs_key.base == rhs_extra.data.base and7441 return lhs_key.type == rhs_extra.data.type and lhs_key.base == rhs_extra.data.base and
7412 lhs_key.inrange == rhs_extra.data.info.inrange and7442 lhs_key.inrange == rhs_extra.data.info.inrange and
7413 std.mem.eql(Constant, lhs_key.indices, rhs_indices);7443 std.mem.eql(Constant, lhs_key.indices, rhs_indices);
...@@ -7767,10 +7797,9 @@ fn getOrPutConstantAggregateAssumeCapacity(...@@ -7767,10 +7797,9 @@ fn getOrPutConstantAggregateAssumeCapacity(
7767 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {7797 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
7768 if (lhs_key.tag != ctx.builder.constant_items.items(.tag)[rhs_index]) return false;7798 if (lhs_key.tag != ctx.builder.constant_items.items(.tag)[rhs_index]) return false;
7769 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];7799 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
7770 const rhs_extra = ctx.builder.constantExtraDataTrail(Constant.Aggregate, rhs_data);7800 var rhs_extra = ctx.builder.constantExtraDataTrail(Constant.Aggregate, rhs_data);
7771 if (lhs_key.type != rhs_extra.data.type) return false;7801 if (lhs_key.type != rhs_extra.data.type) return false;
7772 const rhs_vals: []const Constant =7802 const rhs_vals = rhs_extra.trail.next(@intCast(lhs_key.vals.len), Constant, ctx.builder);
7773 @ptrCast(ctx.builder.constant_extra.items[rhs_extra.end..][0..lhs_key.vals.len]);
7774 return std.mem.eql(Constant, lhs_key.vals, rhs_vals);7803 return std.mem.eql(Constant, lhs_key.vals, rhs_vals);
7775 }7804 }
7776 };7805 };
...@@ -7804,11 +7833,32 @@ fn addConstantExtraAssumeCapacity(self: *Builder, extra: anytype) Constant.Item....@@ -7804,11 +7833,32 @@ fn addConstantExtraAssumeCapacity(self: *Builder, extra: anytype) Constant.Item.
7804 return result;7833 return result;
7805}7834}
78067835
7836const ConstantExtraDataTrail = struct {
7837 index: Constant.Item.ExtraIndex,
7838
7839 fn nextMut(self: *ConstantExtraDataTrail, len: u32, comptime Item: type, builder: *Builder) []Item {
7840 const items: []Item = @ptrCast(builder.constant_extra.items[self.index..][0..len]);
7841 self.index += @intCast(len);
7842 return items;
7843 }
7844
7845 fn next(
7846 self: *ConstantExtraDataTrail,
7847 len: u32,
7848 comptime Item: type,
7849 builder: *const Builder,
7850 ) []const Item {
7851 const items: []const Item = @ptrCast(builder.constant_extra.items[self.index..][0..len]);
7852 self.index += @intCast(len);
7853 return items;
7854 }
7855};
7856
7807fn constantExtraDataTrail(7857fn constantExtraDataTrail(
7808 self: *const Builder,7858 self: *const Builder,
7809 comptime T: type,7859 comptime T: type,
7810 index: Constant.Item.ExtraIndex,7860 index: Constant.Item.ExtraIndex,
7811) struct { data: T, end: Constant.Item.ExtraIndex } {7861) struct { data: T, trail: ConstantExtraDataTrail } {
7812 var result: T = undefined;7862 var result: T = undefined;
7813 const fields = @typeInfo(T).Struct.fields;7863 const fields = @typeInfo(T).Struct.fields;
7814 inline for (fields, self.constant_extra.items[index..][0..fields.len]) |field, value|7864 inline for (fields, self.constant_extra.items[index..][0..fields.len]) |field, value|
...@@ -7818,7 +7868,10 @@ fn constantExtraDataTrail(...@@ -7818,7 +7868,10 @@ fn constantExtraDataTrail(
7818 Constant.GetElementPtr.Info => @bitCast(value),7868 Constant.GetElementPtr.Info => @bitCast(value),
7819 else => @compileError("bad field type: " ++ @typeName(field.type)),7869 else => @compileError("bad field type: " ++ @typeName(field.type)),
7820 };7870 };
7821 return .{ .data = result, .end = index + @as(Constant.Item.ExtraIndex, @intCast(fields.len)) };7871 return .{
7872 .data = result,
7873 .trail = .{ .index = index + @as(Constant.Item.ExtraIndex, @intCast(fields.len)) },
7874 };
7822}7875}
78237876
7824fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Item.ExtraIndex) T {7877fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Item.ExtraIndex) T {