//===-- SPIRVMemoryOps.td - MLIR SPIR-V Memory 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 memory ops for the SPIR-V dialect. It corresponds
// to "3.32.8. Memory Instructions" of the SPIR-V spec.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_DIALECT_SPIRV_IR_MEMORY_OPS
#define MLIR_DIALECT_SPIRV_IR_MEMORY_OPS

include "mlir/Dialect/SPIRV/IR/SPIRVBase.td"

// -----

def SPIRV_AccessChainOp : SPIRV_Op<"AccessChain", [Pure]> {
  let summary = "Create a pointer into a composite object.";

  let description = [{
    Result Type must be an OpTypePointer. Its Type operand must be the type
    reached by walking the Base’s type hierarchy down to the last provided
    index in Indexes, and its Storage Class operand must be the same as the
    Storage Class of Base.

    Base must be a pointer, pointing to the base of a composite object.

    Indexes walk the type hierarchy to the desired depth, potentially down
    to scalar granularity. The first index in Indexes will select the top-
    level member/element/component/element of the base composite. All
    composite constituents use zero-based numbering, as described by their
    OpType… instruction. The second index will apply similarly to that
    result, and so on. Once any non-composite type is reached, there must be
    no remaining (unused) indexes.

     Each index in Indexes

    - must be a scalar integer type,

    - is treated as a signed count, and

    - must be an OpConstant when indexing into a structure.

    <!-- End of AutoGen section -->
    ```
    access-chain-op ::= ssa-id `=` `spirv.AccessChain` ssa-use
                        `[` ssa-use (',' ssa-use)* `]`
                        `:` pointer-type
    ```

    #### Example:

    ```mlir
    %0 = "spirv.Constant"() { value = 1: i32} : () -> i32
    %1 = spirv.Variable : !spirv.ptr<!spirv.struct<f32, !spirv.array<4xf32>>, Function>
    %2 = spirv.AccessChain %1[%0] : !spirv.ptr<!spirv.struct<f32, !spirv.array<4xf32>>, Function>
    %3 = spirv.Load "Function" %2 ["Volatile"] : !spirv.array<4xf32>
    ```
  }];

  let arguments = (ins
    SPIRV_AnyPtr:$base_ptr,
    Variadic<SPIRV_Integer>:$indices
  );

  let results = (outs
    SPIRV_AnyPtr:$component_ptr
  );

  let builders = [OpBuilder<(ins "Value":$basePtr, "ValueRange":$indices)>];

  let hasCanonicalizer = 1;
}

// -----

def SPIRV_CopyMemoryOp : SPIRV_Op<"CopyMemory", []> {
  let summary = [{
    Copy from the memory pointed to by Source to the memory pointed to by
    Target. Both operands must be non-void pointers and having the same <id>
    Type operand in their OpTypePointer type declaration.  Matching Storage
    Class is not required.  The amount of memory copied is the size of the
    type pointed to. The copied type must have a fixed size; i.e., it must
    not be, nor include, any OpTypeRuntimeArray types.
  }];

  let description = [{
    If present, any Memory Operands must begin with a memory operand
    literal. If not present, it is the same as specifying the memory operand
    None. Before version 1.4, at most one memory operands mask can be
    provided. Starting with version 1.4 two masks can be provided, as
    described in Memory Operands. If no masks or only one mask is present,
    it applies to both Source and Target. If two masks are present, the
    first applies to Target and cannot include MakePointerVisible, and the
    second applies to Source and cannot include MakePointerAvailable.

    <!-- End of AutoGen section -->

    ```
    copy-memory-op ::= `spirv.CopyMemory ` storage-class ssa-use
                       storage-class ssa-use
                       (`[` memory-access `]` (`, [` memory-access `]`)?)?
                       ` : ` spirv-element-type
    ```

    #### Example:

    ```mlir
    %0 = spirv.Variable : !spirv.ptr<f32, Function>
    %1 = spirv.Variable : !spirv.ptr<f32, Function>
    spirv.CopyMemory "Function" %0, "Function" %1 : f32
    ```
  }];

  let arguments = (ins
    SPIRV_AnyPtr:$target,
    SPIRV_AnyPtr:$source,
    OptionalAttr<SPIRV_MemoryAccessAttr>:$memory_access,
    OptionalAttr<I32Attr>:$alignment,
    OptionalAttr<SPIRV_MemoryAccessAttr>:$source_memory_access,
    OptionalAttr<I32Attr>:$source_alignment
  );

  let results = (outs);

  let autogenSerialization = 0;
}

// -----

def SPIRV_InBoundsPtrAccessChainOp : SPIRV_Op<"InBoundsPtrAccessChain", [Pure]> {
  let summary = [{
    Has the same semantics as OpPtrAccessChain, with the addition that the
    resulting pointer is known to point within the base object.
  }];

  let description = [{


    <!-- End of AutoGen section -->

    ```
    access-chain-op ::= ssa-id `=` `spirv.InBoundsPtrAccessChain` ssa-use
                        `[` ssa-use (',' ssa-use)* `]`
                        `:` pointer-type
    ```

    #### Example:

    ```mlir
    func @inbounds_ptr_access_chain(%arg0: !spirv.ptr<f32, CrossWorkgroup>, %arg1 : i64) -> () {
      %0 = spirv.InBoundsPtrAccessChain %arg0[%arg1] : !spirv.ptr<f32, CrossWorkgroup>, i64
      ...
    }
    ```
  }];

  let availability = [
    MinVersion<SPIRV_V_1_0>,
    MaxVersion<SPIRV_V_1_6>,
    Extension<[]>,
    Capability<[SPIRV_C_Addresses]>
  ];

  let arguments = (ins
    SPIRV_AnyPtr:$base_ptr,
    SPIRV_Integer:$element,
    Variadic<SPIRV_Integer>:$indices
  );

  let results = (outs
    SPIRV_AnyPtr:$result
  );

  let builders = [OpBuilder<(ins "Value":$basePtr, "Value":$element, "ValueRange":$indices)>];
}

// -----

def SPIRV_LoadOp : SPIRV_Op<"Load", []> {
  let summary = "Load through a pointer.";

  let description = [{
    Result Type is the type of the loaded object. It must be a type with
    fixed size; i.e., it cannot be, nor include, any OpTypeRuntimeArray
    types.

    Pointer is the pointer to load through.  Its type must be an
    OpTypePointer whose Type operand is the same as Result Type.

    If present, any Memory Operands must begin with a memory operand
    literal. If not present, it is the same as specifying the memory operand
    None.

    <!-- End of AutoGen section -->

    ```
    memory-access ::= `"None"` | `"Volatile"` | `"Aligned", ` integer-literal
                    | `"NonTemporal"`

    load-op ::= ssa-id ` = spirv.Load ` storage-class ssa-use
                (`[` memory-access `]`)? ` : ` spirv-element-type
    ```

    #### Example:

    ```mlir
    %0 = spirv.Variable : !spirv.ptr<f32, Function>
    %1 = spirv.Load "Function" %0 : f32
    %2 = spirv.Load "Function" %0 ["Volatile"] : f32
    %3 = spirv.Load "Function" %0 ["Aligned", 4] : f32
    ```
  }];

  let arguments = (ins
    SPIRV_AnyPtr:$ptr,
    OptionalAttr<SPIRV_MemoryAccessAttr>:$memory_access,
    OptionalAttr<I32Attr>:$alignment
  );

  let results = (outs
    SPIRV_Type:$value
  );

  let builders = [
    OpBuilder<(ins "Value":$basePtr,
      CArg<"MemoryAccessAttr", "{}">:$memory_access,
      CArg<"IntegerAttr", "{}">:$alignment)>
  ];
}

// -----

def SPIRV_PtrAccessChainOp : SPIRV_Op<"PtrAccessChain", [Pure]> {
  let summary = [{
    Has the same semantics as OpAccessChain, with the addition of the
    Element operand.
  }];

  let description = [{
    Element is used to do an initial dereference of Base: Base is treated as
    the address of an element in an array, and a new element address is
    computed from Base and Element to become the OpAccessChain Base to
    dereference as per OpAccessChain. This computed Base has the same type
    as the originating Base.

    To compute the new element address, Element is treated as a signed count
    of elements E, relative to the original Base element B, and the address
    of element B + E is computed using enough precision to avoid overflow
    and underflow. For objects in the Uniform, StorageBuffer, or
    PushConstant storage classes, the element's address or location is
    calculated using a stride, which will be the Base-type's Array Stride if
    the Base type is decorated with ArrayStride. For all other objects, the
    implementation calculates the element's address or location.

    With one exception, undefined behavior results when B + E is not an
    element in the same array (same innermost array, if array types are
    nested) as B. The exception being when B + E = L, where L is the length
    of the array: the address computation for element L is done with the
    same stride as any other B + E computation that stays within the array.

    Note: If Base is typed to be a pointer to an array and the desired
    operation is to select an element of that array, OpAccessChain should be
    directly used, as its first Index selects the array element.

    <!-- End of AutoGen section -->

    ```
    [access-chain-op ::= ssa-id `=` `spirv.PtrAccessChain` ssa-use
                        `[` ssa-use (',' ssa-use)* `]`
                        `:` pointer-type
    ```

    #### Example:

    ```mlir
    func @ptr_access_chain(%arg0: !spirv.ptr<f32, CrossWorkgroup>, %arg1 : i64) -> () {
      %0 = spirv.PtrAccessChain %arg0[%arg1] : !spirv.ptr<f32, CrossWorkgroup>, i64
      ...
    }
    ```
  }];

  let availability = [
    MinVersion<SPIRV_V_1_0>,
    MaxVersion<SPIRV_V_1_6>,
    Extension<[]>,
    Capability<[
      SPIRV_C_Addresses, SPIRV_C_PhysicalStorageBufferAddresses,
      SPIRV_C_VariablePointers, SPIRV_C_VariablePointersStorageBuffer]>
  ];

  let arguments = (ins
    SPIRV_AnyPtr:$base_ptr,
    SPIRV_Integer:$element,
    Variadic<SPIRV_Integer>:$indices
  );

  let results = (outs
    SPIRV_AnyPtr:$result
  );

  let builders = [OpBuilder<(ins "Value":$basePtr, "Value":$element, "ValueRange":$indices)>];
}

// -----

def SPIRV_StoreOp : SPIRV_Op<"Store", []> {
  let summary = "Store through a pointer.";

  let description = [{
    Pointer is the pointer to store through.  Its type must be an
    OpTypePointer whose Type operand is the same as the type of Object.

    Object is the object to store.

    If present, any Memory Operands must begin with a memory operand
    literal. If not present, it is the same as specifying the memory operand
    None.

    <!-- End of AutoGen section -->

    ```
    store-op ::= `spirv.Store ` storage-class ssa-use `, ` ssa-use `, `
                  (`[` memory-access `]`)? `:` spirv-element-type
    ```

    #### Example:

    ```mlir
    %0 = spirv.Variable : !spirv.ptr<f32, Function>
    %1 = spirv.FMul ... : f32
    spirv.Store "Function" %0, %1 : f32
    spirv.Store "Function" %0, %1 ["Volatile"] : f32
    spirv.Store "Function" %0, %1 ["Aligned", 4] : f32
    ```
  }];

  let arguments = (ins
    SPIRV_AnyPtr:$ptr,
    SPIRV_Type:$value,
    OptionalAttr<SPIRV_MemoryAccessAttr>:$memory_access,
    OptionalAttr<I32Attr>:$alignment
  );

  let results = (outs);

  let builders = [
    OpBuilder<(ins "Value":$ptr, "Value":$value,
      CArg<"ArrayRef<NamedAttribute>", "{}">:$namedAttrs),
    [{
      $_state.addOperands(ptr);
      $_state.addOperands(value);
      $_state.addAttributes(namedAttrs);
    }]>
  ];
}

// -----

def SPIRV_VariableOp : SPIRV_Op<"Variable", []> {
  let summary = [{
    Allocate an object in memory, resulting in a pointer to it, which can be
    used with OpLoad and OpStore.
  }];

  let description = [{
    Result Type must be an OpTypePointer. Its Type operand is the type of
    object in memory.

    Storage Class is the Storage Class of the memory holding the object.
    Since the op is used to model function-level variables, the storage class
    must be the `Function` Storage Class.

    Initializer is optional. If Initializer is present, it will be the
    initial value of the variable's memory content. Initializer must be an
    <id> from a constant instruction or a global (module scope) OpVariable
    instruction. Initializer must have the same type as the type pointed to
    by Result Type.

    From `SPV_KHR_physical_storage_buffer`:
    If an OpVariable's pointee type is a pointer (or array of pointers) in
    PhysicalStorageBuffer storage class, then the variable must be decorated
    with exactly one of AliasedPointer or RestrictPointer.

    <!-- End of AutoGen section -->

    ```
    variable-op ::= ssa-id `=` `spirv.Variable` (`init(` ssa-use `)`)?
                    attribute-dict? `:` spirv-pointer-type
    ```

    where `init` specifies initializer.

    #### Example:

    ```mlir
    %0 = spirv.Constant ...

    %1 = spirv.Variable : !spirv.ptr<f32, Function>
    %2 = spirv.Variable init(%0): !spirv.ptr<f32, Function>

    %3 = spirv.Variable {aliased_pointer} :
      !spirv.ptr<!spirv.ptr<f32, PhysicalStorageBuffer>, Function>
    ```
  }];

  let arguments = (ins
    SPIRV_StorageClassAttr:$storage_class,
    Optional<AnyType>:$initializer
  );

  let results = (outs
    SPIRV_AnyPtr:$pointer
  );

  let extraClassDeclaration = [{
    ::mlir::spirv::PointerType getPointerType() {
      return ::llvm::cast<::mlir::spirv::PointerType>(getType());
    }
    ::mlir::Type getPointeeType() {
      return getPointerType().getPointeeType();
    }
  }];
}

#endif // MLIR_DIALECT_SPIRV_IR_MEMORY_OPS
