| ... | @@ -629,6 +629,16 @@ const DeclGen = struct { | ... | @@ -629,6 +629,16 @@ const DeclGen = struct { |
| 629 | return self.backingIntBits(ty) == null; | 629 | return self.backingIntBits(ty) == null; |
| 630 | } | 630 | } |
| 631 | | 631 | |
| | 632 | /// Checks whether the type can be directly translated to SPIR-V vectors |
| | 633 | fn isVector(self: *DeclGen, ty: Type) bool { |
| | 634 | const mod = self.module; |
| | 635 | if (ty.zigTypeTag(mod) != .Vector) return false; |
| | 636 | const elem_ty = ty.childType(mod); |
| | 637 | const len = ty.vectorLen(mod); |
| | 638 | const is_scalar = elem_ty.isNumeric(mod) or elem_ty.toIntern() == .bool_type; |
| | 639 | return is_scalar and len > 1 and len <= 4; |
| | 640 | } |
| | 641 | |
| 632 | fn arithmeticTypeInfo(self: *DeclGen, ty: Type) ArithmeticTypeInfo { | 642 | fn arithmeticTypeInfo(self: *DeclGen, ty: Type) ArithmeticTypeInfo { |
| 633 | const mod = self.module; | 643 | const mod = self.module; |
| 634 | const target = self.getTarget(); | 644 | const target = self.getTarget(); |
| ... | @@ -694,6 +704,24 @@ const DeclGen = struct { | ... | @@ -694,6 +704,24 @@ const DeclGen = struct { |
| 694 | /// This function, unlike SpvModule.constInt, takes care to bitcast | 704 | /// This function, unlike SpvModule.constInt, takes care to bitcast |
| 695 | /// the value to an unsigned int first for Kernels. | 705 | /// the value to an unsigned int first for Kernels. |
| 696 | fn constInt(self: *DeclGen, ty_ref: CacheRef, value: anytype) !IdRef { | 706 | fn constInt(self: *DeclGen, ty_ref: CacheRef, value: anytype) !IdRef { |
| | 707 | switch (self.spv.cache.lookup(ty_ref)) { |
| | 708 | .vector_type => |vec_type| { |
| | 709 | const elem_ids = try self.gpa.alloc(IdRef, vec_type.component_count); |
| | 710 | defer self.gpa.free(elem_ids); |
| | 711 | const int_value = try self.constInt(vec_type.component_type, value); |
| | 712 | @memset(elem_ids, int_value); |
| | 713 | |
| | 714 | const constituents_id = self.spv.allocId(); |
| | 715 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ |
| | 716 | .id_result_type = self.typeId(ty_ref), |
| | 717 | .id_result = constituents_id, |
| | 718 | .constituents = elem_ids, |
| | 719 | }); |
| | 720 | return constituents_id; |
| | 721 | }, |
| | 722 | else => {}, |
| | 723 | } |
| | 724 | |
| 697 | if (value < 0) { | 725 | if (value < 0) { |
| 698 | const ty = self.spv.cache.lookup(ty_ref).int_type; | 726 | const ty = self.spv.cache.lookup(ty_ref).int_type; |
| 699 | // Manually truncate the value so that the resulting value | 727 | // Manually truncate the value so that the resulting value |
| ... | @@ -711,6 +739,24 @@ const DeclGen = struct { | ... | @@ -711,6 +739,24 @@ const DeclGen = struct { |
| 711 | | 739 | |
| 712 | /// Emits a float constant | 740 | /// Emits a float constant |
| 713 | fn constFloat(self: *DeclGen, ty_ref: CacheRef, value: f128) !IdRef { | 741 | fn constFloat(self: *DeclGen, ty_ref: CacheRef, value: f128) !IdRef { |
| | 742 | switch (self.spv.cache.lookup(ty_ref)) { |
| | 743 | .vector_type => |vec_type| { |
| | 744 | const elem_ids = try self.gpa.alloc(IdRef, vec_type.component_count); |
| | 745 | defer self.gpa.free(elem_ids); |
| | 746 | const int_value = try self.constFloat(vec_type.component_type, value); |
| | 747 | @memset(elem_ids, int_value); |
| | 748 | |
| | 749 | const constituents_id = self.spv.allocId(); |
| | 750 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ |
| | 751 | .id_result_type = self.typeId(ty_ref), |
| | 752 | .id_result = constituents_id, |
| | 753 | .constituents = elem_ids, |
| | 754 | }); |
| | 755 | return constituents_id; |
| | 756 | }, |
| | 757 | else => {}, |
| | 758 | } |
| | 759 | |
| 714 | const ty = self.spv.cache.lookup(ty_ref).float_type; | 760 | const ty = self.spv.cache.lookup(ty_ref).float_type; |
| 715 | return switch (ty.bits) { | 761 | return switch (ty.bits) { |
| 716 | 16 => try self.spv.resolveId(.{ .float = .{ .ty = ty_ref, .value = .{ .float16 = @floatCast(value) } } }), | 762 | 16 => try self.spv.resolveId(.{ .float = .{ .ty = ty_ref, .value = .{ .float16 = @floatCast(value) } } }), |
| ... | @@ -726,9 +772,9 @@ const DeclGen = struct { | ... | @@ -726,9 +772,9 @@ const DeclGen = struct { |
| 726 | /// if the parameters are in indirect representation, then the result is too. | 772 | /// if the parameters are in indirect representation, then the result is too. |
| 727 | fn constructComposite(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { | 773 | fn constructComposite(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { |
| 728 | const constituents_id = self.spv.allocId(); | 774 | const constituents_id = self.spv.allocId(); |
| 729 | const type_id = try self.resolveTypeId(ty); | 775 | const type_id = try self.resolveType(ty, .direct); |
| 730 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ | 776 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ |
| 731 | .id_result_type = type_id, | 777 | .id_result_type = self.typeId(type_id), |
| 732 | .id_result = constituents_id, | 778 | .id_result = constituents_id, |
| 733 | .constituents = constituents, | 779 | .constituents = constituents, |
| 734 | }); | 780 | }); |
| ... | @@ -1448,12 +1494,11 @@ const DeclGen = struct { | ... | @@ -1448,12 +1494,11 @@ const DeclGen = struct { |
| 1448 | const elem_ty = ty.childType(mod); | 1494 | const elem_ty = ty.childType(mod); |
| 1449 | const elem_ty_ref = try self.resolveType(elem_ty, .indirect); | 1495 | const elem_ty_ref = try self.resolveType(elem_ty, .indirect); |
| 1450 | const len = ty.vectorLen(mod); | 1496 | const len = ty.vectorLen(mod); |
| 1451 | const is_scalar = elem_ty.isNumeric(mod) or elem_ty.toIntern() == .bool_type; | | |
| 1452 | | 1497 | |
| 1453 | const ty_ref = if (is_scalar and len > 1 and len <= 4) | 1498 | const ty_ref = if (self.isVector(ty)) |
| 1454 | try self.spv.vectorType(ty.vectorLen(mod), elem_ty_ref) | 1499 | try self.spv.vectorType(len, elem_ty_ref) |
| 1455 | else | 1500 | else |
| 1456 | try self.spv.arrayType(ty.vectorLen(mod), elem_ty_ref); | 1501 | try self.spv.arrayType(len, elem_ty_ref); |
| 1457 | | 1502 | |
| 1458 | try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref }); | 1503 | try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref }); |
| 1459 | return ty_ref; | 1504 | return ty_ref; |
| ... | @@ -1752,18 +1797,16 @@ const DeclGen = struct { | ... | @@ -1752,18 +1797,16 @@ const DeclGen = struct { |
| 1752 | } | 1797 | } |
| 1753 | | 1798 | |
| 1754 | /// This structure is used as helper for element-wise operations. It is intended | 1799 | /// This structure is used as helper for element-wise operations. It is intended |
| 1755 | /// to be used with both vectors and single elements. | 1800 | /// to be used with vectors, fake vectors (arrays) and single elements. |
| 1756 | const WipElementWise = struct { | 1801 | const WipElementWise = struct { |
| 1757 | dg: *DeclGen, | 1802 | dg: *DeclGen, |
| 1758 | result_ty: Type, | 1803 | result_ty: Type, |
| | 1804 | ty: Type, |
| 1759 | /// Always in direct representation. | 1805 | /// Always in direct representation. |
| 1760 | result_ty_ref: CacheRef, | 1806 | ty_ref: CacheRef, |
| 1761 | scalar_ty: Type, | 1807 | ty_id: IdRef, |
| 1762 | /// Always in direct representation. | 1808 | /// True if the input is an array type. |
| 1763 | scalar_ty_ref: CacheRef, | 1809 | is_array: bool, |
| 1764 | scalar_ty_id: IdRef, | | |
| 1765 | /// True if the input is actually a vector type. | | |
| 1766 | is_vector: bool, | | |
| 1767 | /// The element-wise operation should fill these results before calling finalize(). | 1810 | /// The element-wise operation should fill these results before calling finalize(). |
| 1768 | /// These should all be in **direct** representation! `finalize()` will convert | 1811 | /// These should all be in **direct** representation! `finalize()` will convert |
| 1769 | /// them to indirect if required. | 1812 | /// them to indirect if required. |
| ... | @@ -1774,29 +1817,28 @@ const DeclGen = struct { | ... | @@ -1774,29 +1817,28 @@ const DeclGen = struct { |
| 1774 | } | 1817 | } |
| 1775 | | 1818 | |
| 1776 | /// Utility function to extract the element at a particular index in an | 1819 | /// Utility function to extract the element at a particular index in an |
| 1777 | /// input vector. This type is expected to be a vector if `wip.is_vector`, and | 1820 | /// input array. This type is expected to be a fake vector (array) if `wip.is_array`, and |
| 1778 | /// a scalar otherwise. | 1821 | /// a vector or scalar otherwise. |
| 1779 | fn elementAt(wip: WipElementWise, ty: Type, value: IdRef, index: usize) !IdRef { | 1822 | fn elementAt(wip: WipElementWise, ty: Type, value: IdRef, index: usize) !IdRef { |
| 1780 | const mod = wip.dg.module; | 1823 | const mod = wip.dg.module; |
| 1781 | if (wip.is_vector) { | 1824 | if (wip.is_array) { |
| 1782 | assert(ty.isVector(mod)); | 1825 | assert(ty.isVector(mod)); |
| 1783 | return try wip.dg.extractField(ty.childType(mod), value, @intCast(index)); | 1826 | return try wip.dg.extractField(ty.childType(mod), value, @intCast(index)); |
| 1784 | } else { | 1827 | } else { |
| 1785 | assert(!ty.isVector(mod)); | | |
| 1786 | assert(index == 0); | 1828 | assert(index == 0); |
| 1787 | return value; | 1829 | return value; |
| 1788 | } | 1830 | } |
| 1789 | } | 1831 | } |
| 1790 | | 1832 | |
| 1791 | /// Turns the results of this WipElementWise into a result. This can either | 1833 | /// Turns the results of this WipElementWise into a result. This can be |
| 1792 | /// be a vector or single element, depending on `result_ty`. | 1834 | /// vectors, fake vectors (arrays) and single elements, depending on `result_ty`. |
| 1793 | /// After calling this function, this WIP is no longer usable. | 1835 | /// After calling this function, this WIP is no longer usable. |
| 1794 | /// Results is in `direct` representation. | 1836 | /// Results is in `direct` representation. |
| 1795 | fn finalize(wip: *WipElementWise) !IdRef { | 1837 | fn finalize(wip: *WipElementWise) !IdRef { |
| 1796 | if (wip.is_vector) { | 1838 | if (wip.is_array) { |
| 1797 | // Convert all the constituents to indirect, as required for the array. | 1839 | // Convert all the constituents to indirect, as required for the array. |
| 1798 | for (wip.results) |*result| { | 1840 | for (wip.results) |*result| { |
| 1799 | result.* = try wip.dg.convertToIndirect(wip.scalar_ty, result.*); | 1841 | result.* = try wip.dg.convertToIndirect(wip.ty, result.*); |
| 1800 | } | 1842 | } |
| 1801 | return try wip.dg.constructComposite(wip.result_ty, wip.results); | 1843 | return try wip.dg.constructComposite(wip.result_ty, wip.results); |
| 1802 | } else { | 1844 | } else { |
| ... | @@ -1806,33 +1848,30 @@ const DeclGen = struct { | ... | @@ -1806,33 +1848,30 @@ const DeclGen = struct { |
| 1806 | | 1848 | |
| 1807 | /// Allocate a result id at a particular index, and return it. | 1849 | /// Allocate a result id at a particular index, and return it. |
| 1808 | fn allocId(wip: *WipElementWise, index: usize) IdRef { | 1850 | fn allocId(wip: *WipElementWise, index: usize) IdRef { |
| 1809 | assert(wip.is_vector or index == 0); | 1851 | assert(wip.is_array or index == 0); |
| 1810 | wip.results[index] = wip.dg.spv.allocId(); | 1852 | wip.results[index] = wip.dg.spv.allocId(); |
| 1811 | return wip.results[index]; | 1853 | return wip.results[index]; |
| 1812 | } | 1854 | } |
| 1813 | }; | 1855 | }; |
| 1814 | | 1856 | |
| 1815 | /// Create a new element-wise operation. | 1857 | /// Create a new element-wise operation. |
| 1816 | fn elementWise(self: *DeclGen, result_ty: Type) !WipElementWise { | 1858 | fn elementWise(self: *DeclGen, result_ty: Type, force_element_wise: bool) !WipElementWise { |
| 1817 | const mod = self.module; | 1859 | const mod = self.module; |
| 1818 | // For now, this operation also reasons in terms of `.direct` representation. | 1860 | const is_array = result_ty.isVector(mod) and (!self.isVector(result_ty) or force_element_wise); |
| 1819 | const result_ty_ref = try self.resolveType(result_ty, .direct); | 1861 | const num_results = if (is_array) result_ty.vectorLen(mod) else 1; |
| 1820 | const is_vector = result_ty.isVector(mod); | | |
| 1821 | const num_results = if (is_vector) result_ty.vectorLen(mod) else 1; | | |
| 1822 | const results = try self.gpa.alloc(IdRef, num_results); | 1862 | const results = try self.gpa.alloc(IdRef, num_results); |
| 1823 | for (results) |*result| result.* = undefined; | 1863 | @memset(results, undefined); |
| 1824 | | 1864 | |
| 1825 | const scalar_ty = result_ty.scalarType(mod); | 1865 | const ty = if (is_array) result_ty.scalarType(mod) else result_ty; |
| 1826 | const scalar_ty_ref = try self.resolveType(scalar_ty, .direct); | 1866 | const ty_ref = try self.resolveType(ty, .direct); |
| 1827 | | 1867 | |
| 1828 | return .{ | 1868 | return .{ |
| 1829 | .dg = self, | 1869 | .dg = self, |
| 1830 | .result_ty = result_ty, | 1870 | .result_ty = result_ty, |
| 1831 | .result_ty_ref = result_ty_ref, | 1871 | .ty = ty, |
| 1832 | .scalar_ty = scalar_ty, | 1872 | .ty_ref = ty_ref, |
| 1833 | .scalar_ty_ref = scalar_ty_ref, | 1873 | .ty_id = self.typeId(ty_ref), |
| 1834 | .scalar_ty_id = self.typeId(scalar_ty_ref), | 1874 | .is_array = is_array, |
| 1835 | .is_vector = is_vector, | | |
| 1836 | .results = results, | 1875 | .results = results, |
| 1837 | }; | 1876 | }; |
| 1838 | } | 1877 | } |
| ... | @@ -2160,7 +2199,6 @@ const DeclGen = struct { | ... | @@ -2160,7 +2199,6 @@ const DeclGen = struct { |
| 2160 | fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void { | 2199 | fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void { |
| 2161 | const mod = self.module; | 2200 | const mod = self.module; |
| 2162 | const ip = &mod.intern_pool; | 2201 | const ip = &mod.intern_pool; |
| 2163 | // TODO: remove now-redundant isUnused calls from AIR handler functions | | |
| 2164 | if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) | 2202 | if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip)) |
| 2165 | return; | 2203 | return; |
| 2166 | | 2204 | |
| ... | @@ -2312,11 +2350,11 @@ const DeclGen = struct { | ... | @@ -2312,11 +2350,11 @@ const DeclGen = struct { |
| 2312 | } | 2350 | } |
| 2313 | | 2351 | |
| 2314 | fn binOpSimple(self: *DeclGen, ty: Type, lhs_id: IdRef, rhs_id: IdRef, comptime opcode: Opcode) !IdRef { | 2352 | fn binOpSimple(self: *DeclGen, ty: Type, lhs_id: IdRef, rhs_id: IdRef, comptime opcode: Opcode) !IdRef { |
| 2315 | var wip = try self.elementWise(ty); | 2353 | var wip = try self.elementWise(ty, false); |
| 2316 | defer wip.deinit(); | 2354 | defer wip.deinit(); |
| 2317 | for (0..wip.results.len) |i| { | 2355 | for (0..wip.results.len) |i| { |
| 2318 | try self.func.body.emit(self.spv.gpa, opcode, .{ | 2356 | try self.func.body.emit(self.spv.gpa, opcode, .{ |
| 2319 | .id_result_type = wip.scalar_ty_id, | 2357 | .id_result_type = wip.ty_id, |
| 2320 | .id_result = wip.allocId(i), | 2358 | .id_result = wip.allocId(i), |
| 2321 | .operand_1 = try wip.elementAt(ty, lhs_id, i), | 2359 | .operand_1 = try wip.elementAt(ty, lhs_id, i), |
| 2322 | .operand_2 = try wip.elementAt(ty, rhs_id, i), | 2360 | .operand_2 = try wip.elementAt(ty, rhs_id, i), |
| ... | @@ -2326,8 +2364,6 @@ const DeclGen = struct { | ... | @@ -2326,8 +2364,6 @@ const DeclGen = struct { |
| 2326 | } | 2364 | } |
| 2327 | | 2365 | |
| 2328 | fn airBinOpSimple(self: *DeclGen, inst: Air.Inst.Index, comptime opcode: Opcode) !?IdRef { | 2366 | fn airBinOpSimple(self: *DeclGen, inst: Air.Inst.Index, comptime opcode: Opcode) !?IdRef { |
| 2329 | if (self.liveness.isUnused(inst)) return null; | | |
| 2330 | | | |
| 2331 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 2367 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2332 | const lhs_id = try self.resolve(bin_op.lhs); | 2368 | const lhs_id = try self.resolve(bin_op.lhs); |
| 2333 | const rhs_id = try self.resolve(bin_op.rhs); | 2369 | const rhs_id = try self.resolve(bin_op.rhs); |
| ... | @@ -2337,7 +2373,6 @@ const DeclGen = struct { | ... | @@ -2337,7 +2373,6 @@ const DeclGen = struct { |
| 2337 | } | 2373 | } |
| 2338 | | 2374 | |
| 2339 | fn airShift(self: *DeclGen, inst: Air.Inst.Index, comptime unsigned: Opcode, comptime signed: Opcode) !?IdRef { | 2375 | fn airShift(self: *DeclGen, inst: Air.Inst.Index, comptime unsigned: Opcode, comptime signed: Opcode) !?IdRef { |
| 2340 | if (self.liveness.isUnused(inst)) return null; | | |
| 2341 | const mod = self.module; | 2376 | const mod = self.module; |
| 2342 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 2377 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2343 | const lhs_id = try self.resolve(bin_op.lhs); | 2378 | const lhs_id = try self.resolve(bin_op.lhs); |
| ... | @@ -2345,7 +2380,7 @@ const DeclGen = struct { | ... | @@ -2345,7 +2380,7 @@ const DeclGen = struct { |
| 2345 | | 2380 | |
| 2346 | const result_ty = self.typeOfIndex(inst); | 2381 | const result_ty = self.typeOfIndex(inst); |
| 2347 | const shift_ty = self.typeOf(bin_op.rhs); | 2382 | const shift_ty = self.typeOf(bin_op.rhs); |
| 2348 | const scalar_shift_ty_ref = try self.resolveType(shift_ty.scalarType(mod), .direct); | 2383 | const shift_ty_ref = try self.resolveType(shift_ty, .direct); |
| 2349 | | 2384 | |
| 2350 | const info = self.arithmeticTypeInfo(result_ty); | 2385 | const info = self.arithmeticTypeInfo(result_ty); |
| 2351 | switch (info.class) { | 2386 | switch (info.class) { |
| ... | @@ -2354,7 +2389,7 @@ const DeclGen = struct { | ... | @@ -2354,7 +2389,7 @@ const DeclGen = struct { |
| 2354 | .float, .bool => unreachable, | 2389 | .float, .bool => unreachable, |
| 2355 | } | 2390 | } |
| 2356 | | 2391 | |
| 2357 | var wip = try self.elementWise(result_ty); | 2392 | var wip = try self.elementWise(result_ty, false); |
| 2358 | defer wip.deinit(); | 2393 | defer wip.deinit(); |
| 2359 | for (wip.results, 0..) |*result_id, i| { | 2394 | for (wip.results, 0..) |*result_id, i| { |
| 2360 | const lhs_elem_id = try wip.elementAt(result_ty, lhs_id, i); | 2395 | const lhs_elem_id = try wip.elementAt(result_ty, lhs_id, i); |
| ... | @@ -2362,10 +2397,10 @@ const DeclGen = struct { | ... | @@ -2362,10 +2397,10 @@ const DeclGen = struct { |
| 2362 | | 2397 | |
| 2363 | // Sometimes Zig doesn't make both of the arguments the same types here. SPIR-V expects that, | 2398 | // Sometimes Zig doesn't make both of the arguments the same types here. SPIR-V expects that, |
| 2364 | // so just manually upcast it if required. | 2399 | // so just manually upcast it if required. |
| 2365 | const shift_id = if (scalar_shift_ty_ref != wip.scalar_ty_ref) blk: { | 2400 | const shift_id = if (shift_ty_ref != wip.ty_ref) blk: { |
| 2366 | const shift_id = self.spv.allocId(); | 2401 | const shift_id = self.spv.allocId(); |
| 2367 | try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ | 2402 | try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ |
| 2368 | .id_result_type = wip.scalar_ty_id, | 2403 | .id_result_type = wip.ty_id, |
| 2369 | .id_result = shift_id, | 2404 | .id_result = shift_id, |
| 2370 | .unsigned_value = rhs_elem_id, | 2405 | .unsigned_value = rhs_elem_id, |
| 2371 | }); | 2406 | }); |
| ... | @@ -2374,7 +2409,7 @@ const DeclGen = struct { | ... | @@ -2374,7 +2409,7 @@ const DeclGen = struct { |
| 2374 | | 2409 | |
| 2375 | const value_id = self.spv.allocId(); | 2410 | const value_id = self.spv.allocId(); |
| 2376 | const args = .{ | 2411 | const args = .{ |
| 2377 | .id_result_type = wip.scalar_ty_id, | 2412 | .id_result_type = wip.ty_id, |
| 2378 | .id_result = value_id, | 2413 | .id_result = value_id, |
| 2379 | .base = lhs_elem_id, | 2414 | .base = lhs_elem_id, |
| 2380 | .shift = shift_id, | 2415 | .shift = shift_id, |
| ... | @@ -2386,14 +2421,12 @@ const DeclGen = struct { | ... | @@ -2386,14 +2421,12 @@ const DeclGen = struct { |
| 2386 | try self.func.body.emit(self.spv.gpa, unsigned, args); | 2421 | try self.func.body.emit(self.spv.gpa, unsigned, args); |
| 2387 | } | 2422 | } |
| 2388 | | 2423 | |
| 2389 | result_id.* = try self.normalize(wip.scalar_ty_ref, value_id, info); | 2424 | result_id.* = try self.normalize(wip.ty_ref, value_id, info); |
| 2390 | } | 2425 | } |
| 2391 | return try wip.finalize(); | 2426 | return try wip.finalize(); |
| 2392 | } | 2427 | } |
| 2393 | | 2428 | |
| 2394 | fn airMinMax(self: *DeclGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !?IdRef { | 2429 | fn airMinMax(self: *DeclGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !?IdRef { |
| 2395 | if (self.liveness.isUnused(inst)) return null; | | |
| 2396 | | | |
| 2397 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 2430 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2398 | const lhs_id = try self.resolve(bin_op.lhs); | 2431 | const lhs_id = try self.resolve(bin_op.lhs); |
| 2399 | const rhs_id = try self.resolve(bin_op.rhs); | 2432 | const rhs_id = try self.resolve(bin_op.rhs); |
| ... | @@ -2405,14 +2438,14 @@ const DeclGen = struct { | ... | @@ -2405,14 +2438,14 @@ const DeclGen = struct { |
| 2405 | fn minMax(self: *DeclGen, result_ty: Type, op: std.math.CompareOperator, lhs_id: IdRef, rhs_id: IdRef) !IdRef { | 2438 | fn minMax(self: *DeclGen, result_ty: Type, op: std.math.CompareOperator, lhs_id: IdRef, rhs_id: IdRef) !IdRef { |
| 2406 | const info = self.arithmeticTypeInfo(result_ty); | 2439 | const info = self.arithmeticTypeInfo(result_ty); |
| 2407 | | 2440 | |
| 2408 | var wip = try self.elementWise(result_ty); | 2441 | var wip = try self.elementWise(result_ty, true); |
| 2409 | defer wip.deinit(); | 2442 | defer wip.deinit(); |
| 2410 | for (wip.results, 0..) |*result_id, i| { | 2443 | for (wip.results, 0..) |*result_id, i| { |
| 2411 | const lhs_elem_id = try wip.elementAt(result_ty, lhs_id, i); | 2444 | const lhs_elem_id = try wip.elementAt(result_ty, lhs_id, i); |
| 2412 | const rhs_elem_id = try wip.elementAt(result_ty, rhs_id, i); | 2445 | const rhs_elem_id = try wip.elementAt(result_ty, rhs_id, i); |
| 2413 | | 2446 | |
| 2414 | // TODO: Use fmin for OpenCL | 2447 | // TODO: Use fmin for OpenCL |
| 2415 | const cmp_id = try self.cmp(op, Type.bool, wip.scalar_ty, lhs_elem_id, rhs_elem_id); | 2448 | const cmp_id = try self.cmp(op, Type.bool, wip.ty, lhs_elem_id, rhs_elem_id); |
| 2416 | const selection_id = switch (info.class) { | 2449 | const selection_id = switch (info.class) { |
| 2417 | .float => blk: { | 2450 | .float => blk: { |
| 2418 | // cmp uses OpFOrd. When we have 0 [<>] nan this returns false, | 2451 | // cmp uses OpFOrd. When we have 0 [<>] nan this returns false, |
| ... | @@ -2440,7 +2473,7 @@ const DeclGen = struct { | ... | @@ -2440,7 +2473,7 @@ const DeclGen = struct { |
| 2440 | | 2473 | |
| 2441 | result_id.* = self.spv.allocId(); | 2474 | result_id.* = self.spv.allocId(); |
| 2442 | try self.func.body.emit(self.spv.gpa, .OpSelect, .{ | 2475 | try self.func.body.emit(self.spv.gpa, .OpSelect, .{ |
| 2443 | .id_result_type = wip.scalar_ty_id, | 2476 | .id_result_type = wip.ty_id, |
| 2444 | .id_result = result_id.*, | 2477 | .id_result = result_id.*, |
| 2445 | .condition = selection_id, | 2478 | .condition = selection_id, |
| 2446 | .object_1 = lhs_elem_id, | 2479 | .object_1 = lhs_elem_id, |
| ... | @@ -2505,7 +2538,6 @@ const DeclGen = struct { | ... | @@ -2505,7 +2538,6 @@ const DeclGen = struct { |
| 2505 | comptime sop: Opcode, | 2538 | comptime sop: Opcode, |
| 2506 | comptime uop: Opcode, | 2539 | comptime uop: Opcode, |
| 2507 | ) !?IdRef { | 2540 | ) !?IdRef { |
| 2508 | if (self.liveness.isUnused(inst)) return null; | | |
| 2509 | | 2541 | |
| 2510 | // LHS and RHS are guaranteed to have the same type, and AIR guarantees | 2542 | // LHS and RHS are guaranteed to have the same type, and AIR guarantees |
| 2511 | // the result to be the same as the LHS and RHS, which matches SPIR-V. | 2543 | // the result to be the same as the LHS and RHS, which matches SPIR-V. |
| ... | @@ -2545,7 +2577,7 @@ const DeclGen = struct { | ... | @@ -2545,7 +2577,7 @@ const DeclGen = struct { |
| 2545 | .bool => unreachable, | 2577 | .bool => unreachable, |
| 2546 | }; | 2578 | }; |
| 2547 | | 2579 | |
| 2548 | var wip = try self.elementWise(ty); | 2580 | var wip = try self.elementWise(ty, false); |
| 2549 | defer wip.deinit(); | 2581 | defer wip.deinit(); |
| 2550 | for (wip.results, 0..) |*result_id, i| { | 2582 | for (wip.results, 0..) |*result_id, i| { |
| 2551 | const lhs_elem_id = try wip.elementAt(ty, lhs_id, i); | 2583 | const lhs_elem_id = try wip.elementAt(ty, lhs_id, i); |
| ... | @@ -2553,7 +2585,7 @@ const DeclGen = struct { | ... | @@ -2553,7 +2585,7 @@ const DeclGen = struct { |
| 2553 | | 2585 | |
| 2554 | const value_id = self.spv.allocId(); | 2586 | const value_id = self.spv.allocId(); |
| 2555 | const operands = .{ | 2587 | const operands = .{ |
| 2556 | .id_result_type = wip.scalar_ty_id, | 2588 | .id_result_type = wip.ty_id, |
| 2557 | .id_result = value_id, | 2589 | .id_result = value_id, |
| 2558 | .operand_1 = lhs_elem_id, | 2590 | .operand_1 = lhs_elem_id, |
| 2559 | .operand_2 = rhs_elem_id, | 2591 | .operand_2 = rhs_elem_id, |
| ... | @@ -2568,26 +2600,24 @@ const DeclGen = struct { | ... | @@ -2568,26 +2600,24 @@ const DeclGen = struct { |
| 2568 | | 2600 | |
| 2569 | // TODO: Trap on overflow? Probably going to be annoying. | 2601 | // TODO: Trap on overflow? Probably going to be annoying. |
| 2570 | // TODO: Look into SPV_KHR_no_integer_wrap_decoration which provides NoSignedWrap/NoUnsignedWrap. | 2602 | // TODO: Look into SPV_KHR_no_integer_wrap_decoration which provides NoSignedWrap/NoUnsignedWrap. |
| 2571 | result_id.* = try self.normalize(wip.scalar_ty_ref, value_id, info); | 2603 | result_id.* = try self.normalize(wip.ty_ref, value_id, info); |
| 2572 | } | 2604 | } |
| 2573 | | 2605 | |
| 2574 | return try wip.finalize(); | 2606 | return try wip.finalize(); |
| 2575 | } | 2607 | } |
| 2576 | | 2608 | |
| 2577 | fn airAbs(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2609 | fn airAbs(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2578 | if (self.liveness.isUnused(inst)) return null; | | |
| 2579 | | | |
| 2580 | const mod = self.module; | 2610 | const mod = self.module; |
| 2581 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2611 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2582 | const operand_id = try self.resolve(ty_op.operand); | 2612 | const operand_id = try self.resolve(ty_op.operand); |
| 2583 | // Note: operand_ty may be signed, while ty is always unsigned! | 2613 | // Note: operand_ty may be signed, while ty is always unsigned! |
| 2584 | const operand_ty = self.typeOf(ty_op.operand); | 2614 | const operand_ty = self.typeOf(ty_op.operand); |
| 2585 | const ty = self.typeOfIndex(inst); | 2615 | const result_ty = self.typeOfIndex(inst); |
| 2586 | const info = self.arithmeticTypeInfo(ty); | 2616 | const info = self.arithmeticTypeInfo(result_ty); |
| 2587 | const operand_scalar_ty = operand_ty.scalarType(mod); | 2617 | const operand_scalar_ty = operand_ty.scalarType(mod); |
| 2588 | const operand_scalar_ty_ref = try self.resolveType(operand_scalar_ty, .direct); | 2618 | const operand_scalar_ty_ref = try self.resolveType(operand_scalar_ty, .direct); |
| 2589 | | 2619 | |
| 2590 | var wip = try self.elementWise(ty); | 2620 | var wip = try self.elementWise(result_ty, true); |
| 2591 | defer wip.deinit(); | 2621 | defer wip.deinit(); |
| 2592 | | 2622 | |
| 2593 | const zero_id = switch (info.class) { | 2623 | const zero_id = switch (info.class) { |
| ... | @@ -2615,7 +2645,7 @@ const DeclGen = struct { | ... | @@ -2615,7 +2645,7 @@ const DeclGen = struct { |
| 2615 | .composite_integer => unreachable, // TODO | 2645 | .composite_integer => unreachable, // TODO |
| 2616 | .bool => unreachable, | 2646 | .bool => unreachable, |
| 2617 | } | 2647 | } |
| 2618 | const neg_norm_id = try self.normalize(wip.scalar_ty_ref, neg_id, info); | 2648 | const neg_norm_id = try self.normalize(wip.ty_ref, neg_id, info); |
| 2619 | | 2649 | |
| 2620 | const gt_zero_id = try self.cmp(.gt, Type.bool, operand_scalar_ty, elem_id, zero_id); | 2650 | const gt_zero_id = try self.cmp(.gt, Type.bool, operand_scalar_ty, elem_id, zero_id); |
| 2621 | const abs_id = self.spv.allocId(); | 2651 | const abs_id = self.spv.allocId(); |
| ... | @@ -2627,7 +2657,7 @@ const DeclGen = struct { | ... | @@ -2627,7 +2657,7 @@ const DeclGen = struct { |
| 2627 | .object_2 = neg_norm_id, | 2657 | .object_2 = neg_norm_id, |
| 2628 | }); | 2658 | }); |
| 2629 | // For Shader, we may need to cast from signed to unsigned here. | 2659 | // For Shader, we may need to cast from signed to unsigned here. |
| 2630 | result_id.* = try self.bitCast(wip.scalar_ty, operand_scalar_ty, abs_id); | 2660 | result_id.* = try self.bitCast(wip.ty, operand_scalar_ty, abs_id); |
| 2631 | } | 2661 | } |
| 2632 | return try wip.finalize(); | 2662 | return try wip.finalize(); |
| 2633 | } | 2663 | } |
| ... | @@ -2639,8 +2669,7 @@ const DeclGen = struct { | ... | @@ -2639,8 +2669,7 @@ const DeclGen = struct { |
| 2639 | comptime ucmp: Opcode, | 2669 | comptime ucmp: Opcode, |
| 2640 | comptime scmp: Opcode, | 2670 | comptime scmp: Opcode, |
| 2641 | ) !?IdRef { | 2671 | ) !?IdRef { |
| 2642 | if (self.liveness.isUnused(inst)) return null; | 2672 | const mod = self.module; |
| 2643 | | | |
| 2644 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2673 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2645 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2674 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2646 | const lhs = try self.resolve(extra.lhs); | 2675 | const lhs = try self.resolve(extra.lhs); |
| ... | @@ -2651,6 +2680,10 @@ const DeclGen = struct { | ... | @@ -2651,6 +2680,10 @@ const DeclGen = struct { |
| 2651 | const ov_ty = result_ty.structFieldType(1, self.module); | 2680 | const ov_ty = result_ty.structFieldType(1, self.module); |
| 2652 | | 2681 | |
| 2653 | const bool_ty_ref = try self.resolveType(Type.bool, .direct); | 2682 | const bool_ty_ref = try self.resolveType(Type.bool, .direct); |
| | 2683 | const cmp_ty_ref = if (self.isVector(operand_ty)) |
| | 2684 | try self.spv.vectorType(operand_ty.vectorLen(mod), bool_ty_ref) |
| | 2685 | else |
| | 2686 | bool_ty_ref; |
| 2654 | | 2687 | |
| 2655 | const info = self.arithmeticTypeInfo(operand_ty); | 2688 | const info = self.arithmeticTypeInfo(operand_ty); |
| 2656 | switch (info.class) { | 2689 | switch (info.class) { |
| ... | @@ -2659,9 +2692,9 @@ const DeclGen = struct { | ... | @@ -2659,9 +2692,9 @@ const DeclGen = struct { |
| 2659 | .float, .bool => unreachable, | 2692 | .float, .bool => unreachable, |
| 2660 | } | 2693 | } |
| 2661 | | 2694 | |
| 2662 | var wip_result = try self.elementWise(operand_ty); | 2695 | var wip_result = try self.elementWise(operand_ty, false); |
| 2663 | defer wip_result.deinit(); | 2696 | defer wip_result.deinit(); |
| 2664 | var wip_ov = try self.elementWise(ov_ty); | 2697 | var wip_ov = try self.elementWise(ov_ty, false); |
| 2665 | defer wip_ov.deinit(); | 2698 | defer wip_ov.deinit(); |
| 2666 | for (wip_result.results, wip_ov.results, 0..) |*result_id, *ov_id, i| { | 2699 | for (wip_result.results, wip_ov.results, 0..) |*result_id, *ov_id, i| { |
| 2667 | const lhs_elem_id = try wip_result.elementAt(operand_ty, lhs, i); | 2700 | const lhs_elem_id = try wip_result.elementAt(operand_ty, lhs, i); |
| ... | @@ -2671,14 +2704,14 @@ const DeclGen = struct { | ... | @@ -2671,14 +2704,14 @@ const DeclGen = struct { |
| 2671 | const value_id = self.spv.allocId(); | 2704 | const value_id = self.spv.allocId(); |
| 2672 | | 2705 | |
| 2673 | try self.func.body.emit(self.spv.gpa, add, .{ | 2706 | try self.func.body.emit(self.spv.gpa, add, .{ |
| 2674 | .id_result_type = wip_result.scalar_ty_id, | 2707 | .id_result_type = wip_result.ty_id, |
| 2675 | .id_result = value_id, | 2708 | .id_result = value_id, |
| 2676 | .operand_1 = lhs_elem_id, | 2709 | .operand_1 = lhs_elem_id, |
| 2677 | .operand_2 = rhs_elem_id, | 2710 | .operand_2 = rhs_elem_id, |
| 2678 | }); | 2711 | }); |
| 2679 | | 2712 | |
| 2680 | // Normalize the result so that the comparisons go well | 2713 | // Normalize the result so that the comparisons go well |
| 2681 | result_id.* = try self.normalize(wip_result.scalar_ty_ref, value_id, info); | 2714 | result_id.* = try self.normalize(wip_result.ty_ref, value_id, info); |
| 2682 | | 2715 | |
| 2683 | const overflowed_id = switch (info.signedness) { | 2716 | const overflowed_id = switch (info.signedness) { |
| 2684 | .unsigned => blk: { | 2717 | .unsigned => blk: { |
| ... | @@ -2686,7 +2719,7 @@ const DeclGen = struct { | ... | @@ -2686,7 +2719,7 @@ const DeclGen = struct { |
| 2686 | // For subtraction the conditions need to be swapped. | 2719 | // For subtraction the conditions need to be swapped. |
| 2687 | const overflowed_id = self.spv.allocId(); | 2720 | const overflowed_id = self.spv.allocId(); |
| 2688 | try self.func.body.emit(self.spv.gpa, ucmp, .{ | 2721 | try self.func.body.emit(self.spv.gpa, ucmp, .{ |
| 2689 | .id_result_type = self.typeId(bool_ty_ref), | 2722 | .id_result_type = self.typeId(cmp_ty_ref), |
| 2690 | .id_result = overflowed_id, | 2723 | .id_result = overflowed_id, |
| 2691 | .operand_1 = result_id.*, | 2724 | .operand_1 = result_id.*, |
| 2692 | .operand_2 = lhs_elem_id, | 2725 | .operand_2 = lhs_elem_id, |
| ... | @@ -2712,9 +2745,9 @@ const DeclGen = struct { | ... | @@ -2712,9 +2745,9 @@ const DeclGen = struct { |
| 2712 | // = (rhs < 0) == (lhs > value) | 2745 | // = (rhs < 0) == (lhs > value) |
| 2713 | | 2746 | |
| 2714 | const rhs_lt_zero_id = self.spv.allocId(); | 2747 | const rhs_lt_zero_id = self.spv.allocId(); |
| 2715 | const zero_id = try self.constInt(wip_result.scalar_ty_ref, 0); | 2748 | const zero_id = try self.constInt(wip_result.ty_ref, 0); |
| 2716 | try self.func.body.emit(self.spv.gpa, .OpSLessThan, .{ | 2749 | try self.func.body.emit(self.spv.gpa, .OpSLessThan, .{ |
| 2717 | .id_result_type = self.typeId(bool_ty_ref), | 2750 | .id_result_type = self.typeId(cmp_ty_ref), |
| 2718 | .id_result = rhs_lt_zero_id, | 2751 | .id_result = rhs_lt_zero_id, |
| 2719 | .operand_1 = rhs_elem_id, | 2752 | .operand_1 = rhs_elem_id, |
| 2720 | .operand_2 = zero_id, | 2753 | .operand_2 = zero_id, |
| ... | @@ -2722,7 +2755,7 @@ const DeclGen = struct { | ... | @@ -2722,7 +2755,7 @@ const DeclGen = struct { |
| 2722 | | 2755 | |
| 2723 | const value_gt_lhs_id = self.spv.allocId(); | 2756 | const value_gt_lhs_id = self.spv.allocId(); |
| 2724 | try self.func.body.emit(self.spv.gpa, scmp, .{ | 2757 | try self.func.body.emit(self.spv.gpa, scmp, .{ |
| 2725 | .id_result_type = self.typeId(bool_ty_ref), | 2758 | .id_result_type = self.typeId(cmp_ty_ref), |
| 2726 | .id_result = value_gt_lhs_id, | 2759 | .id_result = value_gt_lhs_id, |
| 2727 | .operand_1 = lhs_elem_id, | 2760 | .operand_1 = lhs_elem_id, |
| 2728 | .operand_2 = result_id.*, | 2761 | .operand_2 = result_id.*, |
| ... | @@ -2730,7 +2763,7 @@ const DeclGen = struct { | ... | @@ -2730,7 +2763,7 @@ const DeclGen = struct { |
| 2730 | | 2763 | |
| 2731 | const overflowed_id = self.spv.allocId(); | 2764 | const overflowed_id = self.spv.allocId(); |
| 2732 | try self.func.body.emit(self.spv.gpa, .OpLogicalEqual, .{ | 2765 | try self.func.body.emit(self.spv.gpa, .OpLogicalEqual, .{ |
| 2733 | .id_result_type = self.typeId(bool_ty_ref), | 2766 | .id_result_type = self.typeId(cmp_ty_ref), |
| 2734 | .id_result = overflowed_id, | 2767 | .id_result = overflowed_id, |
| 2735 | .operand_1 = rhs_lt_zero_id, | 2768 | .operand_1 = rhs_lt_zero_id, |
| 2736 | .operand_2 = value_gt_lhs_id, | 2769 | .operand_2 = value_gt_lhs_id, |
| ... | @@ -2739,7 +2772,7 @@ const DeclGen = struct { | ... | @@ -2739,7 +2772,7 @@ const DeclGen = struct { |
| 2739 | }, | 2772 | }, |
| 2740 | }; | 2773 | }; |
| 2741 | | 2774 | |
| 2742 | ov_id.* = try self.intFromBool(wip_ov.scalar_ty_ref, overflowed_id); | 2775 | ov_id.* = try self.intFromBool(wip_ov.ty_ref, overflowed_id); |
| 2743 | } | 2776 | } |
| 2744 | | 2777 | |
| 2745 | return try self.constructComposite( | 2778 | return try self.constructComposite( |
| ... | @@ -2749,7 +2782,6 @@ const DeclGen = struct { | ... | @@ -2749,7 +2782,6 @@ const DeclGen = struct { |
| 2749 | } | 2782 | } |
| 2750 | | 2783 | |
| 2751 | fn airShlOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2784 | fn airShlOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2752 | if (self.liveness.isUnused(inst)) return null; | | |
| 2753 | const mod = self.module; | 2785 | const mod = self.module; |
| 2754 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2786 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2755 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; | 2787 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | @@ -2759,11 +2791,15 @@ const DeclGen = struct { | ... | @@ -2759,11 +2791,15 @@ const DeclGen = struct { |
| 2759 | const result_ty = self.typeOfIndex(inst); | 2791 | const result_ty = self.typeOfIndex(inst); |
| 2760 | const operand_ty = self.typeOf(extra.lhs); | 2792 | const operand_ty = self.typeOf(extra.lhs); |
| 2761 | const shift_ty = self.typeOf(extra.rhs); | 2793 | const shift_ty = self.typeOf(extra.rhs); |
| 2762 | const scalar_shift_ty_ref = try self.resolveType(shift_ty.scalarType(mod), .direct); | 2794 | const shift_ty_ref = try self.resolveType(shift_ty, .direct); |
| 2763 | | 2795 | |
| 2764 | const ov_ty = result_ty.structFieldType(1, self.module); | 2796 | const ov_ty = result_ty.structFieldType(1, self.module); |
| 2765 | | 2797 | |
| 2766 | const bool_ty_ref = try self.resolveType(Type.bool, .direct); | 2798 | const bool_ty_ref = try self.resolveType(Type.bool, .direct); |
| | 2799 | const cmp_ty_ref = if (self.isVector(operand_ty)) |
| | 2800 | try self.spv.vectorType(operand_ty.vectorLen(mod), bool_ty_ref) |
| | 2801 | else |
| | 2802 | bool_ty_ref; |
| 2767 | | 2803 | |
| 2768 | const info = self.arithmeticTypeInfo(operand_ty); | 2804 | const info = self.arithmeticTypeInfo(operand_ty); |
| 2769 | switch (info.class) { | 2805 | switch (info.class) { |
| ... | @@ -2772,9 +2808,9 @@ const DeclGen = struct { | ... | @@ -2772,9 +2808,9 @@ const DeclGen = struct { |
| 2772 | .float, .bool => unreachable, | 2808 | .float, .bool => unreachable, |
| 2773 | } | 2809 | } |
| 2774 | | 2810 | |
| 2775 | var wip_result = try self.elementWise(operand_ty); | 2811 | var wip_result = try self.elementWise(operand_ty, false); |
| 2776 | defer wip_result.deinit(); | 2812 | defer wip_result.deinit(); |
| 2777 | var wip_ov = try self.elementWise(ov_ty); | 2813 | var wip_ov = try self.elementWise(ov_ty, false); |
| 2778 | defer wip_ov.deinit(); | 2814 | defer wip_ov.deinit(); |
| 2779 | for (wip_result.results, wip_ov.results, 0..) |*result_id, *ov_id, i| { | 2815 | for (wip_result.results, wip_ov.results, 0..) |*result_id, *ov_id, i| { |
| 2780 | const lhs_elem_id = try wip_result.elementAt(operand_ty, lhs, i); | 2816 | const lhs_elem_id = try wip_result.elementAt(operand_ty, lhs, i); |
| ... | @@ -2782,10 +2818,10 @@ const DeclGen = struct { | ... | @@ -2782,10 +2818,10 @@ const DeclGen = struct { |
| 2782 | | 2818 | |
| 2783 | // Sometimes Zig doesn't make both of the arguments the same types here. SPIR-V expects that, | 2819 | // Sometimes Zig doesn't make both of the arguments the same types here. SPIR-V expects that, |
| 2784 | // so just manually upcast it if required. | 2820 | // so just manually upcast it if required. |
| 2785 | const shift_id = if (scalar_shift_ty_ref != wip_result.scalar_ty_ref) blk: { | 2821 | const shift_id = if (shift_ty_ref != wip_result.ty_ref) blk: { |
| 2786 | const shift_id = self.spv.allocId(); | 2822 | const shift_id = self.spv.allocId(); |
| 2787 | try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ | 2823 | try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ |
| 2788 | .id_result_type = wip_result.scalar_ty_id, | 2824 | .id_result_type = wip_result.ty_id, |
| 2789 | .id_result = shift_id, | 2825 | .id_result = shift_id, |
| 2790 | .unsigned_value = rhs_elem_id, | 2826 | .unsigned_value = rhs_elem_id, |
| 2791 | }); | 2827 | }); |
| ... | @@ -2794,18 +2830,18 @@ const DeclGen = struct { | ... | @@ -2794,18 +2830,18 @@ const DeclGen = struct { |
| 2794 | | 2830 | |
| 2795 | const value_id = self.spv.allocId(); | 2831 | const value_id = self.spv.allocId(); |
| 2796 | try self.func.body.emit(self.spv.gpa, .OpShiftLeftLogical, .{ | 2832 | try self.func.body.emit(self.spv.gpa, .OpShiftLeftLogical, .{ |
| 2797 | .id_result_type = wip_result.scalar_ty_id, | 2833 | .id_result_type = wip_result.ty_id, |
| 2798 | .id_result = value_id, | 2834 | .id_result = value_id, |
| 2799 | .base = lhs_elem_id, | 2835 | .base = lhs_elem_id, |
| 2800 | .shift = shift_id, | 2836 | .shift = shift_id, |
| 2801 | }); | 2837 | }); |
| 2802 | result_id.* = try self.normalize(wip_result.scalar_ty_ref, value_id, info); | 2838 | result_id.* = try self.normalize(wip_result.ty_ref, value_id, info); |
| 2803 | | 2839 | |
| 2804 | const right_shift_id = self.spv.allocId(); | 2840 | const right_shift_id = self.spv.allocId(); |
| 2805 | switch (info.signedness) { | 2841 | switch (info.signedness) { |
| 2806 | .signed => { | 2842 | .signed => { |
| 2807 | try self.func.body.emit(self.spv.gpa, .OpShiftRightArithmetic, .{ | 2843 | try self.func.body.emit(self.spv.gpa, .OpShiftRightArithmetic, .{ |
| 2808 | .id_result_type = wip_result.scalar_ty_id, | 2844 | .id_result_type = wip_result.ty_id, |
| 2809 | .id_result = right_shift_id, | 2845 | .id_result = right_shift_id, |
| 2810 | .base = result_id.*, | 2846 | .base = result_id.*, |
| 2811 | .shift = shift_id, | 2847 | .shift = shift_id, |
| ... | @@ -2813,7 +2849,7 @@ const DeclGen = struct { | ... | @@ -2813,7 +2849,7 @@ const DeclGen = struct { |
| 2813 | }, | 2849 | }, |
| 2814 | .unsigned => { | 2850 | .unsigned => { |
| 2815 | try self.func.body.emit(self.spv.gpa, .OpShiftRightLogical, .{ | 2851 | try self.func.body.emit(self.spv.gpa, .OpShiftRightLogical, .{ |
| 2816 | .id_result_type = wip_result.scalar_ty_id, | 2852 | .id_result_type = wip_result.ty_id, |
| 2817 | .id_result = right_shift_id, | 2853 | .id_result = right_shift_id, |
| 2818 | .base = result_id.*, | 2854 | .base = result_id.*, |
| 2819 | .shift = shift_id, | 2855 | .shift = shift_id, |
| ... | @@ -2823,13 +2859,13 @@ const DeclGen = struct { | ... | @@ -2823,13 +2859,13 @@ const DeclGen = struct { |
| 2823 | | 2859 | |
| 2824 | const overflowed_id = self.spv.allocId(); | 2860 | const overflowed_id = self.spv.allocId(); |
| 2825 | try self.func.body.emit(self.spv.gpa, .OpINotEqual, .{ | 2861 | try self.func.body.emit(self.spv.gpa, .OpINotEqual, .{ |
| 2826 | .id_result_type = self.typeId(bool_ty_ref), | 2862 | .id_result_type = self.typeId(cmp_ty_ref), |
| 2827 | .id_result = overflowed_id, | 2863 | .id_result = overflowed_id, |
| 2828 | .operand_1 = lhs_elem_id, | 2864 | .operand_1 = lhs_elem_id, |
| 2829 | .operand_2 = right_shift_id, | 2865 | .operand_2 = right_shift_id, |
| 2830 | }); | 2866 | }); |
| 2831 | | 2867 | |
| 2832 | ov_id.* = try self.intFromBool(wip_ov.scalar_ty_ref, overflowed_id); | 2868 | ov_id.* = try self.intFromBool(wip_ov.ty_ref, overflowed_id); |
| 2833 | } | 2869 | } |
| 2834 | | 2870 | |
| 2835 | return try self.constructComposite( | 2871 | return try self.constructComposite( |
| ... | @@ -2839,8 +2875,6 @@ const DeclGen = struct { | ... | @@ -2839,8 +2875,6 @@ const DeclGen = struct { |
| 2839 | } | 2875 | } |
| 2840 | | 2876 | |
| 2841 | fn airMulAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2877 | fn airMulAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2842 | if (self.liveness.isUnused(inst)) return null; | | |
| 2843 | | | |
| 2844 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 2878 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 2845 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 2879 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 2846 | | 2880 | |
| ... | @@ -2853,19 +2887,19 @@ const DeclGen = struct { | ... | @@ -2853,19 +2887,19 @@ const DeclGen = struct { |
| 2853 | const info = self.arithmeticTypeInfo(ty); | 2887 | const info = self.arithmeticTypeInfo(ty); |
| 2854 | assert(info.class == .float); // .mul_add is only emitted for floats | 2888 | assert(info.class == .float); // .mul_add is only emitted for floats |
| 2855 | | 2889 | |
| 2856 | var wip = try self.elementWise(ty); | 2890 | var wip = try self.elementWise(ty, false); |
| 2857 | defer wip.deinit(); | 2891 | defer wip.deinit(); |
| 2858 | for (0..wip.results.len) |i| { | 2892 | for (0..wip.results.len) |i| { |
| 2859 | const mul_result = self.spv.allocId(); | 2893 | const mul_result = self.spv.allocId(); |
| 2860 | try self.func.body.emit(self.spv.gpa, .OpFMul, .{ | 2894 | try self.func.body.emit(self.spv.gpa, .OpFMul, .{ |
| 2861 | .id_result_type = wip.scalar_ty_id, | 2895 | .id_result_type = wip.ty_id, |
| 2862 | .id_result = mul_result, | 2896 | .id_result = mul_result, |
| 2863 | .operand_1 = try wip.elementAt(ty, mulend1, i), | 2897 | .operand_1 = try wip.elementAt(ty, mulend1, i), |
| 2864 | .operand_2 = try wip.elementAt(ty, mulend2, i), | 2898 | .operand_2 = try wip.elementAt(ty, mulend2, i), |
| 2865 | }); | 2899 | }); |
| 2866 | | 2900 | |
| 2867 | try self.func.body.emit(self.spv.gpa, .OpFAdd, .{ | 2901 | try self.func.body.emit(self.spv.gpa, .OpFAdd, .{ |
| 2868 | .id_result_type = wip.scalar_ty_id, | 2902 | .id_result_type = wip.ty_id, |
| 2869 | .id_result = wip.allocId(i), | 2903 | .id_result = wip.allocId(i), |
| 2870 | .operand_1 = mul_result, | 2904 | .operand_1 = mul_result, |
| 2871 | .operand_2 = try wip.elementAt(ty, addend, i), | 2905 | .operand_2 = try wip.elementAt(ty, addend, i), |
| ... | @@ -2875,20 +2909,16 @@ const DeclGen = struct { | ... | @@ -2875,20 +2909,16 @@ const DeclGen = struct { |
| 2875 | } | 2909 | } |
| 2876 | | 2910 | |
| 2877 | fn airSplat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2911 | fn airSplat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2878 | if (self.liveness.isUnused(inst)) return null; | | |
| 2879 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 2912 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2880 | const operand_id = try self.resolve(ty_op.operand); | 2913 | const operand_id = try self.resolve(ty_op.operand); |
| 2881 | const result_ty = self.typeOfIndex(inst); | 2914 | const result_ty = self.typeOfIndex(inst); |
| 2882 | var wip = try self.elementWise(result_ty); | 2915 | var wip = try self.elementWise(result_ty, true); |
| 2883 | defer wip.deinit(); | 2916 | defer wip.deinit(); |
| 2884 | for (wip.results) |*result_id| { | 2917 | @memset(wip.results, operand_id); |
| 2885 | result_id.* = operand_id; | | |
| 2886 | } | | |
| 2887 | return try wip.finalize(); | 2918 | return try wip.finalize(); |
| 2888 | } | 2919 | } |
| 2889 | | 2920 | |
| 2890 | fn airReduce(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2921 | fn airReduce(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2891 | if (self.liveness.isUnused(inst)) return null; | | |
| 2892 | const mod = self.module; | 2922 | const mod = self.module; |
| 2893 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; | 2923 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 2894 | const operand = try self.resolve(reduce.operand); | 2924 | const operand = try self.resolve(reduce.operand); |
| ... | @@ -2956,7 +2986,6 @@ const DeclGen = struct { | ... | @@ -2956,7 +2986,6 @@ const DeclGen = struct { |
| 2956 | | 2986 | |
| 2957 | fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2987 | fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2958 | const mod = self.module; | 2988 | const mod = self.module; |
| 2959 | if (self.liveness.isUnused(inst)) return null; | | |
| 2960 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 2989 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2961 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; | 2990 | const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 2962 | const a = try self.resolve(extra.a); | 2991 | const a = try self.resolve(extra.a); |
| ... | @@ -2965,20 +2994,20 @@ const DeclGen = struct { | ... | @@ -2965,20 +2994,20 @@ const DeclGen = struct { |
| 2965 | | 2994 | |
| 2966 | const ty = self.typeOfIndex(inst); | 2995 | const ty = self.typeOfIndex(inst); |
| 2967 | | 2996 | |
| 2968 | var wip = try self.elementWise(ty); | 2997 | var wip = try self.elementWise(ty, true); |
| 2969 | defer wip.deinit(); | 2998 | defer wip.deinit(); |
| 2970 | for (wip.results, 0..) |*result_id, i| { | 2999 | for (wip.results, 0..) |*result_id, i| { |
| 2971 | const elem = try mask.elemValue(mod, i); | 3000 | const elem = try mask.elemValue(mod, i); |
| 2972 | if (elem.isUndef(mod)) { | 3001 | if (elem.isUndef(mod)) { |
| 2973 | result_id.* = try self.spv.constUndef(wip.scalar_ty_ref); | 3002 | result_id.* = try self.spv.constUndef(wip.ty_ref); |
| 2974 | continue; | 3003 | continue; |
| 2975 | } | 3004 | } |
| 2976 | | 3005 | |
| 2977 | const index = elem.toSignedInt(mod); | 3006 | const index = elem.toSignedInt(mod); |
| 2978 | if (index >= 0) { | 3007 | if (index >= 0) { |
| 2979 | result_id.* = try self.extractField(wip.scalar_ty, a, @intCast(index)); | 3008 | result_id.* = try self.extractField(wip.ty, a, @intCast(index)); |
| 2980 | } else { | 3009 | } else { |
| 2981 | result_id.* = try self.extractField(wip.scalar_ty, b, @intCast(~index)); | 3010 | result_id.* = try self.extractField(wip.ty, b, @intCast(~index)); |
| 2982 | } | 3011 | } |
| 2983 | } | 3012 | } |
| 2984 | return try wip.finalize(); | 3013 | return try wip.finalize(); |
| ... | @@ -3069,7 +3098,6 @@ const DeclGen = struct { | ... | @@ -3069,7 +3098,6 @@ const DeclGen = struct { |
| 3069 | } | 3098 | } |
| 3070 | | 3099 | |
| 3071 | fn airPtrAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3100 | fn airPtrAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3072 | if (self.liveness.isUnused(inst)) return null; | | |
| 3073 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3101 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3074 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3102 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3075 | const ptr_id = try self.resolve(bin_op.lhs); | 3103 | const ptr_id = try self.resolve(bin_op.lhs); |
| ... | @@ -3081,7 +3109,6 @@ const DeclGen = struct { | ... | @@ -3081,7 +3109,6 @@ const DeclGen = struct { |
| 3081 | } | 3109 | } |
| 3082 | | 3110 | |
| 3083 | fn airPtrSub(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3111 | fn airPtrSub(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3084 | if (self.liveness.isUnused(inst)) return null; | | |
| 3085 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3112 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3086 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3113 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3087 | const ptr_id = try self.resolve(bin_op.lhs); | 3114 | const ptr_id = try self.resolve(bin_op.lhs); |
| ... | @@ -3188,7 +3215,7 @@ const DeclGen = struct { | ... | @@ -3188,7 +3215,7 @@ const DeclGen = struct { |
| 3188 | return result_id; | 3215 | return result_id; |
| 3189 | }, | 3216 | }, |
| 3190 | .Vector => { | 3217 | .Vector => { |
| 3191 | var wip = try self.elementWise(result_ty); | 3218 | var wip = try self.elementWise(result_ty, true); |
| 3192 | defer wip.deinit(); | 3219 | defer wip.deinit(); |
| 3193 | const scalar_ty = ty.scalarType(mod); | 3220 | const scalar_ty = ty.scalarType(mod); |
| 3194 | for (wip.results, 0..) |*result_id, i| { | 3221 | for (wip.results, 0..) |*result_id, i| { |
| ... | @@ -3257,7 +3284,6 @@ const DeclGen = struct { | ... | @@ -3257,7 +3284,6 @@ const DeclGen = struct { |
| 3257 | inst: Air.Inst.Index, | 3284 | inst: Air.Inst.Index, |
| 3258 | comptime op: std.math.CompareOperator, | 3285 | comptime op: std.math.CompareOperator, |
| 3259 | ) !?IdRef { | 3286 | ) !?IdRef { |
| 3260 | if (self.liveness.isUnused(inst)) return null; | | |
| 3261 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3287 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3262 | const lhs_id = try self.resolve(bin_op.lhs); | 3288 | const lhs_id = try self.resolve(bin_op.lhs); |
| 3263 | const rhs_id = try self.resolve(bin_op.rhs); | 3289 | const rhs_id = try self.resolve(bin_op.rhs); |
| ... | @@ -3268,8 +3294,6 @@ const DeclGen = struct { | ... | @@ -3268,8 +3294,6 @@ const DeclGen = struct { |
| 3268 | } | 3294 | } |
| 3269 | | 3295 | |
| 3270 | fn airVectorCmp(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3296 | fn airVectorCmp(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3271 | if (self.liveness.isUnused(inst)) return null; | | |
| 3272 | | | |
| 3273 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3297 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3274 | const vec_cmp = self.air.extraData(Air.VectorCmp, ty_pl.payload).data; | 3298 | const vec_cmp = self.air.extraData(Air.VectorCmp, ty_pl.payload).data; |
| 3275 | const lhs_id = try self.resolve(vec_cmp.lhs); | 3299 | const lhs_id = try self.resolve(vec_cmp.lhs); |
| ... | @@ -3351,7 +3375,6 @@ const DeclGen = struct { | ... | @@ -3351,7 +3375,6 @@ const DeclGen = struct { |
| 3351 | } | 3375 | } |
| 3352 | | 3376 | |
| 3353 | fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3377 | fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3354 | if (self.liveness.isUnused(inst)) return null; | | |
| 3355 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3378 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3356 | const operand_id = try self.resolve(ty_op.operand); | 3379 | const operand_id = try self.resolve(ty_op.operand); |
| 3357 | const operand_ty = self.typeOf(ty_op.operand); | 3380 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -3360,8 +3383,6 @@ const DeclGen = struct { | ... | @@ -3360,8 +3383,6 @@ const DeclGen = struct { |
| 3360 | } | 3383 | } |
| 3361 | | 3384 | |
| 3362 | fn airIntCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3385 | fn airIntCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3363 | if (self.liveness.isUnused(inst)) return null; | | |
| 3364 | | | |
| 3365 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3386 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3366 | const operand_id = try self.resolve(ty_op.operand); | 3387 | const operand_id = try self.resolve(ty_op.operand); |
| 3367 | const src_ty = self.typeOf(ty_op.operand); | 3388 | const src_ty = self.typeOf(ty_op.operand); |
| ... | @@ -3374,19 +3395,19 @@ const DeclGen = struct { | ... | @@ -3374,19 +3395,19 @@ const DeclGen = struct { |
| 3374 | return operand_id; | 3395 | return operand_id; |
| 3375 | } | 3396 | } |
| 3376 | | 3397 | |
| 3377 | var wip = try self.elementWise(dst_ty); | 3398 | var wip = try self.elementWise(dst_ty, false); |
| 3378 | defer wip.deinit(); | 3399 | defer wip.deinit(); |
| 3379 | for (wip.results, 0..) |*result_id, i| { | 3400 | for (wip.results, 0..) |*result_id, i| { |
| 3380 | const elem_id = try wip.elementAt(src_ty, operand_id, i); | 3401 | const elem_id = try wip.elementAt(src_ty, operand_id, i); |
| 3381 | const value_id = self.spv.allocId(); | 3402 | const value_id = self.spv.allocId(); |
| 3382 | switch (dst_info.signedness) { | 3403 | switch (dst_info.signedness) { |
| 3383 | .signed => try self.func.body.emit(self.spv.gpa, .OpSConvert, .{ | 3404 | .signed => try self.func.body.emit(self.spv.gpa, .OpSConvert, .{ |
| 3384 | .id_result_type = wip.scalar_ty_id, | 3405 | .id_result_type = wip.ty_id, |
| 3385 | .id_result = value_id, | 3406 | .id_result = value_id, |
| 3386 | .signed_value = elem_id, | 3407 | .signed_value = elem_id, |
| 3387 | }), | 3408 | }), |
| 3388 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ | 3409 | .unsigned => try self.func.body.emit(self.spv.gpa, .OpUConvert, .{ |
| 3389 | .id_result_type = wip.scalar_ty_id, | 3410 | .id_result_type = wip.ty_id, |
| 3390 | .id_result = value_id, | 3411 | .id_result = value_id, |
| 3391 | .unsigned_value = elem_id, | 3412 | .unsigned_value = elem_id, |
| 3392 | }), | 3413 | }), |
| ... | @@ -3397,7 +3418,7 @@ const DeclGen = struct { | ... | @@ -3397,7 +3418,7 @@ const DeclGen = struct { |
| 3397 | // type, we don't need to normalize when growing the type. The | 3418 | // type, we don't need to normalize when growing the type. The |
| 3398 | // representation is already the same. | 3419 | // representation is already the same. |
| 3399 | if (dst_info.bits < src_info.bits) { | 3420 | if (dst_info.bits < src_info.bits) { |
| 3400 | result_id.* = try self.normalize(wip.scalar_ty_ref, value_id, dst_info); | 3421 | result_id.* = try self.normalize(wip.ty_ref, value_id, dst_info); |
| 3401 | } else { | 3422 | } else { |
| 3402 | result_id.* = value_id; | 3423 | result_id.* = value_id; |
| 3403 | } | 3424 | } |
| ... | @@ -3417,16 +3438,12 @@ const DeclGen = struct { | ... | @@ -3417,16 +3438,12 @@ const DeclGen = struct { |
| 3417 | } | 3438 | } |
| 3418 | | 3439 | |
| 3419 | fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3440 | fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3420 | if (self.liveness.isUnused(inst)) return null; | | |
| 3421 | | | |
| 3422 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 3441 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 3423 | const operand_id = try self.resolve(un_op); | 3442 | const operand_id = try self.resolve(un_op); |
| 3424 | return try self.intFromPtr(operand_id); | 3443 | return try self.intFromPtr(operand_id); |
| 3425 | } | 3444 | } |
| 3426 | | 3445 | |
| 3427 | fn airFloatFromInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3446 | fn airFloatFromInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3428 | if (self.liveness.isUnused(inst)) return null; | | |
| 3429 | | | |
| 3430 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3447 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3431 | const operand_ty = self.typeOf(ty_op.operand); | 3448 | const operand_ty = self.typeOf(ty_op.operand); |
| 3432 | const operand_id = try self.resolve(ty_op.operand); | 3449 | const operand_id = try self.resolve(ty_op.operand); |
| ... | @@ -3451,8 +3468,6 @@ const DeclGen = struct { | ... | @@ -3451,8 +3468,6 @@ const DeclGen = struct { |
| 3451 | } | 3468 | } |
| 3452 | | 3469 | |
| 3453 | fn airIntFromFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3470 | fn airIntFromFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3454 | if (self.liveness.isUnused(inst)) return null; | | |
| 3455 | | | |
| 3456 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3471 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3457 | const operand_id = try self.resolve(ty_op.operand); | 3472 | const operand_id = try self.resolve(ty_op.operand); |
| 3458 | const dest_ty = self.typeOfIndex(inst); | 3473 | const dest_ty = self.typeOfIndex(inst); |
| ... | @@ -3476,24 +3491,20 @@ const DeclGen = struct { | ... | @@ -3476,24 +3491,20 @@ const DeclGen = struct { |
| 3476 | } | 3491 | } |
| 3477 | | 3492 | |
| 3478 | fn airIntFromBool(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3493 | fn airIntFromBool(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3479 | if (self.liveness.isUnused(inst)) return null; | | |
| 3480 | | | |
| 3481 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 3494 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 3482 | const operand_id = try self.resolve(un_op); | 3495 | const operand_id = try self.resolve(un_op); |
| 3483 | const result_ty = self.typeOfIndex(inst); | 3496 | const result_ty = self.typeOfIndex(inst); |
| 3484 | | 3497 | |
| 3485 | var wip = try self.elementWise(result_ty); | 3498 | var wip = try self.elementWise(result_ty, false); |
| 3486 | defer wip.deinit(); | 3499 | defer wip.deinit(); |
| 3487 | for (wip.results, 0..) |*result_id, i| { | 3500 | for (wip.results, 0..) |*result_id, i| { |
| 3488 | const elem_id = try wip.elementAt(Type.bool, operand_id, i); | 3501 | const elem_id = try wip.elementAt(Type.bool, operand_id, i); |
| 3489 | result_id.* = try self.intFromBool(wip.scalar_ty_ref, elem_id); | 3502 | result_id.* = try self.intFromBool(wip.ty_ref, elem_id); |
| 3490 | } | 3503 | } |
| 3491 | return try wip.finalize(); | 3504 | return try wip.finalize(); |
| 3492 | } | 3505 | } |
| 3493 | | 3506 | |
| 3494 | fn airFloatCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3507 | fn airFloatCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3495 | if (self.liveness.isUnused(inst)) return null; | | |
| 3496 | | | |
| 3497 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3508 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3498 | const operand_id = try self.resolve(ty_op.operand); | 3509 | const operand_id = try self.resolve(ty_op.operand); |
| 3499 | const dest_ty = self.typeOfIndex(inst); | 3510 | const dest_ty = self.typeOfIndex(inst); |
| ... | @@ -3509,18 +3520,17 @@ const DeclGen = struct { | ... | @@ -3509,18 +3520,17 @@ const DeclGen = struct { |
| 3509 | } | 3520 | } |
| 3510 | | 3521 | |
| 3511 | fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3522 | fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3512 | if (self.liveness.isUnused(inst)) return null; | | |
| 3513 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3523 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3514 | const operand_id = try self.resolve(ty_op.operand); | 3524 | const operand_id = try self.resolve(ty_op.operand); |
| 3515 | const result_ty = self.typeOfIndex(inst); | 3525 | const result_ty = self.typeOfIndex(inst); |
| 3516 | const info = self.arithmeticTypeInfo(result_ty); | 3526 | const info = self.arithmeticTypeInfo(result_ty); |
| 3517 | | 3527 | |
| 3518 | var wip = try self.elementWise(result_ty); | 3528 | var wip = try self.elementWise(result_ty, false); |
| 3519 | defer wip.deinit(); | 3529 | defer wip.deinit(); |
| 3520 | | 3530 | |
| 3521 | for (0..wip.results.len) |i| { | 3531 | for (0..wip.results.len) |i| { |
| 3522 | const args = .{ | 3532 | const args = .{ |
| 3523 | .id_result_type = wip.scalar_ty_id, | 3533 | .id_result_type = wip.ty_id, |
| 3524 | .id_result = wip.allocId(i), | 3534 | .id_result = wip.allocId(i), |
| 3525 | .operand = try wip.elementAt(result_ty, operand_id, i), | 3535 | .operand = try wip.elementAt(result_ty, operand_id, i), |
| 3526 | }; | 3536 | }; |
| ... | @@ -3541,8 +3551,6 @@ const DeclGen = struct { | ... | @@ -3541,8 +3551,6 @@ const DeclGen = struct { |
| 3541 | } | 3551 | } |
| 3542 | | 3552 | |
| 3543 | fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3553 | fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3544 | if (self.liveness.isUnused(inst)) return null; | | |
| 3545 | | | |
| 3546 | const mod = self.module; | 3554 | const mod = self.module; |
| 3547 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3555 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3548 | const array_ptr_ty = self.typeOf(ty_op.operand); | 3556 | const array_ptr_ty = self.typeOf(ty_op.operand); |
| ... | @@ -3563,15 +3571,10 @@ const DeclGen = struct { | ... | @@ -3563,15 +3571,10 @@ const DeclGen = struct { |
| 3563 | // Convert the pointer-to-array to a pointer to the first element. | 3571 | // Convert the pointer-to-array to a pointer to the first element. |
| 3564 | try self.accessChain(elem_ptr_ty_ref, array_ptr_id, &.{0}); | 3572 | try self.accessChain(elem_ptr_ty_ref, array_ptr_id, &.{0}); |
| 3565 | | 3573 | |
| 3566 | return try self.constructComposite( | 3574 | return try self.constructComposite(slice_ty, &.{ elem_ptr_id, len_id }); |
| 3567 | slice_ty, | | |
| 3568 | &.{ elem_ptr_id, len_id }, | | |
| 3569 | ); | | |
| 3570 | } | 3575 | } |
| 3571 | | 3576 | |
| 3572 | fn airSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3577 | fn airSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3573 | if (self.liveness.isUnused(inst)) return null; | | |
| 3574 | | | |
| 3575 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3578 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3576 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3579 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3577 | const ptr_id = try self.resolve(bin_op.lhs); | 3580 | const ptr_id = try self.resolve(bin_op.lhs); |
| ... | @@ -3580,15 +3583,10 @@ const DeclGen = struct { | ... | @@ -3580,15 +3583,10 @@ const DeclGen = struct { |
| 3580 | | 3583 | |
| 3581 | // Note: Types should not need to be converted to direct, these types | 3584 | // Note: Types should not need to be converted to direct, these types |
| 3582 | // dont need to be converted. | 3585 | // dont need to be converted. |
| 3583 | return try self.constructComposite( | 3586 | return try self.constructComposite(slice_ty, &.{ ptr_id, len_id }); |
| 3584 | slice_ty, | | |
| 3585 | &.{ ptr_id, len_id }, | | |
| 3586 | ); | | |
| 3587 | } | 3587 | } |
| 3588 | | 3588 | |
| 3589 | fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3589 | fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3590 | if (self.liveness.isUnused(inst)) return null; | | |
| 3591 | | | |
| 3592 | const mod = self.module; | 3590 | const mod = self.module; |
| 3593 | const ip = &mod.intern_pool; | 3591 | const ip = &mod.intern_pool; |
| 3594 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3592 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | @@ -3710,7 +3708,6 @@ const DeclGen = struct { | ... | @@ -3710,7 +3708,6 @@ const DeclGen = struct { |
| 3710 | } | 3708 | } |
| 3711 | | 3709 | |
| 3712 | fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef { | 3710 | fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef { |
| 3713 | if (self.liveness.isUnused(inst)) return null; | | |
| 3714 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3711 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3715 | const field_ty = self.typeOfIndex(inst); | 3712 | const field_ty = self.typeOfIndex(inst); |
| 3716 | const operand_id = try self.resolve(ty_op.operand); | 3713 | const operand_id = try self.resolve(ty_op.operand); |
| ... | @@ -3767,8 +3764,6 @@ const DeclGen = struct { | ... | @@ -3767,8 +3764,6 @@ const DeclGen = struct { |
| 3767 | } | 3764 | } |
| 3768 | | 3765 | |
| 3769 | fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3766 | fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3770 | if (self.liveness.isUnused(inst)) return null; | | |
| 3771 | | | |
| 3772 | const mod = self.module; | 3767 | const mod = self.module; |
| 3773 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3768 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3774 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3769 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | @@ -3786,8 +3781,6 @@ const DeclGen = struct { | ... | @@ -3786,8 +3781,6 @@ const DeclGen = struct { |
| 3786 | } | 3781 | } |
| 3787 | | 3782 | |
| 3788 | fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3783 | fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3789 | if (self.liveness.isUnused(inst)) return null; | | |
| 3790 | | | |
| 3791 | const mod = self.module; | 3784 | const mod = self.module; |
| 3792 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3785 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3793 | const array_ty = self.typeOf(bin_op.lhs); | 3786 | const array_ty = self.typeOf(bin_op.lhs); |
| ... | @@ -3808,8 +3801,6 @@ const DeclGen = struct { | ... | @@ -3808,8 +3801,6 @@ const DeclGen = struct { |
| 3808 | } | 3801 | } |
| 3809 | | 3802 | |
| 3810 | fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3803 | fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3811 | if (self.liveness.isUnused(inst)) return null; | | |
| 3812 | | | |
| 3813 | const mod = self.module; | 3804 | const mod = self.module; |
| 3814 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 3805 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3815 | const ptr_ty = self.typeOf(bin_op.lhs); | 3806 | const ptr_ty = self.typeOf(bin_op.lhs); |
| ... | @@ -3866,8 +3857,6 @@ const DeclGen = struct { | ... | @@ -3866,8 +3857,6 @@ const DeclGen = struct { |
| 3866 | } | 3857 | } |
| 3867 | | 3858 | |
| 3868 | fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3859 | fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3869 | if (self.liveness.isUnused(inst)) return null; | | |
| 3870 | | | |
| 3871 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3860 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3872 | const un_ty = self.typeOf(ty_op.operand); | 3861 | const un_ty = self.typeOf(ty_op.operand); |
| 3873 | | 3862 | |
| ... | @@ -3951,8 +3940,6 @@ const DeclGen = struct { | ... | @@ -3951,8 +3940,6 @@ const DeclGen = struct { |
| 3951 | } | 3940 | } |
| 3952 | | 3941 | |
| 3953 | fn airUnionInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3942 | fn airUnionInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3954 | if (self.liveness.isUnused(inst)) return null; | | |
| 3955 | | | |
| 3956 | const mod = self.module; | 3943 | const mod = self.module; |
| 3957 | const ip = &mod.intern_pool; | 3944 | const ip = &mod.intern_pool; |
| 3958 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3945 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | @@ -3969,8 +3956,6 @@ const DeclGen = struct { | ... | @@ -3969,8 +3956,6 @@ const DeclGen = struct { |
| 3969 | } | 3956 | } |
| 3970 | | 3957 | |
| 3971 | fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3958 | fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3972 | if (self.liveness.isUnused(inst)) return null; | | |
| 3973 | | | |
| 3974 | const mod = self.module; | 3959 | const mod = self.module; |
| 3975 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3960 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3976 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; | 3961 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | @@ -4091,7 +4076,6 @@ const DeclGen = struct { | ... | @@ -4091,7 +4076,6 @@ const DeclGen = struct { |
| 4091 | } | 4076 | } |
| 4092 | | 4077 | |
| 4093 | fn airStructFieldPtrIndex(self: *DeclGen, inst: Air.Inst.Index, field_index: u32) !?IdRef { | 4078 | fn airStructFieldPtrIndex(self: *DeclGen, inst: Air.Inst.Index, field_index: u32) !?IdRef { |
| 4094 | if (self.liveness.isUnused(inst)) return null; | | |
| 4095 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4079 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4096 | const struct_ptr = try self.resolve(ty_op.operand); | 4080 | const struct_ptr = try self.resolve(ty_op.operand); |
| 4097 | const struct_ptr_ty = self.typeOf(ty_op.operand); | 4081 | const struct_ptr_ty = self.typeOf(ty_op.operand); |
| ... | @@ -4145,7 +4129,6 @@ const DeclGen = struct { | ... | @@ -4145,7 +4129,6 @@ const DeclGen = struct { |
| 4145 | } | 4129 | } |
| 4146 | | 4130 | |
| 4147 | fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4131 | fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4148 | if (self.liveness.isUnused(inst)) return null; | | |
| 4149 | const mod = self.module; | 4132 | const mod = self.module; |
| 4150 | const ptr_ty = self.typeOfIndex(inst); | 4133 | const ptr_ty = self.typeOfIndex(inst); |
| 4151 | assert(ptr_ty.ptrAddressSpace(mod) == .generic); | 4134 | assert(ptr_ty.ptrAddressSpace(mod) == .generic); |
| ... | @@ -4729,9 +4712,7 @@ const DeclGen = struct { | ... | @@ -4729,9 +4712,7 @@ const DeclGen = struct { |
| 4729 | | 4712 | |
| 4730 | try self.beginSpvBlock(ok_block); | 4713 | try self.beginSpvBlock(ok_block); |
| 4731 | } | 4714 | } |
| 4732 | if (self.liveness.isUnused(inst)) { | 4715 | |
| 4733 | return null; | | |
| 4734 | } | | |
| 4735 | if (!eu_layout.payload_has_bits) { | 4716 | if (!eu_layout.payload_has_bits) { |
| 4736 | return null; | 4717 | return null; |
| 4737 | } | 4718 | } |
| ... | @@ -4741,8 +4722,6 @@ const DeclGen = struct { | ... | @@ -4741,8 +4722,6 @@ const DeclGen = struct { |
| 4741 | } | 4722 | } |
| 4742 | | 4723 | |
| 4743 | fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4724 | fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4744 | if (self.liveness.isUnused(inst)) return null; | | |
| 4745 | | | |
| 4746 | const mod = self.module; | 4725 | const mod = self.module; |
| 4747 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4726 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4748 | const operand_id = try self.resolve(ty_op.operand); | 4727 | const operand_id = try self.resolve(ty_op.operand); |
| ... | @@ -4766,8 +4745,6 @@ const DeclGen = struct { | ... | @@ -4766,8 +4745,6 @@ const DeclGen = struct { |
| 4766 | } | 4745 | } |
| 4767 | | 4746 | |
| 4768 | fn airErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4747 | fn airErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4769 | if (self.liveness.isUnused(inst)) return null; | | |
| 4770 | | | |
| 4771 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4748 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4772 | const operand_id = try self.resolve(ty_op.operand); | 4749 | const operand_id = try self.resolve(ty_op.operand); |
| 4773 | const payload_ty = self.typeOfIndex(inst); | 4750 | const payload_ty = self.typeOfIndex(inst); |
| ... | @@ -4781,8 +4758,6 @@ const DeclGen = struct { | ... | @@ -4781,8 +4758,6 @@ const DeclGen = struct { |
| 4781 | } | 4758 | } |
| 4782 | | 4759 | |
| 4783 | fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4760 | fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4784 | if (self.liveness.isUnused(inst)) return null; | | |
| 4785 | | | |
| 4786 | const mod = self.module; | 4761 | const mod = self.module; |
| 4787 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4762 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4788 | const err_union_ty = self.typeOfIndex(inst); | 4763 | const err_union_ty = self.typeOfIndex(inst); |
| ... | @@ -4804,8 +4779,6 @@ const DeclGen = struct { | ... | @@ -4804,8 +4779,6 @@ const DeclGen = struct { |
| 4804 | } | 4779 | } |
| 4805 | | 4780 | |
| 4806 | fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4781 | fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4807 | if (self.liveness.isUnused(inst)) return null; | | |
| 4808 | | | |
| 4809 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4782 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4810 | const err_union_ty = self.typeOfIndex(inst); | 4783 | const err_union_ty = self.typeOfIndex(inst); |
| 4811 | const operand_id = try self.resolve(ty_op.operand); | 4784 | const operand_id = try self.resolve(ty_op.operand); |
| ... | @@ -4825,8 +4798,6 @@ const DeclGen = struct { | ... | @@ -4825,8 +4798,6 @@ const DeclGen = struct { |
| 4825 | } | 4798 | } |
| 4826 | | 4799 | |
| 4827 | fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef { | 4800 | fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef { |
| 4828 | if (self.liveness.isUnused(inst)) return null; | | |
| 4829 | | | |
| 4830 | const mod = self.module; | 4801 | const mod = self.module; |
| 4831 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4802 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4832 | const operand_id = try self.resolve(un_op); | 4803 | const operand_id = try self.resolve(un_op); |
| ... | @@ -4899,8 +4870,6 @@ const DeclGen = struct { | ... | @@ -4899,8 +4870,6 @@ const DeclGen = struct { |
| 4899 | } | 4870 | } |
| 4900 | | 4871 | |
| 4901 | fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef { | 4872 | fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef { |
| 4902 | if (self.liveness.isUnused(inst)) return null; | | |
| 4903 | | | |
| 4904 | const mod = self.module; | 4873 | const mod = self.module; |
| 4905 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 4874 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4906 | const operand_id = try self.resolve(un_op); | 4875 | const operand_id = try self.resolve(un_op); |
| ... | @@ -4935,8 +4904,6 @@ const DeclGen = struct { | ... | @@ -4935,8 +4904,6 @@ const DeclGen = struct { |
| 4935 | } | 4904 | } |
| 4936 | | 4905 | |
| 4937 | fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4906 | fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4938 | if (self.liveness.isUnused(inst)) return null; | | |
| 4939 | | | |
| 4940 | const mod = self.module; | 4907 | const mod = self.module; |
| 4941 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4908 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4942 | const operand_id = try self.resolve(ty_op.operand); | 4909 | const operand_id = try self.resolve(ty_op.operand); |
| ... | @@ -4953,8 +4920,6 @@ const DeclGen = struct { | ... | @@ -4953,8 +4920,6 @@ const DeclGen = struct { |
| 4953 | } | 4920 | } |
| 4954 | | 4921 | |
| 4955 | fn airUnwrapOptionalPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4922 | fn airUnwrapOptionalPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4956 | if (self.liveness.isUnused(inst)) return null; | | |
| 4957 | | | |
| 4958 | const mod = self.module; | 4923 | const mod = self.module; |
| 4959 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4924 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4960 | const operand_id = try self.resolve(ty_op.operand); | 4925 | const operand_id = try self.resolve(ty_op.operand); |
| ... | @@ -4979,8 +4944,6 @@ const DeclGen = struct { | ... | @@ -4979,8 +4944,6 @@ const DeclGen = struct { |
| 4979 | } | 4944 | } |
| 4980 | | 4945 | |
| 4981 | fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4946 | fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 4982 | if (self.liveness.isUnused(inst)) return null; | | |
| 4983 | | | |
| 4984 | const mod = self.module; | 4947 | const mod = self.module; |
| 4985 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4948 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4986 | const payload_ty = self.typeOf(ty_op.operand); | 4949 | const payload_ty = self.typeOf(ty_op.operand); |