| ... | @@ -10286,7 +10286,7 @@ pub const FuncGen = struct { | ... | @@ -10286,7 +10286,7 @@ pub const FuncGen = struct { |
| 10286 | return self.wip.cast(.addrspacecast, operand, try o.lowerType(inst_ty), ""); | 10286 | return self.wip.cast(.addrspacecast, operand, try o.lowerType(inst_ty), ""); |
| 10287 | } | 10287 | } |
| 10288 | | 10288 | |
| 10289 | fn amdgcnWorkIntrinsic( | 10289 | fn workIntrinsic( |
| 10290 | self: *FuncGen, | 10290 | self: *FuncGen, |
| 10291 | dimension: u32, | 10291 | dimension: u32, |
| 10292 | default: u32, | 10292 | default: u32, |
| ... | @@ -10303,44 +10303,60 @@ pub const FuncGen = struct { | ... | @@ -10303,44 +10303,60 @@ pub const FuncGen = struct { |
| 10303 | fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 10303 | fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10304 | const o = self.ng.object; | 10304 | const o = self.ng.object; |
| 10305 | const target = o.pt.zcu.getTarget(); | 10305 | const target = o.pt.zcu.getTarget(); |
| 10306 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures | | |
| 10307 | | 10306 | |
| 10308 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 10307 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 10309 | const dimension = pl_op.payload; | 10308 | const dimension = pl_op.payload; |
| 10310 | return self.amdgcnWorkIntrinsic(dimension, 0, "amdgcn.workitem.id"); | 10309 | |
| | 10310 | return switch (target.cpu.arch) { |
| | 10311 | .amdgcn => self.workIntrinsic(dimension, 0, "amdgcn.workitem.id"), |
| | 10312 | .nvptx, .nvptx64 => self.workIntrinsic(dimension, 0, "nvvm.read.ptx.sreg.tid"), |
| | 10313 | else => unreachable, |
| | 10314 | }; |
| 10311 | } | 10315 | } |
| 10312 | | 10316 | |
| 10313 | fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 10317 | fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10314 | const o = self.ng.object; | 10318 | const o = self.ng.object; |
| 10315 | const target = o.pt.zcu.getTarget(); | 10319 | const target = o.pt.zcu.getTarget(); |
| 10316 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures | | |
| 10317 | | 10320 | |
| 10318 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 10321 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 10319 | const dimension = pl_op.payload; | 10322 | const dimension = pl_op.payload; |
| 10320 | if (dimension >= 3) return .@"1"; | | |
| 10321 | | | |
| 10322 | // Fetch the dispatch pointer, which points to this structure: | | |
| 10323 | // https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/adae6c61e10d371f7cbc3d0e94ae2c070cab18a4/src/inc/hsa.h#L2913 | | |
| 10324 | const dispatch_ptr = | | |
| 10325 | try self.wip.callIntrinsic(.normal, .none, .@"amdgcn.dispatch.ptr", &.{}, &.{}, ""); | | |
| 10326 | | 10323 | |
| 10327 | // Load the work_group_* member from the struct as u16. | 10324 | switch (target.cpu.arch) { |
| 10328 | // Just treat the dispatch pointer as an array of u16 to keep things simple. | 10325 | .amdgcn => { |
| 10329 | const workgroup_size_ptr = try self.wip.gep(.inbounds, .i16, dispatch_ptr, &.{ | 10326 | if (dimension >= 3) return .@"1"; |
| 10330 | try o.builder.intValue(try o.lowerType(Type.usize), 2 + dimension), | 10327 | |
| 10331 | }, ""); | 10328 | // Fetch the dispatch pointer, which points to this structure: |
| 10332 | const workgroup_size_alignment = comptime Builder.Alignment.fromByteUnits(2); | 10329 | // https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/adae6c61e10d371f7cbc3d0e94ae2c070cab18a4/src/inc/hsa.h#L2913 |
| 10333 | return self.wip.load(.normal, .i16, workgroup_size_ptr, workgroup_size_alignment, ""); | 10330 | const dispatch_ptr = |
| | 10331 | try self.wip.callIntrinsic(.normal, .none, .@"amdgcn.dispatch.ptr", &.{}, &.{}, ""); |
| | 10332 | |
| | 10333 | // Load the work_group_* member from the struct as u16. |
| | 10334 | // Just treat the dispatch pointer as an array of u16 to keep things simple. |
| | 10335 | const workgroup_size_ptr = try self.wip.gep(.inbounds, .i16, dispatch_ptr, &.{ |
| | 10336 | try o.builder.intValue(try o.lowerType(Type.usize), 2 + dimension), |
| | 10337 | }, ""); |
| | 10338 | const workgroup_size_alignment = comptime Builder.Alignment.fromByteUnits(2); |
| | 10339 | return self.wip.load(.normal, .i16, workgroup_size_ptr, workgroup_size_alignment, ""); |
| | 10340 | }, |
| | 10341 | .nvptx, .nvptx64 => { |
| | 10342 | return self.workIntrinsic(dimension, 1, "nvvm.read.ptx.sreg.ntid"); |
| | 10343 | }, |
| | 10344 | else => unreachable, |
| | 10345 | } |
| 10334 | } | 10346 | } |
| 10335 | | 10347 | |
| 10336 | fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | 10348 | fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 10337 | const o = self.ng.object; | 10349 | const o = self.ng.object; |
| 10338 | const target = o.pt.zcu.getTarget(); | 10350 | const target = o.pt.zcu.getTarget(); |
| 10339 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures | | |
| 10340 | | 10351 | |
| 10341 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 10352 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 10342 | const dimension = pl_op.payload; | 10353 | const dimension = pl_op.payload; |
| 10343 | return self.amdgcnWorkIntrinsic(dimension, 0, "amdgcn.workgroup.id"); | 10354 | |
| | 10355 | return switch (target.cpu.arch) { |
| | 10356 | .amdgcn => self.workIntrinsic(dimension, 0, "amdgcn.workgroup.id"), |
| | 10357 | .nvptx, .nvptx64 => self.workIntrinsic(dimension, 0, "nvvm.read.ptx.sreg.ctaid"), |
| | 10358 | else => unreachable, |
| | 10359 | }; |
| 10344 | } | 10360 | } |
| 10345 | | 10361 | |
| 10346 | fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index { | 10362 | fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index { |