23#include "llvm/ADT/APFloat.h"
24#include "llvm/ADT/MapVector.h"
25#include "llvm/ADT/STLExtras.h"
26#include "llvm/ADT/SmallVectorExtras.h"
28#include "mlir/Dialect/Func/IR/FuncOpsDialect.cpp.inc"
37void FuncDialect::initialize() {
40#include "mlir/Dialect/Func/IR/FuncOps.cpp.inc"
42 declarePromisedInterface<ConvertToEmitCPatternInterface, FuncDialect>();
43 declarePromisedInterface<DialectInlinerInterface, FuncDialect>();
44 declarePromisedInterface<ConvertToLLVMPatternInterface, FuncDialect>();
45 declarePromisedInterfaces<bufferization::BufferizableOpInterface, CallOp,
53 if (ConstantOp::isBuildableWith(value, type))
54 return ConstantOp::create(builder, loc, type,
55 llvm::cast<FlatSymbolRefAttr>(value));
65 auto fnAttr = getCalleeAttr();
67 return emitOpError(
"requires a 'callee' symbol reference attribute");
70 return emitOpError() <<
"'" << fnAttr.getValue()
71 <<
"' does not reference a valid function";
77FunctionType CallOp::getCalleeType() {
78 return FunctionType::get(
getContext(), getOperandTypes(), getResultTypes());
86LogicalResult CallIndirectOp::canonicalize(CallIndirectOp indirectCall,
94 auto directCall = CallOp::create(
95 rewriter, indirectCall.getLoc(), indirectCall.getResultTypes(), calledFn,
96 indirectCall.getArgOperands(), indirectCall.getArgAttrsAttr(),
97 indirectCall.getResAttrsAttr());
98 directCall->setDiscardableAttrs(indirectCall->getDiscardableAttrDictionary());
99 rewriter.
replaceOp(indirectCall, directCall.getResults());
108 StringRef fnName = getValue();
113 this->getOperation(), StringAttr::get(
getContext(), fnName));
115 return emitOpError() <<
"reference to undefined function '" << fnName
119 if (fn.getFunctionType() != type)
120 return emitOpError(
"reference to function with mismatched type");
126 return getValueAttr();
129void ConstantOp::getAsmResultNames(
131 setNameFn(getResult(),
"f");
134bool ConstantOp::isBuildableWith(
Attribute value,
Type type) {
135 return llvm::isa<FlatSymbolRefAttr>(value) && llvm::isa<FunctionType>(type);
142FuncOp FuncOp::create(
Location location, StringRef name, FunctionType type,
146 FuncOp::build(builder, state, name, type, attrs);
149FuncOp FuncOp::create(
Location location, StringRef name, FunctionType type,
154FuncOp FuncOp::create(
Location location, StringRef name, FunctionType type,
157 FuncOp
func = create(location, name, type, attrs);
158 func.setAllArgAttrs(argAttrs);
166 state.
addAttribute(getFunctionTypeAttrName(state.
name), TypeAttr::get(type));
170 if (argAttrs.empty())
172 assert(type.getNumInputs() == argAttrs.size());
174 builder, state, argAttrs, {},
175 getArgAttrsAttrName(state.
name), getResAttrsAttrName(state.
name));
186 getFunctionTypeAttrName(
result.name), buildFuncType,
187 getArgAttrsAttrName(
result.name), getResAttrsAttrName(
result.name));
192 p, *
this,
false, getFunctionTypeAttrName(),
193 getArgAttrsAttrName(), getResAttrsAttrName());
198void FuncOp::cloneInto(FuncOp dest,
IRMapping &mapper) {
200 llvm::MapVector<StringAttr, Attribute> newAttrMap;
201 for (
const auto &attr : dest->getDiscardableAttrDictionary().getValue())
202 newAttrMap.insert({attr.getName(), attr.getValue()});
203 for (
const auto &attr : (*this)->getDiscardableAttrDictionary().getValue())
204 newAttrMap.insert({attr.getName(), attr.getValue()});
206 auto newAttrs = llvm::map_to_vector(
207 newAttrMap, [](std::pair<StringAttr, Attribute> attrPair) {
210 dest->setDiscardableAttrs(DictionaryAttr::get(
getContext(), newAttrs));
213 getBody().cloneInto(&dest.getBody(), mapper);
229 FunctionType oldType = getFunctionType();
231 unsigned oldNumArgs = oldType.getNumInputs();
233 newInputs.reserve(oldNumArgs);
234 for (
unsigned i = 0; i != oldNumArgs; ++i)
235 if (!mapper.
contains(getArgument(i)))
236 newInputs.push_back(oldType.getInput(i));
240 if (newInputs.size() != oldNumArgs) {
241 newFunc.setType(FunctionType::get(oldType.getContext(), newInputs,
242 oldType.getResults()));
244 if (
ArrayAttr argAttrs = getAllArgAttrs()) {
246 newArgAttrs.reserve(newInputs.size());
247 for (
unsigned i = 0; i != oldNumArgs; ++i)
248 if (!mapper.
contains(getArgument(i)))
249 newArgAttrs.push_back(argAttrs[i]);
250 newFunc.setAllArgAttrs(newArgAttrs);
256 cloneInto(newFunc, mapper);
259FuncOp FuncOp::clone() {
261 return clone(mapper);
268LogicalResult FuncOp::verifyRegions() {
273 auto resultTypes = getFunctionType().getResults();
274 for (
Block &block : getBody()) {
279 auto returnOp = dyn_cast<RegionBranchTerminatorOpInterface>(&block.back());
284 if (operands.size() != resultTypes.size())
285 return returnOp->emitOpError(
"has ")
286 << operands.size() <<
" operands, but enclosing function (@"
287 << getName() <<
") returns " << resultTypes.size();
289 for (
auto [i, opType] : llvm::enumerate(llvm::zip(operands, resultTypes))) {
290 auto [operand, resTy] = opType;
291 if (operand.get().getType() != resTy)
292 return returnOp->emitError() <<
"type of return operand " << i <<
" ("
293 << operand.get().getType()
294 <<
") doesn't match function result type ("
295 << resTy <<
") in function @" << getName();
306#define GET_OP_CLASSES
307#include "mlir/Dialect/Func/IR/FuncOps.cpp.inc"
Attributes are known-constant values of operations.
MLIRContext * getContext() const
Return the context this attribute belongs to.
Block represents an ordered list of Operations.
This class is a general helper class for creating context-global objects like types,...
FunctionType getFunctionType(TypeRange inputs, TypeRange results)
StringAttr getStringAttr(const Twine &bytes)
A symbol reference with a reference path containing a single element.
This is a utility class for mapping one set of IR entities to another.
bool contains(T from) const
Checks to see if a mapping for 'from' exists.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
NamedAttribute represents a combination of a name and an Attribute value.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This class helps build Operations.
This class represents a single result from folding an operation.
Operation is the basic unit of execution within MLIR.
iterator_range< dialect_attr_iterator > dialect_attr_range
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, NamedAttrList &&attributes, PropertyRef properties, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
This class represents a successor of a region.
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
This class represents a collection of SymbolTables.
virtual Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
A named class for passing around the variadic flag.
LogicalResult verifyCallOpInterface(CallOpInterface call, TypeRange argumentTypes, TypeRange resultTypes)
Verify that the forwarded operands and results of call are in a 1:1 relationship with the given argum...
void addArgAndResultAttrs(Builder &builder, OperationState &result, ArrayRef< DictionaryAttr > argAttrs, ArrayRef< DictionaryAttr > resultAttrs, StringAttr argAttrsName, StringAttr resAttrsName)
Adds argument and result attributes, provided as argAttrs and resultAttrs arguments,...
void printFunctionOp(OpAsmPrinter &p, FunctionOpInterface op, bool isVariadic, StringRef typeAttrName, StringAttr argAttrsName, StringAttr resAttrsName)
Printer implementation for function-like operations.
ParseResult parseFunctionOp(OpAsmParser &parser, OperationState &result, bool allowVariadic, StringAttr typeAttrName, FuncTypeBuilder funcTypeBuilder, StringAttr argAttrsName, StringAttr resAttrsName)
Parser implementation for function-like operations.
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
Operation * cloneWithoutRegions(OpBuilder &b, Operation *op, TypeRange newResultTypes, ValueRange newOperands)
Operation * clone(OpBuilder &b, Operation *op, TypeRange newResultTypes, ValueRange newOperands)
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
llvm::function_ref< Fn > function_ref
This represents an operation in an abstracted form, suitable for use with the builder APIs.
T & getOrAddProperties()
Get (or create) the properties of the provided type to be set on the operation on creation.
void addAttribute(StringRef name, Attribute attr)
Add an attribute with the specified name.
Region * addRegion()
Create a region that should be attached to the operation.