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) {
311311 .function,
312312 .vararg_function,
313313 => {
314 const extra = builder.typeExtraDataTrail(Type.Function, item.data);
315 return @ptrCast(builder.type_extra.items[extra.end..][0..extra.data.params_len]);
314 var extra = builder.typeExtraDataTrail(Type.Function, item.data);
315 return extra.trail.next(extra.data.params_len, Type, builder);
316316 },
317317 else => unreachable,
318318 }
......@@ -519,8 +519,8 @@ pub const Type = enum(u32) {
519519 .structure,
520520 .packed_structure,
521521 => {
522 const extra = builder.typeExtraDataTrail(Type.Structure, item.data);
523 return @ptrCast(builder.type_extra.items[extra.end..][0..extra.data.fields_len]);
522 var extra = builder.typeExtraDataTrail(Type.Structure, item.data);
523 return extra.trail.next(extra.data.fields_len, Type, builder);
524524 },
525525 .named_structure => return builder.typeExtraData(Type.NamedStructure, item.data).body
526526 .structFields(builder),
......@@ -539,9 +539,8 @@ pub const Type = enum(u32) {
539539 .structure,
540540 .packed_structure,
541541 => {
542 const extra = builder.typeExtraDataTrail(Type.Structure, item.data);
543 const fields: []const Type =
544 @ptrCast(builder.type_extra.items[extra.end..][0..extra.data.fields_len]);
542 var extra = builder.typeExtraDataTrail(Type.Structure, item.data);
543 const fields = extra.trail.next(extra.data.fields_len, Type, builder);
545544 return fields[indices[0]].childTypeAt(indices[1..], builder);
546545 },
547546 .named_structure => builder.typeExtraData(Type.NamedStructure, item.data).body
......@@ -590,9 +589,8 @@ pub const Type = enum(u32) {
590589 .metadata => "Metadata",
591590 }),
592591 .function, .vararg_function => |kind| {
593 const extra = data.builder.typeExtraDataTrail(Type.Function, item.data);
594 const params: []const Type =
595 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.params_len]);
592 var extra = data.builder.typeExtraDataTrail(Type.Function, item.data);
593 const params = extra.trail.next(extra.data.params_len, Type, data.builder);
596594 try writer.print("f_{m}", .{extra.data.ret.fmt(data.builder)});
597595 for (params) |param| try writer.print("{m}", .{param.fmt(data.builder)});
598596 switch (kind) {
......@@ -605,11 +603,9 @@ pub const Type = enum(u32) {
605603 .integer => try writer.print("i{d}", .{item.data}),
606604 .pointer => try writer.print("p{d}", .{item.data}),
607605 .target => {
608 const extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
609 const types: []const Type =
610 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.types_len]);
611 const ints: []const u32 = @ptrCast(data.builder.type_extra.items[extra.end +
612 extra.data.types_len ..][0..extra.data.ints_len]);
606 var extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
607 const types = extra.trail.next(extra.data.types_len, Type, data.builder);
608 const ints = extra.trail.next(extra.data.ints_len, u32, data.builder);
613609 try writer.print("t{s}", .{extra.data.name.toSlice(data.builder).?});
614610 for (types) |ty| try writer.print("_{m}", .{ty.fmt(data.builder)});
615611 for (ints) |int| try writer.print("_{d}", .{int});
......@@ -636,9 +632,8 @@ pub const Type = enum(u32) {
636632 try writer.print("a{d}{m}", .{ extra.length(), extra.child.fmt(data.builder) });
637633 },
638634 .structure, .packed_structure => {
639 const extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);
640 const fields: []const Type =
641 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.fields_len]);
635 var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);
636 const fields = extra.trail.next(extra.data.fields_len, Type, data.builder);
642637 try writer.writeAll("sl_");
643638 for (fields) |field| try writer.print("{m}", .{field.fmt(data.builder)});
644639 try writer.writeByte('s');
......@@ -656,9 +651,8 @@ pub const Type = enum(u32) {
656651 switch (item.tag) {
657652 .simple => unreachable,
658653 .function, .vararg_function => |kind| {
659 const extra = data.builder.typeExtraDataTrail(Type.Function, item.data);
660 const params: []const Type =
661 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.params_len]);
654 var extra = data.builder.typeExtraDataTrail(Type.Function, item.data);
655 const params = extra.trail.next(extra.data.params_len, Type, data.builder);
662656 if (!comptime std.mem.eql(u8, fmt_str, ">"))
663657 try writer.print("{%} ", .{extra.data.ret.fmt(data.builder)});
664658 if (!comptime std.mem.eql(u8, fmt_str, "<")) {
......@@ -681,11 +675,9 @@ pub const Type = enum(u32) {
681675 .integer => try writer.print("i{d}", .{item.data}),
682676 .pointer => try writer.print("ptr{}", .{@as(AddrSpace, @enumFromInt(item.data))}),
683677 .target => {
684 const extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
685 const types: []const Type =
686 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.types_len]);
687 const ints: []const u32 = @ptrCast(data.builder.type_extra.items[extra.end +
688 extra.data.types_len ..][0..extra.data.ints_len]);
678 var extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
679 const types = extra.trail.next(extra.data.types_len, Type, data.builder);
680 const ints = extra.trail.next(extra.data.ints_len, u32, data.builder);
689681 try writer.print(
690682 \\target({"}
691683 , .{extra.data.name.fmt(data.builder)});
......@@ -714,9 +706,8 @@ pub const Type = enum(u32) {
714706 try writer.print("[{d} x {%}]", .{ extra.length(), extra.child.fmt(data.builder) });
715707 },
716708 .structure, .packed_structure => |kind| {
717 const extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);
718 const fields: []const Type =
719 @ptrCast(data.builder.type_extra.items[extra.end..][0..extra.data.fields_len]);
709 var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data);
710 const fields = extra.trail.next(extra.data.fields_len, Type, data.builder);
720711 switch (kind) {
721712 .structure => {},
722713 .packed_structure => try writer.writeByte('<'),
......@@ -812,10 +803,8 @@ pub const Type = enum(u32) {
812803 => {
813804 if (try visited.fetchPut(builder.gpa, self, {})) |_| return false;
814805
815 const extra = builder.typeExtraDataTrail(Type.Structure, item.data);
816 const fields: []const Type = @ptrCast(
817 builder.type_extra.items[extra.end..][0..extra.data.fields_len],
818 );
806 var extra = builder.typeExtraDataTrail(Type.Structure, item.data);
807 const fields = extra.trail.next(extra.data.fields_len, Type, builder);
819808 for (fields) |field| {
820809 if (field.isVector(builder) and field.vectorKind(builder) == .scalable)
821810 return false;
......@@ -1639,9 +1628,8 @@ pub const Function = struct {
16391628 .extractelement => wip.extraData(ExtractElement, instruction.data)
16401629 .val.typeOfWip(wip).childType(wip.builder),
16411630 .extractvalue => {
1642 const extra = wip.extraDataTrail(ExtractValue, instruction.data);
1643 const indices: []const u32 =
1644 wip.extra.items[extra.end..][0..extra.data.indices_len];
1631 var extra = wip.extraDataTrail(ExtractValue, instruction.data);
1632 const indices = extra.trail.next(extra.data.indices_len, u32, wip);
16451633 return extra.data.val.typeOfWip(wip).childTypeAt(indices, wip.builder);
16461634 },
16471635 .@"fcmp false",
......@@ -1694,9 +1682,8 @@ pub const Function = struct {
16941682 .getelementptr,
16951683 .@"getelementptr inbounds",
16961684 => {
1697 const extra = wip.extraDataTrail(GetElementPtr, instruction.data);
1698 const indices: []const Value =
1699 @ptrCast(wip.extra.items[extra.end..][0..extra.data.indices_len]);
1685 var extra = wip.extraDataTrail(GetElementPtr, instruction.data);
1686 const indices = extra.trail.next(extra.data.indices_len, Value, wip);
17001687 const base_ty = extra.data.base.typeOfWip(wip);
17011688 if (!base_ty.isVector(wip.builder)) for (indices) |index| {
17021689 const index_ty = index.typeOfWip(wip);
......@@ -1829,9 +1816,8 @@ pub const Function = struct {
18291816 .extractelement => function.extraData(ExtractElement, instruction.data)
18301817 .val.typeOf(function_index, builder).childType(builder),
18311818 .extractvalue => {
1832 const extra = function.extraDataTrail(ExtractValue, instruction.data);
1833 const indices: []const u32 =
1834 function.extra[extra.end..][0..extra.data.indices_len];
1819 var extra = function.extraDataTrail(ExtractValue, instruction.data);
1820 const indices = extra.trail.next(extra.data.indices_len, u32, function);
18351821 return extra.data.val.typeOf(function_index, builder)
18361822 .childTypeAt(indices, builder);
18371823 },
......@@ -1885,9 +1871,8 @@ pub const Function = struct {
18851871 .getelementptr,
18861872 .@"getelementptr inbounds",
18871873 => {
1888 const extra = function.extraDataTrail(GetElementPtr, instruction.data);
1889 const indices: []const Value =
1890 @ptrCast(function.extra[extra.end..][0..extra.data.indices_len]);
1874 var extra = function.extraDataTrail(GetElementPtr, instruction.data);
1875 const indices = extra.trail.next(extra.data.indices_len, Value, function);
18911876 const base_ty = extra.data.base.typeOf(function_index, builder);
18921877 if (!base_ty.isVector(builder)) for (indices) |index| {
18931878 const index_ty = index.typeOf(function_index, builder);
......@@ -1908,10 +1893,9 @@ pub const Function = struct {
19081893 .phi,
19091894 .@"phi fast",
19101895 => {
1911 const extra = function.extraDataTrail(Phi, instruction.data);
1912 const incoming_vals: []const Value =
1913 @ptrCast(function.extra[extra.end..][0..extra.data.incoming_len]);
1914 return incoming_vals[0].typeOf(function_index, builder);
1896 var extra = function.extraDataTrail(Phi, instruction.data);
1897 const vals = extra.trail.next(extra.data.incoming_len, Value, function);
1898 return vals[0].typeOf(function_index, builder);
19151899 },
19161900 .select,
19171901 .@"select fast",
......@@ -2112,11 +2096,32 @@ pub const Function = struct {
21122096 return argument_index.toValue();
21132097 }
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
21152120 fn extraDataTrail(
21162121 self: *const Function,
21172122 comptime T: type,
21182123 index: Instruction.ExtraIndex,
2119 ) struct { data: T, end: Instruction.ExtraIndex } {
2124 ) struct { data: T, trail: ExtraDataTrail } {
21202125 var result: T = undefined;
21212126 const fields = @typeInfo(T).Struct.fields;
21222127 inline for (fields, self.extra[index..][0..fields.len]) |field, value|
......@@ -2126,7 +2131,10 @@ pub const Function = struct {
21262131 MemoryAccessInfo, Instruction.Alloca.Info => @bitCast(value),
21272132 else => @compileError("bad field type: " ++ @typeName(field.type)),
21282133 };
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 };
21302138 }
21312139
21322140 fn extraData(self: *const Function, comptime T: type, index: Instruction.ExtraIndex) T {
......@@ -2315,14 +2323,10 @@ pub const WipFunction = struct {
23152323 wip: *WipFunction,
23162324 ) Allocator.Error!void {
23172325 const instruction = wip.instructions.get(@intFromEnum(self.instruction));
2318 const 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]);
2326 var extra = wip.extraDataTrail(Instruction.Switch, instruction.data);
23232327 assert(val.typeOf(wip.builder) == extra.data.val.typeOfWip(wip));
2324 case_vals[self.index] = val;
2325 case_dests[self.index] = dest;
2328 extra.trail.nextMut(extra.data.cases_len, Constant, wip)[self.index] = val;
2329 extra.trail.nextMut(extra.data.cases_len, Block.Index, wip)[self.index] = dest;
23262330 self.index += 1;
23272331 dest.ptr(wip).branches += 1;
23282332 if (wip.builder.useLibLlvm())
......@@ -3113,13 +3117,10 @@ pub const WipFunction = struct {
31133117 const incoming_len = self.block.ptrConst(wip).incoming;
31143118 assert(vals.len == incoming_len and blocks.len == incoming_len);
31153119 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);
31173121 for (vals) |val| assert(val.typeOfWip(wip) == extra.data.type);
3118 const incoming_vals: []Value = @ptrCast(wip.extra.items[extra.end..][0..incoming_len]);
3119 const incoming_blocks: []Block.Index =
3120 @ptrCast(wip.extra.items[extra.end + incoming_len ..][0..incoming_len]);
3121 @memcpy(incoming_vals, vals);
3122 @memcpy(incoming_blocks, blocks);
3122 @memcpy(extra.trail.nextMut(incoming_len, Value, wip), vals);
3123 @memcpy(extra.trail.nextMut(incoming_len, Block.Index, wip), blocks);
31233124 if (wip.builder.useLibLlvm()) {
31243125 const ExpectedContents = extern struct {
31253126 [expected_incoming_len]*llvm.Value,
......@@ -3504,9 +3505,8 @@ pub const WipFunction = struct {
35043505 });
35053506 },
35063507 .extractvalue => {
3507 const extra = self.extraDataTrail(Instruction.ExtractValue, instruction.data);
3508 const indices: []const u32 =
3509 self.extra.items[extra.end..][0..extra.data.indices_len];
3508 var extra = self.extraDataTrail(Instruction.ExtractValue, instruction.data);
3509 const indices = extra.trail.next(extra.data.indices_len, u32, self);
35103510 instruction.data = wip_extra.addExtra(Instruction.ExtractValue{
35113511 .val = instructions.map(extra.data.val),
35123512 .indices_len = extra.data.indices_len,
......@@ -3520,9 +3520,8 @@ pub const WipFunction = struct {
35203520 .getelementptr,
35213521 .@"getelementptr inbounds",
35223522 => {
3523 const extra = self.extraDataTrail(Instruction.GetElementPtr, instruction.data);
3524 const indices: []const Value =
3525 @ptrCast(self.extra.items[extra.end..][0..extra.data.indices_len]);
3523 var extra = self.extraDataTrail(Instruction.GetElementPtr, instruction.data);
3524 const indices = extra.trail.next(extra.data.indices_len, Value, self);
35263525 instruction.data = wip_extra.addExtra(Instruction.GetElementPtr{
35273526 .type = extra.data.type,
35283527 .base = instructions.map(extra.data.base),
......@@ -3539,9 +3538,8 @@ pub const WipFunction = struct {
35393538 });
35403539 },
35413540 .insertvalue => {
3542 const extra = self.extraDataTrail(Instruction.InsertValue, instruction.data);
3543 const indices: []const u32 =
3544 self.extra.items[extra.end..][0..extra.data.indices_len];
3541 var extra = self.extraDataTrail(Instruction.InsertValue, instruction.data);
3542 const indices = extra.trail.next(extra.data.indices_len, u32, self);
35453543 instruction.data = wip_extra.addExtra(Instruction.InsertValue{
35463544 .val = instructions.map(extra.data.val),
35473545 .elem = instructions.map(extra.data.elem),
......@@ -3564,12 +3562,10 @@ pub const WipFunction = struct {
35643562 .phi,
35653563 .@"phi fast",
35663564 => {
3567 const extra = self.extraDataTrail(Instruction.WipPhi, instruction.data);
35683565 const incoming_len = current_block.incoming;
3569 const incoming_vals: []const Value =
3570 @ptrCast(self.extra.items[extra.end..][0..incoming_len]);
3571 const incoming_blocks: []const Block.Index =
3572 @ptrCast(self.extra.items[extra.end + incoming_len ..][0..incoming_len]);
3566 var extra = self.extraDataTrail(Instruction.WipPhi, instruction.data);
3567 const incoming_vals = extra.trail.next(incoming_len, Value, self);
3568 const incoming_blocks = extra.trail.next(incoming_len, Block.Index, self);
35733569 instruction.data = wip_extra.addExtra(Instruction.Phi{
35743570 .incoming_len = incoming_len,
35753571 });
......@@ -3607,11 +3603,9 @@ pub const WipFunction = struct {
36073603 });
36083604 },
36093605 .@"switch" => {
3610 const extra = self.extraDataTrail(Instruction.Switch, instruction.data);
3611 const case_vals: []const Constant =
3612 @ptrCast(self.extra.items[extra.end..][0..extra.data.cases_len]);
3613 const case_blocks: []const Block.Index = @ptrCast(self.extra
3614 .items[extra.end + extra.data.cases_len ..][0..extra.data.cases_len]);
3606 var extra = self.extraDataTrail(Instruction.Switch, instruction.data);
3607 const case_vals = extra.trail.next(extra.data.cases_len, Constant, self);
3608 const case_blocks = extra.trail.next(extra.data.cases_len, Block.Index, self);
36153609 instruction.data = wip_extra.addExtra(Instruction.Switch{
36163610 .val = instructions.map(extra.data.val),
36173611 .default = extra.data.default,
......@@ -3956,11 +3950,32 @@ pub const WipFunction = struct {
39563950 return result;
39573951 }
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
39593974 fn extraDataTrail(
39603975 self: *const WipFunction,
39613976 comptime T: type,
39623977 index: Instruction.ExtraIndex,
3963 ) struct { data: T, end: Instruction.ExtraIndex } {
3978 ) struct { data: T, trail: ExtraDataTrail } {
39643979 var result: T = undefined;
39653980 const fields = @typeInfo(T).Struct.fields;
39663981 inline for (fields, self.extra.items[index..][0..fields.len]) |field, value|
......@@ -3970,7 +3985,10 @@ pub const WipFunction = struct {
39703985 MemoryAccessInfo, Instruction.Alloca.Info => @bitCast(value),
39713986 else => @compileError("bad field type: " ++ @typeName(field.type)),
39723987 };
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 };
39743992 }
39753993
39763994 fn extraData(self: *const WipFunction, comptime T: type, index: Instruction.ExtraIndex) T {
......@@ -4315,9 +4333,9 @@ pub const Constant = enum(u32) {
43154333 .getelementptr,
43164334 .@"getelementptr inbounds",
43174335 => {
4318 const extra = builder.constantExtraDataTrail(GetElementPtr, item.data);
4319 const indices: []const Constant = @ptrCast(builder.constant_extra
4320 .items[extra.end..][0..extra.data.info.indices_len]);
4336 var extra = builder.constantExtraDataTrail(GetElementPtr, item.data);
4337 const indices =
4338 extra.trail.next(extra.data.info.indices_len, Constant, builder);
43214339 const base_ty = extra.data.base.typeOf(builder);
43224340 if (!base_ty.isVector(builder)) for (indices) |index| {
43234341 const index_ty = index.typeOf(builder);
......@@ -4392,10 +4410,9 @@ pub const Constant = enum(u32) {
43924410 return extra.lo_lo == 0 and extra.lo_hi == 0 and extra.hi == 0;
43934411 },
43944412 .vector => {
4395 const extra = builder.constantExtraDataTrail(Aggregate, item.data);
4396 const len = extra.data.type.aggregateLen(builder);
4397 const vals: []const Constant =
4398 @ptrCast(builder.constant_extra.items[extra.end..][0..len]);
4413 var extra = builder.constantExtraDataTrail(Aggregate, item.data);
4414 const len: u32 = @intCast(extra.data.type.aggregateLen(builder));
4415 const vals = extra.trail.next(len, Constant, builder);
43994416 for (vals) |val| if (!val.isZeroInit(builder)) return false;
44004417 return true;
44014418 },
......@@ -4549,10 +4566,9 @@ pub const Constant = enum(u32) {
45494566 .array,
45504567 .vector,
45514568 => |tag| {
4552 const extra = data.builder.constantExtraDataTrail(Aggregate, item.data);
4553 const len = extra.data.type.aggregateLen(data.builder);
4554 const vals: []const Constant =
4555 @ptrCast(data.builder.constant_extra.items[extra.end..][0..len]);
4569 var extra = data.builder.constantExtraDataTrail(Aggregate, item.data);
4570 const len: u32 = @intCast(extra.data.type.aggregateLen(data.builder));
4571 const vals = extra.trail.next(len, Constant, data.builder);
45564572 try writer.writeAll(switch (tag) {
45574573 .structure => "{ ",
45584574 .packed_structure => "<{ ",
......@@ -4631,9 +4647,9 @@ pub const Constant = enum(u32) {
46314647 .getelementptr,
46324648 .@"getelementptr inbounds",
46334649 => |tag| {
4634 const extra = data.builder.constantExtraDataTrail(GetElementPtr, item.data);
4635 const indices: []const Constant = @ptrCast(data.builder.constant_extra
4636 .items[extra.end..][0..extra.data.info.indices_len]);
4650 var extra = data.builder.constantExtraDataTrail(GetElementPtr, item.data);
4651 const indices =
4652 extra.trail.next(extra.data.info.indices_len, Constant, data.builder);
46374653 try writer.print("{s} ({%}, {%}", .{
46384654 @tagName(tag),
46394655 extra.data.type.fmt(data.builder),
......@@ -5243,9 +5259,8 @@ pub fn namedTypeSetBody(
52435259 @intFromEnum(body_type);
52445260 if (self.useLibLlvm()) {
52455261 const body_item = self.type_items.items[@intFromEnum(body_type)];
5246 const body_extra = self.typeExtraDataTrail(Type.Structure, body_item.data);
5247 const body_fields: []const Type =
5248 @ptrCast(self.type_extra.items[body_extra.end..][0..body_extra.data.fields_len]);
5262 var body_extra = self.typeExtraDataTrail(Type.Structure, body_item.data);
5263 const body_fields = body_extra.trail.next(body_extra.data.fields_len, Type, self);
52495264 const llvm_fields = try self.gpa.alloc(*llvm.Type, body_fields.len);
52505265 defer self.gpa.free(llvm_fields);
52515266 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
59475962 });
59485963 },
59495964 .extractvalue => |tag| {
5950 const extra =
5965 var extra =
59515966 function.extraDataTrail(Function.Instruction.ExtractValue, instruction.data);
5952 const indices: []const u32 =
5953 function.extra[extra.end..][0..extra.data.indices_len];
5967 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
59545968 try writer.print(" %{} = {s} {%}", .{
59555969 instruction_index.name(&function).fmt(self),
59565970 @tagName(tag),
......@@ -5976,12 +5990,11 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
59765990 .getelementptr,
59775991 .@"getelementptr inbounds",
59785992 => |tag| {
5979 const extra = function.extraDataTrail(
5993 var extra = function.extraDataTrail(
59805994 Function.Instruction.GetElementPtr,
59815995 instruction.data,
59825996 );
5983 const indices: []const Value =
5984 @ptrCast(function.extra[extra.end..][0..extra.data.indices_len]);
5997 const indices = extra.trail.next(extra.data.indices_len, Value, &function);
59855998 try writer.print(" %{} = {s} {%}, {%}", .{
59865999 instruction_index.name(&function).fmt(self),
59876000 @tagName(tag),
......@@ -6005,10 +6018,9 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
60056018 });
60066019 },
60076020 .insertvalue => |tag| {
6008 const extra =
6021 var extra =
60096022 function.extraDataTrail(Function.Instruction.InsertValue, instruction.data);
6010 const indices: []const u32 =
6011 function.extra[extra.end..][0..extra.data.indices_len];
6023 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
60126024 try writer.print(" %{} = {s} {%}, {%}", .{
60136025 instruction_index.name(&function).fmt(self),
60146026 @tagName(tag),
......@@ -6063,12 +6075,10 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
60636075 .phi,
60646076 .@"phi fast",
60656077 => |tag| {
6066 const extra =
6067 function.extraDataTrail(Function.Instruction.Phi, instruction.data);
6068 const vals: []const Value =
6069 @ptrCast(function.extra[extra.end..][0..extra.data.incoming_len]);
6070 const blocks: []const Function.Block.Index = @ptrCast(function.extra[extra.end +
6071 extra.data.incoming_len ..][0..extra.data.incoming_len]);
6078 var extra = function.extraDataTrail(Function.Instruction.Phi, instruction.data);
6079 const vals = extra.trail.next(extra.data.incoming_len, Value, &function);
6080 const blocks =
6081 extra.trail.next(extra.data.incoming_len, Function.Block.Index, &function);
60726082 try writer.print(" %{} = {s} {%} ", .{
60736083 instruction_index.name(&function).fmt(self),
60746084 @tagName(tag),
......@@ -6125,12 +6135,11 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator
61256135 });
61266136 },
61276137 .@"switch" => |tag| {
6128 const extra =
6138 var extra =
61296139 function.extraDataTrail(Function.Instruction.Switch, instruction.data);
6130 const vals: []const Constant =
6131 @ptrCast(function.extra[extra.end..][0..extra.data.cases_len]);
6132 const blocks: []const Function.Block.Index = @ptrCast(function.extra[extra.end +
6133 extra.data.cases_len ..][0..extra.data.cases_len]);
6140 const vals = extra.trail.next(extra.data.cases_len, Constant, &function);
6141 const blocks =
6142 extra.trail.next(extra.data.cases_len, Function.Block.Index, &function);
61346143 try writer.print(" {s} {%}, {%} [", .{
61356144 @tagName(tag),
61366145 extra.data.val.fmt(function_index, self),
......@@ -6216,9 +6225,8 @@ fn fnTypeAssumeCapacity(
62166225 }
62176226 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
62186227 const rhs_data = ctx.builder.type_items.items[rhs_index];
6219 const rhs_extra = ctx.builder.typeExtraDataTrail(Type.Function, rhs_data.data);
6220 const rhs_params: []const Type =
6221 @ptrCast(ctx.builder.type_extra.items[rhs_extra.end..][0..rhs_extra.data.params_len]);
6228 var rhs_extra = ctx.builder.typeExtraDataTrail(Type.Function, rhs_data.data);
6229 const rhs_params = rhs_extra.trail.next(rhs_extra.data.params_len, Type, ctx.builder);
62226230 return rhs_data.tag == tag and lhs_key.ret == rhs_extra.data.ret and
62236231 std.mem.eql(Type, lhs_key.params, rhs_params);
62246232 }
......@@ -6400,9 +6408,8 @@ fn structTypeAssumeCapacity(
64006408 }
64016409 pub fn eql(ctx: @This(), lhs_key: []const Type, _: void, rhs_index: usize) bool {
64026410 const rhs_data = ctx.builder.type_items.items[rhs_index];
6403 const rhs_extra = ctx.builder.typeExtraDataTrail(Type.Structure, rhs_data.data);
6404 const rhs_fields: []const Type =
6405 @ptrCast(ctx.builder.type_extra.items[rhs_extra.end..][0..rhs_extra.data.fields_len]);
6411 var rhs_extra = ctx.builder.typeExtraDataTrail(Type.Structure, rhs_data.data);
6412 const rhs_fields = rhs_extra.trail.next(rhs_extra.data.fields_len, Type, ctx.builder);
64066413 return rhs_data.tag == tag and std.mem.eql(Type, lhs_key, rhs_fields);
64076414 }
64086415 };
......@@ -6542,11 +6549,32 @@ fn addTypeExtraAssumeCapacity(self: *Builder, extra: anytype) Type.Item.ExtraInd
65426549 return result;
65436550}
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
65456573fn typeExtraDataTrail(
65466574 self: *const Builder,
65476575 comptime T: type,
65486576 index: Type.Item.ExtraIndex,
6549) struct { data: T, end: Type.Item.ExtraIndex } {
6577) struct { data: T, trail: TypeExtraDataTrail } {
65506578 var result: T = undefined;
65516579 const fields = @typeInfo(T).Struct.fields;
65526580 inline for (fields, self.type_extra.items[index..][0..fields.len]) |field, value|
......@@ -6555,7 +6583,10 @@ fn typeExtraDataTrail(
65556583 String, Type => @enumFromInt(value),
65566584 else => @compileError("bad field type: " ++ @typeName(field.type)),
65576585 };
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 };
65596590}
65606591
65616592fn typeExtraData(self: *const Builder, comptime T: type, index: Type.Item.ExtraIndex) T {
......@@ -6914,7 +6945,7 @@ fn structConstAssumeCapacity(
69146945 vals: []const Constant,
69156946) if (build_options.have_llvm) Allocator.Error!Constant else Constant {
69166947 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) {
69186949 .structure, .packed_structure => type_item.data,
69196950 .named_structure => data: {
69206951 const body_ty = self.typeExtraData(Type.NamedStructure, type_item.data).body;
......@@ -6926,8 +6957,7 @@ fn structConstAssumeCapacity(
69266957 },
69276958 else => unreachable,
69286959 });
6929 const fields: []const Type =
6930 @ptrCast(self.type_extra.items[extra.end..][0..extra.data.fields_len]);
6960 const fields = extra.trail.next(extra.data.fields_len, Type, self);
69316961 for (fields, vals) |field, val| assert(field == val.typeOf(self));
69326962
69336963 for (vals) |val| {
......@@ -7405,9 +7435,9 @@ fn gepConstAssumeCapacity(
74057435 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
74067436 if (ctx.builder.constant_items.items(.tag)[rhs_index] != tag) return false;
74077437 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
7408 const rhs_extra = ctx.builder.constantExtraDataTrail(Constant.GetElementPtr, rhs_data);
7409 const rhs_indices: []const Constant = @ptrCast(ctx.builder.constant_extra
7410 .items[rhs_extra.end..][0..rhs_extra.data.info.indices_len]);
7438 var rhs_extra = ctx.builder.constantExtraDataTrail(Constant.GetElementPtr, rhs_data);
7439 const rhs_indices =
7440 rhs_extra.trail.next(rhs_extra.data.info.indices_len, Constant, ctx.builder);
74117441 return lhs_key.type == rhs_extra.data.type and lhs_key.base == rhs_extra.data.base and
74127442 lhs_key.inrange == rhs_extra.data.info.inrange and
74137443 std.mem.eql(Constant, lhs_key.indices, rhs_indices);
......@@ -7767,10 +7797,9 @@ fn getOrPutConstantAggregateAssumeCapacity(
77677797 pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
77687798 if (lhs_key.tag != ctx.builder.constant_items.items(.tag)[rhs_index]) return false;
77697799 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);
77717801 if (lhs_key.type != rhs_extra.data.type) return false;
7772 const rhs_vals: []const Constant =
7773 @ptrCast(ctx.builder.constant_extra.items[rhs_extra.end..][0..lhs_key.vals.len]);
7802 const rhs_vals = rhs_extra.trail.next(@intCast(lhs_key.vals.len), Constant, ctx.builder);
77747803 return std.mem.eql(Constant, lhs_key.vals, rhs_vals);
77757804 }
77767805 };
......@@ -7804,11 +7833,32 @@ fn addConstantExtraAssumeCapacity(self: *Builder, extra: anytype) Constant.Item.
78047833 return result;
78057834}
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
78077857fn constantExtraDataTrail(
78087858 self: *const Builder,
78097859 comptime T: type,
78107860 index: Constant.Item.ExtraIndex,
7811) struct { data: T, end: Constant.Item.ExtraIndex } {
7861) struct { data: T, trail: ConstantExtraDataTrail } {
78127862 var result: T = undefined;
78137863 const fields = @typeInfo(T).Struct.fields;
78147864 inline for (fields, self.constant_extra.items[index..][0..fields.len]) |field, value|
......@@ -7818,7 +7868,10 @@ fn constantExtraDataTrail(
78187868 Constant.GetElementPtr.Info => @bitCast(value),
78197869 else => @compileError("bad field type: " ++ @typeName(field.type)),
78207870 };
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 };
78227875}
78237876
78247877fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Item.ExtraIndex) T {