1//===-- LLVMInterfaces.td - LLVM Interfaces ----------------*- 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 defines interfaces for the LLVM dialect in MLIR. 10// 11//===----------------------------------------------------------------------===// 12 13#ifndef LLVMIR_INTERFACES 14#define LLVMIR_INTERFACES 15 16include "mlir/IR/OpBase.td" 17 18def FastmathFlagsInterface : OpInterface<"FastmathFlagsInterface"> { 19 let description = [{ 20 Access to op fastmath flags. 21 }]; 22 23 let cppNamespace = "::mlir::LLVM"; 24 25 let methods = [ 26 InterfaceMethod< 27 /*desc=*/ "Returns a FastmathFlagsAttr attribute for the operation", 28 /*returnType=*/ "::mlir::LLVM::FastmathFlagsAttr", 29 /*methodName=*/ "getFastmathAttr", 30 /*args=*/ (ins), 31 /*methodBody=*/ [{}], 32 /*defaultImpl=*/ [{ 33 auto op = cast<ConcreteOp>(this->getOperation()); 34 return op.getFastmathFlagsAttr(); 35 }] 36 >, 37 StaticInterfaceMethod< 38 /*desc=*/ [{Returns the name of the FastmathFlagsAttr attribute 39 for the operation}], 40 /*returnType=*/ "::llvm::StringRef", 41 /*methodName=*/ "getFastmathAttrName", 42 /*args=*/ (ins), 43 /*methodBody=*/ [{}], 44 /*defaultImpl=*/ [{ 45 return "fastmathFlags"; 46 }] 47 > 48 ]; 49} 50 51def IntegerOverflowFlagsInterface : OpInterface<"IntegerOverflowFlagsInterface"> { 52 let description = [{ 53 This interface defines an LLVM operation with integer overflow flags and 54 provides a uniform API for accessing them. 55 }]; 56 57 let cppNamespace = "::mlir::LLVM"; 58 59 let methods = [ 60 InterfaceMethod<[{ 61 Get the integer overflow flags for the operation. 62 }], "IntegerOverflowFlags", "getOverflowFlags", (ins), [{}], [{ 63 return $_op.getProperties().overflowFlags; 64 }]>, 65 InterfaceMethod<[{ 66 Set the integer overflow flags for the operation. 67 }], "void", "setOverflowFlags", (ins "IntegerOverflowFlags":$flags), [{}], [{ 68 $_op.getProperties().overflowFlags = flags; 69 }]>, 70 InterfaceMethod<[{ 71 Returns whether the operation has the No Unsigned Wrap keyword. 72 }], "bool", "hasNoUnsignedWrap", (ins), [{}], [{ 73 return bitEnumContainsAll($_op.getOverflowFlags(), 74 IntegerOverflowFlags::nuw); 75 }]>, 76 InterfaceMethod<[{ 77 Returns whether the operation has the No Signed Wrap keyword. 78 }], "bool", "hasNoSignedWrap", (ins), [{}], [{ 79 return bitEnumContainsAll($_op.getOverflowFlags(), 80 IntegerOverflowFlags::nsw); 81 }]>, 82 StaticInterfaceMethod<[{ 83 Get the attribute name of the overflow flags property. 84 }], "StringRef", "getOverflowFlagsAttrName", (ins), [{}], [{ 85 return "overflowFlags"; 86 }]>, 87 ]; 88} 89 90def ExactFlagInterface : OpInterface<"ExactFlagInterface"> { 91 let description = [{ 92 This interface defines an LLVM operation with an exact flag and 93 provides a uniform API for accessing it. 94 }]; 95 96 let cppNamespace = "::mlir::LLVM"; 97 98 let methods = [ 99 InterfaceMethod<[{ 100 Get the exact flag for the operation. 101 }], "bool", "getIsExact", (ins), [{}], [{ 102 return $_op.getProperties().isExact; 103 }]>, 104 InterfaceMethod<[{ 105 Set the exact flag for the operation. 106 }], "void", "setIsExact", (ins "bool":$isExact), [{}], [{ 107 $_op.getProperties().isExact = isExact; 108 }]>, 109 StaticInterfaceMethod<[{ 110 Get the attribute name of the isExact property. 111 }], "StringRef", "getIsExactName", (ins), [{}], [{ 112 return "isExact"; 113 }]>, 114 ]; 115} 116 117def DisjointFlagInterface : OpInterface<"DisjointFlagInterface"> { 118 let description = [{ 119 This interface defines an LLVM operation with a disjoint flag and 120 provides a uniform API for accessing it. 121 }]; 122 123 let cppNamespace = "::mlir::LLVM"; 124 125 let methods = [ 126 InterfaceMethod<[{ 127 Get the disjoint flag for the operation. 128 }], "bool", "getIsDisjoint", (ins), [{}], [{ 129 return $_op.getProperties().isDisjoint; 130 }]>, 131 InterfaceMethod<[{ 132 Set the disjoint flag for the operation. 133 }], "void", "setIsDisjoint", (ins "bool":$isDisjoint), [{}], [{ 134 $_op.getProperties().isDisjoint = isDisjoint; 135 }]>, 136 StaticInterfaceMethod<[{ 137 Get the attribute name of the isDisjoint property. 138 }], "StringRef", "getIsDisjointName", (ins), [{}], [{ 139 return "isDisjoint"; 140 }]>, 141 ]; 142} 143 144def NonNegFlagInterface : OpInterface<"NonNegFlagInterface"> { 145 let description = [{ 146 This interface defines an LLVM operation with an nneg flag and 147 provides a uniform API for accessing it. 148 }]; 149 150 let cppNamespace = "::mlir::LLVM"; 151 152 let methods = [ 153 InterfaceMethod<[{ 154 Get the nneg flag for the operation. 155 }], "bool", "getNonNeg", (ins), [{}], [{ 156 return $_op.getProperties().nonNeg; 157 }]>, 158 InterfaceMethod<[{ 159 Set the nneg flag for the operation. 160 }], "void", "setNonNeg", (ins "bool":$nonNeg), [{}], [{ 161 $_op.getProperties().nonNeg = nonNeg; 162 }]>, 163 StaticInterfaceMethod<[{ 164 Get the attribute name of the nonNeg property. 165 }], "StringRef", "getNonNegName", (ins), [{}], [{ 166 return "nonNeg"; 167 }]>, 168 ]; 169} 170 171def BranchWeightOpInterface : OpInterface<"BranchWeightOpInterface"> { 172 let description = [{ 173 An interface for operations that can carry branch weights metadata. It 174 provides setters and getters for the operation's branch weights attribute. 175 The default implementation of the interface methods expect the operation to 176 have an attribute of type DenseI32ArrayAttr named branch_weights. 177 }]; 178 179 let cppNamespace = "::mlir::LLVM"; 180 181 let methods = [ 182 InterfaceMethod< 183 /*desc=*/ "Returns the branch weights attribute or nullptr", 184 /*returnType=*/ "::mlir::DenseI32ArrayAttr", 185 /*methodName=*/ "getBranchWeightsOrNull", 186 /*args=*/ (ins), 187 /*methodBody=*/ [{}], 188 /*defaultImpl=*/ [{ 189 auto op = cast<ConcreteOp>(this->getOperation()); 190 return op.getBranchWeightsAttr(); 191 }] 192 >, 193 InterfaceMethod< 194 /*desc=*/ "Sets the branch weights attribute", 195 /*returnType=*/ "void", 196 /*methodName=*/ "setBranchWeights", 197 /*args=*/ (ins "::mlir::DenseI32ArrayAttr":$attr), 198 /*methodBody=*/ [{}], 199 /*defaultImpl=*/ [{ 200 auto op = cast<ConcreteOp>(this->getOperation()); 201 op.setBranchWeightsAttr(attr); 202 }] 203 > 204 ]; 205} 206 207def AccessGroupOpInterface : OpInterface<"AccessGroupOpInterface"> { 208 let description = [{ 209 An interface for memory operations that can carry access groups metadata. 210 It provides setters and getters for the operation's access groups attribute. 211 The default implementations of the interface methods expect the operation 212 to have an attribute of type ArrayAttr named access_groups. 213 }]; 214 215 let cppNamespace = "::mlir::LLVM"; 216 let verify = [{ return detail::verifyAccessGroupOpInterface($_op); }]; 217 218 let methods = [ 219 InterfaceMethod< 220 /*desc=*/ "Returns the access groups attribute or nullptr", 221 /*returnType=*/ "::mlir::ArrayAttr", 222 /*methodName=*/ "getAccessGroupsOrNull", 223 /*args=*/ (ins), 224 /*methodBody=*/ [{}], 225 /*defaultImpl=*/ [{ 226 auto op = cast<ConcreteOp>(this->getOperation()); 227 return op.getAccessGroupsAttr(); 228 }] 229 >, 230 InterfaceMethod< 231 /*desc=*/ "Sets the access groups attribute", 232 /*returnType=*/ "void", 233 /*methodName=*/ "setAccessGroups", 234 /*args=*/ (ins "const ::mlir::ArrayAttr":$attr), 235 /*methodBody=*/ [{}], 236 /*defaultImpl=*/ [{ 237 auto op = cast<ConcreteOp>(this->getOperation()); 238 op.setAccessGroupsAttr(attr); 239 }] 240 > 241 ]; 242} 243 244def AliasAnalysisOpInterface : OpInterface<"AliasAnalysisOpInterface"> { 245 let description = [{ 246 An interface for memory operations that can carry alias analysis metadata. 247 It provides setters and getters for the operation's alias analysis 248 attributes. The default implementations of the interface methods expect 249 the operation to have attributes of type ArrayAttr named alias_scopes, 250 noalias_scopes, and tbaa. 251 }]; 252 253 let cppNamespace = "::mlir::LLVM"; 254 let verify = [{ return detail::verifyAliasAnalysisOpInterface($_op); }]; 255 256 let methods = [ 257 InterfaceMethod< 258 /*desc=*/ "Returns the alias scopes attribute or nullptr", 259 /*returnType=*/ "::mlir::ArrayAttr", 260 /*methodName=*/ "getAliasScopesOrNull", 261 /*args=*/ (ins), 262 /*methodBody=*/ [{}], 263 /*defaultImpl=*/ [{ 264 auto op = cast<ConcreteOp>(this->getOperation()); 265 return op.getAliasScopesAttr(); 266 }] 267 >, 268 InterfaceMethod< 269 /*desc=*/ "Sets the alias scopes attribute", 270 /*returnType=*/ "void", 271 /*methodName=*/ "setAliasScopes", 272 /*args=*/ (ins "const ::mlir::ArrayAttr":$attr), 273 /*methodBody=*/ [{}], 274 /*defaultImpl=*/ [{ 275 auto op = cast<ConcreteOp>(this->getOperation()); 276 op.setAliasScopesAttr(attr); 277 }] 278 >, 279 InterfaceMethod< 280 /*desc=*/ "Returns the noalias scopes attribute or nullptr", 281 /*returnType=*/ "::mlir::ArrayAttr", 282 /*methodName=*/ "getNoAliasScopesOrNull", 283 /*args=*/ (ins), 284 /*methodBody=*/ [{}], 285 /*defaultImpl=*/ [{ 286 auto op = cast<ConcreteOp>(this->getOperation()); 287 return op.getNoaliasScopesAttr(); 288 }] 289 >, 290 InterfaceMethod< 291 /*desc=*/ "Sets the noalias scopes attribute", 292 /*returnType=*/ "void", 293 /*methodName=*/ "setNoAliasScopes", 294 /*args=*/ (ins "const ::mlir::ArrayAttr":$attr), 295 /*methodBody=*/ [{}], 296 /*defaultImpl=*/ [{ 297 auto op = cast<ConcreteOp>(this->getOperation()); 298 op.setNoaliasScopesAttr(attr); 299 }] 300 >, 301 InterfaceMethod< 302 /*desc=*/ "Returns the tbaa attribute or nullptr", 303 /*returnType=*/ "::mlir::ArrayAttr", 304 /*methodName=*/ "getTBAATagsOrNull", 305 /*args=*/ (ins), 306 /*methodBody=*/ [{}], 307 /*defaultImpl=*/ [{ 308 auto op = cast<ConcreteOp>(this->getOperation()); 309 return op.getTbaaAttr(); 310 }] 311 >, 312 InterfaceMethod< 313 /*desc=*/ "Sets the tbaa attribute", 314 /*returnType=*/ "void", 315 /*methodName=*/ "setTBAATags", 316 /*args=*/ (ins "const ::mlir::ArrayAttr":$attr), 317 /*methodBody=*/ [{}], 318 /*defaultImpl=*/ [{ 319 auto op = cast<ConcreteOp>(this->getOperation()); 320 op.setTbaaAttr(attr); 321 }] 322 >, 323 InterfaceMethod< 324 /*desc=*/ "Returns a list of all pointer operands accessed by the " 325 "operation", 326 /*returnType=*/ "::llvm::SmallVector<::mlir::Value>", 327 /*methodName=*/ "getAccessedOperands", 328 /*args=*/ (ins) 329 > 330 ]; 331} 332 333def FPExceptionBehaviorOpInterface : OpInterface<"FPExceptionBehaviorOpInterface"> { 334 let description = [{ 335 An interface for operations receiving an exception behavior attribute 336 controlling FP exception behavior. 337 }]; 338 339 let cppNamespace = "::mlir::LLVM"; 340 341 let methods = [ 342 InterfaceMethod< 343 /*desc=*/ "Returns a FPExceptionBehavior attribute for the operation", 344 /*returnType=*/ "::mlir::LLVM::FPExceptionBehaviorAttr", 345 /*methodName=*/ "getFPExceptionBehaviorAttr", 346 /*args=*/ (ins), 347 /*methodBody=*/ [{}], 348 /*defaultImpl=*/ [{ 349 auto op = cast<ConcreteOp>(this->getOperation()); 350 return op.getFpExceptionBehaviorAttr(); 351 }] 352 >, 353 StaticInterfaceMethod< 354 /*desc=*/ [{Returns the name of the FPExceptionBehaviorAttr 355 attribute for the operation}], 356 /*returnType=*/ "::llvm::StringRef", 357 /*methodName=*/ "getFPExceptionBehaviorAttrName", 358 /*args=*/ (ins), 359 /*methodBody=*/ [{}], 360 /*defaultImpl=*/ [{ 361 return "fpExceptionBehavior"; 362 }] 363 > 364 ]; 365} 366 367def RoundingModeOpInterface : OpInterface<"RoundingModeOpInterface"> { 368 let description = [{ 369 An interface for operations receiving a rounding mode attribute 370 controlling FP rounding mode. 371 }]; 372 373 let cppNamespace = "::mlir::LLVM"; 374 375 let methods = [ 376 InterfaceMethod< 377 /*desc=*/ "Returns a RoundingMode attribute for the operation", 378 /*returnType=*/ "::mlir::LLVM::RoundingModeAttr", 379 /*methodName=*/ "getRoundingModeAttr", 380 /*args=*/ (ins), 381 /*methodBody=*/ [{}], 382 /*defaultImpl=*/ [{ 383 auto op = cast<ConcreteOp>(this->getOperation()); 384 return op.getRoundingmodeAttr(); 385 }] 386 >, 387 StaticInterfaceMethod< 388 /*desc=*/ [{Returns the name of the RoundingModeAttr attribute 389 for the operation}], 390 /*returnType=*/ "::llvm::StringRef", 391 /*methodName=*/ "getRoundingModeAttrName", 392 /*args=*/ (ins), 393 /*methodBody=*/ [{}], 394 /*defaultImpl=*/ [{ 395 return "roundingmode"; 396 }] 397 >, 398 ]; 399} 400 401//===----------------------------------------------------------------------===// 402// LLVM dialect type interfaces. 403//===----------------------------------------------------------------------===// 404 405// An interface for LLVM pointer element types. 406def LLVM_PointerElementTypeInterface 407 : TypeInterface<"PointerElementTypeInterface"> { 408 let cppNamespace = "::mlir::LLVM"; 409 410 let description = [{ 411 An interface for types that are allowed as elements of LLVM pointer type. 412 Such types must have a size. 413 }]; 414 415 let methods = [ 416 InterfaceMethod< 417 /*description=*/"Returns the size of the type in bytes.", 418 /*retTy=*/"unsigned", 419 /*methodName=*/"getSizeInBytes", 420 /*args=*/(ins "const ::mlir::DataLayout &":$dataLayout), 421 /*methodBody=*/"", 422 /*defaultImplementation=*/[{ 423 return dataLayout.getTypeSize($_type); 424 }] 425 > 426 ]; 427} 428 429//===----------------------------------------------------------------------===// 430// LLVM dialect attr interfaces. 431//===----------------------------------------------------------------------===// 432 433def LLVM_DIRecursiveTypeAttrInterface 434 : AttrInterface<"DIRecursiveTypeAttrInterface"> { 435 let description = [{ 436 This attribute represents a DITypeAttr that is recursive. Only DITypeAttrs 437 that translate to LLVM DITypes that support mutation should implement this 438 interface. 439 440 There are two modes for conforming attributes: 441 442 1. "rec-decl": 443 - This attr is a recursive declaration identified by a recId. 444 445 2. "rec-self": 446 - This attr is considered a recursive self reference. 447 - This attr itself is a placeholder type that should be conceptually 448 replaced with the closest parent attr of the same type with the same 449 recId. 450 451 For example, to represent a linked list struct: 452 453 #rec_self = di_composite_type<recId = 0> 454 #ptr = di_derived_type<baseType: #rec_self, ...> 455 #field = di_derived_type<name = "next", baseType: #ptr, ...> 456 #rec = di_composite_type<recId = 0, name = "Node", elements: #field, ...> 457 #var = di_local_variable<type = #rec, ...> 458 459 Note that a rec-self without an outer rec-decl with the same recId is 460 conceptually the same as an "unbound" variable. The context needs to provide 461 meaning to the rec-self. 462 }]; 463 let cppNamespace = "::mlir::LLVM"; 464 let methods = [ 465 InterfaceMethod<[{ 466 Get whether this attr describes a recursive self reference. 467 }], "bool", "getIsRecSelf", (ins)>, 468 InterfaceMethod<[{ 469 Get the recursive ID used for matching "rec-decl" with "rec-self". 470 If this attr instance is not recursive, return a null attribute. 471 }], "DistinctAttr", "getRecId", (ins)>, 472 InterfaceMethod<[{ 473 Get a copy of this type attr but with the recursive ID set to `recId`. 474 }], "DIRecursiveTypeAttrInterface", "withRecId", 475 (ins "DistinctAttr":$recId)>, 476 StaticInterfaceMethod<[{ 477 Build a rec-self instance using the provided `recId`. 478 }], "DIRecursiveTypeAttrInterface", "getRecSelf", 479 (ins "DistinctAttr":$recId)> 480 ]; 481} 482 483#endif // LLVMIR_INTERFACES 484