1//===- BuiltinOps.td - Builtin operation 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// Defines the set of builtin MLIR operations, or the set of operations 10// necessary for the validity of and defining the IR. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef BUILTIN_OPS 15#define BUILTIN_OPS 16 17include "mlir/IR/SymbolInterfaces.td" 18include "mlir/Interfaces/CallInterfaces.td" 19 20def Builtin_Dialect : Dialect { 21 let summary = 22 "A dialect containing the builtin Attributes, Operations, and Types"; 23 24 let name = ""; 25 let cppNamespace = "::mlir"; 26} 27 28// Base class for Builtin dialect ops. 29class Builtin_Op<string mnemonic, list<OpTrait> traits = []> : 30 Op<Builtin_Dialect, mnemonic, traits>; 31 32//===----------------------------------------------------------------------===// 33// FuncOp 34//===----------------------------------------------------------------------===// 35 36def FuncOp : Builtin_Op<"func", [ 37 AffineScope, AutomaticAllocationScope, CallableOpInterface, FunctionLike, 38 IsolatedFromAbove, Symbol 39]> { 40 let summary = "An operation with a name containing a single `SSACFG` region"; 41 let description = [{ 42 Operations within the function cannot implicitly capture values defined 43 outside of the function, i.e. Functions are `IsolatedFromAbove`. All 44 external references must use function arguments or attributes that establish 45 a symbolic connection (e.g. symbols referenced by name via a string 46 attribute like SymbolRefAttr). An external function declaration (used when 47 referring to a function declared in some other module) has no body. While 48 the MLIR textual form provides a nice inline syntax for function arguments, 49 they are internally represented as “block arguments” to the first block in 50 the region. 51 52 Only dialect attribute names may be specified in the attribute dictionaries 53 for function arguments, results, or the function itself. 54 55 Example: 56 57 ```mlir 58 // External function definitions. 59 func @abort() 60 func @scribble(i32, i64, memref<? x 128 x f32, #layout_map0>) -> f64 61 62 // A function that returns its argument twice: 63 func @count(%x: i64) -> (i64, i64) 64 attributes {fruit: "banana"} { 65 return %x, %x: i64, i64 66 } 67 68 // A function with an argument attribute 69 func @example_fn_arg(%x: i32 {swift.self = unit}) 70 71 // A function with a result attribute 72 func @example_fn_result() -> (f64 {dialectName.attrName = 0 : i64}) 73 74 // A function with an attribute 75 func @example_fn_attr() attributes {dialectName.attrName = false} 76 ``` 77 }]; 78 79 let arguments = (ins SymbolNameAttr:$sym_name, 80 TypeAttr:$type, 81 OptionalAttr<StrAttr>:$sym_visibility); 82 let regions = (region AnyRegion:$body); 83 84 let builders = [OpBuilderDAG<(ins 85 "StringRef":$name, "FunctionType":$type, 86 CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs, 87 CArg<"ArrayRef<MutableDictionaryAttr>", "{}">:$argAttrs) 88 >]; 89 let extraClassDeclaration = [{ 90 static FuncOp create(Location location, StringRef name, FunctionType type, 91 ArrayRef<NamedAttribute> attrs = {}); 92 static FuncOp create(Location location, StringRef name, FunctionType type, 93 iterator_range<dialect_attr_iterator> attrs); 94 static FuncOp create(Location location, StringRef name, FunctionType type, 95 ArrayRef<NamedAttribute> attrs, 96 ArrayRef<MutableDictionaryAttr> argAttrs); 97 98 /// Create a deep copy of this function and all of its blocks, remapping any 99 /// operands that use values outside of the function using the map that is 100 /// provided (leaving them alone if no entry is present). If the mapper 101 /// contains entries for function arguments, these arguments are not 102 /// included in the new function. Replaces references to cloned sub-values 103 /// with the corresponding value that is copied, and adds those mappings to 104 /// the mapper. 105 FuncOp clone(BlockAndValueMapping &mapper); 106 FuncOp clone(); 107 108 /// Clone the internal blocks and attributes from this function into dest. 109 /// Any cloned blocks are appended to the back of dest. This function 110 /// asserts that the attributes of the current function and dest are 111 /// compatible. 112 void cloneInto(FuncOp dest, BlockAndValueMapping &mapper); 113 114 //===------------------------------------------------------------------===// 115 // CallableOpInterface 116 //===------------------------------------------------------------------===// 117 118 /// Returns the region on the current operation that is callable. This may 119 /// return null in the case of an external callable object, e.g. an external 120 /// function. 121 Region *getCallableRegion() { return isExternal() ? nullptr : &getBody(); } 122 123 /// Returns the results types that the callable region produces when 124 /// executed. 125 ArrayRef<Type> getCallableResults() { return getType().getResults(); } 126 127 //===------------------------------------------------------------------===// 128 // SymbolOpInterface Methods 129 //===------------------------------------------------------------------===// 130 131 bool isDeclaration() { return isExternal(); } 132 133 private: 134 // This trait needs access to the hooks defined below. 135 friend class OpTrait::FunctionLike<FuncOp>; 136 137 /// Returns the number of arguments. This is a hook for 138 /// OpTrait::FunctionLike. 139 unsigned getNumFuncArguments() { return getType().getInputs().size(); } 140 141 /// Returns the number of results. This is a hook for OpTrait::FunctionLike. 142 unsigned getNumFuncResults() { return getType().getResults().size(); } 143 144 /// Hook for OpTrait::FunctionLike, called after verifying that the 'type' 145 /// attribute is present and checks if it holds a function type. Ensures 146 /// getType, getNumFuncArguments, and getNumFuncResults can be called 147 /// safely. 148 LogicalResult verifyType() { 149 auto type = getTypeAttr().getValue(); 150 if (!type.isa<FunctionType>()) 151 return emitOpError("requires '" + getTypeAttrName() + 152 "' attribute of function type"); 153 return success(); 154 } 155 }]; 156 let parser = [{ return ::parseFuncOp(parser, result); }]; 157 let printer = [{ return ::print(*this, p); }]; 158 let verifier = [{ return ::verify(*this); }]; 159} 160 161//===----------------------------------------------------------------------===// 162// ModuleOp 163//===----------------------------------------------------------------------===// 164 165def ModuleOp : Builtin_Op<"module", [ 166 AffineScope, IsolatedFromAbove, NoRegionArguments, SymbolTable, Symbol, 167 SingleBlockImplicitTerminator<"ModuleTerminatorOp"> 168]> { 169 let summary = "A top level container operation"; 170 let description = [{ 171 A `module` represents a top-level container operation. It contains a single 172 SSACFG region containing a single block which can contain any 173 operations. Operations within this region cannot implicitly capture values 174 defined outside the module, i.e. Modules are `IsolatedFromAbove`. Modules 175 have an optional symbol name which can be used to refer to them in 176 operations. 177 178 Example: 179 180 ```mlir 181 module { 182 func @foo() 183 } 184 ``` 185 }]; 186 187 let arguments = (ins OptionalAttr<SymbolNameAttr>:$sym_name, 188 OptionalAttr<StrAttr>:$sym_visibility); 189 let regions = (region SizedRegion<1>:$body); 190 191 let assemblyFormat = "($sym_name^)? attr-dict-with-keyword $body"; 192 let builders = [OpBuilderDAG<(ins CArg<"Optional<StringRef>", "{}">:$name)>]; 193 let extraClassDeclaration = [{ 194 /// Construct a module from the given location with an optional name. 195 static ModuleOp create(Location loc, Optional<StringRef> name = llvm::None); 196 197 /// Return the name of this module if present. 198 Optional<StringRef> getName() { return sym_name(); } 199 200 //===------------------------------------------------------------------===// 201 // SymbolOpInterface Methods 202 //===------------------------------------------------------------------===// 203 204 /// A ModuleOp may optionally define a symbol. 205 bool isOptionalSymbol() { return true; } 206 }]; 207 let verifier = [{ return ::verify(*this); }]; 208 209 // We need to ensure the block inside the region is properly terminated; 210 // the auto-generated builders do not guarantee that. 211 let skipDefaultBuilders = 1; 212} 213 214//===----------------------------------------------------------------------===// 215// ModuleTerminatorOp 216//===----------------------------------------------------------------------===// 217 218def ModuleTerminatorOp : Builtin_Op<"module_terminator", [ 219 Terminator, HasParent<"ModuleOp"> 220]> { 221 let summary = "A pseudo op that marks the end of a module"; 222 let description = [{ 223 `module_terminator` is a special terminator operation for the body of a 224 `module`, it has no semantic meaning beyond keeping the body of a `module` 225 well-formed. 226 }]; 227 let assemblyFormat = "attr-dict"; 228} 229 230#endif // BUILTIN_OPS 231