• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//===-- SPIRVCompositeOps.td - MLIR SPIR-V Composite Ops ---*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains composite ops for SPIR-V dialect. It corresponds
10// to "3.32.12. Composite Instructions" of the SPIR-V spec.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef SPIRV_COMPOSITE_OPS
15#define SPIRV_COMPOSITE_OPS
16
17include "mlir/Dialect/SPIRV/SPIRVBase.td"
18include "mlir/Interfaces/SideEffectInterfaces.td"
19
20// -----
21
22def SPV_CompositeConstructOp : SPV_Op<"CompositeConstruct", [NoSideEffect]> {
23  let summary = [{
24    Construct a new composite object from a set of constituent objects that
25    will fully form it.
26  }];
27
28  let description = [{
29    Result Type must be a composite type, whose top-level
30    members/elements/components/columns have the same type as the types of
31    the operands, with one exception. The exception is that for constructing
32    a vector, the operands may also be vectors with the same component type
33    as the Result Type component type. When constructing a vector, the total
34    number of components in all the operands must equal the number of
35    components in Result Type.
36
37    Constituents will become members of a structure, or elements of an
38    array, or components of a vector, or columns of a matrix. There must be
39    exactly one Constituent for each top-level
40    member/element/component/column of the result, with one exception. The
41    exception is that for constructing a vector, a contiguous subset of the
42    scalars consumed can be represented by a vector operand instead. The
43    Constituents must appear in the order needed by the definition of the
44    type of the result. When constructing a vector, there must be at least
45    two Constituent operands.
46
47    <!-- End of AutoGen section -->
48
49    ```
50    composite-construct-op ::= ssa-id `=` `spv.CompositeConstruct`
51                               (ssa-use (`,` ssa-use)* )? `:` composite-type
52    ```
53
54    #### Example:
55
56    ```mlir
57    %0 = spv.CompositeConstruct %1, %2, %3 : vector<3xf32>
58    ```
59  }];
60
61  let arguments = (ins
62    Variadic<SPV_Type>:$constituents
63  );
64
65  let results = (outs
66    SPV_Composite:$result
67  );
68}
69
70// -----
71
72def SPV_CompositeExtractOp : SPV_Op<"CompositeExtract", [NoSideEffect]> {
73  let summary = "Extract a part of a composite object.";
74
75  let description = [{
76    Result Type must be the type of object selected by the last provided
77    index.  The instruction result is the extracted object.
78
79    Composite is the composite to extract from.
80
81    Indexes walk the type hierarchy, potentially down to component
82    granularity, to select the part to extract. All indexes must be in
83    bounds.  All composite constituents use zero-based numbering, as
84    described by their OpType… instruction.
85
86    <!-- End of AutoGen section -->
87
88    ```
89    composite-extract-op ::= ssa-id `=` `spv.CompositeExtract` ssa-use
90                             `[` integer-literal (',' integer-literal)* `]`
91                             `:` composite-type
92    ```
93
94    #### Example:
95
96    ```mlir
97    %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function>
98    %1 = spv.Load "Function" %0 ["Volatile"] : !spv.array<4x!spv.array<4xf32>>
99    %2 = spv.CompositeExtract %1[1 : i32] : !spv.array<4x!spv.array<4xf32>>
100    ```
101
102  }];
103
104  let arguments = (ins
105    SPV_Composite:$composite,
106    I32ArrayAttr:$indices
107  );
108
109  let results = (outs
110    SPV_Type:$component
111  );
112
113  let builders = [
114    OpBuilderDAG<(ins "Value":$composite, "ArrayRef<int32_t>":$indices)>
115  ];
116
117  let hasFolder = 1;
118}
119
120// -----
121
122def SPV_CompositeInsertOp : SPV_Op<"CompositeInsert", [NoSideEffect]> {
123  let summary = [{
124    Make a copy of a composite object, while modifying one part of it.
125  }];
126
127  let description = [{
128    Result Type must be the same type as Composite.
129
130    Object is the object to use as the modified part.
131
132    Composite is the composite to copy all but the modified part from.
133
134    Indexes walk the type hierarchy of Composite to the desired depth,
135    potentially down to component granularity, to select the part to modify.
136    All indexes must be in bounds. All composite constituents use zero-based
137    numbering, as described by their OpType… instruction. The type of the
138    part selected to modify must match the type of Object.
139
140    <!-- End of AutoGen section -->
141
142    ```
143    composite-insert-op ::= ssa-id `=` `spv.CompositeInsert` ssa-use, ssa-use
144                            `[` integer-literal (',' integer-literal)* `]`
145                            `:` object-type `into` composite-type
146    ```
147
148    #### Example:
149
150    ```mlir
151    %0 = spv.CompositeInsert %object, %composite[1 : i32] : f32 into !spv.array<4xf32>
152    ```
153  }];
154
155  let arguments = (ins
156    SPV_Type:$object,
157    SPV_Composite:$composite,
158    I32ArrayAttr:$indices
159  );
160
161  let results = (outs
162    SPV_Composite:$result
163  );
164
165  let builders = [
166    OpBuilderDAG<(ins "Value":$object, "Value":$composite,
167      "ArrayRef<int32_t>":$indices)>
168  ];
169}
170
171// -----
172
173def SPV_VectorExtractDynamicOp : SPV_Op<"VectorExtractDynamic",
174            [NoSideEffect,
175            TypesMatchWith<"type of 'result' matches element type of 'vector'",
176                     "vector", "result",
177                     "$_self.cast<mlir::VectorType>().getElementType()">]> {
178  let summary = [{
179    Extract a single, dynamically selected, component of a vector.
180  }];
181
182  let description = [{
183    Result Type must be a scalar type.
184
185    Vector must have a type OpTypeVector whose Component Type is Result
186    Type.
187
188    Index must be a scalar integer. It is interpreted as a 0-based index of
189    which component of Vector to extract.
190
191    Behavior is undefined if Index's value is less than zero or greater than
192    or equal to the number of components in Vector.
193
194    <!-- End of AutoGen section -->
195
196    ```
197	scalar-type ::= integer-type | float-type | boolean-type
198    vector-extract-dynamic-op ::= `spv.VectorExtractDynamic ` ssa-use `[` ssa-use `]`
199                                    `:` `vector<` integer-literal `x` scalar-type `>` `,`
200                                    integer-type
201    ```mlir
202
203    #### Example:
204
205    ```
206    %2 = spv.VectorExtractDynamic %0[%1] : vector<8xf32>, i32
207    ```
208  }];
209
210  let arguments = (ins
211    SPV_Vector:$vector,
212    SPV_Integer:$index
213  );
214
215  let results = (outs
216    SPV_Scalar:$result
217  );
218
219  let verifier = [{ return success(); }];
220
221  let assemblyFormat = [{
222    $vector `[` $index `]` attr-dict `:` type($vector) `,` type($index)
223  }];
224
225}
226
227// -----
228
229def SPV_VectorInsertDynamicOp : SPV_Op<"VectorInsertDynamic",
230        [NoSideEffect,
231        TypesMatchWith<"type of 'component' matches element type of 'vector'",
232                "vector", "component",
233                "$_self.cast<mlir::VectorType>().getElementType()">,
234                AllTypesMatch<["vector", "result"]>]> {
235  let summary = [{
236    Make a copy of a vector, with a single, variably selected, component
237    modified.
238  }];
239
240  let description = [{
241    Result Type must be an OpTypeVector.
242
243    Vector must have the same type as Result Type and is the vector that the
244    non-written components are copied from.
245
246    Component is the value supplied for the component selected by Index. It
247    must have the same type as the type of components in Result Type.
248
249    Index must be a scalar integer. It is interpreted as a 0-based index of
250    which component to modify.
251
252    Behavior is undefined if Index's value is less than zero or greater than
253    or equal to the number of components in Vector.
254
255    <!-- End of AutoGen section -->
256
257    ```
258    scalar-type ::= integer-type | float-type | boolean-type
259    vector-insert-dynamic-op ::= `spv.VectorInsertDynamic ` ssa-use `,`
260                                  ssa-use `[` ssa-use `]`
261                                  `:` `vector<` integer-literal `x` scalar-type `>` `,`
262                                  integer-type
263    ```mlir
264
265    #### Example:
266
267    ```
268    %scalar = ... : f32
269    %2 = spv.VectorInsertDynamic %scalar %0[%1] : f32, vector<8xf32>, i32
270    ```
271  }];
272
273  let arguments = (ins
274    SPV_Vector:$vector,
275    SPV_Scalar:$component,
276    SPV_Integer:$index
277  );
278
279  let results = (outs
280    SPV_Vector:$result
281  );
282
283  let verifier = [{ return success(); }];
284
285  let assemblyFormat = [{
286    $component `,` $vector `[` $index `]` attr-dict `:` type($vector) `,` type($index)
287  }];
288}
289
290// -----
291
292#endif // SPIRV_COMPOSITE_OPS
293