| ... | ... | @@ -1684,6 +1684,13 @@ 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. |
| 1687 | 1694 | fn derivedPtrType(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id { |
| 1688 | 1695 | return cg.ptrType( |
| 1689 | 1696 | try cg.pointeeType(@"addrspace", derivation.elem_ty, false), |
| ... | ... | @@ -1696,13 +1703,6 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1696 | 1703 | const zcu = cg.zcu; |
| 1697 | 1704 | const target = zcu.getTarget(); |
| 1698 | 1705 | |
| 1699 | | // A variable on Vulkan and OpenGL is used through its own pointer, so a `nav` resolves this only |
| 1700 | | // where it is used; a type emitted and left unused stays in the module. |
| 1701 | | const result_ty_id = switch (derivation.addr) { |
| 1702 | | .nav => undefined, |
| 1703 | | else => try cg.derivedPtrType(@"addrspace", derivation), |
| 1704 | | }; |
| 1705 | | |
| 1706 | 1706 | switch (derivation.addr) { |
| 1707 | 1707 | .comptime_alloc, .comptime_field => unreachable, |
| 1708 | 1708 | .int => |int| { |
| ... | ... | @@ -1717,6 +1717,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1717 | 1717 | // TODO: This can probably be an OpSpecConstantOp Bitcast, but |
| 1718 | 1718 | // that is not implemented by Mesa yet. Therefore, just generate it |
| 1719 | 1719 | // as a runtime operation. |
| 1720 | const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); |
| 1720 | 1721 | const result_ptr_id = cg.allocId(); |
| 1721 | 1722 | const value_id = try cg.constInt(.usize, int); |
| 1722 | 1723 | try cg.body.emit(gpa, .OpConvertUToPtr, .{ |
| ... | ... | @@ -1759,12 +1760,12 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1759 | 1760 | |
| 1760 | 1761 | const nav_ty_id = try cg.resolveType(nav_ty, .indirect); |
| 1761 | 1762 | const decl_ptr_ty_id = try cg.ptrType(nav_ty_id, cg.storageClass(as)); |
| 1762 | | const nav_result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); |
| 1763 | | if (decl_ptr_ty_id == nav_result_ty_id) return var_id; |
| 1763 | const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); |
| 1764 | if (decl_ptr_ty_id == result_ty_id) return var_id; |
| 1764 | 1765 | |
| 1765 | 1766 | const casted_ptr_id = cg.allocId(); |
| 1766 | 1767 | try cg.body.emit(gpa, .OpBitcast, .{ |
| 1767 | | .id_result_type = nav_result_ty_id, |
| 1768 | .id_result_type = result_ty_id, |
| 1768 | 1769 | .id_result = casted_ptr_id, |
| 1769 | 1770 | .operand = var_id, |
| 1770 | 1771 | }); |
| ... | ... | @@ -1781,7 +1782,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1781 | 1782 | } |
| 1782 | 1783 | |
| 1783 | 1784 | if (!uav_ty.hasRuntimeBits(zcu) and uav_ty.zigTypeTag(zcu) != .spirv) { |
| 1784 | | return cg.constUndef(result_ty_id); |
| 1785 | return cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation)); |
| 1785 | 1786 | } |
| 1786 | 1787 | |
| 1787 | 1788 | if (cg.storageClass(@"addrspace") != .function) { |
| ... | ... | @@ -1798,7 +1799,7 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1798 | 1799 | .opt_payload => @panic("TODO"), |
| 1799 | 1800 | .field => |derived| return cg.structFieldPtr( |
| 1800 | 1801 | @"addrspace", |
| 1801 | | result_ty_id, |
| 1802 | try cg.derivedPtrType(@"addrspace", derivation), |
| 1802 | 1803 | derivation.elem_ty, |
| 1803 | 1804 | derived.parent.elem_ty, |
| 1804 | 1805 | try cg.derivePtr(@"addrspace", derived.parent.*), |
| ... | ... | @@ -1850,12 +1851,13 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1850 | 1851 | const zero = try cg.constInt(.u32, 0); |
| 1851 | 1852 | const ids = try cg.id_scratch.addManyAsSlice(gpa, depth); |
| 1852 | 1853 | @memset(ids, zero); |
| 1853 | | return cg.accessChainId(result_ty_id, parent_ptr_id, ids); |
| 1854 | return cg.accessChainId(try cg.derivedPtrType(@"addrspace", derivation), parent_ptr_id, ids); |
| 1854 | 1855 | } else { |
| 1855 | 1856 | return parent_ptr_id; |
| 1856 | 1857 | } |
| 1857 | 1858 | } |
| 1858 | 1859 | if (target.os.tag == .opencl) { |
| 1860 | const result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); |
| 1859 | 1861 | const result_ptr_id = cg.allocId(); |
| 1860 | 1862 | try cg.body.emit(gpa, .OpBitcast, .{ |
| 1861 | 1863 | .id_result_type = result_ty_id, |