| //===-- SPIRVBarrierOps.td - MLIR SPIR-V Barrier Ops -------*- tablegen -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains barrier ops for the SPIR-V dialect. It corresponds |
| // to "3.32.20. Barrrier Instructions" of the SPIR-V spec. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef MLIR_DIALECT_SPIRV_IR_BARRIER_OPS |
| #define MLIR_DIALECT_SPIRV_IR_BARRIER_OPS |
| |
| include "mlir/Dialect/SPIRV/IR/SPIRVBase.td" |
| |
| // ----- |
| |
| def SPV_ControlBarrierOp : SPV_Op<"ControlBarrier", []> { |
| let summary = [{ |
| Wait for other invocations of this module to reach the current point of |
| execution. |
| }]; |
| |
| let description = [{ |
| All invocations of this module within Execution scope must reach this |
| point of execution before any invocation will proceed beyond it. |
| |
| When Execution is Workgroup or larger, behavior is undefined if this |
| instruction is used in control flow that is non-uniform within |
| Execution. When Execution is Subgroup or Invocation, the behavior of |
| this instruction in non-uniform control flow is defined by the client |
| API. |
| |
| If Semantics is not None, this instruction also serves as an |
| OpMemoryBarrier instruction, and must also perform and adhere to the |
| description and semantics of an OpMemoryBarrier instruction with the |
| same Memory and Semantics operands. This allows atomically specifying |
| both a control barrier and a memory barrier (that is, without needing |
| two instructions). If Semantics is None, Memory is ignored. |
| |
| Before version 1.3, it is only valid to use this instruction with |
| TessellationControl, GLCompute, or Kernel execution models. There is no |
| such restriction starting with version 1.3. |
| |
| When used with the TessellationControl execution model, it also |
| implicitly synchronizes the Output Storage Class: Writes to Output |
| variables performed by any invocation executed prior to a |
| OpControlBarrier will be visible to any other invocation after return |
| from that OpControlBarrier. |
| |
| <!-- End of AutoGen section --> |
| |
| ``` |
| scope ::= `"CrossDevice"` | `"Device"` | `"Workgroup"` | ... |
| |
| memory-semantics ::= `"None"` | `"Acquire"` | "Release"` | ... |
| |
| control-barrier-op ::= `spv.ControlBarrier` scope, scope, memory-semantics |
| ``` |
| |
| #### Example: |
| |
| ```mlir |
| spv.ControlBarrier "Workgroup", "Device", "Acquire|UniformMemory" |
| |
| ``` |
| }]; |
| |
| let arguments = (ins |
| SPV_ScopeAttr:$execution_scope, |
| SPV_ScopeAttr:$memory_scope, |
| SPV_MemorySemanticsAttr:$memory_semantics |
| ); |
| |
| let results = (outs); |
| |
| let verifier = [{ return verifyMemorySemantics(getOperation(), memory_semantics()); }]; |
| |
| let autogenSerialization = 0; |
| |
| let assemblyFormat = [{ |
| $execution_scope `,` $memory_scope `,` $memory_semantics attr-dict |
| }]; |
| } |
| |
| // ----- |
| |
| def SPV_MemoryBarrierOp : SPV_Op<"MemoryBarrier", []> { |
| let summary = "Control the order that memory accesses are observed."; |
| |
| let description = [{ |
| Ensures that memory accesses issued before this instruction will be |
| observed before memory accesses issued after this instruction. This |
| control is ensured only for memory accesses issued by this invocation |
| and observed by another invocation executing within Memory scope. If the |
| Vulkan memory model is declared, this ordering only applies to memory |
| accesses that use the NonPrivatePointer memory operand or |
| NonPrivateTexel image operand. |
| |
| Semantics declares what kind of memory is being controlled and what kind |
| of control to apply. |
| |
| To execute both a memory barrier and a control barrier, see |
| OpControlBarrier. |
| |
| <!-- End of AutoGen section --> |
| |
| ``` |
| scope ::= `"CrossDevice"` | `"Device"` | `"Workgroup"` | ... |
| |
| memory-semantics ::= `"None"` | `"Acquire"` | `"Release"` | ... |
| |
| memory-barrier-op ::= `spv.MemoryBarrier` scope, memory-semantics |
| ``` |
| |
| #### Example: |
| |
| ```mlir |
| spv.MemoryBarrier "Device", "Acquire|UniformMemory" |
| |
| ``` |
| }]; |
| |
| let arguments = (ins |
| SPV_ScopeAttr:$memory_scope, |
| SPV_MemorySemanticsAttr:$memory_semantics |
| ); |
| |
| let results = (outs); |
| |
| let verifier = [{ return verifyMemorySemantics(getOperation(), memory_semantics()); }]; |
| |
| let autogenSerialization = 0; |
| |
| let assemblyFormat = "$memory_scope `,` $memory_semantics attr-dict"; |
| } |
| |
| #endif // MLIR_DIALECT_SPIRV_IR_BARRIER_OPS |