| author | |
| committer | |
| log | 82f6f164a1af6557451e580dcf3197ad94e5437e |
| tree | 6a88050cac9da741c2ae8434ef0fe2989c411ee5 |
| parent | c7d65fa3685a5f48cfedaa7a1adf758e1dc6d219 |
Key.PtrType is now an extern struct so that hashing it can be done by
reinterpreting bytes directly. It also uses the same representation for
type_pointer Tag encoding and the Key. Accessing pointer attributes now
requires packed struct access, however, many operations are now a copy
of a u32 rather than several independent fields.
This function moves the top two most used Key variants - pointer types
and pointer values - to use a single-shot hash function that branches
for small keys instead of calling memcpy.
As a result, perf against merge-base went from 1.17x ± 0.04 slower to
1.12x ± 0.04 slower. After the pointer value hashing was changed, total
CPU instructions spent in memcpy went from 4.40% to 4.08%, and after
additionally improving pointer type hashing, it further decreased to
3.72%.8 files changed, 527 insertions(+), 392 deletions(-)
src/InternPool.zig+282-202| ... | @@ -249,35 +249,47 @@ pub const Key = union(enum) { | ... | @@ -249,35 +249,47 @@ pub const Key = union(enum) { |
| 249 | } | 249 | } |
| 250 | }; | 250 | }; |
| 251 | 251 | ||
| 252 | pub const PtrType = struct { | 252 | /// Extern layout so it can be hashed with `std.mem.asBytes`. |
| 253 | elem_type: Index, | 253 | pub const PtrType = extern struct { |
| 254 | child: Index, | ||
| 254 | sentinel: Index = .none, | 255 | sentinel: Index = .none, |
| 255 | /// `none` indicates the ABI alignment of the pointee_type. In this | 256 | flags: Flags = .{}, |
| 256 | /// case, this field *must* be set to `none`, otherwise the | 257 | packed_offset: PackedOffset = .{ .bit_offset = 0, .host_size = 0 }, |
| 257 | /// `InternPool` equality and hashing functions will return incorrect | ||
| 258 | /// results. | ||
| 259 | alignment: Alignment = .none, | ||
| 260 | /// If this is non-zero it means the pointer points to a sub-byte | ||
| 261 | /// range of data, which is backed by a "host integer" with this | ||
| 262 | /// number of bytes. | ||
| 263 | /// When host_size=pointee_abi_size and bit_offset=0, this must be | ||
| 264 | /// represented with host_size=0 instead. | ||
| 265 | host_size: u16 = 0, | ||
| 266 | bit_offset: u16 = 0, | ||
| 267 | vector_index: VectorIndex = .none, | ||
| 268 | size: std.builtin.Type.Pointer.Size = .One, | ||
| 269 | is_const: bool = false, | ||
| 270 | is_volatile: bool = false, | ||
| 271 | is_allowzero: bool = false, | ||
| 272 | /// See src/target.zig defaultAddressSpace function for how to obtain | ||
| 273 | /// an appropriate value for this field. | ||
| 274 | address_space: std.builtin.AddressSpace = .generic, | ||
| 275 | 258 | ||
| 276 | pub const VectorIndex = enum(u16) { | 259 | pub const VectorIndex = enum(u16) { |
| 277 | none = std.math.maxInt(u16), | 260 | none = std.math.maxInt(u16), |
| 278 | runtime = std.math.maxInt(u16) - 1, | 261 | runtime = std.math.maxInt(u16) - 1, |
| 279 | _, | 262 | _, |
| 280 | }; | 263 | }; |
| 264 | |||
| 265 | pub const Flags = packed struct(u32) { | ||
| 266 | size: Size = .One, | ||
| 267 | /// `none` indicates the ABI alignment of the pointee_type. In this | ||
| 268 | /// case, this field *must* be set to `none`, otherwise the | ||
| 269 | /// `InternPool` equality and hashing functions will return incorrect | ||
| 270 | /// results. | ||
| 271 | alignment: Alignment = .none, | ||
| 272 | is_const: bool = false, | ||
| 273 | is_volatile: bool = false, | ||
| 274 | is_allowzero: bool = false, | ||
| 275 | /// See src/target.zig defaultAddressSpace function for how to obtain | ||
| 276 | /// an appropriate value for this field. | ||
| 277 | address_space: AddressSpace = .generic, | ||
| 278 | vector_index: VectorIndex = .none, | ||
| 279 | }; | ||
| 280 | |||
| 281 | pub const PackedOffset = packed struct(u32) { | ||
| 282 | /// If this is non-zero it means the pointer points to a sub-byte | ||
| 283 | /// range of data, which is backed by a "host integer" with this | ||
| 284 | /// number of bytes. | ||
| 285 | /// When host_size=pointee_abi_size and bit_offset=0, this must be | ||
| 286 | /// represented with host_size=0 instead. | ||
| 287 | host_size: u16, | ||
| 288 | bit_offset: u16, | ||
| 289 | }; | ||
| 290 | |||
| 291 | pub const Size = std.builtin.Type.Pointer.Size; | ||
| 292 | pub const AddressSpace = std.builtin.AddressSpace; | ||
| 281 | }; | 293 | }; |
| 282 | 294 | ||
| 283 | pub const ArrayType = struct { | 295 | pub const ArrayType = struct { |
| ... | @@ -635,17 +647,13 @@ pub const Key = union(enum) { | ... | @@ -635,17 +647,13 @@ pub const Key = union(enum) { |
| 635 | } | 647 | } |
| 636 | 648 | ||
| 637 | pub fn hash64(key: Key, ip: *const InternPool) u64 { | 649 | pub fn hash64(key: Key, ip: *const InternPool) u64 { |
| 638 | var hasher = std.hash.Wyhash.init(0); | 650 | const asBytes = std.mem.asBytes; |
| 639 | key.hashWithHasher(&hasher, ip); | ||
| 640 | return hasher.final(); | ||
| 641 | } | ||
| 642 | |||
| 643 | pub fn hashWithHasher(key: Key, hasher: *std.hash.Wyhash, ip: *const InternPool) void { | ||
| 644 | const KeyTag = @typeInfo(Key).Union.tag_type.?; | 651 | const KeyTag = @typeInfo(Key).Union.tag_type.?; |
| 645 | std.hash.autoHash(hasher, @as(KeyTag, key)); | 652 | const seed = @enumToInt(@as(KeyTag, key)); |
| 646 | switch (key) { | 653 | switch (key) { |
| 654 | .ptr_type => |x| return WyhashKing.hash(seed, asBytes(&x)), | ||
| 655 | |||
| 647 | inline .int_type, | 656 | inline .int_type, |
| 648 | .ptr_type, | ||
| 649 | .array_type, | 657 | .array_type, |
| 650 | .vector_type, | 658 | .vector_type, |
| 651 | .opt_type, | 659 | .opt_type, |
| ... | @@ -663,73 +671,110 @@ pub const Key = union(enum) { | ... | @@ -663,73 +671,110 @@ pub const Key = union(enum) { |
| 663 | .enum_literal, | 671 | .enum_literal, |
| 664 | .enum_tag, | 672 | .enum_tag, |
| 665 | .inferred_error_set_type, | 673 | .inferred_error_set_type, |
| 666 | => |info| std.hash.autoHash(hasher, info), | 674 | => |info| { |
| 675 | var hasher = std.hash.Wyhash.init(seed); | ||
| 676 | std.hash.autoHash(&hasher, info); | ||
| 677 | return hasher.final(); | ||
| 678 | }, | ||
| 667 | 679 | ||
| 668 | .runtime_value => |runtime_value| std.hash.autoHash(hasher, runtime_value.val), | 680 | .runtime_value => |runtime_value| { |
| 669 | .opaque_type => |opaque_type| std.hash.autoHash(hasher, opaque_type.decl), | 681 | var hasher = std.hash.Wyhash.init(seed); |
| 670 | .enum_type => |enum_type| std.hash.autoHash(hasher, enum_type.decl), | 682 | std.hash.autoHash(&hasher, runtime_value.val); |
| 683 | return hasher.final(); | ||
| 684 | }, | ||
| 685 | .opaque_type => |opaque_type| { | ||
| 686 | var hasher = std.hash.Wyhash.init(seed); | ||
| 687 | std.hash.autoHash(&hasher, opaque_type.decl); | ||
| 688 | return hasher.final(); | ||
| 689 | }, | ||
| 690 | .enum_type => |enum_type| { | ||
| 691 | var hasher = std.hash.Wyhash.init(seed); | ||
| 692 | std.hash.autoHash(&hasher, enum_type.decl); | ||
| 693 | return hasher.final(); | ||
| 694 | }, | ||
| 671 | 695 | ||
| 672 | .variable => |variable| std.hash.autoHash(hasher, variable.decl), | 696 | .variable => |variable| { |
| 697 | var hasher = std.hash.Wyhash.init(seed); | ||
| 698 | std.hash.autoHash(&hasher, variable.decl); | ||
| 699 | return hasher.final(); | ||
| 700 | }, | ||
| 673 | .extern_func => |extern_func| { | 701 | .extern_func => |extern_func| { |
| 674 | std.hash.autoHash(hasher, extern_func.ty); | 702 | var hasher = std.hash.Wyhash.init(seed); |
| 675 | std.hash.autoHash(hasher, extern_func.decl); | 703 | std.hash.autoHash(&hasher, extern_func.ty); |
| 704 | std.hash.autoHash(&hasher, extern_func.decl); | ||
| 705 | return hasher.final(); | ||
| 676 | }, | 706 | }, |
| 677 | .func => |func| { | 707 | .func => |func| { |
| 678 | std.hash.autoHash(hasher, func.ty); | 708 | var hasher = std.hash.Wyhash.init(seed); |
| 679 | std.hash.autoHash(hasher, func.index); | 709 | std.hash.autoHash(&hasher, func.ty); |
| 710 | std.hash.autoHash(&hasher, func.index); | ||
| 711 | return hasher.final(); | ||
| 680 | }, | 712 | }, |
| 681 | 713 | ||
| 682 | .int => |int| { | 714 | .int => |int| { |
| 715 | var hasher = std.hash.Wyhash.init(seed); | ||
| 683 | // Canonicalize all integers by converting them to BigIntConst. | 716 | // Canonicalize all integers by converting them to BigIntConst. |
| 684 | switch (int.storage) { | 717 | switch (int.storage) { |
| 685 | .u64, .i64, .big_int => { | 718 | .u64, .i64, .big_int => { |
| 686 | var buffer: Key.Int.Storage.BigIntSpace = undefined; | 719 | var buffer: Key.Int.Storage.BigIntSpace = undefined; |
| 687 | const big_int = int.storage.toBigInt(&buffer); | 720 | const big_int = int.storage.toBigInt(&buffer); |
| 688 | 721 | ||
| 689 | std.hash.autoHash(hasher, int.ty); | 722 | std.hash.autoHash(&hasher, int.ty); |
| 690 | std.hash.autoHash(hasher, big_int.positive); | 723 | std.hash.autoHash(&hasher, big_int.positive); |
| 691 | for (big_int.limbs) |limb| std.hash.autoHash(hasher, limb); | 724 | for (big_int.limbs) |limb| std.hash.autoHash(&hasher, limb); |
| 692 | }, | 725 | }, |
| 693 | .lazy_align, .lazy_size => |lazy_ty| { | 726 | .lazy_align, .lazy_size => |lazy_ty| { |
| 694 | std.hash.autoHash( | 727 | std.hash.autoHash( |
| 695 | hasher, | 728 | &hasher, |
| 696 | @as(@typeInfo(Key.Int.Storage).Union.tag_type.?, int.storage), | 729 | @as(@typeInfo(Key.Int.Storage).Union.tag_type.?, int.storage), |
| 697 | ); | 730 | ); |
| 698 | std.hash.autoHash(hasher, lazy_ty); | 731 | std.hash.autoHash(&hasher, lazy_ty); |
| 699 | }, | 732 | }, |
| 700 | } | 733 | } |
| 734 | return hasher.final(); | ||
| 701 | }, | 735 | }, |
| 702 | 736 | ||
| 703 | .float => |float| { | 737 | .float => |float| { |
| 704 | std.hash.autoHash(hasher, float.ty); | 738 | var hasher = std.hash.Wyhash.init(seed); |
| 739 | std.hash.autoHash(&hasher, float.ty); | ||
| 705 | switch (float.storage) { | 740 | switch (float.storage) { |
| 706 | inline else => |val| std.hash.autoHash( | 741 | inline else => |val| std.hash.autoHash( |
| 707 | hasher, | 742 | &hasher, |
| 708 | @bitCast(std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(val))), val), | 743 | @bitCast(std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(val))), val), |
| 709 | ), | 744 | ), |
| 710 | } | 745 | } |
| 746 | return hasher.final(); | ||
| 711 | }, | 747 | }, |
| 712 | 748 | ||
| 713 | .ptr => |ptr| { | 749 | .ptr => |ptr| { |
| 714 | std.hash.autoHash(hasher, ptr.ty); | ||
| 715 | std.hash.autoHash(hasher, ptr.len); | ||
| 716 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. | 750 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. |
| 717 | // This is sound due to pointer provenance rules. | 751 | // This is sound due to pointer provenance rules. |
| 718 | std.hash.autoHash(hasher, @as(@typeInfo(Key.Ptr.Addr).Union.tag_type.?, ptr.addr)); | 752 | const addr: @typeInfo(Key.Ptr.Addr).Union.tag_type.? = ptr.addr; |
| 719 | switch (ptr.addr) { | 753 | const seed2 = seed + @enumToInt(addr); |
| 720 | .decl => |decl| std.hash.autoHash(hasher, decl), | 754 | const common = asBytes(&ptr.ty) ++ asBytes(&ptr.len); |
| 721 | .mut_decl => |mut_decl| std.hash.autoHash(hasher, mut_decl), | 755 | return switch (ptr.addr) { |
| 722 | .int => |int| std.hash.autoHash(hasher, int), | 756 | .decl => |x| WyhashKing.hash(seed2, common ++ asBytes(&x)), |
| 723 | .eu_payload => |eu_payload| std.hash.autoHash(hasher, eu_payload), | 757 | |
| 724 | .opt_payload => |opt_payload| std.hash.autoHash(hasher, opt_payload), | 758 | .mut_decl => |x| WyhashKing.hash( |
| 725 | .comptime_field => |comptime_field| std.hash.autoHash(hasher, comptime_field), | 759 | seed2, |
| 726 | .elem => |elem| std.hash.autoHash(hasher, elem), | 760 | asBytes(&x.decl) ++ asBytes(&x.runtime_index), |
| 727 | .field => |field| std.hash.autoHash(hasher, field), | 761 | ), |
| 728 | } | 762 | |
| 763 | .int, .eu_payload, .opt_payload, .comptime_field => |int| WyhashKing.hash( | ||
| 764 | seed2, | ||
| 765 | asBytes(&int), | ||
| 766 | ), | ||
| 767 | |||
| 768 | .elem, .field => |x| WyhashKing.hash( | ||
| 769 | seed2, | ||
| 770 | asBytes(&x.base) ++ asBytes(&x.index), | ||
| 771 | ), | ||
| 772 | }; | ||
| 729 | }, | 773 | }, |
| 730 | 774 | ||
| 731 | .aggregate => |aggregate| { | 775 | .aggregate => |aggregate| { |
| 732 | std.hash.autoHash(hasher, aggregate.ty); | 776 | var hasher = std.hash.Wyhash.init(seed); |
| 777 | std.hash.autoHash(&hasher, aggregate.ty); | ||
| 733 | const len = ip.aggregateTypeLen(aggregate.ty); | 778 | const len = ip.aggregateTypeLen(aggregate.ty); |
| 734 | const child = switch (ip.indexToKey(aggregate.ty)) { | 779 | const child = switch (ip.indexToKey(aggregate.ty)) { |
| 735 | .array_type => |array_type| array_type.child, | 780 | .array_type => |array_type| array_type.child, |
| ... | @@ -741,16 +786,16 @@ pub const Key = union(enum) { | ... | @@ -741,16 +786,16 @@ pub const Key = union(enum) { |
| 741 | if (child == .u8_type) { | 786 | if (child == .u8_type) { |
| 742 | switch (aggregate.storage) { | 787 | switch (aggregate.storage) { |
| 743 | .bytes => |bytes| for (bytes[0..@intCast(usize, len)]) |byte| { | 788 | .bytes => |bytes| for (bytes[0..@intCast(usize, len)]) |byte| { |
| 744 | std.hash.autoHash(hasher, KeyTag.int); | 789 | std.hash.autoHash(&hasher, KeyTag.int); |
| 745 | std.hash.autoHash(hasher, byte); | 790 | std.hash.autoHash(&hasher, byte); |
| 746 | }, | 791 | }, |
| 747 | .elems => |elems| for (elems[0..@intCast(usize, len)]) |elem| { | 792 | .elems => |elems| for (elems[0..@intCast(usize, len)]) |elem| { |
| 748 | const elem_key = ip.indexToKey(elem); | 793 | const elem_key = ip.indexToKey(elem); |
| 749 | std.hash.autoHash(hasher, @as(KeyTag, elem_key)); | 794 | std.hash.autoHash(&hasher, @as(KeyTag, elem_key)); |
| 750 | switch (elem_key) { | 795 | switch (elem_key) { |
| 751 | .undef => {}, | 796 | .undef => {}, |
| 752 | .int => |int| std.hash.autoHash( | 797 | .int => |int| std.hash.autoHash( |
| 753 | hasher, | 798 | &hasher, |
| 754 | @intCast(u8, int.storage.u64), | 799 | @intCast(u8, int.storage.u64), |
| 755 | ), | 800 | ), |
| 756 | else => unreachable, | 801 | else => unreachable, |
| ... | @@ -760,11 +805,11 @@ pub const Key = union(enum) { | ... | @@ -760,11 +805,11 @@ pub const Key = union(enum) { |
| 760 | const elem_key = ip.indexToKey(elem); | 805 | const elem_key = ip.indexToKey(elem); |
| 761 | var remaining = len; | 806 | var remaining = len; |
| 762 | while (remaining > 0) : (remaining -= 1) { | 807 | while (remaining > 0) : (remaining -= 1) { |
| 763 | std.hash.autoHash(hasher, @as(KeyTag, elem_key)); | 808 | std.hash.autoHash(&hasher, @as(KeyTag, elem_key)); |
| 764 | switch (elem_key) { | 809 | switch (elem_key) { |
| 765 | .undef => {}, | 810 | .undef => {}, |
| 766 | .int => |int| std.hash.autoHash( | 811 | .int => |int| std.hash.autoHash( |
| 767 | hasher, | 812 | &hasher, |
| 768 | @intCast(u8, int.storage.u64), | 813 | @intCast(u8, int.storage.u64), |
| 769 | ), | 814 | ), |
| 770 | else => unreachable, | 815 | else => unreachable, |
| ... | @@ -772,47 +817,60 @@ pub const Key = union(enum) { | ... | @@ -772,47 +817,60 @@ pub const Key = union(enum) { |
| 772 | } | 817 | } |
| 773 | }, | 818 | }, |
| 774 | } | 819 | } |
| 775 | return; | 820 | return hasher.final(); |
| 776 | } | 821 | } |
| 777 | 822 | ||
| 778 | switch (aggregate.storage) { | 823 | switch (aggregate.storage) { |
| 779 | .bytes => unreachable, | 824 | .bytes => unreachable, |
| 780 | .elems => |elems| for (elems[0..@intCast(usize, len)]) |elem| | 825 | .elems => |elems| for (elems[0..@intCast(usize, len)]) |elem| |
| 781 | std.hash.autoHash(hasher, elem), | 826 | std.hash.autoHash(&hasher, elem), |
| 782 | .repeated_elem => |elem| { | 827 | .repeated_elem => |elem| { |
| 783 | var remaining = len; | 828 | var remaining = len; |
| 784 | while (remaining > 0) : (remaining -= 1) std.hash.autoHash(hasher, elem); | 829 | while (remaining > 0) : (remaining -= 1) std.hash.autoHash(&hasher, elem); |
| 785 | }, | 830 | }, |
| 786 | } | 831 | } |
| 832 | return hasher.final(); | ||
| 787 | }, | 833 | }, |
| 788 | 834 | ||
| 789 | .error_set_type => |error_set_type| { | 835 | .error_set_type => |error_set_type| { |
| 790 | for (error_set_type.names) |elem| std.hash.autoHash(hasher, elem); | 836 | var hasher = std.hash.Wyhash.init(seed); |
| 837 | for (error_set_type.names) |elem| std.hash.autoHash(&hasher, elem); | ||
| 838 | return hasher.final(); | ||
| 791 | }, | 839 | }, |
| 792 | 840 | ||
| 793 | .anon_struct_type => |anon_struct_type| { | 841 | .anon_struct_type => |anon_struct_type| { |
| 794 | for (anon_struct_type.types) |elem| std.hash.autoHash(hasher, elem); | 842 | var hasher = std.hash.Wyhash.init(seed); |
| 795 | for (anon_struct_type.values) |elem| std.hash.autoHash(hasher, elem); | 843 | for (anon_struct_type.types) |elem| std.hash.autoHash(&hasher, elem); |
| 796 | for (anon_struct_type.names) |elem| std.hash.autoHash(hasher, elem); | 844 | for (anon_struct_type.values) |elem| std.hash.autoHash(&hasher, elem); |
| 845 | for (anon_struct_type.names) |elem| std.hash.autoHash(&hasher, elem); | ||
| 846 | return hasher.final(); | ||
| 797 | }, | 847 | }, |
| 798 | 848 | ||
| 799 | .func_type => |func_type| { | 849 | .func_type => |func_type| { |
| 800 | for (func_type.param_types) |param_type| std.hash.autoHash(hasher, param_type); | 850 | var hasher = std.hash.Wyhash.init(seed); |
| 801 | std.hash.autoHash(hasher, func_type.return_type); | 851 | for (func_type.param_types) |param_type| std.hash.autoHash(&hasher, param_type); |
| 802 | std.hash.autoHash(hasher, func_type.comptime_bits); | 852 | std.hash.autoHash(&hasher, func_type.return_type); |
| 803 | std.hash.autoHash(hasher, func_type.noalias_bits); | 853 | std.hash.autoHash(&hasher, func_type.comptime_bits); |
| 804 | std.hash.autoHash(hasher, func_type.alignment); | 854 | std.hash.autoHash(&hasher, func_type.noalias_bits); |
| 805 | std.hash.autoHash(hasher, func_type.cc); | 855 | std.hash.autoHash(&hasher, func_type.alignment); |
| 806 | std.hash.autoHash(hasher, func_type.is_var_args); | 856 | std.hash.autoHash(&hasher, func_type.cc); |
| 807 | std.hash.autoHash(hasher, func_type.is_generic); | 857 | std.hash.autoHash(&hasher, func_type.is_var_args); |
| 808 | std.hash.autoHash(hasher, func_type.is_noinline); | 858 | std.hash.autoHash(&hasher, func_type.is_generic); |
| 859 | std.hash.autoHash(&hasher, func_type.is_noinline); | ||
| 860 | return hasher.final(); | ||
| 809 | }, | 861 | }, |
| 810 | 862 | ||
| 811 | .memoized_decl => |memoized_decl| std.hash.autoHash(hasher, memoized_decl.val), | 863 | .memoized_decl => |memoized_decl| { |
| 864 | var hasher = std.hash.Wyhash.init(seed); | ||
| 865 | std.hash.autoHash(&hasher, memoized_decl.val); | ||
| 866 | return hasher.final(); | ||
| 867 | }, | ||
| 812 | 868 | ||
| 813 | .memoized_call => |memoized_call| { | 869 | .memoized_call => |memoized_call| { |
| 814 | std.hash.autoHash(hasher, memoized_call.func); | 870 | var hasher = std.hash.Wyhash.init(seed); |
| 815 | for (memoized_call.arg_values) |arg| std.hash.autoHash(hasher, arg); | 871 | std.hash.autoHash(&hasher, memoized_call.func); |
| 872 | for (memoized_call.arg_values) |arg| std.hash.autoHash(&hasher, arg); | ||
| 873 | return hasher.final(); | ||
| 816 | }, | 874 | }, |
| 817 | } | 875 | } |
| 818 | } | 876 | } |
| ... | @@ -1340,7 +1398,7 @@ pub const Index = enum(u32) { | ... | @@ -1340,7 +1398,7 @@ pub const Index = enum(u32) { |
| 1340 | type_array_big: struct { data: *Array }, | 1398 | type_array_big: struct { data: *Array }, |
| 1341 | type_array_small: struct { data: *Vector }, | 1399 | type_array_small: struct { data: *Vector }, |
| 1342 | type_vector: struct { data: *Vector }, | 1400 | type_vector: struct { data: *Vector }, |
| 1343 | type_pointer: struct { data: *Pointer }, | 1401 | type_pointer: struct { data: *Tag.TypePointer }, |
| 1344 | type_slice: DataIsIndex, | 1402 | type_slice: DataIsIndex, |
| 1345 | type_optional: DataIsIndex, | 1403 | type_optional: DataIsIndex, |
| 1346 | type_anyframe: DataIsIndex, | 1404 | type_anyframe: DataIsIndex, |
| ... | @@ -1564,44 +1622,56 @@ pub const static_keys = [_]Key{ | ... | @@ -1564,44 +1622,56 @@ pub const static_keys = [_]Key{ |
| 1564 | .{ .simple_type = .type_info }, | 1622 | .{ .simple_type = .type_info }, |
| 1565 | 1623 | ||
| 1566 | .{ .ptr_type = .{ | 1624 | .{ .ptr_type = .{ |
| 1567 | .elem_type = .u8_type, | 1625 | .child = .u8_type, |
| 1568 | .size = .Many, | 1626 | .flags = .{ |
| 1627 | .size = .Many, | ||
| 1628 | }, | ||
| 1569 | } }, | 1629 | } }, |
| 1570 | 1630 | ||
| 1571 | // manyptr_const_u8_type | 1631 | // manyptr_const_u8_type |
| 1572 | .{ .ptr_type = .{ | 1632 | .{ .ptr_type = .{ |
| 1573 | .elem_type = .u8_type, | 1633 | .child = .u8_type, |
| 1574 | .size = .Many, | 1634 | .flags = .{ |
| 1575 | .is_const = true, | 1635 | .size = .Many, |
| 1636 | .is_const = true, | ||
| 1637 | }, | ||
| 1576 | } }, | 1638 | } }, |
| 1577 | 1639 | ||
| 1578 | // manyptr_const_u8_sentinel_0_type | 1640 | // manyptr_const_u8_sentinel_0_type |
| 1579 | .{ .ptr_type = .{ | 1641 | .{ .ptr_type = .{ |
| 1580 | .elem_type = .u8_type, | 1642 | .child = .u8_type, |
| 1581 | .sentinel = .zero_u8, | 1643 | .sentinel = .zero_u8, |
| 1582 | .size = .Many, | 1644 | .flags = .{ |
| 1583 | .is_const = true, | 1645 | .size = .Many, |
| 1646 | .is_const = true, | ||
| 1647 | }, | ||
| 1584 | } }, | 1648 | } }, |
| 1585 | 1649 | ||
| 1586 | .{ .ptr_type = .{ | 1650 | .{ .ptr_type = .{ |
| 1587 | .elem_type = .comptime_int_type, | 1651 | .child = .comptime_int_type, |
| 1588 | .size = .One, | 1652 | .flags = .{ |
| 1589 | .is_const = true, | 1653 | .size = .One, |
| 1654 | .is_const = true, | ||
| 1655 | }, | ||
| 1590 | } }, | 1656 | } }, |
| 1591 | 1657 | ||
| 1592 | // slice_const_u8_type | 1658 | // slice_const_u8_type |
| 1593 | .{ .ptr_type = .{ | 1659 | .{ .ptr_type = .{ |
| 1594 | .elem_type = .u8_type, | 1660 | .child = .u8_type, |
| 1595 | .size = .Slice, | 1661 | .flags = .{ |
| 1596 | .is_const = true, | 1662 | .size = .Slice, |
| 1663 | .is_const = true, | ||
| 1664 | }, | ||
| 1597 | } }, | 1665 | } }, |
| 1598 | 1666 | ||
| 1599 | // slice_const_u8_sentinel_0_type | 1667 | // slice_const_u8_sentinel_0_type |
| 1600 | .{ .ptr_type = .{ | 1668 | .{ .ptr_type = .{ |
| 1601 | .elem_type = .u8_type, | 1669 | .child = .u8_type, |
| 1602 | .sentinel = .zero_u8, | 1670 | .sentinel = .zero_u8, |
| 1603 | .size = .Slice, | 1671 | .flags = .{ |
| 1604 | .is_const = true, | 1672 | .size = .Slice, |
| 1673 | .is_const = true, | ||
| 1674 | }, | ||
| 1605 | } }, | 1675 | } }, |
| 1606 | 1676 | ||
| 1607 | // anyerror_void_error_union_type | 1677 | // anyerror_void_error_union_type |
| ... | @@ -1702,7 +1772,6 @@ pub const Tag = enum(u8) { | ... | @@ -1702,7 +1772,6 @@ pub const Tag = enum(u8) { |
| 1702 | /// data is payload to Vector. | 1772 | /// data is payload to Vector. |
| 1703 | type_vector, | 1773 | type_vector, |
| 1704 | /// A fully explicitly specified pointer type. | 1774 | /// A fully explicitly specified pointer type. |
| 1705 | /// data is payload to Pointer. | ||
| 1706 | type_pointer, | 1775 | type_pointer, |
| 1707 | /// A slice type. | 1776 | /// A slice type. |
| 1708 | /// data is Index of underlying pointer type. | 1777 | /// data is Index of underlying pointer type. |
| ... | @@ -1941,6 +2010,7 @@ pub const Tag = enum(u8) { | ... | @@ -1941,6 +2010,7 @@ pub const Tag = enum(u8) { |
| 1941 | const Func = Key.Func; | 2010 | const Func = Key.Func; |
| 1942 | const Union = Key.Union; | 2011 | const Union = Key.Union; |
| 1943 | const MemoizedDecl = Key.MemoizedDecl; | 2012 | const MemoizedDecl = Key.MemoizedDecl; |
| 2013 | const TypePointer = Key.PtrType; | ||
| 1944 | 2014 | ||
| 1945 | fn Payload(comptime tag: Tag) type { | 2015 | fn Payload(comptime tag: Tag) type { |
| 1946 | return switch (tag) { | 2016 | return switch (tag) { |
| ... | @@ -1949,7 +2019,7 @@ pub const Tag = enum(u8) { | ... | @@ -1949,7 +2019,7 @@ pub const Tag = enum(u8) { |
| 1949 | .type_array_big => Array, | 2019 | .type_array_big => Array, |
| 1950 | .type_array_small => Vector, | 2020 | .type_array_small => Vector, |
| 1951 | .type_vector => Vector, | 2021 | .type_vector => Vector, |
| 1952 | .type_pointer => Pointer, | 2022 | .type_pointer => TypePointer, |
| 1953 | .type_slice => unreachable, | 2023 | .type_slice => unreachable, |
| 1954 | .type_optional => unreachable, | 2024 | .type_optional => unreachable, |
| 1955 | .type_anyframe => unreachable, | 2025 | .type_anyframe => unreachable, |
| ... | @@ -2167,32 +2237,6 @@ pub const SimpleValue = enum(u32) { | ... | @@ -2167,32 +2237,6 @@ pub const SimpleValue = enum(u32) { |
| 2167 | generic_poison, | 2237 | generic_poison, |
| 2168 | }; | 2238 | }; |
| 2169 | 2239 | ||
| 2170 | pub const Pointer = struct { | ||
| 2171 | child: Index, | ||
| 2172 | sentinel: Index, | ||
| 2173 | flags: Flags, | ||
| 2174 | packed_offset: PackedOffset, | ||
| 2175 | |||
| 2176 | pub const Flags = packed struct(u32) { | ||
| 2177 | size: Size, | ||
| 2178 | alignment: Alignment, | ||
| 2179 | is_const: bool, | ||
| 2180 | is_volatile: bool, | ||
| 2181 | is_allowzero: bool, | ||
| 2182 | address_space: AddressSpace, | ||
| 2183 | vector_index: VectorIndex, | ||
| 2184 | }; | ||
| 2185 | |||
| 2186 | pub const PackedOffset = packed struct(u32) { | ||
| 2187 | host_size: u16, | ||
| 2188 | bit_offset: u16, | ||
| 2189 | }; | ||
| 2190 | |||
| 2191 | pub const Size = std.builtin.Type.Pointer.Size; | ||
| 2192 | pub const AddressSpace = std.builtin.AddressSpace; | ||
| 2193 | pub const VectorIndex = Key.PtrType.VectorIndex; | ||
| 2194 | }; | ||
| 2195 | |||
| 2196 | /// Stored as a power-of-two, with one special value to indicate none. | 2240 | /// Stored as a power-of-two, with one special value to indicate none. |
| 2197 | pub const Alignment = enum(u6) { | 2241 | pub const Alignment = enum(u6) { |
| 2198 | none = std.math.maxInt(u6), | 2242 | none = std.math.maxInt(u6), |
| ... | @@ -2531,39 +2575,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -2531,39 +2575,13 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 2531 | } }; | 2575 | } }; |
| 2532 | }, | 2576 | }, |
| 2533 | 2577 | ||
| 2534 | .type_pointer => { | 2578 | .type_pointer => .{ .ptr_type = ip.extraData(Tag.TypePointer, data) }, |
| 2535 | const ptr_info = ip.extraData(Pointer, data); | ||
| 2536 | return .{ .ptr_type = .{ | ||
| 2537 | .elem_type = ptr_info.child, | ||
| 2538 | .sentinel = ptr_info.sentinel, | ||
| 2539 | .alignment = ptr_info.flags.alignment, | ||
| 2540 | .size = ptr_info.flags.size, | ||
| 2541 | .is_const = ptr_info.flags.is_const, | ||
| 2542 | .is_volatile = ptr_info.flags.is_volatile, | ||
| 2543 | .is_allowzero = ptr_info.flags.is_allowzero, | ||
| 2544 | .address_space = ptr_info.flags.address_space, | ||
| 2545 | .vector_index = ptr_info.flags.vector_index, | ||
| 2546 | .host_size = ptr_info.packed_offset.host_size, | ||
| 2547 | .bit_offset = ptr_info.packed_offset.bit_offset, | ||
| 2548 | } }; | ||
| 2549 | }, | ||
| 2550 | 2579 | ||
| 2551 | .type_slice => { | 2580 | .type_slice => { |
| 2552 | assert(ip.items.items(.tag)[data] == .type_pointer); | 2581 | assert(ip.items.items(.tag)[data] == .type_pointer); |
| 2553 | const ptr_info = ip.extraData(Pointer, ip.items.items(.data)[data]); | 2582 | var ptr_info = ip.extraData(Tag.TypePointer, ip.items.items(.data)[data]); |
| 2554 | return .{ .ptr_type = .{ | 2583 | ptr_info.flags.size = .Slice; |
| 2555 | .elem_type = ptr_info.child, | 2584 | return .{ .ptr_type = ptr_info }; |
| 2556 | .sentinel = ptr_info.sentinel, | ||
| 2557 | .alignment = ptr_info.flags.alignment, | ||
| 2558 | .size = .Slice, | ||
| 2559 | .is_const = ptr_info.flags.is_const, | ||
| 2560 | .is_volatile = ptr_info.flags.is_volatile, | ||
| 2561 | .is_allowzero = ptr_info.flags.is_allowzero, | ||
| 2562 | .address_space = ptr_info.flags.address_space, | ||
| 2563 | .vector_index = ptr_info.flags.vector_index, | ||
| 2564 | .host_size = ptr_info.packed_offset.host_size, | ||
| 2565 | .bit_offset = ptr_info.packed_offset.bit_offset, | ||
| 2566 | } }; | ||
| 2567 | }, | 2585 | }, |
| 2568 | 2586 | ||
| 2569 | .type_optional => .{ .opt_type = @intToEnum(Index, data) }, | 2587 | .type_optional => .{ .opt_type = @intToEnum(Index, data) }, |
| ... | @@ -3066,13 +3084,13 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3066,13 +3084,13 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3066 | }); | 3084 | }); |
| 3067 | }, | 3085 | }, |
| 3068 | .ptr_type => |ptr_type| { | 3086 | .ptr_type => |ptr_type| { |
| 3069 | assert(ptr_type.elem_type != .none); | 3087 | assert(ptr_type.child != .none); |
| 3070 | assert(ptr_type.sentinel == .none or ip.typeOf(ptr_type.sentinel) == ptr_type.elem_type); | 3088 | assert(ptr_type.sentinel == .none or ip.typeOf(ptr_type.sentinel) == ptr_type.child); |
| 3071 | 3089 | ||
| 3072 | if (ptr_type.size == .Slice) { | 3090 | if (ptr_type.flags.size == .Slice) { |
| 3073 | _ = ip.map.pop(); | 3091 | _ = ip.map.pop(); |
| 3074 | var new_key = key; | 3092 | var new_key = key; |
| 3075 | new_key.ptr_type.size = .Many; | 3093 | new_key.ptr_type.flags.size = .Many; |
| 3076 | const ptr_type_index = try ip.get(gpa, new_key); | 3094 | const ptr_type_index = try ip.get(gpa, new_key); |
| 3077 | assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing); | 3095 | assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing); |
| 3078 | try ip.items.ensureUnusedCapacity(gpa, 1); | 3096 | try ip.items.ensureUnusedCapacity(gpa, 1); |
| ... | @@ -3083,27 +3101,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3083,27 +3101,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3083 | return @intToEnum(Index, ip.items.len - 1); | 3101 | return @intToEnum(Index, ip.items.len - 1); |
| 3084 | } | 3102 | } |
| 3085 | 3103 | ||
| 3086 | const is_allowzero = ptr_type.is_allowzero or ptr_type.size == .C; | 3104 | var ptr_type_adjusted = ptr_type; |
| 3105 | if (ptr_type.flags.size == .C) ptr_type_adjusted.flags.is_allowzero = true; | ||
| 3087 | 3106 | ||
| 3088 | ip.items.appendAssumeCapacity(.{ | 3107 | ip.items.appendAssumeCapacity(.{ |
| 3089 | .tag = .type_pointer, | 3108 | .tag = .type_pointer, |
| 3090 | .data = try ip.addExtra(gpa, Pointer{ | 3109 | .data = try ip.addExtra(gpa, ptr_type_adjusted), |
| 3091 | .child = ptr_type.elem_type, | ||
| 3092 | .sentinel = ptr_type.sentinel, | ||
| 3093 | .flags = .{ | ||
| 3094 | .alignment = ptr_type.alignment, | ||
| 3095 | .is_const = ptr_type.is_const, | ||
| 3096 | .is_volatile = ptr_type.is_volatile, | ||
| 3097 | .is_allowzero = is_allowzero, | ||
| 3098 | .size = ptr_type.size, | ||
| 3099 | .address_space = ptr_type.address_space, | ||
| 3100 | .vector_index = ptr_type.vector_index, | ||
| 3101 | }, | ||
| 3102 | .packed_offset = .{ | ||
| 3103 | .host_size = ptr_type.host_size, | ||
| 3104 | .bit_offset = ptr_type.bit_offset, | ||
| 3105 | }, | ||
| 3106 | }), | ||
| 3107 | }); | 3110 | }); |
| 3108 | }, | 3111 | }, |
| 3109 | .array_type => |array_type| { | 3112 | .array_type => |array_type| { |
| ... | @@ -3379,7 +3382,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3379,7 +3382,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3379 | const ptr_type = ip.indexToKey(ptr.ty).ptr_type; | 3382 | const ptr_type = ip.indexToKey(ptr.ty).ptr_type; |
| 3380 | switch (ptr.len) { | 3383 | switch (ptr.len) { |
| 3381 | .none => { | 3384 | .none => { |
| 3382 | assert(ptr_type.size != .Slice); | 3385 | assert(ptr_type.flags.size != .Slice); |
| 3383 | switch (ptr.addr) { | 3386 | switch (ptr.addr) { |
| 3384 | .decl => |decl| ip.items.appendAssumeCapacity(.{ | 3387 | .decl => |decl| ip.items.appendAssumeCapacity(.{ |
| 3385 | .tag = .ptr_decl, | 3388 | .tag = .ptr_decl, |
| ... | @@ -3410,10 +3413,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3410,10 +3413,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3410 | switch (ptr.addr) { | 3413 | switch (ptr.addr) { |
| 3411 | .int => assert(ip.typeOf(base) == .usize_type), | 3414 | .int => assert(ip.typeOf(base) == .usize_type), |
| 3412 | .eu_payload => assert(ip.indexToKey( | 3415 | .eu_payload => assert(ip.indexToKey( |
| 3413 | ip.indexToKey(ip.typeOf(base)).ptr_type.elem_type, | 3416 | ip.indexToKey(ip.typeOf(base)).ptr_type.child, |
| 3414 | ) == .error_union_type), | 3417 | ) == .error_union_type), |
| 3415 | .opt_payload => assert(ip.indexToKey( | 3418 | .opt_payload => assert(ip.indexToKey( |
| 3416 | ip.indexToKey(ip.typeOf(base)).ptr_type.elem_type, | 3419 | ip.indexToKey(ip.typeOf(base)).ptr_type.child, |
| 3417 | ) == .opt_type), | 3420 | ) == .opt_type), |
| 3418 | else => unreachable, | 3421 | else => unreachable, |
| 3419 | } | 3422 | } |
| ... | @@ -3433,10 +3436,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3433,10 +3436,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3433 | .elem, .field => |base_index| { | 3436 | .elem, .field => |base_index| { |
| 3434 | const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type; | 3437 | const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type; |
| 3435 | switch (ptr.addr) { | 3438 | switch (ptr.addr) { |
| 3436 | .elem => assert(base_ptr_type.size == .Many), | 3439 | .elem => assert(base_ptr_type.flags.size == .Many), |
| 3437 | .field => { | 3440 | .field => { |
| 3438 | assert(base_ptr_type.size == .One); | 3441 | assert(base_ptr_type.flags.size == .One); |
| 3439 | switch (ip.indexToKey(base_ptr_type.elem_type)) { | 3442 | switch (ip.indexToKey(base_ptr_type.child)) { |
| 3440 | .anon_struct_type => |anon_struct_type| { | 3443 | .anon_struct_type => |anon_struct_type| { |
| 3441 | assert(ptr.addr == .field); | 3444 | assert(ptr.addr == .field); |
| 3442 | assert(base_index.index < anon_struct_type.types.len); | 3445 | assert(base_index.index < anon_struct_type.types.len); |
| ... | @@ -3451,7 +3454,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3451,7 +3454,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3451 | }, | 3454 | }, |
| 3452 | .ptr_type => |slice_type| { | 3455 | .ptr_type => |slice_type| { |
| 3453 | assert(ptr.addr == .field); | 3456 | assert(ptr.addr == .field); |
| 3454 | assert(slice_type.size == .Slice); | 3457 | assert(slice_type.flags.size == .Slice); |
| 3455 | assert(base_index.index < 2); | 3458 | assert(base_index.index < 2); |
| 3456 | }, | 3459 | }, |
| 3457 | else => unreachable, | 3460 | else => unreachable, |
| ... | @@ -3485,12 +3488,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3485,12 +3488,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3485 | // TODO: change Key.Ptr for slices to reference the manyptr value | 3488 | // TODO: change Key.Ptr for slices to reference the manyptr value |
| 3486 | // rather than having an addr field directly. Then we can avoid | 3489 | // rather than having an addr field directly. Then we can avoid |
| 3487 | // these problematic calls to pop(), get(), and getOrPutAdapted(). | 3490 | // these problematic calls to pop(), get(), and getOrPutAdapted(). |
| 3488 | assert(ptr_type.size == .Slice); | 3491 | assert(ptr_type.flags.size == .Slice); |
| 3489 | _ = ip.map.pop(); | 3492 | _ = ip.map.pop(); |
| 3490 | var new_key = key; | 3493 | var new_key = key; |
| 3491 | new_key.ptr.ty = ip.slicePtrType(ptr.ty); | 3494 | new_key.ptr.ty = ip.slicePtrType(ptr.ty); |
| 3492 | new_key.ptr.len = .none; | 3495 | new_key.ptr.len = .none; |
| 3493 | assert(ip.indexToKey(new_key.ptr.ty).ptr_type.size == .Many); | 3496 | assert(ip.indexToKey(new_key.ptr.ty).ptr_type.flags.size == .Many); |
| 3494 | const ptr_index = try ip.get(gpa, new_key); | 3497 | const ptr_index = try ip.get(gpa, new_key); |
| 3495 | assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing); | 3498 | assert(!(try ip.map.getOrPutAdapted(gpa, key, adapter)).found_existing); |
| 3496 | try ip.items.ensureUnusedCapacity(gpa, 1); | 3499 | try ip.items.ensureUnusedCapacity(gpa, 1); |
| ... | @@ -4302,10 +4305,10 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 { | ... | @@ -4302,10 +4305,10 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 { |
| 4302 | NullTerminatedString => @enumToInt(@field(extra, field.name)), | 4305 | NullTerminatedString => @enumToInt(@field(extra, field.name)), |
| 4303 | OptionalNullTerminatedString => @enumToInt(@field(extra, field.name)), | 4306 | OptionalNullTerminatedString => @enumToInt(@field(extra, field.name)), |
| 4304 | i32 => @bitCast(u32, @field(extra, field.name)), | 4307 | i32 => @bitCast(u32, @field(extra, field.name)), |
| 4305 | Pointer.Flags => @bitCast(u32, @field(extra, field.name)), | 4308 | Tag.TypePointer.Flags => @bitCast(u32, @field(extra, field.name)), |
| 4306 | TypeFunction.Flags => @bitCast(u32, @field(extra, field.name)), | 4309 | TypeFunction.Flags => @bitCast(u32, @field(extra, field.name)), |
| 4307 | Pointer.PackedOffset => @bitCast(u32, @field(extra, field.name)), | 4310 | Tag.TypePointer.PackedOffset => @bitCast(u32, @field(extra, field.name)), |
| 4308 | Pointer.VectorIndex => @enumToInt(@field(extra, field.name)), | 4311 | Tag.TypePointer.VectorIndex => @enumToInt(@field(extra, field.name)), |
| 4309 | Tag.Variable.Flags => @bitCast(u32, @field(extra, field.name)), | 4312 | Tag.Variable.Flags => @bitCast(u32, @field(extra, field.name)), |
| 4310 | else => @compileError("bad field type: " ++ @typeName(field.type)), | 4313 | else => @compileError("bad field type: " ++ @typeName(field.type)), |
| 4311 | }); | 4314 | }); |
| ... | @@ -4370,10 +4373,10 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct | ... | @@ -4370,10 +4373,10 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct |
| 4370 | NullTerminatedString => @intToEnum(NullTerminatedString, int32), | 4373 | NullTerminatedString => @intToEnum(NullTerminatedString, int32), |
| 4371 | OptionalNullTerminatedString => @intToEnum(OptionalNullTerminatedString, int32), | 4374 | OptionalNullTerminatedString => @intToEnum(OptionalNullTerminatedString, int32), |
| 4372 | i32 => @bitCast(i32, int32), | 4375 | i32 => @bitCast(i32, int32), |
| 4373 | Pointer.Flags => @bitCast(Pointer.Flags, int32), | 4376 | Tag.TypePointer.Flags => @bitCast(Tag.TypePointer.Flags, int32), |
| 4374 | TypeFunction.Flags => @bitCast(TypeFunction.Flags, int32), | 4377 | TypeFunction.Flags => @bitCast(TypeFunction.Flags, int32), |
| 4375 | Pointer.PackedOffset => @bitCast(Pointer.PackedOffset, int32), | 4378 | Tag.TypePointer.PackedOffset => @bitCast(Tag.TypePointer.PackedOffset, int32), |
| 4376 | Pointer.VectorIndex => @intToEnum(Pointer.VectorIndex, int32), | 4379 | Tag.TypePointer.VectorIndex => @intToEnum(Tag.TypePointer.VectorIndex, int32), |
| 4377 | Tag.Variable.Flags => @bitCast(Tag.Variable.Flags, int32), | 4380 | Tag.Variable.Flags => @bitCast(Tag.Variable.Flags, int32), |
| 4378 | else => @compileError("bad field type: " ++ @typeName(field.type)), | 4381 | else => @compileError("bad field type: " ++ @typeName(field.type)), |
| 4379 | }; | 4382 | }; |
| ... | @@ -4487,7 +4490,7 @@ test "basic usage" { | ... | @@ -4487,7 +4490,7 @@ test "basic usage" { |
| 4487 | 4490 | ||
| 4488 | pub fn childType(ip: *const InternPool, i: Index) Index { | 4491 | pub fn childType(ip: *const InternPool, i: Index) Index { |
| 4489 | return switch (ip.indexToKey(i)) { | 4492 | return switch (ip.indexToKey(i)) { |
| 4490 | .ptr_type => |ptr_type| ptr_type.elem_type, | 4493 | .ptr_type => |ptr_type| ptr_type.child, |
| 4491 | .vector_type => |vector_type| vector_type.child, | 4494 | .vector_type => |vector_type| vector_type.child, |
| 4492 | .array_type => |array_type| array_type.child, | 4495 | .array_type => |array_type| array_type.child, |
| 4493 | .opt_type, .anyframe_type => |child| child, | 4496 | .opt_type, .anyframe_type => |child| child, |
| ... | @@ -4559,7 +4562,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -4559,7 +4562,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 4559 | return ip.get(gpa, .{ .ptr = .{ | 4562 | return ip.get(gpa, .{ .ptr = .{ |
| 4560 | .ty = new_ty, | 4563 | .ty = new_ty, |
| 4561 | .addr = .{ .int = .zero_usize }, | 4564 | .addr = .{ .int = .zero_usize }, |
| 4562 | .len = switch (ip.indexToKey(new_ty).ptr_type.size) { | 4565 | .len = switch (ip.indexToKey(new_ty).ptr_type.flags.size) { |
| 4563 | .One, .Many, .C => .none, | 4566 | .One, .Many, .C => .none, |
| 4564 | .Slice => try ip.get(gpa, .{ .undef = .usize_type }), | 4567 | .Slice => try ip.get(gpa, .{ .undef = .usize_type }), |
| 4565 | }, | 4568 | }, |
| ... | @@ -4623,7 +4626,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al | ... | @@ -4623,7 +4626,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al |
| 4623 | .none => try ip.get(gpa, .{ .ptr = .{ | 4626 | .none => try ip.get(gpa, .{ .ptr = .{ |
| 4624 | .ty = new_ty, | 4627 | .ty = new_ty, |
| 4625 | .addr = .{ .int = .zero_usize }, | 4628 | .addr = .{ .int = .zero_usize }, |
| 4626 | .len = switch (ip.indexToKey(new_ty).ptr_type.size) { | 4629 | .len = switch (ip.indexToKey(new_ty).ptr_type.flags.size) { |
| 4627 | .One, .Many, .C => .none, | 4630 | .One, .Many, .C => .none, |
| 4628 | .Slice => try ip.get(gpa, .{ .undef = .usize_type }), | 4631 | .Slice => try ip.get(gpa, .{ .undef = .usize_type }), |
| 4629 | }, | 4632 | }, |
| ... | @@ -4889,7 +4892,7 @@ fn dumpFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -4889,7 +4892,7 @@ fn dumpFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 4889 | .type_array_small => @sizeOf(Vector), | 4892 | .type_array_small => @sizeOf(Vector), |
| 4890 | .type_array_big => @sizeOf(Array), | 4893 | .type_array_big => @sizeOf(Array), |
| 4891 | .type_vector => @sizeOf(Vector), | 4894 | .type_vector => @sizeOf(Vector), |
| 4892 | .type_pointer => @sizeOf(Pointer), | 4895 | .type_pointer => @sizeOf(Tag.TypePointer), |
| 4893 | .type_slice => 0, | 4896 | .type_slice => 0, |
| 4894 | .type_optional => 0, | 4897 | .type_optional => 0, |
| 4895 | .type_anyframe => 0, | 4898 | .type_anyframe => 0, |
| ... | @@ -5007,6 +5010,7 @@ fn dumpFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -5007,6 +5010,7 @@ fn dumpFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 5007 | pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool { | 5010 | pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool { |
| 5008 | const values = ctx.map.values(); | 5011 | const values = ctx.map.values(); |
| 5009 | return values[a_index].bytes > values[b_index].bytes; | 5012 | return values[a_index].bytes > values[b_index].bytes; |
| 5013 | //return values[a_index].count > values[b_index].count; | ||
| 5010 | } | 5014 | } |
| 5011 | }; | 5015 | }; |
| 5012 | counts.sort(SortContext{ .map = &counts }); | 5016 | counts.sort(SortContext{ .map = &counts }); |
| ... | @@ -5621,3 +5625,79 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois | ... | @@ -5621,3 +5625,79 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois |
| 5621 | .none => unreachable, // special tag | 5625 | .none => unreachable, // special tag |
| 5622 | }; | 5626 | }; |
| 5623 | } | 5627 | } |
| 5628 | |||
| 5629 | /// I got this from King, using this temporarily until std lib hashing can be | ||
| 5630 | /// improved to make stateless hashing performant. Currently the | ||
| 5631 | /// implementations suffer from not special casing small lengths and not taking | ||
| 5632 | /// advantage of comptime-known lengths, both of which this implementation | ||
| 5633 | /// does. | ||
| 5634 | const WyhashKing = struct { | ||
| 5635 | inline fn mum(pair: *[2]u64) void { | ||
| 5636 | const x = @as(u128, pair[0]) *% pair[1]; | ||
| 5637 | pair[0] = @truncate(u64, x); | ||
| 5638 | pair[1] = @truncate(u64, x >> 64); | ||
| 5639 | } | ||
| 5640 | |||
| 5641 | inline fn mix(a: u64, b: u64) u64 { | ||
| 5642 | var pair = [_]u64{ a, b }; | ||
| 5643 | mum(&pair); | ||
| 5644 | return pair[0] ^ pair[1]; | ||
| 5645 | } | ||
| 5646 | |||
| 5647 | inline fn read(comptime I: type, in: []const u8) I { | ||
| 5648 | return std.mem.readIntLittle(I, in[0..@sizeOf(I)]); | ||
| 5649 | } | ||
| 5650 | |||
| 5651 | const secret = [_]u64{ | ||
| 5652 | 0xa0761d6478bd642f, | ||
| 5653 | 0xe7037ed1a0b428db, | ||
| 5654 | 0x8ebc6af09c88c6e3, | ||
| 5655 | 0x589965cc75374cc3, | ||
| 5656 | }; | ||
| 5657 | |||
| 5658 | fn hash(seed: u64, input: anytype) u64 { | ||
| 5659 | var in: []const u8 = input; | ||
| 5660 | var last = std.mem.zeroes([2]u64); | ||
| 5661 | const starting_len: u64 = input.len; | ||
| 5662 | var state = seed ^ mix(seed ^ secret[0], secret[1]); | ||
| 5663 | |||
| 5664 | if (in.len <= 16) { | ||
| 5665 | if (in.len >= 4) { | ||
| 5666 | const end = (in.len >> 3) << 2; | ||
| 5667 | last[0] = (@as(u64, read(u32, in)) << 32) | read(u32, in[end..]); | ||
| 5668 | last[1] = (@as(u64, read(u32, in[in.len - 4 ..])) << 32) | read(u32, in[in.len - 4 - end ..]); | ||
| 5669 | } else if (in.len > 0) { | ||
| 5670 | last[0] = (@as(u64, in[0]) << 16) | (@as(u64, in[in.len >> 1]) << 8) | in[in.len - 1]; | ||
| 5671 | } | ||
| 5672 | } else { | ||
| 5673 | large: { | ||
| 5674 | if (in.len <= 48) break :large; | ||
| 5675 | var split = [_]u64{ state, state, state }; | ||
| 5676 | while (true) { | ||
| 5677 | for (&split, 0..) |*lane, i| { | ||
| 5678 | const a = read(u64, in[(i * 2) * 8 ..]) ^ secret[i + 1]; | ||
| 5679 | const b = read(u64, in[((i * 2) + 1) * 8 ..]) ^ lane.*; | ||
| 5680 | lane.* = mix(a, b); | ||
| 5681 | } | ||
| 5682 | in = in[48..]; | ||
| 5683 | if (in.len > 48) continue; | ||
| 5684 | state = split[0] ^ (split[1] ^ split[2]); | ||
| 5685 | break :large; | ||
| 5686 | } | ||
| 5687 | } | ||
| 5688 | while (true) { | ||
| 5689 | if (in.len <= 16) break; | ||
| 5690 | state = mix(read(u64, in) ^ secret[1], read(u64, in[8..]) ^ state); | ||
| 5691 | in = in[16..]; | ||
| 5692 | if (in.len <= 16) break; | ||
| 5693 | } | ||
| 5694 | last[0] = read(u64, in[in.len - 16 ..]); | ||
| 5695 | last[1] = read(u64, in[in.len - 8 ..]); | ||
| 5696 | } | ||
| 5697 | |||
| 5698 | last[0] ^= secret[1]; | ||
| 5699 | last[1] ^= state; | ||
| 5700 | mum(&last); | ||
| 5701 | return mix(last[0] ^ secret[0] ^ starting_len, last[1] ^ secret[1]); | ||
| 5702 | } | ||
| 5703 | }; |
src/Module.zig+38-31| ... | @@ -6430,8 +6430,10 @@ pub fn populateTestFunctions( | ... | @@ -6430,8 +6430,10 @@ pub fn populateTestFunctions( |
| 6430 | // func | 6430 | // func |
| 6431 | try mod.intern(.{ .ptr = .{ | 6431 | try mod.intern(.{ .ptr = .{ |
| 6432 | .ty = try mod.intern(.{ .ptr_type = .{ | 6432 | .ty = try mod.intern(.{ .ptr_type = .{ |
| 6433 | .elem_type = test_decl.ty.toIntern(), | 6433 | .child = test_decl.ty.toIntern(), |
| 6434 | .is_const = true, | 6434 | .flags = .{ |
| 6435 | .is_const = true, | ||
| 6436 | }, | ||
| 6435 | } }), | 6437 | } }), |
| 6436 | .addr = .{ .decl = test_decl_index }, | 6438 | .addr = .{ .decl = test_decl_index }, |
| 6437 | } }), | 6439 | } }), |
| ... | @@ -6466,9 +6468,11 @@ pub fn populateTestFunctions( | ... | @@ -6466,9 +6468,11 @@ pub fn populateTestFunctions( |
| 6466 | 6468 | ||
| 6467 | { | 6469 | { |
| 6468 | const new_ty = try mod.ptrType(.{ | 6470 | const new_ty = try mod.ptrType(.{ |
| 6469 | .elem_type = test_fn_ty.toIntern(), | 6471 | .child = test_fn_ty.toIntern(), |
| 6470 | .is_const = true, | 6472 | .flags = .{ |
| 6471 | .size = .Slice, | 6473 | .is_const = true, |
| 6474 | .size = .Slice, | ||
| 6475 | }, | ||
| 6472 | }); | 6476 | }); |
| 6473 | const new_val = decl.val; | 6477 | const new_val = decl.val; |
| 6474 | const new_init = try mod.intern(.{ .ptr = .{ | 6478 | const new_init = try mod.intern(.{ .ptr = .{ |
| ... | @@ -6681,65 +6685,68 @@ pub fn optionalType(mod: *Module, child_type: InternPool.Index) Allocator.Error! | ... | @@ -6681,65 +6685,68 @@ pub fn optionalType(mod: *Module, child_type: InternPool.Index) Allocator.Error! |
| 6681 | 6685 | ||
| 6682 | pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type { | 6686 | pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type { |
| 6683 | var canon_info = info; | 6687 | var canon_info = info; |
| 6684 | const have_elem_layout = info.elem_type.toType().layoutIsResolved(mod); | 6688 | const have_elem_layout = info.child.toType().layoutIsResolved(mod); |
| 6685 | 6689 | ||
| 6686 | if (info.size == .C) canon_info.is_allowzero = true; | 6690 | if (info.flags.size == .C) canon_info.flags.is_allowzero = true; |
| 6687 | 6691 | ||
| 6688 | // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee | 6692 | // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee |
| 6689 | // type, we change it to 0 here. If this causes an assertion trip because the | 6693 | // type, we change it to 0 here. If this causes an assertion trip because the |
| 6690 | // pointee type needs to be resolved more, that needs to be done before calling | 6694 | // pointee type needs to be resolved more, that needs to be done before calling |
| 6691 | // this ptr() function. | 6695 | // this ptr() function. |
| 6692 | if (info.alignment.toByteUnitsOptional()) |info_align| { | 6696 | if (info.flags.alignment.toByteUnitsOptional()) |info_align| { |
| 6693 | if (have_elem_layout and info_align == info.elem_type.toType().abiAlignment(mod)) { | 6697 | if (have_elem_layout and info_align == info.child.toType().abiAlignment(mod)) { |
| 6694 | canon_info.alignment = .none; | 6698 | canon_info.flags.alignment = .none; |
| 6695 | } | 6699 | } |
| 6696 | } | 6700 | } |
| 6697 | 6701 | ||
| 6698 | switch (info.vector_index) { | 6702 | switch (info.flags.vector_index) { |
| 6699 | // Canonicalize host_size. If it matches the bit size of the pointee type, | 6703 | // Canonicalize host_size. If it matches the bit size of the pointee type, |
| 6700 | // we change it to 0 here. If this causes an assertion trip, the pointee type | 6704 | // we change it to 0 here. If this causes an assertion trip, the pointee type |
| 6701 | // needs to be resolved before calling this ptr() function. | 6705 | // needs to be resolved before calling this ptr() function. |
| 6702 | .none => if (have_elem_layout and info.host_size != 0) { | 6706 | .none => if (have_elem_layout and info.packed_offset.host_size != 0) { |
| 6703 | const elem_bit_size = info.elem_type.toType().bitSize(mod); | 6707 | const elem_bit_size = info.child.toType().bitSize(mod); |
| 6704 | assert(info.bit_offset + elem_bit_size <= info.host_size * 8); | 6708 | assert(info.packed_offset.bit_offset + elem_bit_size <= info.packed_offset.host_size * 8); |
| 6705 | if (info.host_size * 8 == elem_bit_size) { | 6709 | if (info.packed_offset.host_size * 8 == elem_bit_size) { |
| 6706 | canon_info.host_size = 0; | 6710 | canon_info.packed_offset.host_size = 0; |
| 6707 | } | 6711 | } |
| 6708 | }, | 6712 | }, |
| 6709 | .runtime => {}, | 6713 | .runtime => {}, |
| 6710 | _ => assert(@enumToInt(info.vector_index) < info.host_size), | 6714 | _ => assert(@enumToInt(info.flags.vector_index) < info.packed_offset.host_size), |
| 6711 | } | 6715 | } |
| 6712 | 6716 | ||
| 6713 | return (try intern(mod, .{ .ptr_type = canon_info })).toType(); | 6717 | return (try intern(mod, .{ .ptr_type = canon_info })).toType(); |
| 6714 | } | 6718 | } |
| 6715 | 6719 | ||
| 6716 | pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | 6720 | pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { |
| 6717 | return ptrType(mod, .{ .elem_type = child_type.toIntern() }); | 6721 | return ptrType(mod, .{ .child = child_type.toIntern() }); |
| 6718 | } | 6722 | } |
| 6719 | 6723 | ||
| 6720 | pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | 6724 | pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { |
| 6721 | return ptrType(mod, .{ .elem_type = child_type.toIntern(), .is_const = true }); | 6725 | return ptrType(mod, .{ |
| 6726 | .child = child_type.toIntern(), | ||
| 6727 | .flags = .{ | ||
| 6728 | .is_const = true, | ||
| 6729 | }, | ||
| 6730 | }); | ||
| 6722 | } | 6731 | } |
| 6723 | 6732 | ||
| 6724 | pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | 6733 | pub fn manyConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { |
| 6725 | return ptrType(mod, .{ .elem_type = child_type.toIntern(), .size = .Many, .is_const = true }); | 6734 | return ptrType(mod, .{ |
| 6735 | .child = child_type.toIntern(), | ||
| 6736 | .flags = .{ | ||
| 6737 | .size = .Many, | ||
| 6738 | .is_const = true, | ||
| 6739 | }, | ||
| 6740 | }); | ||
| 6726 | } | 6741 | } |
| 6727 | 6742 | ||
| 6728 | pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type { | 6743 | pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type { |
| 6729 | const info = Type.ptrInfoIp(&mod.intern_pool, ptr_ty.toIntern()); | 6744 | const info = Type.ptrInfoIp(&mod.intern_pool, ptr_ty.toIntern()); |
| 6730 | return mod.ptrType(.{ | 6745 | return mod.ptrType(.{ |
| 6731 | .elem_type = new_child.toIntern(), | 6746 | .child = new_child.toIntern(), |
| 6732 | |||
| 6733 | .sentinel = info.sentinel, | 6747 | .sentinel = info.sentinel, |
| 6734 | .alignment = info.alignment, | 6748 | .flags = info.flags, |
| 6735 | .host_size = info.host_size, | 6749 | .packed_offset = info.packed_offset, |
| 6736 | .bit_offset = info.bit_offset, | ||
| 6737 | .vector_index = info.vector_index, | ||
| 6738 | .size = info.size, | ||
| 6739 | .is_const = info.is_const, | ||
| 6740 | .is_volatile = info.is_volatile, | ||
| 6741 | .is_allowzero = info.is_allowzero, | ||
| 6742 | .address_space = info.address_space, | ||
| 6743 | }); | 6750 | }); |
| 6744 | } | 6751 | } |
| 6745 | 6752 |
src/Sema.zig+104-72| ... | @@ -2490,9 +2490,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -2490,9 +2490,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 2490 | const operand = try trash_block.addBitCast(pointee_ty, .void_value); | 2490 | const operand = try trash_block.addBitCast(pointee_ty, .void_value); |
| 2491 | 2491 | ||
| 2492 | const ptr_ty = try mod.ptrType(.{ | 2492 | const ptr_ty = try mod.ptrType(.{ |
| 2493 | .elem_type = pointee_ty.toIntern(), | 2493 | .child = pointee_ty.toIntern(), |
| 2494 | .alignment = ia1.alignment, | 2494 | .flags = .{ |
| 2495 | .address_space = addr_space, | 2495 | .alignment = ia1.alignment, |
| 2496 | .address_space = addr_space, | ||
| 2497 | }, | ||
| 2496 | }); | 2498 | }); |
| 2497 | const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr); | 2499 | const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr); |
| 2498 | 2500 | ||
| ... | @@ -2519,9 +2521,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -2519,9 +2521,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 2519 | try sema.resolveTypeLayout(pointee_ty); | 2521 | try sema.resolveTypeLayout(pointee_ty); |
| 2520 | } | 2522 | } |
| 2521 | const ptr_ty = try mod.ptrType(.{ | 2523 | const ptr_ty = try mod.ptrType(.{ |
| 2522 | .elem_type = pointee_ty.toIntern(), | 2524 | .child = pointee_ty.toIntern(), |
| 2523 | .alignment = alignment, | 2525 | .flags = .{ |
| 2524 | .address_space = addr_space, | 2526 | .alignment = alignment, |
| 2527 | .address_space = addr_space, | ||
| 2528 | }, | ||
| 2525 | }); | 2529 | }); |
| 2526 | try sema.maybeQueueFuncBodyAnalysis(decl_index); | 2530 | try sema.maybeQueueFuncBodyAnalysis(decl_index); |
| 2527 | return sema.addConstant(ptr_ty, (try mod.intern(.{ .ptr = .{ | 2531 | return sema.addConstant(ptr_ty, (try mod.intern(.{ .ptr = .{ |
| ... | @@ -3771,10 +3775,12 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3771,10 +3775,12 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3771 | if (iac.is_const) try decl.intern(mod); | 3775 | if (iac.is_const) try decl.intern(mod); |
| 3772 | const final_elem_ty = decl.ty; | 3776 | const final_elem_ty = decl.ty; |
| 3773 | const final_ptr_ty = try mod.ptrType(.{ | 3777 | const final_ptr_ty = try mod.ptrType(.{ |
| 3774 | .elem_type = final_elem_ty.toIntern(), | 3778 | .child = final_elem_ty.toIntern(), |
| 3775 | .is_const = false, | 3779 | .flags = .{ |
| 3776 | .alignment = iac.alignment, | 3780 | .is_const = false, |
| 3777 | .address_space = target_util.defaultAddressSpace(target, .local), | 3781 | .alignment = iac.alignment, |
| 3782 | .address_space = target_util.defaultAddressSpace(target, .local), | ||
| 3783 | }, | ||
| 3778 | }); | 3784 | }); |
| 3779 | 3785 | ||
| 3780 | try sema.maybeQueueFuncBodyAnalysis(decl_index); | 3786 | try sema.maybeQueueFuncBodyAnalysis(decl_index); |
| ... | @@ -3797,9 +3803,11 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3797,9 +3803,11 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3797 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none); | 3803 | const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_inst_list, .none); |
| 3798 | 3804 | ||
| 3799 | const final_ptr_ty = try mod.ptrType(.{ | 3805 | const final_ptr_ty = try mod.ptrType(.{ |
| 3800 | .elem_type = final_elem_ty.toIntern(), | 3806 | .child = final_elem_ty.toIntern(), |
| 3801 | .alignment = ia1.alignment, | 3807 | .flags = .{ |
| 3802 | .address_space = target_util.defaultAddressSpace(target, .local), | 3808 | .alignment = ia1.alignment, |
| 3809 | .address_space = target_util.defaultAddressSpace(target, .local), | ||
| 3810 | }, | ||
| 3803 | }); | 3811 | }); |
| 3804 | 3812 | ||
| 3805 | if (!ia1.is_const) { | 3813 | if (!ia1.is_const) { |
| ... | @@ -3916,9 +3924,11 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3916,9 +3924,11 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3916 | defer trash_block.instructions.deinit(gpa); | 3924 | defer trash_block.instructions.deinit(gpa); |
| 3917 | 3925 | ||
| 3918 | const mut_final_ptr_ty = try mod.ptrType(.{ | 3926 | const mut_final_ptr_ty = try mod.ptrType(.{ |
| 3919 | .elem_type = final_elem_ty.toIntern(), | 3927 | .child = final_elem_ty.toIntern(), |
| 3920 | .alignment = ia1.alignment, | 3928 | .flags = .{ |
| 3921 | .address_space = target_util.defaultAddressSpace(target, .local), | 3929 | .alignment = ia1.alignment, |
| 3930 | .address_space = target_util.defaultAddressSpace(target, .local), | ||
| 3931 | }, | ||
| 3922 | }); | 3932 | }); |
| 3923 | const dummy_ptr = try trash_block.addTy(.alloc, mut_final_ptr_ty); | 3933 | const dummy_ptr = try trash_block.addTy(.alloc, mut_final_ptr_ty); |
| 3924 | const empty_trash_count = trash_block.instructions.items.len; | 3934 | const empty_trash_count = trash_block.instructions.items.len; |
| ... | @@ -12038,7 +12048,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -12038,7 +12048,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 12038 | 12048 | ||
| 12039 | const has_field = hf: { | 12049 | const has_field = hf: { |
| 12040 | switch (ip.indexToKey(ty.toIntern())) { | 12050 | switch (ip.indexToKey(ty.toIntern())) { |
| 12041 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 12051 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 12042 | .Slice => { | 12052 | .Slice => { |
| 12043 | if (mem.eql(u8, field_name, "ptr")) break :hf true; | 12053 | if (mem.eql(u8, field_name, "ptr")) break :hf true; |
| 12044 | if (mem.eql(u8, field_name, "len")) break :hf true; | 12054 | if (mem.eql(u8, field_name, "len")) break :hf true; |
| ... | @@ -16019,9 +16029,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16019,9 +16029,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16019 | ); | 16029 | ); |
| 16020 | break :v try mod.intern(.{ .ptr = .{ | 16030 | break :v try mod.intern(.{ .ptr = .{ |
| 16021 | .ty = (try mod.ptrType(.{ | 16031 | .ty = (try mod.ptrType(.{ |
| 16022 | .elem_type = param_info_ty.toIntern(), | 16032 | .child = param_info_ty.toIntern(), |
| 16023 | .size = .Slice, | 16033 | .flags = .{ |
| 16024 | .is_const = true, | 16034 | .size = .Slice, |
| 16035 | .is_const = true, | ||
| 16036 | }, | ||
| 16025 | })).toIntern(), | 16037 | })).toIntern(), |
| 16026 | .addr = .{ .decl = new_decl }, | 16038 | .addr = .{ .decl = new_decl }, |
| 16027 | .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(), | 16039 | .len = (try mod.intValue(Type.usize, param_vals.len)).toIntern(), |
| ... | @@ -16329,9 +16341,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16329,9 +16341,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16329 | 16341 | ||
| 16330 | // Build our ?[]const Error value | 16342 | // Build our ?[]const Error value |
| 16331 | const slice_errors_ty = try mod.ptrType(.{ | 16343 | const slice_errors_ty = try mod.ptrType(.{ |
| 16332 | .elem_type = error_field_ty.toIntern(), | 16344 | .child = error_field_ty.toIntern(), |
| 16333 | .size = .Slice, | 16345 | .flags = .{ |
| 16334 | .is_const = true, | 16346 | .size = .Slice, |
| 16347 | .is_const = true, | ||
| 16348 | }, | ||
| 16335 | }); | 16349 | }); |
| 16336 | const opt_slice_errors_ty = try mod.optionalType(slice_errors_ty.toIntern()); | 16350 | const opt_slice_errors_ty = try mod.optionalType(slice_errors_ty.toIntern()); |
| 16337 | const errors_payload_val: InternPool.Index = if (error_field_vals) |vals| v: { | 16351 | const errors_payload_val: InternPool.Index = if (error_field_vals) |vals| v: { |
| ... | @@ -16471,9 +16485,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16471,9 +16485,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16471 | ); | 16485 | ); |
| 16472 | break :v try mod.intern(.{ .ptr = .{ | 16486 | break :v try mod.intern(.{ .ptr = .{ |
| 16473 | .ty = (try mod.ptrType(.{ | 16487 | .ty = (try mod.ptrType(.{ |
| 16474 | .elem_type = enum_field_ty.toIntern(), | 16488 | .child = enum_field_ty.toIntern(), |
| 16475 | .size = .Slice, | 16489 | .flags = .{ |
| 16476 | .is_const = true, | 16490 | .size = .Slice, |
| 16491 | .is_const = true, | ||
| 16492 | }, | ||
| 16477 | })).toIntern(), | 16493 | })).toIntern(), |
| 16478 | .addr = .{ .decl = new_decl }, | 16494 | .addr = .{ .decl = new_decl }, |
| 16479 | .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(), | 16495 | .len = (try mod.intValue(Type.usize, enum_field_vals.len)).toIntern(), |
| ... | @@ -16614,9 +16630,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16614,9 +16630,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16614 | ); | 16630 | ); |
| 16615 | break :v try mod.intern(.{ .ptr = .{ | 16631 | break :v try mod.intern(.{ .ptr = .{ |
| 16616 | .ty = (try mod.ptrType(.{ | 16632 | .ty = (try mod.ptrType(.{ |
| 16617 | .elem_type = union_field_ty.toIntern(), | 16633 | .child = union_field_ty.toIntern(), |
| 16618 | .size = .Slice, | 16634 | .flags = .{ |
| 16619 | .is_const = true, | 16635 | .size = .Slice, |
| 16636 | .is_const = true, | ||
| 16637 | }, | ||
| 16620 | })).toIntern(), | 16638 | })).toIntern(), |
| 16621 | .addr = .{ .decl = new_decl }, | 16639 | .addr = .{ .decl = new_decl }, |
| 16622 | .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(), | 16640 | .len = (try mod.intValue(Type.usize, union_field_vals.len)).toIntern(), |
| ... | @@ -16833,9 +16851,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16833,9 +16851,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16833 | ); | 16851 | ); |
| 16834 | break :v try mod.intern(.{ .ptr = .{ | 16852 | break :v try mod.intern(.{ .ptr = .{ |
| 16835 | .ty = (try mod.ptrType(.{ | 16853 | .ty = (try mod.ptrType(.{ |
| 16836 | .elem_type = struct_field_ty.toIntern(), | 16854 | .child = struct_field_ty.toIntern(), |
| 16837 | .size = .Slice, | 16855 | .flags = .{ |
| 16838 | .is_const = true, | 16856 | .size = .Slice, |
| 16857 | .is_const = true, | ||
| 16858 | }, | ||
| 16839 | })).toIntern(), | 16859 | })).toIntern(), |
| 16840 | .addr = .{ .decl = new_decl }, | 16860 | .addr = .{ .decl = new_decl }, |
| 16841 | .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(), | 16861 | .len = (try mod.intValue(Type.usize, struct_field_vals.len)).toIntern(), |
| ... | @@ -16976,9 +16996,11 @@ fn typeInfoDecls( | ... | @@ -16976,9 +16996,11 @@ fn typeInfoDecls( |
| 16976 | ); | 16996 | ); |
| 16977 | return try mod.intern(.{ .ptr = .{ | 16997 | return try mod.intern(.{ .ptr = .{ |
| 16978 | .ty = (try mod.ptrType(.{ | 16998 | .ty = (try mod.ptrType(.{ |
| 16979 | .elem_type = declaration_ty.toIntern(), | 16999 | .child = declaration_ty.toIntern(), |
| 16980 | .size = .Slice, | 17000 | .flags = .{ |
| 16981 | .is_const = true, | 17001 | .size = .Slice, |
| 17002 | .is_const = true, | ||
| 17003 | }, | ||
| 16982 | })).toIntern(), | 17004 | })).toIntern(), |
| 16983 | .addr = .{ .decl = new_decl }, | 17005 | .addr = .{ .decl = new_decl }, |
| 16984 | .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(), | 17006 | .len = (try mod.intValue(Type.usize, decl_vals.items.len)).toIntern(), |
| ... | @@ -18047,16 +18069,20 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -18047,16 +18069,20 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18047 | } | 18069 | } |
| 18048 | 18070 | ||
| 18049 | const ty = try mod.ptrType(.{ | 18071 | const ty = try mod.ptrType(.{ |
| 18050 | .elem_type = elem_ty.toIntern(), | 18072 | .child = elem_ty.toIntern(), |
| 18051 | .sentinel = sentinel, | 18073 | .sentinel = sentinel, |
| 18052 | .alignment = abi_align, | 18074 | .flags = .{ |
| 18053 | .address_space = address_space, | 18075 | .alignment = abi_align, |
| 18054 | .bit_offset = bit_offset, | 18076 | .address_space = address_space, |
| 18055 | .host_size = host_size, | 18077 | .is_const = !inst_data.flags.is_mutable, |
| 18056 | .is_const = !inst_data.flags.is_mutable, | 18078 | .is_allowzero = inst_data.flags.is_allowzero, |
| 18057 | .is_allowzero = inst_data.flags.is_allowzero, | 18079 | .is_volatile = inst_data.flags.is_volatile, |
| 18058 | .is_volatile = inst_data.flags.is_volatile, | 18080 | .size = inst_data.size, |
| 18059 | .size = inst_data.size, | 18081 | }, |
| 18082 | .packed_offset = .{ | ||
| 18083 | .bit_offset = bit_offset, | ||
| 18084 | .host_size = host_size, | ||
| 18085 | }, | ||
| 18060 | }); | 18086 | }); |
| 18061 | return sema.addType(ty); | 18087 | return sema.addType(ty); |
| 18062 | } | 18088 | } |
| ... | @@ -19209,14 +19235,16 @@ fn zirReify( | ... | @@ -19209,14 +19235,16 @@ fn zirReify( |
| 19209 | } | 19235 | } |
| 19210 | 19236 | ||
| 19211 | const ty = try mod.ptrType(.{ | 19237 | const ty = try mod.ptrType(.{ |
| 19212 | .size = ptr_size, | 19238 | .child = elem_ty.toIntern(), |
| 19213 | .is_const = is_const_val.toBool(), | ||
| 19214 | .is_volatile = is_volatile_val.toBool(), | ||
| 19215 | .alignment = abi_align, | ||
| 19216 | .address_space = mod.toEnum(std.builtin.AddressSpace, address_space_val), | ||
| 19217 | .elem_type = elem_ty.toIntern(), | ||
| 19218 | .is_allowzero = is_allowzero_val.toBool(), | ||
| 19219 | .sentinel = actual_sentinel, | 19239 | .sentinel = actual_sentinel, |
| 19240 | .flags = .{ | ||
| 19241 | .size = ptr_size, | ||
| 19242 | .is_const = is_const_val.toBool(), | ||
| 19243 | .is_volatile = is_volatile_val.toBool(), | ||
| 19244 | .alignment = abi_align, | ||
| 19245 | .address_space = mod.toEnum(std.builtin.AddressSpace, address_space_val), | ||
| 19246 | .is_allowzero = is_allowzero_val.toBool(), | ||
| 19247 | }, | ||
| 19220 | }); | 19248 | }); |
| 19221 | return sema.addType(ty); | 19249 | return sema.addType(ty); |
| 19222 | }, | 19250 | }, |
| ... | @@ -22714,9 +22742,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -22714,9 +22742,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 22714 | try sema.analyzeSlicePtr(block, dest_src, new_dest_ptr, new_dest_ptr_ty) | 22742 | try sema.analyzeSlicePtr(block, dest_src, new_dest_ptr, new_dest_ptr_ty) |
| 22715 | else if (new_dest_ptr_ty.ptrSize(mod) == .One) ptr: { | 22743 | else if (new_dest_ptr_ty.ptrSize(mod) == .One) ptr: { |
| 22716 | var dest_manyptr_ty_key = mod.intern_pool.indexToKey(new_dest_ptr_ty.toIntern()).ptr_type; | 22744 | var dest_manyptr_ty_key = mod.intern_pool.indexToKey(new_dest_ptr_ty.toIntern()).ptr_type; |
| 22717 | assert(dest_manyptr_ty_key.size == .One); | 22745 | assert(dest_manyptr_ty_key.flags.size == .One); |
| 22718 | dest_manyptr_ty_key.elem_type = dest_elem_ty.toIntern(); | 22746 | dest_manyptr_ty_key.child = dest_elem_ty.toIntern(); |
| 22719 | dest_manyptr_ty_key.size = .Many; | 22747 | dest_manyptr_ty_key.flags.size = .Many; |
| 22720 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrType(dest_manyptr_ty_key), new_dest_ptr, dest_src); | 22748 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrType(dest_manyptr_ty_key), new_dest_ptr, dest_src); |
| 22721 | } else new_dest_ptr; | 22749 | } else new_dest_ptr; |
| 22722 | 22750 | ||
| ... | @@ -22725,9 +22753,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -22725,9 +22753,9 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 22725 | try sema.analyzeSlicePtr(block, src_src, new_src_ptr, new_src_ptr_ty) | 22753 | try sema.analyzeSlicePtr(block, src_src, new_src_ptr, new_src_ptr_ty) |
| 22726 | else if (new_src_ptr_ty.ptrSize(mod) == .One) ptr: { | 22754 | else if (new_src_ptr_ty.ptrSize(mod) == .One) ptr: { |
| 22727 | var src_manyptr_ty_key = mod.intern_pool.indexToKey(new_src_ptr_ty.toIntern()).ptr_type; | 22755 | var src_manyptr_ty_key = mod.intern_pool.indexToKey(new_src_ptr_ty.toIntern()).ptr_type; |
| 22728 | assert(src_manyptr_ty_key.size == .One); | 22756 | assert(src_manyptr_ty_key.flags.size == .One); |
| 22729 | src_manyptr_ty_key.elem_type = src_elem_ty.toIntern(); | 22757 | src_manyptr_ty_key.child = src_elem_ty.toIntern(); |
| 22730 | src_manyptr_ty_key.size = .Many; | 22758 | src_manyptr_ty_key.flags.size = .Many; |
| 22731 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrType(src_manyptr_ty_key), new_src_ptr, src_src); | 22759 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrType(src_manyptr_ty_key), new_src_ptr, src_src); |
| 22732 | } else new_src_ptr; | 22760 | } else new_src_ptr; |
| 22733 | 22761 | ||
| ... | @@ -24036,8 +24064,10 @@ fn panicWithMsg( | ... | @@ -24036,8 +24064,10 @@ fn panicWithMsg( |
| 24036 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); | 24064 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 24037 | const target = mod.getTarget(); | 24065 | const target = mod.getTarget(); |
| 24038 | const ptr_stack_trace_ty = try mod.ptrType(.{ | 24066 | const ptr_stack_trace_ty = try mod.ptrType(.{ |
| 24039 | .elem_type = stack_trace_ty.toIntern(), | 24067 | .child = stack_trace_ty.toIntern(), |
| 24040 | .address_space = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic | 24068 | .flags = .{ |
| 24069 | .address_space = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic | ||
| 24070 | }, | ||
| 24041 | }); | 24071 | }); |
| 24042 | const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern()); | 24072 | const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern()); |
| 24043 | const null_stack_trace = try sema.addConstant(opt_ptr_stack_trace_ty, (try mod.intern(.{ .opt = .{ | 24073 | const null_stack_trace = try sema.addConstant(opt_ptr_stack_trace_ty, (try mod.intern(.{ .opt = .{ |
| ... | @@ -29630,10 +29660,12 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo | ... | @@ -29630,10 +29660,12 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: boo |
| 29630 | const decl = mod.declPtr(decl_index); | 29660 | const decl = mod.declPtr(decl_index); |
| 29631 | const decl_tv = try decl.typedValue(); | 29661 | const decl_tv = try decl.typedValue(); |
| 29632 | const ptr_ty = try mod.ptrType(.{ | 29662 | const ptr_ty = try mod.ptrType(.{ |
| 29633 | .elem_type = decl_tv.ty.toIntern(), | 29663 | .child = decl_tv.ty.toIntern(), |
| 29634 | .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"), | 29664 | .flags = .{ |
| 29635 | .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true, | 29665 | .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"), |
| 29636 | .address_space = decl.@"addrspace", | 29666 | .is_const = if (decl.val.getVariable(mod)) |variable| variable.is_const else true, |
| 29667 | .address_space = decl.@"addrspace", | ||
| 29668 | }, | ||
| 29637 | }); | 29669 | }); |
| 29638 | if (analyze_fn_body) { | 29670 | if (analyze_fn_body) { |
| 29639 | try sema.maybeQueueFuncBodyAnalysis(decl_index); | 29671 | try sema.maybeQueueFuncBodyAnalysis(decl_index); |
| ... | @@ -30025,10 +30057,10 @@ fn analyzeSlice( | ... | @@ -30025,10 +30057,10 @@ fn analyzeSlice( |
| 30025 | try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty) | 30057 | try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty) |
| 30026 | else if (array_ty.zigTypeTag(mod) == .Array) ptr: { | 30058 | else if (array_ty.zigTypeTag(mod) == .Array) ptr: { |
| 30027 | var manyptr_ty_key = mod.intern_pool.indexToKey(slice_ty.toIntern()).ptr_type; | 30059 | var manyptr_ty_key = mod.intern_pool.indexToKey(slice_ty.toIntern()).ptr_type; |
| 30028 | assert(manyptr_ty_key.elem_type == array_ty.toIntern()); | 30060 | assert(manyptr_ty_key.child == array_ty.toIntern()); |
| 30029 | assert(manyptr_ty_key.size == .One); | 30061 | assert(manyptr_ty_key.flags.size == .One); |
| 30030 | manyptr_ty_key.elem_type = elem_ty.toIntern(); | 30062 | manyptr_ty_key.child = elem_ty.toIntern(); |
| 30031 | manyptr_ty_key.size = .Many; | 30063 | manyptr_ty_key.flags.size = .Many; |
| 30032 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrType(manyptr_ty_key), ptr_or_slice, ptr_src); | 30064 | break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrType(manyptr_ty_key), ptr_or_slice, ptr_src); |
| 30033 | } else ptr_or_slice; | 30065 | } else ptr_or_slice; |
| 30034 | 30066 | ||
| ... | @@ -31972,7 +32004,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { | ... | @@ -31972,7 +32004,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 31972 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 32004 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 31973 | .int_type => false, | 32005 | .int_type => false, |
| 31974 | .ptr_type => |ptr_type| { | 32006 | .ptr_type => |ptr_type| { |
| 31975 | const child_ty = ptr_type.elem_type.toType(); | 32007 | const child_ty = ptr_type.child.toType(); |
| 31976 | if (child_ty.zigTypeTag(mod) == .Fn) { | 32008 | if (child_ty.zigTypeTag(mod) == .Fn) { |
| 31977 | return mod.typeToFunc(child_ty).?.is_generic; | 32009 | return mod.typeToFunc(child_ty).?.is_generic; |
| 31978 | } else { | 32010 | } else { |
| ... | @@ -33917,15 +33949,15 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError | ... | @@ -33917,15 +33949,15 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError |
| 33917 | fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { | 33949 | fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { |
| 33918 | const mod = sema.mod; | 33950 | const mod = sema.mod; |
| 33919 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 33951 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 33920 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 33952 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 33921 | .One, .Many, .C => ty, | 33953 | .One, .Many, .C => ty, |
| 33922 | .Slice => null, | 33954 | .Slice => null, |
| 33923 | }, | 33955 | }, |
| 33924 | .opt_type => |opt_child| switch (mod.intern_pool.indexToKey(opt_child)) { | 33956 | .opt_type => |opt_child| switch (mod.intern_pool.indexToKey(opt_child)) { |
| 33925 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 33957 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 33926 | .Slice, .C => null, | 33958 | .Slice, .C => null, |
| 33927 | .Many, .One => { | 33959 | .Many, .One => { |
| 33928 | if (ptr_type.is_allowzero) return null; | 33960 | if (ptr_type.flags.is_allowzero) return null; |
| 33929 | 33961 | ||
| 33930 | // optionals of zero sized types behave like bools, not pointers | 33962 | // optionals of zero sized types behave like bools, not pointers |
| 33931 | const payload_ty = opt_child.toType(); | 33963 | const payload_ty = opt_child.toType(); |
| ... | @@ -33956,7 +33988,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { | ... | @@ -33956,7 +33988,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 33956 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 33988 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 33957 | .int_type => return false, | 33989 | .int_type => return false, |
| 33958 | .ptr_type => |ptr_type| { | 33990 | .ptr_type => |ptr_type| { |
| 33959 | const child_ty = ptr_type.elem_type.toType(); | 33991 | const child_ty = ptr_type.child.toType(); |
| 33960 | if (child_ty.zigTypeTag(mod) == .Fn) { | 33992 | if (child_ty.zigTypeTag(mod) == .Fn) { |
| 33961 | return mod.typeToFunc(child_ty).?.is_generic; | 33993 | return mod.typeToFunc(child_ty).?.is_generic; |
| 33962 | } else { | 33994 | } else { |
src/codegen.zig+2-2| ... | @@ -673,7 +673,7 @@ fn lowerParentPtr( | ... | @@ -673,7 +673,7 @@ fn lowerParentPtr( |
| 673 | mod.intern_pool.typeOf(elem.base).toType().elemType2(mod).abiSize(mod))), | 673 | mod.intern_pool.typeOf(elem.base).toType().elemType2(mod).abiSize(mod))), |
| 674 | ), | 674 | ), |
| 675 | .field => |field| { | 675 | .field => |field| { |
| 676 | const base_type = mod.intern_pool.indexToKey(mod.intern_pool.typeOf(field.base)).ptr_type.elem_type; | 676 | const base_type = mod.intern_pool.indexToKey(mod.intern_pool.typeOf(field.base)).ptr_type.child; |
| 677 | return lowerParentPtr( | 677 | return lowerParentPtr( |
| 678 | bin_file, | 678 | bin_file, |
| 679 | src_loc, | 679 | src_loc, |
| ... | @@ -681,7 +681,7 @@ fn lowerParentPtr( | ... | @@ -681,7 +681,7 @@ fn lowerParentPtr( |
| 681 | code, | 681 | code, |
| 682 | debug_output, | 682 | debug_output, |
| 683 | reloc_info.offset(switch (mod.intern_pool.indexToKey(base_type)) { | 683 | reloc_info.offset(switch (mod.intern_pool.indexToKey(base_type)) { |
| 684 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 684 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 685 | .One, .Many, .C => unreachable, | 685 | .One, .Many, .C => unreachable, |
| 686 | .Slice => switch (field.index) { | 686 | .Slice => switch (field.index) { |
| 687 | 0 => 0, | 687 | 0 => 0, |
src/codegen/c.zig+6-4| ... | @@ -630,7 +630,7 @@ pub const DeclGen = struct { | ... | @@ -630,7 +630,7 @@ pub const DeclGen = struct { |
| 630 | try writer.writeByte(')'); | 630 | try writer.writeByte(')'); |
| 631 | } | 631 | } |
| 632 | try writer.writeAll("&("); | 632 | try writer.writeAll("&("); |
| 633 | if (mod.intern_pool.indexToKey(ptr_base_ty.toIntern()).ptr_type.size == .One) | 633 | if (mod.intern_pool.indexToKey(ptr_base_ty.toIntern()).ptr_type.flags.size == .One) |
| 634 | try writer.writeByte('*'); | 634 | try writer.writeByte('*'); |
| 635 | try dg.renderParentPtr(writer, elem.base, location); | 635 | try dg.renderParentPtr(writer, elem.base, location); |
| 636 | try writer.print(")[{d}]", .{elem.index}); | 636 | try writer.print(")[{d}]", .{elem.index}); |
| ... | @@ -642,7 +642,7 @@ pub const DeclGen = struct { | ... | @@ -642,7 +642,7 @@ pub const DeclGen = struct { |
| 642 | _ = try dg.typeToIndex(base_ty, .complete); | 642 | _ = try dg.typeToIndex(base_ty, .complete); |
| 643 | const field_ty = switch (mod.intern_pool.indexToKey(base_ty.toIntern())) { | 643 | const field_ty = switch (mod.intern_pool.indexToKey(base_ty.toIntern())) { |
| 644 | .anon_struct_type, .struct_type, .union_type => base_ty.structFieldType(field.index, mod), | 644 | .anon_struct_type, .struct_type, .union_type => base_ty.structFieldType(field.index, mod), |
| 645 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 645 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 646 | .One, .Many, .C => unreachable, | 646 | .One, .Many, .C => unreachable, |
| 647 | .Slice => switch (field.index) { | 647 | .Slice => switch (field.index) { |
| 648 | Value.slice_ptr_index => base_ty.slicePtrFieldType(mod), | 648 | Value.slice_ptr_index => base_ty.slicePtrFieldType(mod), |
| ... | @@ -6285,8 +6285,10 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -6285,8 +6285,10 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6285 | // casted to a regular pointer, otherwise an error like this occurs: | 6285 | // casted to a regular pointer, otherwise an error like this occurs: |
| 6286 | // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable | 6286 | // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable |
| 6287 | const elem_ptr_ty = try mod.ptrType(.{ | 6287 | const elem_ptr_ty = try mod.ptrType(.{ |
| 6288 | .size = .C, | 6288 | .child = elem_ty.ip_index, |
| 6289 | .elem_type = elem_ty.ip_index, | 6289 | .flags = .{ |
| 6290 | .size = .C, | ||
| 6291 | }, | ||
| 6290 | }); | 6292 | }); |
| 6291 | 6293 | ||
| 6292 | const index = try f.allocLocal(inst, Type.usize); | 6294 | const index = try f.allocLocal(inst, Type.usize); |
src/codegen/llvm.zig+37-27| ... | @@ -1577,25 +1577,27 @@ pub const Object = struct { | ... | @@ -1577,25 +1577,27 @@ pub const Object = struct { |
| 1577 | const ptr_info = Type.ptrInfoIp(&mod.intern_pool, ty.toIntern()); | 1577 | const ptr_info = Type.ptrInfoIp(&mod.intern_pool, ty.toIntern()); |
| 1578 | 1578 | ||
| 1579 | if (ptr_info.sentinel != .none or | 1579 | if (ptr_info.sentinel != .none or |
| 1580 | ptr_info.address_space != .generic or | 1580 | ptr_info.flags.address_space != .generic or |
| 1581 | ptr_info.bit_offset != 0 or | 1581 | ptr_info.packed_offset.bit_offset != 0 or |
| 1582 | ptr_info.host_size != 0 or | 1582 | ptr_info.packed_offset.host_size != 0 or |
| 1583 | ptr_info.vector_index != .none or | 1583 | ptr_info.flags.vector_index != .none or |
| 1584 | ptr_info.is_allowzero or | 1584 | ptr_info.flags.is_allowzero or |
| 1585 | ptr_info.is_const or | 1585 | ptr_info.flags.is_const or |
| 1586 | ptr_info.is_volatile or | 1586 | ptr_info.flags.is_volatile or |
| 1587 | ptr_info.size == .Many or ptr_info.size == .C or | 1587 | ptr_info.flags.size == .Many or ptr_info.flags.size == .C or |
| 1588 | !ptr_info.elem_type.toType().hasRuntimeBitsIgnoreComptime(mod)) | 1588 | !ptr_info.child.toType().hasRuntimeBitsIgnoreComptime(mod)) |
| 1589 | { | 1589 | { |
| 1590 | const bland_ptr_ty = try mod.ptrType(.{ | 1590 | const bland_ptr_ty = try mod.ptrType(.{ |
| 1591 | .elem_type = if (!ptr_info.elem_type.toType().hasRuntimeBitsIgnoreComptime(mod)) | 1591 | .child = if (!ptr_info.child.toType().hasRuntimeBitsIgnoreComptime(mod)) |
| 1592 | .anyopaque_type | 1592 | .anyopaque_type |
| 1593 | else | 1593 | else |
| 1594 | ptr_info.elem_type, | 1594 | ptr_info.child, |
| 1595 | .alignment = ptr_info.alignment, | 1595 | .flags = .{ |
| 1596 | .size = switch (ptr_info.size) { | 1596 | .alignment = ptr_info.flags.alignment, |
| 1597 | .Many, .C, .One => .One, | 1597 | .size = switch (ptr_info.flags.size) { |
| 1598 | .Slice => .Slice, | 1598 | .Many, .C, .One => .One, |
| 1599 | .Slice => .Slice, | ||
| 1600 | }, | ||
| 1599 | }, | 1601 | }, |
| 1600 | }); | 1602 | }); |
| 1601 | const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve); | 1603 | const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve); |
| ... | @@ -1683,7 +1685,7 @@ pub const Object = struct { | ... | @@ -1683,7 +1685,7 @@ pub const Object = struct { |
| 1683 | return full_di_ty; | 1685 | return full_di_ty; |
| 1684 | } | 1686 | } |
| 1685 | 1687 | ||
| 1686 | const elem_di_ty = try o.lowerDebugType(ptr_info.elem_type.toType(), .fwd); | 1688 | const elem_di_ty = try o.lowerDebugType(ptr_info.child.toType(), .fwd); |
| 1687 | const name = try ty.nameAlloc(gpa, o.module); | 1689 | const name = try ty.nameAlloc(gpa, o.module); |
| 1688 | defer gpa.free(name); | 1690 | defer gpa.free(name); |
| 1689 | const ptr_di_ty = dib.createPointerType( | 1691 | const ptr_di_ty = dib.createPointerType( |
| ... | @@ -5856,8 +5858,10 @@ pub const FuncGen = struct { | ... | @@ -5856,8 +5858,10 @@ pub const FuncGen = struct { |
| 5856 | const struct_llvm_ty = try self.dg.lowerType(struct_ty); | 5858 | const struct_llvm_ty = try self.dg.lowerType(struct_ty); |
| 5857 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); | 5859 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); |
| 5858 | const field_ptr_ty = try mod.ptrType(.{ | 5860 | const field_ptr_ty = try mod.ptrType(.{ |
| 5859 | .elem_type = llvm_field.ty.toIntern(), | 5861 | .child = llvm_field.ty.toIntern(), |
| 5860 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment), | 5862 | .flags = .{ |
| 5863 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment), | ||
| 5864 | }, | ||
| 5861 | }); | 5865 | }); |
| 5862 | if (isByRef(field_ty, mod)) { | 5866 | if (isByRef(field_ty, mod)) { |
| 5863 | if (canElideLoad(self, body_tail)) | 5867 | if (canElideLoad(self, body_tail)) |
| ... | @@ -6732,8 +6736,10 @@ pub const FuncGen = struct { | ... | @@ -6732,8 +6736,10 @@ pub const FuncGen = struct { |
| 6732 | const struct_llvm_ty = try self.dg.lowerType(struct_ty); | 6736 | const struct_llvm_ty = try self.dg.lowerType(struct_ty); |
| 6733 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); | 6737 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); |
| 6734 | const field_ptr_ty = try mod.ptrType(.{ | 6738 | const field_ptr_ty = try mod.ptrType(.{ |
| 6735 | .elem_type = llvm_field.ty.toIntern(), | 6739 | .child = llvm_field.ty.toIntern(), |
| 6736 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment), | 6740 | .flags = .{ |
| 6741 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment), | ||
| 6742 | }, | ||
| 6737 | }); | 6743 | }); |
| 6738 | return self.load(field_ptr, field_ptr_ty); | 6744 | return self.load(field_ptr, field_ptr_ty); |
| 6739 | } | 6745 | } |
| ... | @@ -9131,10 +9137,12 @@ pub const FuncGen = struct { | ... | @@ -9131,10 +9137,12 @@ pub const FuncGen = struct { |
| 9131 | indices[1] = llvm_u32.constInt(llvm_i, .False); | 9137 | indices[1] = llvm_u32.constInt(llvm_i, .False); |
| 9132 | const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, ""); | 9138 | const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, ""); |
| 9133 | const field_ptr_ty = try mod.ptrType(.{ | 9139 | const field_ptr_ty = try mod.ptrType(.{ |
| 9134 | .elem_type = self.typeOf(elem).toIntern(), | 9140 | .child = self.typeOf(elem).toIntern(), |
| 9135 | .alignment = InternPool.Alignment.fromNonzeroByteUnits( | 9141 | .flags = .{ |
| 9136 | result_ty.structFieldAlign(i, mod), | 9142 | .alignment = InternPool.Alignment.fromNonzeroByteUnits( |
| 9137 | ), | 9143 | result_ty.structFieldAlign(i, mod), |
| 9144 | ), | ||
| 9145 | }, | ||
| 9138 | }); | 9146 | }); |
| 9139 | try self.store(field_ptr, field_ptr_ty, llvm_elem, .NotAtomic); | 9147 | try self.store(field_ptr, field_ptr_ty, llvm_elem, .NotAtomic); |
| 9140 | } | 9148 | } |
| ... | @@ -9160,7 +9168,7 @@ pub const FuncGen = struct { | ... | @@ -9160,7 +9168,7 @@ pub const FuncGen = struct { |
| 9160 | 9168 | ||
| 9161 | const array_info = result_ty.arrayInfo(mod); | 9169 | const array_info = result_ty.arrayInfo(mod); |
| 9162 | const elem_ptr_ty = try mod.ptrType(.{ | 9170 | const elem_ptr_ty = try mod.ptrType(.{ |
| 9163 | .elem_type = array_info.elem_type.toIntern(), | 9171 | .child = array_info.elem_type.toIntern(), |
| 9164 | }); | 9172 | }); |
| 9165 | 9173 | ||
| 9166 | for (elements, 0..) |elem, i| { | 9174 | for (elements, 0..) |elem, i| { |
| ... | @@ -9282,8 +9290,10 @@ pub const FuncGen = struct { | ... | @@ -9282,8 +9290,10 @@ pub const FuncGen = struct { |
| 9282 | const index_type = self.context.intType(32); | 9290 | const index_type = self.context.intType(32); |
| 9283 | 9291 | ||
| 9284 | const field_ptr_ty = try mod.ptrType(.{ | 9292 | const field_ptr_ty = try mod.ptrType(.{ |
| 9285 | .elem_type = field.ty.toIntern(), | 9293 | .child = field.ty.toIntern(), |
| 9286 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(field_align), | 9294 | .flags = .{ |
| 9295 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(field_align), | ||
| 9296 | }, | ||
| 9287 | }); | 9297 | }); |
| 9288 | if (layout.tag_size == 0) { | 9298 | if (layout.tag_size == 0) { |
| 9289 | const indices: [3]*llvm.Value = .{ | 9299 | const indices: [3]*llvm.Value = .{ |
src/type.zig+56-52| ... | @@ -85,7 +85,7 @@ pub const Type = struct { | ... | @@ -85,7 +85,7 @@ pub const Type = struct { |
| 85 | 85 | ||
| 86 | /// Asserts the type is a pointer. | 86 | /// Asserts the type is a pointer. |
| 87 | pub fn ptrIsMutable(ty: Type, mod: *const Module) bool { | 87 | pub fn ptrIsMutable(ty: Type, mod: *const Module) bool { |
| 88 | return !mod.intern_pool.indexToKey(ty.toIntern()).ptr_type.is_const; | 88 | return !mod.intern_pool.indexToKey(ty.toIntern()).ptr_type.flags.is_const; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | pub const ArrayInfo = struct { | 91 | pub const ArrayInfo = struct { |
| ... | @@ -488,7 +488,7 @@ pub const Type = struct { | ... | @@ -488,7 +488,7 @@ pub const Type = struct { |
| 488 | // Pointers to zero-bit types still have a runtime address; however, pointers | 488 | // Pointers to zero-bit types still have a runtime address; however, pointers |
| 489 | // to comptime-only types do not, with the exception of function pointers. | 489 | // to comptime-only types do not, with the exception of function pointers. |
| 490 | if (ignore_comptime_only) return true; | 490 | if (ignore_comptime_only) return true; |
| 491 | const child_ty = ptr_type.elem_type.toType(); | 491 | const child_ty = ptr_type.child.toType(); |
| 492 | if (child_ty.zigTypeTag(mod) == .Fn) return !mod.typeToFunc(child_ty).?.is_generic; | 492 | if (child_ty.zigTypeTag(mod) == .Fn) return !mod.typeToFunc(child_ty).?.is_generic; |
| 493 | if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty)); | 493 | if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty)); |
| 494 | return !comptimeOnly(ty, mod); | 494 | return !comptimeOnly(ty, mod); |
| ... | @@ -689,7 +689,7 @@ pub const Type = struct { | ... | @@ -689,7 +689,7 @@ pub const Type = struct { |
| 689 | 689 | ||
| 690 | .array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod), | 690 | .array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod), |
| 691 | .opt_type => ty.isPtrLikeOptional(mod), | 691 | .opt_type => ty.isPtrLikeOptional(mod), |
| 692 | .ptr_type => |ptr_type| ptr_type.size != .Slice, | 692 | .ptr_type => |ptr_type| ptr_type.flags.size != .Slice, |
| 693 | 693 | ||
| 694 | .simple_type => |t| switch (t) { | 694 | .simple_type => |t| switch (t) { |
| 695 | .f16, | 695 | .f16, |
| ... | @@ -823,13 +823,13 @@ pub const Type = struct { | ... | @@ -823,13 +823,13 @@ pub const Type = struct { |
| 823 | pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !u32 { | 823 | pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !u32 { |
| 824 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 824 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 825 | .ptr_type => |ptr_type| { | 825 | .ptr_type => |ptr_type| { |
| 826 | if (ptr_type.alignment.toByteUnitsOptional()) |a| { | 826 | if (ptr_type.flags.alignment.toByteUnitsOptional()) |a| { |
| 827 | return @intCast(u32, a); | 827 | return @intCast(u32, a); |
| 828 | } else if (opt_sema) |sema| { | 828 | } else if (opt_sema) |sema| { |
| 829 | const res = try ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .{ .sema = sema }); | 829 | const res = try ptr_type.child.toType().abiAlignmentAdvanced(mod, .{ .sema = sema }); |
| 830 | return res.scalar; | 830 | return res.scalar; |
| 831 | } else { | 831 | } else { |
| 832 | return (ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; | 832 | return (ptr_type.child.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; |
| 833 | } | 833 | } |
| 834 | }, | 834 | }, |
| 835 | .opt_type => |child| child.toType().ptrAlignmentAdvanced(mod, opt_sema), | 835 | .opt_type => |child| child.toType().ptrAlignmentAdvanced(mod, opt_sema), |
| ... | @@ -839,8 +839,8 @@ pub const Type = struct { | ... | @@ -839,8 +839,8 @@ pub const Type = struct { |
| 839 | 839 | ||
| 840 | pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace { | 840 | pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace { |
| 841 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 841 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 842 | .ptr_type => |ptr_type| ptr_type.address_space, | 842 | .ptr_type => |ptr_type| ptr_type.flags.address_space, |
| 843 | .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space, | 843 | .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.flags.address_space, |
| 844 | else => unreachable, | 844 | else => unreachable, |
| 845 | }; | 845 | }; |
| 846 | } | 846 | } |
| ... | @@ -1297,7 +1297,7 @@ pub const Type = struct { | ... | @@ -1297,7 +1297,7 @@ pub const Type = struct { |
| 1297 | if (int_type.bits == 0) return AbiSizeAdvanced{ .scalar = 0 }; | 1297 | if (int_type.bits == 0) return AbiSizeAdvanced{ .scalar = 0 }; |
| 1298 | return AbiSizeAdvanced{ .scalar = intAbiSize(int_type.bits, target) }; | 1298 | return AbiSizeAdvanced{ .scalar = intAbiSize(int_type.bits, target) }; |
| 1299 | }, | 1299 | }, |
| 1300 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 1300 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1301 | .Slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 }, | 1301 | .Slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 }, |
| 1302 | else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) }, | 1302 | else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) }, |
| 1303 | }, | 1303 | }, |
| ... | @@ -1620,7 +1620,7 @@ pub const Type = struct { | ... | @@ -1620,7 +1620,7 @@ pub const Type = struct { |
| 1620 | 1620 | ||
| 1621 | switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1621 | switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1622 | .int_type => |int_type| return int_type.bits, | 1622 | .int_type => |int_type| return int_type.bits, |
| 1623 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 1623 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1624 | .Slice => return target.ptrBitWidth() * 2, | 1624 | .Slice => return target.ptrBitWidth() * 2, |
| 1625 | else => return target.ptrBitWidth(), | 1625 | else => return target.ptrBitWidth(), |
| 1626 | }, | 1626 | }, |
| ... | @@ -1795,7 +1795,7 @@ pub const Type = struct { | ... | @@ -1795,7 +1795,7 @@ pub const Type = struct { |
| 1795 | 1795 | ||
| 1796 | pub fn isSinglePointer(ty: Type, mod: *const Module) bool { | 1796 | pub fn isSinglePointer(ty: Type, mod: *const Module) bool { |
| 1797 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1797 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1798 | .ptr_type => |ptr_info| ptr_info.size == .One, | 1798 | .ptr_type => |ptr_info| ptr_info.flags.size == .One, |
| 1799 | else => false, | 1799 | else => false, |
| 1800 | }; | 1800 | }; |
| 1801 | } | 1801 | } |
| ... | @@ -1808,14 +1808,14 @@ pub const Type = struct { | ... | @@ -1808,14 +1808,14 @@ pub const Type = struct { |
| 1808 | /// Returns `null` if `ty` is not a pointer. | 1808 | /// Returns `null` if `ty` is not a pointer. |
| 1809 | pub fn ptrSizeOrNull(ty: Type, mod: *const Module) ?std.builtin.Type.Pointer.Size { | 1809 | pub fn ptrSizeOrNull(ty: Type, mod: *const Module) ?std.builtin.Type.Pointer.Size { |
| 1810 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1810 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1811 | .ptr_type => |ptr_info| ptr_info.size, | 1811 | .ptr_type => |ptr_info| ptr_info.flags.size, |
| 1812 | else => null, | 1812 | else => null, |
| 1813 | }; | 1813 | }; |
| 1814 | } | 1814 | } |
| 1815 | 1815 | ||
| 1816 | pub fn isSlice(ty: Type, mod: *const Module) bool { | 1816 | pub fn isSlice(ty: Type, mod: *const Module) bool { |
| 1817 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1817 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1818 | .ptr_type => |ptr_type| ptr_type.size == .Slice, | 1818 | .ptr_type => |ptr_type| ptr_type.flags.size == .Slice, |
| 1819 | else => false, | 1819 | else => false, |
| 1820 | }; | 1820 | }; |
| 1821 | } | 1821 | } |
| ... | @@ -1826,7 +1826,7 @@ pub const Type = struct { | ... | @@ -1826,7 +1826,7 @@ pub const Type = struct { |
| 1826 | 1826 | ||
| 1827 | pub fn isConstPtr(ty: Type, mod: *const Module) bool { | 1827 | pub fn isConstPtr(ty: Type, mod: *const Module) bool { |
| 1828 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1828 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1829 | .ptr_type => |ptr_type| ptr_type.is_const, | 1829 | .ptr_type => |ptr_type| ptr_type.flags.is_const, |
| 1830 | else => false, | 1830 | else => false, |
| 1831 | }; | 1831 | }; |
| 1832 | } | 1832 | } |
| ... | @@ -1837,14 +1837,14 @@ pub const Type = struct { | ... | @@ -1837,14 +1837,14 @@ pub const Type = struct { |
| 1837 | 1837 | ||
| 1838 | pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool { | 1838 | pub fn isVolatilePtrIp(ty: Type, ip: *const InternPool) bool { |
| 1839 | return switch (ip.indexToKey(ty.toIntern())) { | 1839 | return switch (ip.indexToKey(ty.toIntern())) { |
| 1840 | .ptr_type => |ptr_type| ptr_type.is_volatile, | 1840 | .ptr_type => |ptr_type| ptr_type.flags.is_volatile, |
| 1841 | else => false, | 1841 | else => false, |
| 1842 | }; | 1842 | }; |
| 1843 | } | 1843 | } |
| 1844 | 1844 | ||
| 1845 | pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool { | 1845 | pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool { |
| 1846 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1846 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1847 | .ptr_type => |ptr_type| ptr_type.is_allowzero, | 1847 | .ptr_type => |ptr_type| ptr_type.flags.is_allowzero, |
| 1848 | .opt_type => true, | 1848 | .opt_type => true, |
| 1849 | else => false, | 1849 | else => false, |
| 1850 | }; | 1850 | }; |
| ... | @@ -1852,21 +1852,21 @@ pub const Type = struct { | ... | @@ -1852,21 +1852,21 @@ pub const Type = struct { |
| 1852 | 1852 | ||
| 1853 | pub fn isCPtr(ty: Type, mod: *const Module) bool { | 1853 | pub fn isCPtr(ty: Type, mod: *const Module) bool { |
| 1854 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1854 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1855 | .ptr_type => |ptr_type| ptr_type.size == .C, | 1855 | .ptr_type => |ptr_type| ptr_type.flags.size == .C, |
| 1856 | else => false, | 1856 | else => false, |
| 1857 | }; | 1857 | }; |
| 1858 | } | 1858 | } |
| 1859 | 1859 | ||
| 1860 | pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool { | 1860 | pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool { |
| 1861 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1861 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1862 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 1862 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1863 | .Slice => false, | 1863 | .Slice => false, |
| 1864 | .One, .Many, .C => true, | 1864 | .One, .Many, .C => true, |
| 1865 | }, | 1865 | }, |
| 1866 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { | 1866 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { |
| 1867 | .ptr_type => |p| switch (p.size) { | 1867 | .ptr_type => |p| switch (p.flags.size) { |
| 1868 | .Slice, .C => false, | 1868 | .Slice, .C => false, |
| 1869 | .Many, .One => !p.is_allowzero, | 1869 | .Many, .One => !p.flags.is_allowzero, |
| 1870 | }, | 1870 | }, |
| 1871 | else => false, | 1871 | else => false, |
| 1872 | }, | 1872 | }, |
| ... | @@ -1887,14 +1887,14 @@ pub const Type = struct { | ... | @@ -1887,14 +1887,14 @@ pub const Type = struct { |
| 1887 | pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool { | 1887 | pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool { |
| 1888 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1888 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1889 | .opt_type => |child_type| switch (mod.intern_pool.indexToKey(child_type)) { | 1889 | .opt_type => |child_type| switch (mod.intern_pool.indexToKey(child_type)) { |
| 1890 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 1890 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1891 | .C => false, | 1891 | .C => false, |
| 1892 | .Slice, .Many, .One => !ptr_type.is_allowzero, | 1892 | .Slice, .Many, .One => !ptr_type.flags.is_allowzero, |
| 1893 | }, | 1893 | }, |
| 1894 | .error_set_type => true, | 1894 | .error_set_type => true, |
| 1895 | else => false, | 1895 | else => false, |
| 1896 | }, | 1896 | }, |
| 1897 | .ptr_type => |ptr_type| ptr_type.size == .C, | 1897 | .ptr_type => |ptr_type| ptr_type.flags.size == .C, |
| 1898 | else => false, | 1898 | else => false, |
| 1899 | }; | 1899 | }; |
| 1900 | } | 1900 | } |
| ... | @@ -1904,11 +1904,11 @@ pub const Type = struct { | ... | @@ -1904,11 +1904,11 @@ pub const Type = struct { |
| 1904 | /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`. | 1904 | /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`. |
| 1905 | pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool { | 1905 | pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool { |
| 1906 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1906 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1907 | .ptr_type => |ptr_type| ptr_type.size == .C, | 1907 | .ptr_type => |ptr_type| ptr_type.flags.size == .C, |
| 1908 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { | 1908 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { |
| 1909 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 1909 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1910 | .Slice, .C => false, | 1910 | .Slice, .C => false, |
| 1911 | .Many, .One => !ptr_type.is_allowzero, | 1911 | .Many, .One => !ptr_type.flags.is_allowzero, |
| 1912 | }, | 1912 | }, |
| 1913 | else => false, | 1913 | else => false, |
| 1914 | }, | 1914 | }, |
| ... | @@ -1938,9 +1938,9 @@ pub const Type = struct { | ... | @@ -1938,9 +1938,9 @@ pub const Type = struct { |
| 1938 | /// For anyframe->T, returns T. | 1938 | /// For anyframe->T, returns T. |
| 1939 | pub fn elemType2(ty: Type, mod: *const Module) Type { | 1939 | pub fn elemType2(ty: Type, mod: *const Module) Type { |
| 1940 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1940 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1941 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 1941 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| 1942 | .One => ptr_type.elem_type.toType().shallowElemType(mod), | 1942 | .One => ptr_type.child.toType().shallowElemType(mod), |
| 1943 | .Many, .C, .Slice => ptr_type.elem_type.toType(), | 1943 | .Many, .C, .Slice => ptr_type.child.toType(), |
| 1944 | }, | 1944 | }, |
| 1945 | .anyframe_type => |child| { | 1945 | .anyframe_type => |child| { |
| 1946 | assert(child != .none); | 1946 | assert(child != .none); |
| ... | @@ -1974,7 +1974,7 @@ pub const Type = struct { | ... | @@ -1974,7 +1974,7 @@ pub const Type = struct { |
| 1974 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 1974 | return switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 1975 | .opt_type => |child| child.toType(), | 1975 | .opt_type => |child| child.toType(), |
| 1976 | .ptr_type => |ptr_type| b: { | 1976 | .ptr_type => |ptr_type| b: { |
| 1977 | assert(ptr_type.size == .C); | 1977 | assert(ptr_type.flags.size == .C); |
| 1978 | break :b ty; | 1978 | break :b ty; |
| 1979 | }, | 1979 | }, |
| 1980 | else => unreachable, | 1980 | else => unreachable, |
| ... | @@ -2390,7 +2390,7 @@ pub const Type = struct { | ... | @@ -2390,7 +2390,7 @@ pub const Type = struct { |
| 2390 | 2390 | ||
| 2391 | pub fn fnReturnTypeIp(ty: Type, ip: *const InternPool) Type { | 2391 | pub fn fnReturnTypeIp(ty: Type, ip: *const InternPool) Type { |
| 2392 | return switch (ip.indexToKey(ty.toIntern())) { | 2392 | return switch (ip.indexToKey(ty.toIntern())) { |
| 2393 | .ptr_type => |ptr_type| ip.indexToKey(ptr_type.elem_type).func_type.return_type, | 2393 | .ptr_type => |ptr_type| ip.indexToKey(ptr_type.child).func_type.return_type, |
| 2394 | .func_type => |func_type| func_type.return_type, | 2394 | .func_type => |func_type| func_type.return_type, |
| 2395 | else => unreachable, | 2395 | else => unreachable, |
| 2396 | }.toType(); | 2396 | }.toType(); |
| ... | @@ -2672,7 +2672,7 @@ pub const Type = struct { | ... | @@ -2672,7 +2672,7 @@ pub const Type = struct { |
| 2672 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { | 2672 | else => switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 2673 | .int_type => false, | 2673 | .int_type => false, |
| 2674 | .ptr_type => |ptr_type| { | 2674 | .ptr_type => |ptr_type| { |
| 2675 | const child_ty = ptr_type.elem_type.toType(); | 2675 | const child_ty = ptr_type.child.toType(); |
| 2676 | if (child_ty.zigTypeTag(mod) == .Fn) { | 2676 | if (child_ty.zigTypeTag(mod) == .Fn) { |
| 2677 | return false; | 2677 | return false; |
| 2678 | } else { | 2678 | } else { |
| ... | @@ -3374,17 +3374,17 @@ pub const Type = struct { | ... | @@ -3374,17 +3374,17 @@ pub const Type = struct { |
| 3374 | 3374 | ||
| 3375 | pub fn fromKey(p: InternPool.Key.PtrType) Data { | 3375 | pub fn fromKey(p: InternPool.Key.PtrType) Data { |
| 3376 | return .{ | 3376 | return .{ |
| 3377 | .pointee_type = p.elem_type.toType(), | 3377 | .pointee_type = p.child.toType(), |
| 3378 | .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null, | 3378 | .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null, |
| 3379 | .@"align" = @intCast(u32, p.alignment.toByteUnits(0)), | 3379 | .@"align" = @intCast(u32, p.flags.alignment.toByteUnits(0)), |
| 3380 | .@"addrspace" = p.address_space, | 3380 | .@"addrspace" = p.flags.address_space, |
| 3381 | .bit_offset = p.bit_offset, | 3381 | .bit_offset = p.packed_offset.bit_offset, |
| 3382 | .host_size = p.host_size, | 3382 | .host_size = p.packed_offset.host_size, |
| 3383 | .vector_index = p.vector_index, | 3383 | .vector_index = p.flags.vector_index, |
| 3384 | .@"allowzero" = p.is_allowzero, | 3384 | .@"allowzero" = p.flags.is_allowzero, |
| 3385 | .mutable = !p.is_const, | 3385 | .mutable = !p.flags.is_const, |
| 3386 | .@"volatile" = p.is_volatile, | 3386 | .@"volatile" = p.flags.is_volatile, |
| 3387 | .size = p.size, | 3387 | .size = p.flags.size, |
| 3388 | }; | 3388 | }; |
| 3389 | } | 3389 | } |
| 3390 | }; | 3390 | }; |
| ... | @@ -3478,17 +3478,21 @@ pub const Type = struct { | ... | @@ -3478,17 +3478,21 @@ pub const Type = struct { |
| 3478 | } | 3478 | } |
| 3479 | 3479 | ||
| 3480 | return mod.ptrType(.{ | 3480 | return mod.ptrType(.{ |
| 3481 | .elem_type = d.pointee_type.ip_index, | 3481 | .child = d.pointee_type.ip_index, |
| 3482 | .sentinel = if (d.sentinel) |s| s.ip_index else .none, | 3482 | .sentinel = if (d.sentinel) |s| s.ip_index else .none, |
| 3483 | .alignment = InternPool.Alignment.fromByteUnits(d.@"align"), | 3483 | .flags = .{ |
| 3484 | .host_size = d.host_size, | 3484 | .alignment = InternPool.Alignment.fromByteUnits(d.@"align"), |
| 3485 | .bit_offset = d.bit_offset, | 3485 | .vector_index = d.vector_index, |
| 3486 | .vector_index = d.vector_index, | 3486 | .size = d.size, |
| 3487 | .size = d.size, | 3487 | .is_const = !d.mutable, |
| 3488 | .is_const = !d.mutable, | 3488 | .is_volatile = d.@"volatile", |
| 3489 | .is_volatile = d.@"volatile", | 3489 | .is_allowzero = d.@"allowzero", |
| 3490 | .is_allowzero = d.@"allowzero", | 3490 | .address_space = d.@"addrspace", |
| 3491 | .address_space = d.@"addrspace", | 3491 | }, |
| 3492 | .packed_offset = .{ | ||
| 3493 | .host_size = d.host_size, | ||
| 3494 | .bit_offset = d.bit_offset, | ||
| 3495 | }, | ||
| 3492 | }); | 3496 | }); |
| 3493 | } | 3497 | } |
| 3494 | 3498 |
src/value.zig+2-2| ... | @@ -2080,8 +2080,8 @@ pub const Value = struct { | ... | @@ -2080,8 +2080,8 @@ pub const Value = struct { |
| 2080 | else => val, | 2080 | else => val, |
| 2081 | }; | 2081 | }; |
| 2082 | var ptr_ty_key = mod.intern_pool.indexToKey(elem_ptr_ty.toIntern()).ptr_type; | 2082 | var ptr_ty_key = mod.intern_pool.indexToKey(elem_ptr_ty.toIntern()).ptr_type; |
| 2083 | assert(ptr_ty_key.size != .Slice); | 2083 | assert(ptr_ty_key.flags.size != .Slice); |
| 2084 | ptr_ty_key.size = .Many; | 2084 | ptr_ty_key.flags.size = .Many; |
| 2085 | return (try mod.intern(.{ .ptr = .{ | 2085 | return (try mod.intern(.{ .ptr = .{ |
| 2086 | .ty = elem_ptr_ty.toIntern(), | 2086 | .ty = elem_ptr_ty.toIntern(), |
| 2087 | .addr = .{ .elem = .{ | 2087 | .addr = .{ .elem = .{ |