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 "StringRef", "getName", (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 "StringRef":$name), [{}], 44 /*defaultImplementation=*/[{ 45 this->getOperation()->setAttr( 46 mlir::SymbolTable::getSymbolAttrName(), 47 StringAttr::get(name, this->getOperation()->getContext())); 48 }] 49 >, 50 InterfaceMethod<"Gets the visibility of this symbol.", 51 "mlir::SymbolTable::Visibility", "getVisibility", (ins), [{}], 52 /*defaultImplementation=*/[{ 53 return mlir::SymbolTable::getSymbolVisibility(this->getOperation()); 54 }] 55 >, 56 InterfaceMethod<"Returns true if this symbol has nested visibility.", 57 "bool", "isNested", (ins), [{}], 58 /*defaultImplementation=*/[{ 59 return getVisibility() == mlir::SymbolTable::Visibility::Nested; 60 }] 61 >, 62 InterfaceMethod<"Returns true if this symbol has private visibility.", 63 "bool", "isPrivate", (ins), [{}], 64 /*defaultImplementation=*/[{ 65 return getVisibility() == mlir::SymbolTable::Visibility::Private; 66 }] 67 >, 68 InterfaceMethod<"Returns true if this symbol has public visibility.", 69 "bool", "isPublic", (ins), [{}], 70 /*defaultImplementation=*/[{ 71 return getVisibility() == mlir::SymbolTable::Visibility::Public; 72 }] 73 >, 74 InterfaceMethod<"Sets the visibility of this symbol.", 75 "void", "setVisibility", (ins "mlir::SymbolTable::Visibility":$vis), [{}], 76 /*defaultImplementation=*/[{ 77 mlir::SymbolTable::setSymbolVisibility(this->getOperation(), vis); 78 }] 79 >, 80 InterfaceMethod<"Sets the visibility of this symbol to be nested.", 81 "void", "setNested", (ins), [{}], 82 /*defaultImplementation=*/[{ 83 setVisibility(mlir::SymbolTable::Visibility::Nested); 84 }] 85 >, 86 InterfaceMethod<"Sets the visibility of this symbol to be private.", 87 "void", "setPrivate", (ins), [{}], 88 /*defaultImplementation=*/[{ 89 setVisibility(mlir::SymbolTable::Visibility::Private); 90 }] 91 >, 92 InterfaceMethod<"Sets the visibility of this symbol to be public.", 93 "void", "setPublic", (ins), [{}], 94 /*defaultImplementation=*/[{ 95 setVisibility(mlir::SymbolTable::Visibility::Public); 96 }] 97 >, 98 InterfaceMethod<[{ 99 Get all of the uses of the current symbol that are nested within the 100 given operation 'from'. 101 Note: See mlir::SymbolTable::getSymbolUses for more details. 102 }], 103 "Optional<::mlir::SymbolTable::UseRange>", "getSymbolUses", 104 (ins "Operation *":$from), [{}], 105 /*defaultImplementation=*/[{ 106 return ::mlir::SymbolTable::getSymbolUses(this->getOperation(), from); 107 }] 108 >, 109 InterfaceMethod<[{ 110 Return if the current symbol is known to have no uses that are nested 111 within the given operation 'from'. 112 Note: See mlir::SymbolTable::symbolKnownUseEmpty for more details. 113 }], 114 "bool", "symbolKnownUseEmpty", (ins "Operation *":$from), [{}], 115 /*defaultImplementation=*/[{ 116 return ::mlir::SymbolTable::symbolKnownUseEmpty(this->getOperation(), 117 from); 118 }] 119 >, 120 InterfaceMethod<[{ 121 Attempt to replace all uses of the current symbol with the provided 122 symbol 'newSymbol' that are nested within the given operation 'from'. 123 Note: See mlir::SymbolTable::replaceAllSymbolUses for more details. 124 }], 125 "LogicalResult", "replaceAllSymbolUses", (ins "StringRef":$newSymbol, 126 "Operation *":$from), [{}], 127 /*defaultImplementation=*/[{ 128 return ::mlir::SymbolTable::replaceAllSymbolUses(this->getOperation(), 129 newSymbol, from); 130 }] 131 >, 132 InterfaceMethod<[{ 133 Returns true if this operation optionally defines a symbol based on the 134 presence of the symbol name. 135 }], 136 "bool", "isOptionalSymbol", (ins), [{}], 137 /*defaultImplementation=*/[{ return false; }] 138 >, 139 InterfaceMethod<[{ 140 Returns true if this operation can be discarded if it has no remaining 141 symbol uses. 142 }], 143 "bool", "canDiscardOnUseEmpty", (ins), [{}], 144 /*defaultImplementation=*/[{ 145 // By default, base this on the visibility alone. A symbol can be 146 // discarded as long as it is not public. Only public symbols may be 147 // visible from outside of the IR. 148 return getVisibility() != ::mlir::SymbolTable::Visibility::Public; 149 }] 150 >, 151 InterfaceMethod<[{ 152 Returns true if this operation is a declaration of a symbol (as opposed 153 to a definition). 154 }], 155 "bool", "isDeclaration", (ins), [{}], 156 /*defaultImplementation=*/[{ 157 // By default, assume that the operation defines a symbol. 158 return false; 159 }] 160 >, 161 ]; 162 163 let verify = [{ 164 // If this is an optional symbol, bail out early if possible. 165 auto concreteOp = cast<ConcreteOp>($_op); 166 if (concreteOp.isOptionalSymbol()) { 167 if(!concreteOp.getAttr(::mlir::SymbolTable::getSymbolAttrName())) 168 return success(); 169 } 170 if (::mlir::failed(::mlir::detail::verifySymbol($_op))) 171 return ::mlir::failure(); 172 if (concreteOp.isDeclaration() && concreteOp.isPublic()) 173 return concreteOp.emitOpError("symbol declaration cannot have public " 174 "visibility"); 175 return success(); 176 }]; 177 178 let extraClassDeclaration = [{ 179 /// Custom classof that handles the case where the symbol is optional. 180 static bool classof(Operation *op) { 181 auto *concept = getInterfaceFor(op); 182 if (!concept) 183 return false; 184 return !concept->isOptionalSymbol(op) || 185 op->getAttr(::mlir::SymbolTable::getSymbolAttrName()); 186 } 187 }]; 188 189 let extraTraitClassDeclaration = [{ 190 using Visibility = mlir::SymbolTable::Visibility; 191 }]; 192} 193 194//===----------------------------------------------------------------------===// 195// SymbolUserOpInterface 196//===----------------------------------------------------------------------===// 197 198def SymbolUserOpInterface : OpInterface<"SymbolUserOpInterface"> { 199 let description = [{ 200 This interface describes an operation that may use a `Symbol`. This 201 interface allows for users of symbols to hook into verification and other 202 symbol related utilities that are either costly or otherwise disallowed 203 within a traditional operation. 204 }]; 205 let cppNamespace = "::mlir"; 206 207 let methods = [ 208 InterfaceMethod<"Verify the symbol uses held by this operation.", 209 "LogicalResult", "verifySymbolUses", 210 (ins "::mlir::SymbolTableCollection &":$symbolTable) 211 >, 212 ]; 213} 214 215//===----------------------------------------------------------------------===// 216// Symbol Traits 217//===----------------------------------------------------------------------===// 218 219// Op defines a symbol table. 220def SymbolTable : NativeOpTrait<"SymbolTable">; 221 222#endif // MLIR_IR_SYMBOLINTERFACES 223