| ... | ... | @@ -311,8 +311,8 @@ pub const Type = enum(u32) { |
| 311 | 311 | .function, |
| 312 | 312 | .vararg_function, |
| 313 | 313 | => { |
| 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); |
| 316 | 316 | }, |
| 317 | 317 | else => unreachable, |
| 318 | 318 | } |
| ... | ... | @@ -519,8 +519,8 @@ pub const Type = enum(u32) { |
| 519 | 519 | .structure, |
| 520 | 520 | .packed_structure, |
| 521 | 521 | => { |
| 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); |
| 524 | 524 | }, |
| 525 | 525 | .named_structure => return builder.typeExtraData(Type.NamedStructure, item.data).body |
| 526 | 526 | .structFields(builder), |
| ... | ... | @@ -539,9 +539,8 @@ pub const Type = enum(u32) { |
| 539 | 539 | .structure, |
| 540 | 540 | .packed_structure, |
| 541 | 541 | => { |
| 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); |
| 545 | 544 | return fields[indices[0]].childTypeAt(indices[1..], builder); |
| 546 | 545 | }, |
| 547 | 546 | .named_structure => builder.typeExtraData(Type.NamedStructure, item.data).body |
| ... | ... | @@ -590,9 +589,8 @@ pub const Type = enum(u32) { |
| 590 | 589 | .metadata => "Metadata", |
| 591 | 590 | }), |
| 592 | 591 | .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); |
| 596 | 594 | try writer.print("f_{m}", .{extra.data.ret.fmt(data.builder)}); |
| 597 | 595 | for (params) |param| try writer.print("{m}", .{param.fmt(data.builder)}); |
| 598 | 596 | switch (kind) { |
| ... | ... | @@ -605,11 +603,9 @@ pub const Type = enum(u32) { |
| 605 | 603 | .integer => try writer.print("i{d}", .{item.data}), |
| 606 | 604 | .pointer => try writer.print("p{d}", .{item.data}), |
| 607 | 605 | .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); |
| 613 | 609 | try writer.print("t{s}", .{extra.data.name.toSlice(data.builder).?}); |
| 614 | 610 | for (types) |ty| try writer.print("_{m}", .{ty.fmt(data.builder)}); |
| 615 | 611 | for (ints) |int| try writer.print("_{d}", .{int}); |
| ... | ... | @@ -636,9 +632,8 @@ pub const Type = enum(u32) { |
| 636 | 632 | try writer.print("a{d}{m}", .{ extra.length(), extra.child.fmt(data.builder) }); |
| 637 | 633 | }, |
| 638 | 634 | .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); |
| 642 | 637 | try writer.writeAll("sl_"); |
| 643 | 638 | for (fields) |field| try writer.print("{m}", .{field.fmt(data.builder)}); |
| 644 | 639 | try writer.writeByte('s'); |
| ... | ... | @@ -656,9 +651,8 @@ pub const Type = enum(u32) { |
| 656 | 651 | switch (item.tag) { |
| 657 | 652 | .simple => unreachable, |
| 658 | 653 | .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); |
| 662 | 656 | if (!comptime std.mem.eql(u8, fmt_str, ">")) |
| 663 | 657 | try writer.print("{%} ", .{extra.data.ret.fmt(data.builder)}); |
| 664 | 658 | if (!comptime std.mem.eql(u8, fmt_str, "<")) { |
| ... | ... | @@ -681,11 +675,9 @@ pub const Type = enum(u32) { |
| 681 | 675 | .integer => try writer.print("i{d}", .{item.data}), |
| 682 | 676 | .pointer => try writer.print("ptr{}", .{@as(AddrSpace, @enumFromInt(item.data))}), |
| 683 | 677 | .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); |
| 689 | 681 | try writer.print( |
| 690 | 682 | \\target({"} |
| 691 | 683 | , .{extra.data.name.fmt(data.builder)}); |
| ... | ... | @@ -714,9 +706,8 @@ pub const Type = enum(u32) { |
| 714 | 706 | try writer.print("[{d} x {%}]", .{ extra.length(), extra.child.fmt(data.builder) }); |
| 715 | 707 | }, |
| 716 | 708 | .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); |
| 720 | 711 | switch (kind) { |
| 721 | 712 | .structure => {}, |
| 722 | 713 | .packed_structure => try writer.writeByte('<'), |
| ... | ... | @@ -812,10 +803,8 @@ pub const Type = enum(u32) { |
| 812 | 803 | => { |
| 813 | 804 | if (try visited.fetchPut(builder.gpa, self, {})) |_| return false; |
| 814 | 805 | |
| 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); |
| 819 | 808 | for (fields) |field| { |
| 820 | 809 | if (field.isVector(builder) and field.vectorKind(builder) == .scalable) |
| 821 | 810 | return false; |
| ... | ... | @@ -1639,9 +1628,8 @@ pub const Function = struct { |
| 1639 | 1628 | .extractelement => wip.extraData(ExtractElement, instruction.data) |
| 1640 | 1629 | .val.typeOfWip(wip).childType(wip.builder), |
| 1641 | 1630 | .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); |
| 1645 | 1633 | return extra.data.val.typeOfWip(wip).childTypeAt(indices, wip.builder); |
| 1646 | 1634 | }, |
| 1647 | 1635 | .@"fcmp false", |
| ... | ... | @@ -1694,9 +1682,8 @@ pub const Function = struct { |
| 1694 | 1682 | .getelementptr, |
| 1695 | 1683 | .@"getelementptr inbounds", |
| 1696 | 1684 | => { |
| 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); |
| 1700 | 1687 | const base_ty = extra.data.base.typeOfWip(wip); |
| 1701 | 1688 | if (!base_ty.isVector(wip.builder)) for (indices) |index| { |
| 1702 | 1689 | const index_ty = index.typeOfWip(wip); |
| ... | ... | @@ -1829,9 +1816,8 @@ pub const Function = struct { |
| 1829 | 1816 | .extractelement => function.extraData(ExtractElement, instruction.data) |
| 1830 | 1817 | .val.typeOf(function_index, builder).childType(builder), |
| 1831 | 1818 | .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); |
| 1835 | 1821 | return extra.data.val.typeOf(function_index, builder) |
| 1836 | 1822 | .childTypeAt(indices, builder); |
| 1837 | 1823 | }, |
| ... | ... | @@ -1885,9 +1871,8 @@ pub const Function = struct { |
| 1885 | 1871 | .getelementptr, |
| 1886 | 1872 | .@"getelementptr inbounds", |
| 1887 | 1873 | => { |
| 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); |
| 1891 | 1876 | const base_ty = extra.data.base.typeOf(function_index, builder); |
| 1892 | 1877 | if (!base_ty.isVector(builder)) for (indices) |index| { |
| 1893 | 1878 | const index_ty = index.typeOf(function_index, builder); |
| ... | ... | @@ -1908,10 +1893,9 @@ pub const Function = struct { |
| 1908 | 1893 | .phi, |
| 1909 | 1894 | .@"phi fast", |
| 1910 | 1895 | => { |
| 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); |
| 1915 | 1899 | }, |
| 1916 | 1900 | .select, |
| 1917 | 1901 | .@"select fast", |
| ... | ... | @@ -2112,11 +2096,32 @@ pub const Function = struct { |
| 2112 | 2096 | return argument_index.toValue(); |
| 2113 | 2097 | } |
| 2114 | 2098 | |
| 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 | 2120 | fn extraDataTrail( |
| 2116 | 2121 | self: *const Function, |
| 2117 | 2122 | comptime T: type, |
| 2118 | 2123 | index: Instruction.ExtraIndex, |
| 2119 | | ) struct { data: T, end: Instruction.ExtraIndex } { |
| 2124 | ) struct { data: T, trail: ExtraDataTrail } { |
| 2120 | 2125 | var result: T = undefined; |
| 2121 | 2126 | const fields = @typeInfo(T).Struct.fields; |
| 2122 | 2127 | inline for (fields, self.extra[index..][0..fields.len]) |field, value| |
| ... | ... | @@ -2126,7 +2131,10 @@ pub const Function = struct { |
| 2126 | 2131 | MemoryAccessInfo, Instruction.Alloca.Info => @bitCast(value), |
| 2127 | 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 | } |
| 2131 | 2139 | |
| 2132 | 2140 | fn extraData(self: *const Function, comptime T: type, index: Instruction.ExtraIndex) T { |
| ... | ... | @@ -2315,14 +2323,10 @@ pub const WipFunction = struct { |
| 2315 | 2323 | wip: *WipFunction, |
| 2316 | 2324 | ) Allocator.Error!void { |
| 2317 | 2325 | 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); |
| 2323 | 2327 | 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; |
| 2326 | 2330 | self.index += 1; |
| 2327 | 2331 | dest.ptr(wip).branches += 1; |
| 2328 | 2332 | if (wip.builder.useLibLlvm()) |
| ... | ... | @@ -3113,13 +3117,10 @@ pub const WipFunction = struct { |
| 3113 | 3117 | const incoming_len = self.block.ptrConst(wip).incoming; |
| 3114 | 3118 | assert(vals.len == incoming_len and blocks.len == incoming_len); |
| 3115 | 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 | 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]); |
| 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); |
| 3123 | 3124 | if (wip.builder.useLibLlvm()) { |
| 3124 | 3125 | const ExpectedContents = extern struct { |
| 3125 | 3126 | [expected_incoming_len]*llvm.Value, |
| ... | ... | @@ -3504,9 +3505,8 @@ pub const WipFunction = struct { |
| 3504 | 3505 | }); |
| 3505 | 3506 | }, |
| 3506 | 3507 | .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); |
| 3510 | 3510 | instruction.data = wip_extra.addExtra(Instruction.ExtractValue{ |
| 3511 | 3511 | .val = instructions.map(extra.data.val), |
| 3512 | 3512 | .indices_len = extra.data.indices_len, |
| ... | ... | @@ -3520,9 +3520,8 @@ pub const WipFunction = struct { |
| 3520 | 3520 | .getelementptr, |
| 3521 | 3521 | .@"getelementptr inbounds", |
| 3522 | 3522 | => { |
| 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); |
| 3526 | 3525 | instruction.data = wip_extra.addExtra(Instruction.GetElementPtr{ |
| 3527 | 3526 | .type = extra.data.type, |
| 3528 | 3527 | .base = instructions.map(extra.data.base), |
| ... | ... | @@ -3539,9 +3538,8 @@ pub const WipFunction = struct { |
| 3539 | 3538 | }); |
| 3540 | 3539 | }, |
| 3541 | 3540 | .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); |
| 3545 | 3543 | instruction.data = wip_extra.addExtra(Instruction.InsertValue{ |
| 3546 | 3544 | .val = instructions.map(extra.data.val), |
| 3547 | 3545 | .elem = instructions.map(extra.data.elem), |
| ... | ... | @@ -3564,12 +3562,10 @@ pub const WipFunction = struct { |
| 3564 | 3562 | .phi, |
| 3565 | 3563 | .@"phi fast", |
| 3566 | 3564 | => { |
| 3567 | | const extra = self.extraDataTrail(Instruction.WipPhi, instruction.data); |
| 3568 | 3565 | 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); |
| 3573 | 3569 | instruction.data = wip_extra.addExtra(Instruction.Phi{ |
| 3574 | 3570 | .incoming_len = incoming_len, |
| 3575 | 3571 | }); |
| ... | ... | @@ -3607,11 +3603,9 @@ pub const WipFunction = struct { |
| 3607 | 3603 | }); |
| 3608 | 3604 | }, |
| 3609 | 3605 | .@"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); |
| 3615 | 3609 | instruction.data = wip_extra.addExtra(Instruction.Switch{ |
| 3616 | 3610 | .val = instructions.map(extra.data.val), |
| 3617 | 3611 | .default = extra.data.default, |
| ... | ... | @@ -3956,11 +3950,32 @@ pub const WipFunction = struct { |
| 3956 | 3950 | return result; |
| 3957 | 3951 | } |
| 3958 | 3952 | |
| 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 | 3974 | fn extraDataTrail( |
| 3960 | 3975 | self: *const WipFunction, |
| 3961 | 3976 | comptime T: type, |
| 3962 | 3977 | index: Instruction.ExtraIndex, |
| 3963 | | ) struct { data: T, end: Instruction.ExtraIndex } { |
| 3978 | ) struct { data: T, trail: ExtraDataTrail } { |
| 3964 | 3979 | var result: T = undefined; |
| 3965 | 3980 | const fields = @typeInfo(T).Struct.fields; |
| 3966 | 3981 | inline for (fields, self.extra.items[index..][0..fields.len]) |field, value| |
| ... | ... | @@ -3970,7 +3985,10 @@ pub const WipFunction = struct { |
| 3970 | 3985 | MemoryAccessInfo, Instruction.Alloca.Info => @bitCast(value), |
| 3971 | 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 | } |
| 3975 | 3993 | |
| 3976 | 3994 | fn extraData(self: *const WipFunction, comptime T: type, index: Instruction.ExtraIndex) T { |
| ... | ... | @@ -4315,9 +4333,9 @@ pub const Constant = enum(u32) { |
| 4315 | 4333 | .getelementptr, |
| 4316 | 4334 | .@"getelementptr inbounds", |
| 4317 | 4335 | => { |
| 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); |
| 4321 | 4339 | const base_ty = extra.data.base.typeOf(builder); |
| 4322 | 4340 | if (!base_ty.isVector(builder)) for (indices) |index| { |
| 4323 | 4341 | const index_ty = index.typeOf(builder); |
| ... | ... | @@ -4392,10 +4410,9 @@ pub const Constant = enum(u32) { |
| 4392 | 4410 | return extra.lo_lo == 0 and extra.lo_hi == 0 and extra.hi == 0; |
| 4393 | 4411 | }, |
| 4394 | 4412 | .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); |
| 4399 | 4416 | for (vals) |val| if (!val.isZeroInit(builder)) return false; |
| 4400 | 4417 | return true; |
| 4401 | 4418 | }, |
| ... | ... | @@ -4549,10 +4566,9 @@ pub const Constant = enum(u32) { |
| 4549 | 4566 | .array, |
| 4550 | 4567 | .vector, |
| 4551 | 4568 | => |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); |
| 4556 | 4572 | try writer.writeAll(switch (tag) { |
| 4557 | 4573 | .structure => "{ ", |
| 4558 | 4574 | .packed_structure => "<{ ", |
| ... | ... | @@ -4631,9 +4647,9 @@ pub const Constant = enum(u32) { |
| 4631 | 4647 | .getelementptr, |
| 4632 | 4648 | .@"getelementptr inbounds", |
| 4633 | 4649 | => |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); |
| 4637 | 4653 | try writer.print("{s} ({%}, {%}", .{ |
| 4638 | 4654 | @tagName(tag), |
| 4639 | 4655 | extra.data.type.fmt(data.builder), |
| ... | ... | @@ -5243,9 +5259,8 @@ pub fn namedTypeSetBody( |
| 5243 | 5259 | @intFromEnum(body_type); |
| 5244 | 5260 | if (self.useLibLlvm()) { |
| 5245 | 5261 | 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); |
| 5249 | 5264 | const llvm_fields = try self.gpa.alloc(*llvm.Type, body_fields.len); |
| 5250 | 5265 | defer self.gpa.free(llvm_fields); |
| 5251 | 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 | 5962 | }); |
| 5948 | 5963 | }, |
| 5949 | 5964 | .extractvalue => |tag| { |
| 5950 | | const extra = |
| 5965 | var extra = |
| 5951 | 5966 | 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); |
| 5954 | 5968 | try writer.print(" %{} = {s} {%}", .{ |
| 5955 | 5969 | instruction_index.name(&function).fmt(self), |
| 5956 | 5970 | @tagName(tag), |
| ... | ... | @@ -5976,12 +5990,11 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator |
| 5976 | 5990 | .getelementptr, |
| 5977 | 5991 | .@"getelementptr inbounds", |
| 5978 | 5992 | => |tag| { |
| 5979 | | const extra = function.extraDataTrail( |
| 5993 | var extra = function.extraDataTrail( |
| 5980 | 5994 | Function.Instruction.GetElementPtr, |
| 5981 | 5995 | instruction.data, |
| 5982 | 5996 | ); |
| 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); |
| 5985 | 5998 | try writer.print(" %{} = {s} {%}, {%}", .{ |
| 5986 | 5999 | instruction_index.name(&function).fmt(self), |
| 5987 | 6000 | @tagName(tag), |
| ... | ... | @@ -6005,10 +6018,9 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator |
| 6005 | 6018 | }); |
| 6006 | 6019 | }, |
| 6007 | 6020 | .insertvalue => |tag| { |
| 6008 | | const extra = |
| 6021 | var extra = |
| 6009 | 6022 | 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); |
| 6012 | 6024 | try writer.print(" %{} = {s} {%}, {%}", .{ |
| 6013 | 6025 | instruction_index.name(&function).fmt(self), |
| 6014 | 6026 | @tagName(tag), |
| ... | ... | @@ -6063,12 +6075,10 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator |
| 6063 | 6075 | .phi, |
| 6064 | 6076 | .@"phi fast", |
| 6065 | 6077 | => |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); |
| 6072 | 6082 | try writer.print(" %{} = {s} {%} ", .{ |
| 6073 | 6083 | instruction_index.name(&function).fmt(self), |
| 6074 | 6084 | @tagName(tag), |
| ... | ... | @@ -6125,12 +6135,11 @@ pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator |
| 6125 | 6135 | }); |
| 6126 | 6136 | }, |
| 6127 | 6137 | .@"switch" => |tag| { |
| 6128 | | const extra = |
| 6138 | var extra = |
| 6129 | 6139 | 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); |
| 6134 | 6143 | try writer.print(" {s} {%}, {%} [", .{ |
| 6135 | 6144 | @tagName(tag), |
| 6136 | 6145 | extra.data.val.fmt(function_index, self), |
| ... | ... | @@ -6216,9 +6225,8 @@ fn fnTypeAssumeCapacity( |
| 6216 | 6225 | } |
| 6217 | 6226 | pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { |
| 6218 | 6227 | 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); |
| 6222 | 6230 | return rhs_data.tag == tag and lhs_key.ret == rhs_extra.data.ret and |
| 6223 | 6231 | std.mem.eql(Type, lhs_key.params, rhs_params); |
| 6224 | 6232 | } |
| ... | ... | @@ -6400,9 +6408,8 @@ fn structTypeAssumeCapacity( |
| 6400 | 6408 | } |
| 6401 | 6409 | pub fn eql(ctx: @This(), lhs_key: []const Type, _: void, rhs_index: usize) bool { |
| 6402 | 6410 | 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); |
| 6406 | 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 | 6549 | return result; |
| 6543 | 6550 | } |
| 6544 | 6551 | |
| 6552 | const 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 | |
| 6545 | 6573 | fn typeExtraDataTrail( |
| 6546 | 6574 | self: *const Builder, |
| 6547 | 6575 | comptime T: type, |
| 6548 | 6576 | index: Type.Item.ExtraIndex, |
| 6549 | | ) struct { data: T, end: Type.Item.ExtraIndex } { |
| 6577 | ) struct { data: T, trail: TypeExtraDataTrail } { |
| 6550 | 6578 | var result: T = undefined; |
| 6551 | 6579 | const fields = @typeInfo(T).Struct.fields; |
| 6552 | 6580 | inline for (fields, self.type_extra.items[index..][0..fields.len]) |field, value| |
| ... | ... | @@ -6555,7 +6583,10 @@ fn typeExtraDataTrail( |
| 6555 | 6583 | String, Type => @enumFromInt(value), |
| 6556 | 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 | } |
| 6560 | 6591 | |
| 6561 | 6592 | fn typeExtraData(self: *const Builder, comptime T: type, index: Type.Item.ExtraIndex) T { |
| ... | ... | @@ -6914,7 +6945,7 @@ fn structConstAssumeCapacity( |
| 6914 | 6945 | vals: []const Constant, |
| 6915 | 6946 | ) if (build_options.have_llvm) Allocator.Error!Constant else Constant { |
| 6916 | 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 | 6949 | .structure, .packed_structure => type_item.data, |
| 6919 | 6950 | .named_structure => data: { |
| 6920 | 6951 | const body_ty = self.typeExtraData(Type.NamedStructure, type_item.data).body; |
| ... | ... | @@ -6926,8 +6957,7 @@ fn structConstAssumeCapacity( |
| 6926 | 6957 | }, |
| 6927 | 6958 | else => unreachable, |
| 6928 | 6959 | }); |
| 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); |
| 6931 | 6961 | for (fields, vals) |field, val| assert(field == val.typeOf(self)); |
| 6932 | 6962 | |
| 6933 | 6963 | for (vals) |val| { |
| ... | ... | @@ -7405,9 +7435,9 @@ fn gepConstAssumeCapacity( |
| 7405 | 7435 | pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { |
| 7406 | 7436 | if (ctx.builder.constant_items.items(.tag)[rhs_index] != tag) return false; |
| 7407 | 7437 | 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); |
| 7411 | 7441 | return lhs_key.type == rhs_extra.data.type and lhs_key.base == rhs_extra.data.base and |
| 7412 | 7442 | lhs_key.inrange == rhs_extra.data.info.inrange and |
| 7413 | 7443 | std.mem.eql(Constant, lhs_key.indices, rhs_indices); |
| ... | ... | @@ -7767,10 +7797,9 @@ fn getOrPutConstantAggregateAssumeCapacity( |
| 7767 | 7797 | pub fn eql(ctx: @This(), lhs_key: Key, _: void, rhs_index: usize) bool { |
| 7768 | 7798 | if (lhs_key.tag != ctx.builder.constant_items.items(.tag)[rhs_index]) return false; |
| 7769 | 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 | 7801 | 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); |
| 7774 | 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 | 7833 | return result; |
| 7805 | 7834 | } |
| 7806 | 7835 | |
| 7836 | const 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 | |
| 7807 | 7857 | fn constantExtraDataTrail( |
| 7808 | 7858 | self: *const Builder, |
| 7809 | 7859 | comptime T: type, |
| 7810 | 7860 | index: Constant.Item.ExtraIndex, |
| 7811 | | ) struct { data: T, end: Constant.Item.ExtraIndex } { |
| 7861 | ) struct { data: T, trail: ConstantExtraDataTrail } { |
| 7812 | 7862 | var result: T = undefined; |
| 7813 | 7863 | const fields = @typeInfo(T).Struct.fields; |
| 7814 | 7864 | inline for (fields, self.constant_extra.items[index..][0..fields.len]) |field, value| |
| ... | ... | @@ -7818,7 +7868,10 @@ fn constantExtraDataTrail( |
| 7818 | 7868 | Constant.GetElementPtr.Info => @bitCast(value), |
| 7819 | 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 | } |
| 7823 | 7876 | |
| 7824 | 7877 | fn constantExtraData(self: *const Builder, comptime T: type, index: Constant.Item.ExtraIndex) T { |