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));
67 return emitOpError(
"requires a 'callee' symbol reference attribute");
71 <<
"' does not reference a valid function";
77FunctionType CallOp::getCalleeType() {
78 return FunctionType::get(
getContext(), getOperandTypes(), getResultTypes());
86LogicalResult CallIndirectOp::canonicalize(CallIndirectOp indirectCall,
89 SymbolRefAttr calledFn;
95 indirectCall.getResultTypes(),
96 indirectCall.getArgOperands());
105 StringRef fnName = getValue();
110 this->getOperation(), StringAttr::get(
getContext(), fnName));
112 return emitOpError() <<
"reference to undefined function '" << fnName
116 if (fn.getFunctionType() != type)
117 return emitOpError(
"reference to function with mismatched type");
123 return getValueAttr();
126void ConstantOp::getAsmResultNames(
128 setNameFn(getResult(),
"f");
131bool ConstantOp::isBuildableWith(
Attribute value,
Type type) {
132 return llvm::isa<FlatSymbolRefAttr>(value) && llvm::isa<FunctionType>(type);
139FuncOp FuncOp::create(
Location location, StringRef name, FunctionType type,
143 FuncOp::build(builder, state, name, type, attrs);
146FuncOp FuncOp::create(
Location location, StringRef name, FunctionType type,
151FuncOp FuncOp::create(
Location location, StringRef name, FunctionType type,
154 FuncOp
func = create(location, name, type, attrs);
155 func.setAllArgAttrs(argAttrs);
164 state.
addAttribute(getFunctionTypeAttrName(state.
name), TypeAttr::get(type));
168 if (argAttrs.empty())
170 assert(type.getNumInputs() == argAttrs.size());
172 builder, state, argAttrs, {},
173 getArgAttrsAttrName(state.
name), getResAttrsAttrName(state.
name));
184 getFunctionTypeAttrName(
result.name), buildFuncType,
185 getArgAttrsAttrName(
result.name), getResAttrsAttrName(
result.name));
190 p, *
this,
false, getFunctionTypeAttrName(),
191 getArgAttrsAttrName(), getResAttrsAttrName());
196void FuncOp::cloneInto(FuncOp dest,
IRMapping &mapper) {
198 llvm::MapVector<StringAttr, Attribute> newAttrMap;
199 for (
const auto &attr : dest->getAttrs())
200 newAttrMap.insert({attr.getName(), attr.getValue()});
201 for (
const auto &attr : (*this)->getAttrs())
202 newAttrMap.insert({attr.getName(), attr.getValue()});
204 auto newAttrs = llvm::map_to_vector(
205 newAttrMap, [](std::pair<StringAttr, Attribute> attrPair) {
208 dest->setAttrs(DictionaryAttr::get(
getContext(), newAttrs));
211 getBody().cloneInto(&dest.getBody(), mapper);
227 FunctionType oldType = getFunctionType();
229 unsigned oldNumArgs = oldType.getNumInputs();
231 newInputs.reserve(oldNumArgs);
232 for (
unsigned i = 0; i != oldNumArgs; ++i)
233 if (!mapper.
contains(getArgument(i)))
234 newInputs.push_back(oldType.getInput(i));
238 if (newInputs.size() != oldNumArgs) {
239 newFunc.setType(FunctionType::get(oldType.getContext(), newInputs,
240 oldType.getResults()));
242 if (
ArrayAttr argAttrs = getAllArgAttrs()) {
244 newArgAttrs.reserve(newInputs.size());
245 for (
unsigned i = 0; i != oldNumArgs; ++i)
246 if (!mapper.
contains(getArgument(i)))
247 newArgAttrs.push_back(argAttrs[i]);
248 newFunc.setAllArgAttrs(newArgAttrs);
254 cloneInto(newFunc, mapper);
257FuncOp FuncOp::clone() {
259 return clone(mapper);
266LogicalResult FuncOp::verifyRegions() {
271 auto resultTypes = getFunctionType().getResults();
272 for (
Block &block : getBody()) {
277 auto returnOp = dyn_cast<RegionBranchTerminatorOpInterface>(&block.back());
282 if (operands.size() != resultTypes.size())
283 return returnOp->emitOpError(
"has ")
284 << operands.size() <<
" operands, but enclosing function (@"
285 << getName() <<
") returns " << resultTypes.size();
287 for (
auto [i, opType] : llvm::enumerate(llvm::zip(operands, resultTypes))) {
288 auto [operand, resTy] = opType;
289 if (operand.get().getType() != resTy)
290 return returnOp->emitError() <<
"type of return operand " << i <<
" ("
291 << operand.get().getType()
292 <<
") doesn't match function result type ("
293 << resTy <<
") in function @" << getName();
304#define GET_OP_CLASSES
305#include "mlir/Dialect/Func/IR/FuncOps.cpp.inc"
p<< " : "<< getMemRefType()<< ", "<< getType();}static LogicalResult verifyVectorMemoryOp(Operation *op, MemRefType memrefType, VectorType vectorType) { if(memrefType.getElementType() !=vectorType.getElementType()) return op-> emitOpError("requires memref and vector types of the same elemental type")
Given a list of lists of parsed operands, populates uniqueOperands with unique operands.
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.
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
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,...
static StringRef getSymbolAttrName()
Return the name of the attribute used for symbol names.
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.
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.