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