xref: /llvm-project/mlir/include/mlir/Dialect/OpenMP/OpenMPOpBase.td (revision 6568062ff1821f561c834f9f216fba0293e6f1c4)
1//===- OpenMPOpBase.td - OpenMP dialect shared definitions -*- 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 shared definitions for the OpenMP dialect.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef OPENMP_OP_BASE
14#define OPENMP_OP_BASE
15
16include "mlir/Dialect/OpenMP/OpenMPAttrDefs.td"
17include "mlir/Dialect/OpenMP/OpenMPDialect.td"
18include "mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td"
19include "mlir/Dialect/OpenMP/OpenMPTypeInterfaces.td"
20include "mlir/IR/OpBase.td"
21
22//===----------------------------------------------------------------------===//
23// OpenMP dialect type constraints.
24//===----------------------------------------------------------------------===//
25
26class OpenMP_Type<string name, string typeMnemonic> :
27      TypeDef<OpenMP_Dialect, name> {
28  let mnemonic = typeMnemonic;
29}
30
31// Type which can be constraint accepting standard integers and indices.
32def IntLikeType : AnyTypeOf<[AnyInteger, Index]>;
33
34def OpenMP_PointerLikeType : TypeAlias<OpenMP_PointerLikeTypeInterface,
35	"OpenMP-compatible variable type">;
36
37def OpenMP_MapBoundsType : OpenMP_Type<"MapBounds", "map_bounds_ty"> {
38  let summary = "Type for representing omp map clause bounds information";
39}
40
41//===----------------------------------------------------------------------===//
42// Base classes for OpenMP dialect operations.
43//===----------------------------------------------------------------------===//
44
45// Base class for representing OpenMP clauses.
46//
47// Clauses are meant to be used in a mixin-style pattern to help define OpenMP
48// operations in a scalable way, since often the same clause can be applied to
49// multiple different operations.
50//
51// To keep the representation of clauses consistent across different operations,
52// each clause must define a set of arguments (values and attributes) which will
53// become input arguments of each OpenMP operation that accepts that clause.
54//
55// It is also recommended that an assembly format and description are defined
56// for each clause wherever posible, to make sure they are always printed,
57// parsed and described in the same way.
58//
59// Optionally, operation traits and extra class declarations might be attached
60// to clauses, which will be forwarded to all operations that include them.
61//
62// An `OpenMP_Op` can inhibit the inheritance of `traits`, `arguments`,
63// `description` and `extraClassDeclaration` fields from any given
64// `OpenMP_Clause` by setting to 1 the corresponding "skip" template argument
65// bit. Additionally, the `skipAssemblyFormat` bit inhibits the inheritance of
66// fields used to populate `OpenMP_Op`'s `assemblyFormat` (i.e.
67// `reqAssemblyFormat` and `optAssemblyFormat`).
68class OpenMP_Clause<bit skipTraits, bit skipArguments, bit skipAssemblyFormat,
69                    bit skipDescription, bit skipExtraClassDeclaration> {
70  bit ignoreTraits = skipTraits;
71  list<Trait> traits = [];
72
73  bit ignoreArgs = skipArguments;
74  dag arguments;
75
76  bit ignoreAsmFormat = skipAssemblyFormat;
77  string reqAssemblyFormat = "";
78  string optAssemblyFormat = "";
79
80  bit ignoreDesc = skipDescription;
81  string description = "";
82
83  bit ignoreExtraDecl = skipExtraClassDeclaration;
84  string extraClassDeclaration = "";
85}
86
87// Base class for representing OpenMP operations.
88//
89// This is a subclass of the builtin `Op` for the OpenMP dialect. By default,
90// some of its fields are initialized according to the list of OpenMP clauses
91// passed as template argument:
92//   - `traits`: It is a union of the traits list passed as template argument
93//     and those inherited from the `traits` field of all clauses.
94//   - `arguments`: They are a concatenation of clause-inherited arguments. They
95//     are saved to a `clausesArgs` field to allow overriding the arguments
96//     field in the definition of the operation and still being able to include
97//     those inherited from clauses.
98//   - `assemblyFormat`: It is a concatenation of the `reqAssemblyFormat`
99//     followed by an `oilist()` containing the `optAssemblyFormat` of all
100//     clauses. The format string is completed with $region (if `singleRegion =
101//     true`) followed by `attr-dict`. This field remains uninitialized if no
102//     non-empty `{req,opt}AssemblyFormat` strings are inherited from clauses.
103//     The `clausesAssemblyFormat` field holds all the format string except for
104//     "$region attr-dict", and the `clauses{Req,Opt}AssemblyFormat` fields
105//     hold the required and optional parts of the format string separately, so
106//     that an operation overriding `assemblyFormat` can still benefit from the
107//     auto-generated format for its clauses.
108//   - `description`: This is still required to be defined by the operation.
109//     However, a `clausesDescription` field is provided containing a
110//     concatenation of descriptions of all clauses, to be appended to the
111//     operation's `description` field.
112//   - `extraClassDeclaration`: It contains a concatenation of the
113//     `extraClassDeclaration` of all clauses. This string is also stored in
114//     `clausesExtraClassDeclaration`, so that an operation overriding this
115//     field can append the clause-inherited ones as well.
116//
117// The `regions` field will contain a single `AnyRegion:$region` element if the
118// `singleRegion` bit template argument is set to 1. Otherwise, it will be
119// empty.
120class OpenMP_Op<string mnemonic, list<Trait> traits = [],
121                list<OpenMP_Clause> clauses = [], bit singleRegion = false> :
122    Op<OpenMP_Dialect, mnemonic,
123    // The resulting operation's traits list will be the concatenation of
124    // explicit operation traits and all traits attached to the clauses of the
125    // operation. Repetitions are skipped.
126    !listconcat(traits,
127      !listremove(
128        !foldl([]<Trait>,
129               !foreach(clause,
130                        !filter(fClause, clauses, !not(fClause.ignoreTraits)),
131                        clause.traits),
132               acc, traitList, !listconcat(acc, !listremove(traitList, acc))),
133        traits
134      )
135    )> {
136  list<OpenMP_Clause> clauseList = clauses;
137
138  // Aggregate `arguments` fields of all clauses into a single dag, to be used
139  // by operations to populate their `arguments` field.
140  defvar argsFilteredClauses =
141    !filter(clause, clauses, !not(clause.ignoreArgs));
142
143  dag clausesArgs =
144    !foldl((ins), !foreach(clause, argsFilteredClauses, clause.arguments),
145           acc, argList, !con(acc, argList));
146
147  // Create assembly format string by concatenating format strings separately
148  // for required and optional clauses. Then, required clauses format strings
149  // are joined with spaces in between. Optional clauses format strings are
150  // wrapped into an unsorted list of optional values and separated by "|"
151  // characters.
152
153  // Required clauses.
154  defvar asmFormatFilteredReqClauses =
155    !filter(clause, clauses, !not(!or(clause.ignoreAsmFormat,
156                                     !empty(clause.reqAssemblyFormat))));
157
158  defvar asmFormatReqClauseStrings =
159    !foreach(clause, asmFormatFilteredReqClauses, clause.reqAssemblyFormat);
160
161  string clausesReqAssemblyFormat = !interleave(asmFormatReqClauseStrings, " ");
162
163  // Optional clauses.
164  defvar asmFormatFilteredOptClauses =
165    !filter(clause, clauses, !not(!or(clause.ignoreAsmFormat,
166                                     !empty(clause.optAssemblyFormat))));
167
168  defvar asmFormatOptClauseStrings =
169    !foreach(clause, asmFormatFilteredOptClauses, clause.optAssemblyFormat);
170
171  string clausesOptAssemblyFormat = !interleave(asmFormatOptClauseStrings, "|");
172
173  string clausesAssemblyFormat =
174    !if(!empty(asmFormatReqClauseStrings), "", clausesReqAssemblyFormat # " ") #
175    !if(!empty(asmFormatOptClauseStrings), "",
176        "oilist(" # clausesOptAssemblyFormat # ")");
177
178  // Put together descriptions of all clauses into a single string.
179  defvar descFilteredClauses =
180    !filter(clause, clauses, !not(clause.ignoreDesc));
181
182  string clausesDescription =
183    !interleave(!foreach(clause, descFilteredClauses, clause.description), "");
184
185  // Aggregate `extraClassDeclaration` of all clauses that define it.
186  defvar extraDeclFilteredClauses =
187    !filter(clause, clauses, !not(clause.ignoreExtraDecl));
188
189  string clausesExtraClassDeclaration =
190    !interleave(!foreach(clause, extraDeclFilteredClauses,
191                         clause.extraClassDeclaration), "\n");
192
193  // The default arguments, assembly format and extra class declarations for
194  // OpenMP operations are those defined by their args and clauses.
195  let arguments = clausesArgs;
196  let assemblyFormat =
197    !if(!empty(clausesAssemblyFormat), ?,
198        clausesAssemblyFormat # !if(singleRegion, " $region", "") #
199        " attr-dict");
200  let extraClassDeclaration = clausesExtraClassDeclaration;
201
202  // By default, the op will have zero regions. Setting `singleRegion = true`
203  // will result in a single region named `$region`.
204  let regions = !if(singleRegion, (region AnyRegion:$region), (region));
205}
206
207#endif  // OPENMP_OP_BASE
208