1//===- SymbolInterfaces.td - Interfaces for symbol 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 a set of interfaces and traits that can be used to define 10// properties of symbol and symbol table operations. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef MLIR_IR_SYMBOLINTERFACES 15#define MLIR_IR_SYMBOLINTERFACES 16 17include "mlir/IR/OpBase.td" 18 19//===----------------------------------------------------------------------===// 20// SymbolOpInterface 21//===----------------------------------------------------------------------===// 22 23def Symbol : OpInterface<"SymbolOpInterface"> { 24 let description = [{ 25 This interface describes an operation that may define a `Symbol`. A `Symbol` 26 operation resides immediately within a region that defines a `SymbolTable`. 27 See [Symbols and SymbolTables](../SymbolsAndSymbolTables.md) for more details 28 and constraints on `Symbol` operations. 29 }]; 30 let cppNamespace = "::mlir"; 31 32 let methods = [ 33 InterfaceMethod<"Returns the name of this symbol.", 34 "::mlir::StringAttr", "getNameAttr", (ins), [{ 35 // Don't rely on the trait implementation as optional symbol operations 36 // may override this. 37 return mlir::SymbolTable::getSymbolName($_op); 38 }], /*defaultImplementation=*/[{ 39 return mlir::SymbolTable::getSymbolName(this->getOperation()); 40 }] 41 >, 42 InterfaceMethod<"Sets the name of this symbol.", 43 "void", "setName", (ins "::mlir::StringAttr":$name), [{}], 44 /*defaultImplementation=*/[{ 45 this->getOperation()->setAttr( 46 mlir::SymbolTable::getSymbolAttrName(), name); 47 }] 48 >, 49 InterfaceMethod<"Gets the visibility of this symbol.", 50 "mlir::SymbolTable::Visibility", "getVisibility", (ins), [{}], 51 /*defaultImplementation=*/[{ 52 return mlir::SymbolTable::getSymbolVisibility(this->getOperation()); 53 }] 54 >, 55 InterfaceMethod<"Returns true if this symbol has nested visibility.", 56 "bool", "isNested", (ins), [{}], 57 /*defaultImplementation=*/[{ 58 return getVisibility() == mlir::SymbolTable::Visibility::Nested; 59 }] 60 >, 61 InterfaceMethod<"Returns true if this symbol has private visibility.", 62 "bool", "isPrivate", (ins), [{}], 63 /*defaultImplementation=*/[{ 64 return getVisibility() == mlir::SymbolTable::Visibility::Private; 65 }] 66 >, 67 InterfaceMethod<"Returns true if this symbol has public visibility.", 68 "bool", "isPublic", (ins), [{}], 69 /*defaultImplementation=*/[{ 70 return getVisibility() == mlir::SymbolTable::Visibility::Public; 71 }] 72 >, 73 InterfaceMethod<"Sets the visibility of this symbol.", 74 "void", "setVisibility", (ins "mlir::SymbolTable::Visibility":$vis), [{}], 75 /*defaultImplementation=*/[{ 76 mlir::SymbolTable::setSymbolVisibility(this->getOperation(), vis); 77 }] 78 >, 79 InterfaceMethod<"Sets the visibility of this symbol to be nested.", 80 "void", "setNested", (ins), [{}], 81 /*defaultImplementation=*/[{ 82 setVisibility(mlir::SymbolTable::Visibility::Nested); 83 }] 84 >, 85 InterfaceMethod<"Sets the visibility of this symbol to be private.", 86 "void", "setPrivate", (ins), [{}], 87 /*defaultImplementation=*/[{ 88 setVisibility(mlir::SymbolTable::Visibility::Private); 89 }] 90 >, 91 InterfaceMethod<"Sets the visibility of this symbol to be public.", 92 "void", "setPublic", (ins), [{}], 93 /*defaultImplementation=*/[{ 94 setVisibility(mlir::SymbolTable::Visibility::Public); 95 }] 96 >, 97 InterfaceMethod<[{ 98 Get all of the uses of the current symbol that are nested within the 99 given operation 'from'. 100 Note: See mlir::SymbolTable::getSymbolUses for more details. 101 }], 102 "::std::optional<::mlir::SymbolTable::UseRange>", "getSymbolUses", 103 (ins "::mlir::Operation *":$from), [{}], 104 /*defaultImplementation=*/[{ 105 return ::mlir::SymbolTable::getSymbolUses(this->getOperation(), from); 106 }] 107 >, 108 InterfaceMethod<[{ 109 Return if the current symbol is known to have no uses that are nested 110 within the given operation 'from'. 111 Note: See mlir::SymbolTable::symbolKnownUseEmpty for more details. 112 }], 113 "bool", "symbolKnownUseEmpty", (ins "::mlir::Operation *":$from), [{}], 114 /*defaultImplementation=*/[{ 115 return ::mlir::SymbolTable::symbolKnownUseEmpty(this->getOperation(), 116 from); 117 }] 118 >, 119 InterfaceMethod<[{ 120 Attempt to replace all uses of the current symbol with the provided 121 symbol 'newSymbol' that are nested within the given operation 'from'. 122 Note: See mlir::SymbolTable::replaceAllSymbolUses for more details. 123 }], 124 "::llvm::LogicalResult", "replaceAllSymbolUses", 125 (ins "::mlir::StringAttr":$newSymbol, "::mlir::Operation *":$from), [{}], 126 /*defaultImplementation=*/[{ 127 return ::mlir::SymbolTable::replaceAllSymbolUses(this->getOperation(), 128 newSymbol, from); 129 }] 130 >, 131 InterfaceMethod<[{ 132 Returns true if this operation optionally defines a symbol based on the 133 presence of the symbol name. 134 }], 135 "bool", "isOptionalSymbol", (ins), [{}], 136 /*defaultImplementation=*/[{ return false; }] 137 >, 138 InterfaceMethod<[{ 139 Returns true if this operation can be discarded if it has no remaining 140 symbol uses. 141 }], 142 "bool", "canDiscardOnUseEmpty", (ins), [{}], 143 /*defaultImplementation=*/[{ 144 // By default, base this on the visibility alone. A symbol can be 145 // discarded as long as it is not public. Only public symbols may be 146 // visible from outside of the IR. 147 return getVisibility() != ::mlir::SymbolTable::Visibility::Public; 148 }] 149 >, 150 InterfaceMethod<[{ 151 Returns true if this operation is a declaration of a symbol (as opposed 152 to a definition). 153 }], 154 "bool", "isDeclaration", (ins), [{}], 155 /*defaultImplementation=*/[{ 156 // By default, assume that the operation defines a symbol. 157 return false; 158 }] 159 >, 160 ]; 161 162 let verify = [{ 163 // If this is an optional symbol, bail out early if possible. 164 auto concreteOp = cast<ConcreteOp>($_op); 165 if (concreteOp.isOptionalSymbol()) { 166 if(!concreteOp->getInherentAttr(::mlir::SymbolTable::getSymbolAttrName()).value_or(Attribute{})) 167 return success(); 168 } 169 if (::mlir::failed(::mlir::detail::verifySymbol($_op))) 170 return ::mlir::failure(); 171 if (concreteOp.isDeclaration() && concreteOp.isPublic()) 172 return concreteOp.emitOpError("symbol declaration cannot have public " 173 "visibility"); 174 auto parent = $_op->getParentOp(); 175 if (parent && !parent->hasTrait<OpTrait::SymbolTable>() && parent->isRegistered()) { 176 return concreteOp.emitOpError("symbol's parent must have the SymbolTable " 177 "trait"); 178 } 179 return success(); 180 }]; 181 182 let extraSharedClassDeclaration = [{ 183 using Visibility = mlir::SymbolTable::Visibility; 184 185 /// Convenience version of `getNameAttr` that returns a StringRef. 186 ::mlir::StringRef getName() { 187 return getNameAttr().getValue(); 188 } 189 190 /// Convenience version of `setName` that take a StringRef. 191 void setName(::mlir::StringRef name) { 192 setName(::mlir::StringAttr::get($_op->getContext(), name)); 193 } 194 }]; 195 196 // Add additional classof checks to properly handle "optional" symbols. 197 let extraClassOf = [{ 198 return $_op->hasAttr(::mlir::SymbolTable::getSymbolAttrName()); 199 }]; 200} 201 202//===----------------------------------------------------------------------===// 203// SymbolUserOpInterface 204//===----------------------------------------------------------------------===// 205 206def SymbolUserOpInterface : OpInterface<"SymbolUserOpInterface"> { 207 let description = [{ 208 This interface describes an operation that may use a `Symbol`. This 209 interface allows for users of symbols to hook into verification and other 210 symbol related utilities that are either costly or otherwise disallowed 211 within a traditional operation. 212 }]; 213 let cppNamespace = "::mlir"; 214 215 let methods = [ 216 InterfaceMethod<"Verify the symbol uses held by this operation.", 217 "::llvm::LogicalResult", "verifySymbolUses", 218 (ins "::mlir::SymbolTableCollection &":$symbolTable) 219 >, 220 ]; 221} 222 223//===----------------------------------------------------------------------===// 224// Symbol Traits 225//===----------------------------------------------------------------------===// 226 227// Op defines a symbol table. 228def SymbolTable : NativeOpTrait<"SymbolTable">; 229 230#endif // MLIR_IR_SYMBOLINTERFACES 231