| ... | ... | @@ -1684,16 +1684,25 @@ fn constantPtr(cg: *CodeGen, ptr_val: Value) !Id { |
| 1684 | 1684 | return cg.derivePtr(ptr_val.typeOf(zcu).ptrAddressSpace(zcu), derivation); |
| 1685 | 1685 | } |
| 1686 | 1686 | |
| 1687 | /// Emits the pointer type that one step of a pointer derivation results in, along with its |
| 1688 | /// pointee type. A derivation is the sequence of steps that builds a comptime-known pointer: a |
| 1689 | /// base address, such as a declaration, an anonymous value or an integer, followed by field, |
| 1690 | /// element and cast steps, each of which is lowered on its own. |
| 1691 | /// This function emits instructions on every call, and they stay in the module whether or not they |
| 1692 | /// are read, so it should only be called where the resulting type is used: a buffer struct emitted |
| 1693 | /// without `Block` fails validation even when nothing refers to it. |
| 1694 | fn derivedPtrType(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id { |
| 1695 | return cg.ptrType( |
| 1696 | try cg.pointeeType(@"addrspace", derivation.elem_ty, false), |
| 1697 | cg.storageClass(@"addrspace"), |
| 1698 | ); |
| 1699 | } |
| 1700 | |
| 1687 | 1701 | fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id { |
| 1688 | 1702 | const gpa = cg.gpa; |
| 1689 | 1703 | const zcu = cg.zcu; |
| 1690 | 1704 | const target = zcu.getTarget(); |
| 1691 | 1705 | |
| 1692 | | const result_ty_id = try cg.ptrType( |
| 1693 | | try cg.pointeeType(@"addrspace", derivation.elem_ty, false), |
| 1694 | | cg.storageClass(@"addrspace"), |
| 1695 | | ); |
| 1696 | | |
| 1697 | 1706 | switch (derivation.addr) { |
| 1698 | 1707 | .comptime_alloc, .comptime_field => unreachable, |
| 1699 | 1708 | .int => |int| { |
| ... | ... | @@ -1708,6 +1717,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1708 | 1717 | // TODO: This can probably be an OpSpecConstantOp Bitcast, but |
| 1709 | 1718 | // that is not implemented by Mesa yet. Therefore, just generate it |
| 1710 | 1719 | // as a runtime operation. |
| 1720 | const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); |
| 1711 | 1721 | const result_ptr_id = cg.allocId(); |
| 1712 | 1722 | const value_id = try cg.constInt(.usize, int); |
| 1713 | 1723 | try cg.body.emit(gpa, .OpConvertUToPtr, .{ |
| ... | ... | @@ -1727,10 +1737,10 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1727 | 1737 | |
| 1728 | 1738 | if (ip.isFunctionType(nav_ty.toIntern())) { |
| 1729 | 1739 | if (is_extern) return try cg.resolveExternFn(nav_index); |
| 1730 | | return try cg.constUndef(result_ty_id); |
| 1740 | return try cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation)); |
| 1731 | 1741 | } |
| 1732 | 1742 | if (!nav_ty.hasRuntimeBits(zcu) and nav_ty.zigTypeTag(zcu) != .spirv) { |
| 1733 | | return cg.constUndef(result_ty_id); |
| 1743 | return cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation)); |
| 1734 | 1744 | } |
| 1735 | 1745 | if (!is_extern) { |
| 1736 | 1746 | return cg.todo("pointer to constant '{f}'", .{nav.fqn.fmt(ip)}); |
| ... | ... | @@ -1739,20 +1749,20 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1739 | 1749 | const as = nav.resolved.?.@"addrspace"; |
| 1740 | 1750 | assert(as != .generic); |
| 1741 | 1751 | |
| 1742 | | const storage_class = cg.storageClass(as); |
| 1743 | 1752 | const var_id = try cg.resolveNav(nav_index); |
| 1744 | | const nav_ty_id = try cg.resolveType(nav_ty, .indirect); |
| 1745 | | const decl_ptr_ty_id = try cg.ptrType(nav_ty_id, storage_class); |
| 1746 | 1753 | if (cg.needsLayout(as, nav_ty)) { |
| 1747 | 1754 | try cg.block_var_ids.put(gpa, var_id, {}); |
| 1748 | 1755 | } |
| 1749 | | |
| 1750 | | if (decl_ptr_ty_id == result_ty_id) return var_id; |
| 1751 | 1756 | switch (target.os.tag) { |
| 1752 | 1757 | .vulkan, .opengl => return var_id, |
| 1753 | 1758 | else => {}, |
| 1754 | 1759 | } |
| 1755 | 1760 | |
| 1761 | const nav_ty_id = try cg.resolveType(nav_ty, .indirect); |
| 1762 | const decl_ptr_ty_id = try cg.ptrType(nav_ty_id, cg.storageClass(as)); |
| 1763 | const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); |
| 1764 | if (decl_ptr_ty_id == result_ty_id) return var_id; |
| 1765 | |
| 1756 | 1766 | const casted_ptr_id = cg.allocId(); |
| 1757 | 1767 | try cg.body.emit(gpa, .OpBitcast, .{ |
| 1758 | 1768 | .id_result_type = result_ty_id, |
| ... | ... | @@ -1772,7 +1782,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1772 | 1782 | } |
| 1773 | 1783 | |
| 1774 | 1784 | if (!uav_ty.hasRuntimeBits(zcu) and uav_ty.zigTypeTag(zcu) != .spirv) { |
| 1775 | | return cg.constUndef(result_ty_id); |
| 1785 | return cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation)); |
| 1776 | 1786 | } |
| 1777 | 1787 | |
| 1778 | 1788 | if (cg.storageClass(@"addrspace") != .function) { |
| ... | ... | @@ -1789,7 +1799,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1789 | 1799 | .opt_payload => @panic("TODO"), |
| 1790 | 1800 | .field => |derived| return cg.structFieldPtr( |
| 1791 | 1801 | @"addrspace", |
| 1792 | | result_ty_id, |
| 1802 | try cg.derivedPtrType(@"addrspace", derivation), |
| 1793 | 1803 | derivation.elem_ty, |
| 1794 | 1804 | derived.parent.elem_ty, |
| 1795 | 1805 | try cg.derivePtr(@"addrspace", derived.parent.*), |
| ... | ... | @@ -1801,7 +1811,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1801 | 1811 | .many => .many_ptr, |
| 1802 | 1812 | }, |
| 1803 | 1813 | @"addrspace", |
| 1804 | | derived.parent.elem_ty, |
| 1814 | derivation.elem_ty, |
| 1805 | 1815 | try cg.derivePtr(@"addrspace", derived.parent.*), |
| 1806 | 1816 | try cg.constInt(.usize, derived.elem_index), |
| 1807 | 1817 | ), |
| ... | ... | @@ -1841,12 +1851,13 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1841 | 1851 | const zero = try cg.constInt(.u32, 0); |
| 1842 | 1852 | const ids = try cg.id_scratch.addManyAsSlice(gpa, depth); |
| 1843 | 1853 | @memset(ids, zero); |
| 1844 | | return cg.accessChainId(result_ty_id, parent_ptr_id, ids); |
| 1854 | return cg.accessChainId(try cg.derivedPtrType(@"addrspace", derivation), parent_ptr_id, ids); |
| 1845 | 1855 | } else { |
| 1846 | 1856 | return parent_ptr_id; |
| 1847 | 1857 | } |
| 1848 | 1858 | } |
| 1849 | 1859 | if (target.os.tag == .opencl) { |
| 1860 | const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); |
| 1850 | 1861 | const result_ptr_id = cg.allocId(); |
| 1851 | 1862 | try cg.body.emit(gpa, .OpBitcast, .{ |
| 1852 | 1863 | .id_result_type = result_ty_id, |