aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-03-18 15:59:56 +0100
committerVeikka Tuominen <git@vexu.eu>2023-03-30 12:20:24 +0300
commit3357c59cebacb6b60da865376b20d2b307d12ec1 (patch)
tree51edbb19a1f063888bac386c6a51ba250e361b11 /src/Sema.zig
parent83051b0cbf31b76e824d3911a7f4a0be3c0cf94d (diff)
downloadzig-3357c59cebacb6b60da865376b20d2b307d12ec1.tar.gz
zig-3357c59cebacb6b60da865376b20d2b307d12ec1.zip
new builtins: @workItemId, @workGroupId, @workGroupSize
* @workItemId returns the index of the work item in a work group for a dimension. * @workGroupId returns the index of the work group in the kernel dispatch for a dimension. * @workGroupSize returns the size of the work group for a dimension. These builtins are mainly useful for GPU backends. They are currently only implemented for the AMDGCN LLVM backend.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 1f375853cb..da93a2906a 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -1164,6 +1164,9 @@ fn analyzeBodyInner(
.c_va_start => try sema.zirCVaStart( block, extended),
.const_cast, => try sema.zirConstCast( block, extended),
.volatile_cast, => try sema.zirVolatileCast( block, extended),
+ .work_item_id => try sema.zirWorkItem( block, extended, extended.opcode),
+ .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode),
+ .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode),
// zig fmt: on
.fence => {
@@ -22437,6 +22440,42 @@ fn zirBuiltinExtern(
return sema.addConstant(ty, ref);
}
+fn zirWorkItem(
+ sema: *Sema,
+ block: *Block,
+ extended: Zir.Inst.Extended.InstData,
+ zir_tag: Zir.Inst.Extended,
+) CompileError!Air.Inst.Ref {
+ const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+ const dimension_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const builtin_src = LazySrcLoc.nodeOffset(extra.node);
+ const target = sema.mod.getTarget();
+
+ switch (target.cpu.arch) {
+ // TODO: Allow for other GPU targets.
+ .amdgcn => {},
+ else => {
+ return sema.fail(block, builtin_src, "builtin only available on GPU targets; targeted architecture is {s}", .{@tagName(target.cpu.arch)});
+ },
+ }
+
+ const dimension = @intCast(u32, try sema.resolveInt(block, dimension_src, extra.operand, Type.u32, "dimension must be comptime-known"));
+ try sema.requireRuntimeBlock(block, builtin_src, null);
+
+ return block.addInst(.{
+ .tag = switch (zir_tag) {
+ .work_item_id => .work_item_id,
+ .work_group_size => .work_group_size,
+ .work_group_id => .work_group_id,
+ else => unreachable,
+ },
+ .data = .{ .pl_op = .{
+ .operand = .none,
+ .payload = dimension,
+ } },
+ });
+}
+
fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void {
if (block.is_comptime) {
const msg = msg: {