Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions mlir/docs/Interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -753,20 +753,22 @@ interface section goes as follows:
- (`C++ class` -- `ODS class`(if applicable))

##### CallInterfaces

* `OpWithArgumentAttributesInterface` - Used to represent operations that may
carry argument and result attributes. It is inherited by both
CallOpInterface and CallableOpInterface.
- `ArrayAttr getArgAttrsAttr()`
- `ArrayAttr getResAttrsAttr()`
- `void setArgAttrsAttr(ArrayAttr)`
- `void setResAttrsAttr(ArrayAttr)`
- `Attribute removeArgAttrsAttr()`
- `Attribute removeResAttrsAttr()`
* `CallOpInterface` - Used to represent operations like 'call'
- `CallInterfaceCallable getCallableForCallee()`
- `void setCalleeFromCallable(CallInterfaceCallable)`
* `CallableOpInterface` - Used to represent the target callee of call.
- `Region * getCallableRegion()`
- `ArrayRef<Type> getArgumentTypes()`
- `ArrayRef<Type> getResultsTypes()`
- `ArrayAttr getArgAttrsAttr()`
- `ArrayAttr getResAttrsAttr()`
- `void setArgAttrsAttr(ArrayAttr)`
- `void setResAttrsAttr(ArrayAttr)`
- `Attribute removeArgAttrsAttr()`
- `Attribute removeResAttrsAttr()`

##### RegionKindInterfaces

Expand Down
88 changes: 88 additions & 0 deletions mlir/include/mlir/Interfaces/CallImplementation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//===- CallImplementation.h - Call and Callable Op utilities ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file provides utility functions for implementing call-like and
// callable-like operations, in particular, parsing, printing and verification
// components common to these operations.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_INTERFACES_CALLIMPLEMENTATION_H
#define MLIR_INTERFACES_CALLIMPLEMENTATION_H

#include "mlir/IR/OpImplementation.h"
#include "mlir/Interfaces/CallInterfaces.h"

namespace mlir {

namespace call_interface_impl {

/// Parse a function or call result list.
///
/// function-result-list ::= function-result-list-parens
/// | non-function-type
/// function-result-list-parens ::= `(` `)`
/// | `(` function-result-list-no-parens `)`
/// function-result-list-no-parens ::= function-result (`,` function-result)*
/// function-result ::= type attribute-dict?
///
ParseResult
parseFunctionResultList(OpAsmParser &parser, SmallVectorImpl<Type> &resultTypes,
SmallVectorImpl<DictionaryAttr> &resultAttrs);

/// Parses a function signature using `parser`. This does not deal with function
/// signatures containing SSA region arguments (to parse these signatures, use
/// function_interface_impl::parseFunctionSignature). When
/// `mustParseEmptyResult`, `-> ()` is expected when there is no result type.
///
/// no-ssa-function-signature ::= `(` no-ssa-function-arg-list `)`
/// -> function-result-list
/// no-ssa-function-arg-list ::= no-ssa-function-arg
/// (`,` no-ssa-function-arg)*
/// no-ssa-function-arg ::= type attribute-dict?
ParseResult parseFunctionSignature(OpAsmParser &parser,
SmallVectorImpl<Type> &argTypes,
SmallVectorImpl<DictionaryAttr> &argAttrs,
SmallVectorImpl<Type> &resultTypes,
SmallVectorImpl<DictionaryAttr> &resultAttrs,
bool mustParseEmptyResult = true);

/// Print a function signature for a call or callable operation. If a body
/// region is provided, the SSA arguments are printed in the signature. When
/// `printEmptyResult` is false, `-> function-result-list` is omitted when
/// `resultTypes` is empty.
///
/// function-signature ::= ssa-function-signature
/// | no-ssa-function-signature
/// ssa-function-signature ::= `(` ssa-function-arg-list `)`
/// -> function-result-list
/// ssa-function-arg-list ::= ssa-function-arg (`,` ssa-function-arg)*
/// ssa-function-arg ::= `%`name `:` type attribute-dict?
void printFunctionSignature(OpAsmPrinter &p, ArgumentAttributesOpInterface op,
TypeRange argTypes, bool isVariadic,
TypeRange resultTypes, Region *body = nullptr,
bool printEmptyResult = true);

/// Adds argument and result attributes, provided as `argAttrs` and
/// `resultAttrs` arguments, to the list of operation attributes in `result`.
/// Internally, argument and result attributes are stored as dict attributes
/// with special names given by getResultAttrName, getArgumentAttrName.
void addArgAndResultAttrs(Builder &builder, OperationState &result,
ArrayRef<DictionaryAttr> argAttrs,
ArrayRef<DictionaryAttr> resultAttrs,
StringAttr argAttrsName, StringAttr resAttrsName);
void addArgAndResultAttrs(Builder &builder, OperationState &result,
ArrayRef<OpAsmParser::Argument> args,
ArrayRef<DictionaryAttr> resultAttrs,
StringAttr argAttrsName, StringAttr resAttrsName);

} // namespace call_interface_impl

} // namespace mlir

#endif // MLIR_INTERFACES_CALLIMPLEMENTATION_H
88 changes: 47 additions & 41 deletions mlir/include/mlir/Interfaces/CallInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,53 @@

include "mlir/IR/OpBase.td"


/// Interface for operations with arguments attributes (both call-like
/// and callable operations).
def ArgumentAttributesOpInterface : OpInterface<"ArgumentAttributesOpInterface"> {
let description = [{
A call-like or callable operation that can hold attributes for its arguments
and results.
}];
let cppNamespace = "::mlir";
let methods = [
InterfaceMethod<[{
Get the array of argument attribute dictionaries. The method should
return an array attribute containing only dictionary attributes equal in
number to the number of arguments. Alternatively, the method can
return null to indicate that the region has no argument attributes.
}],
"::mlir::ArrayAttr", "getArgAttrsAttr">,
InterfaceMethod<[{
Get the array of result attribute dictionaries. The method should return
an array attribute containing only dictionary attributes equal in number
to the number of results. Alternatively, the method can return
null to indicate that the region has no result attributes.
}],
"::mlir::ArrayAttr", "getResAttrsAttr">,
InterfaceMethod<[{
Set the array of argument attribute dictionaries.
}],
"void", "setArgAttrsAttr", (ins "::mlir::ArrayAttr":$attrs)>,
InterfaceMethod<[{
Set the array of result attribute dictionaries.
}],
"void", "setResAttrsAttr", (ins "::mlir::ArrayAttr":$attrs)>,
InterfaceMethod<[{
Remove the array of argument attribute dictionaries. This is the same as
setting all argument attributes to an empty dictionary. The method should
return the removed attribute.
}],
"::mlir::Attribute", "removeArgAttrsAttr">,
InterfaceMethod<[{
Remove the array of result attribute dictionaries. This is the same as
setting all result attributes to an empty dictionary. The method should
return the removed attribute.
}],
"::mlir::Attribute", "removeResAttrsAttr">
];
}

// `CallInterfaceCallable`: This is a type used to represent a single callable
// region. A callable is either a symbol, or an SSA value, that is referenced by
// a call-like operation. This represents the destination of the call.
Expand Down Expand Up @@ -113,47 +160,6 @@ def CallableOpInterface : OpInterface<"CallableOpInterface"> {
allow for this method may be called on function declarations).
}],
"::llvm::ArrayRef<::mlir::Type>", "getResultTypes">,

InterfaceMethod<[{
Get the array of argument attribute dictionaries. The method should
return an array attribute containing only dictionary attributes equal in
number to the number of region arguments. Alternatively, the method can
return null to indicate that the region has no argument attributes.
}],
"::mlir::ArrayAttr", "getArgAttrsAttr", (ins),
/*methodBody=*/[{}], /*defaultImplementation=*/[{ return nullptr; }]>,
InterfaceMethod<[{
Get the array of result attribute dictionaries. The method should return
an array attribute containing only dictionary attributes equal in number
to the number of region results. Alternatively, the method can return
null to indicate that the region has no result attributes.
}],
"::mlir::ArrayAttr", "getResAttrsAttr", (ins),
/*methodBody=*/[{}], /*defaultImplementation=*/[{ return nullptr; }]>,
InterfaceMethod<[{
Set the array of argument attribute dictionaries.
}],
"void", "setArgAttrsAttr", (ins "::mlir::ArrayAttr":$attrs),
/*methodBody=*/[{}], /*defaultImplementation=*/[{ return; }]>,
InterfaceMethod<[{
Set the array of result attribute dictionaries.
}],
"void", "setResAttrsAttr", (ins "::mlir::ArrayAttr":$attrs),
/*methodBody=*/[{}], /*defaultImplementation=*/[{ return; }]>,
InterfaceMethod<[{
Remove the array of argument attribute dictionaries. This is the same as
setting all argument attributes to an empty dictionary. The method should
return the removed attribute.
}],
"::mlir::Attribute", "removeArgAttrsAttr", (ins),
/*methodBody=*/[{}], /*defaultImplementation=*/[{ return nullptr; }]>,
InterfaceMethod<[{
Remove the array of result attribute dictionaries. This is the same as
setting all result attributes to an empty dictionary. The method should
return the removed attribute.
}],
"::mlir::Attribute", "removeResAttrsAttr", (ins),
/*methodBody=*/[{}], /*defaultImplementation=*/[{ return nullptr; }]>,
];
}

Expand Down
24 changes: 8 additions & 16 deletions mlir/include/mlir/Interfaces/FunctionImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define MLIR_IR_FUNCTIONIMPLEMENTATION_H_

#include "mlir/IR/OpImplementation.h"
#include "mlir/Interfaces/CallImplementation.h"
#include "mlir/Interfaces/FunctionInterfaces.h"

namespace mlir {
Expand All @@ -33,19 +34,6 @@ class VariadicFlag {
bool variadic;
};

/// Adds argument and result attributes, provided as `argAttrs` and
/// `resultAttrs` arguments, to the list of operation attributes in `result`.
/// Internally, argument and result attributes are stored as dict attributes
/// with special names given by getResultAttrName, getArgumentAttrName.
void addArgAndResultAttrs(Builder &builder, OperationState &result,
ArrayRef<DictionaryAttr> argAttrs,
ArrayRef<DictionaryAttr> resultAttrs,
StringAttr argAttrsName, StringAttr resAttrsName);
void addArgAndResultAttrs(Builder &builder, OperationState &result,
ArrayRef<OpAsmParser::Argument> args,
ArrayRef<DictionaryAttr> resultAttrs,
StringAttr argAttrsName, StringAttr resAttrsName);

/// Callback type for `parseFunctionOp`, the callback should produce the
/// type that will be associated with a function-like operation from lists of
/// function arguments and results, VariadicFlag indicates whether the function
Expand Down Expand Up @@ -84,9 +72,13 @@ void printFunctionOp(OpAsmPrinter &p, FunctionOpInterface op, bool isVariadic,

/// Prints the signature of the function-like operation `op`. Assumes `op` has
/// is a FunctionOpInterface and has passed verification.
void printFunctionSignature(OpAsmPrinter &p, FunctionOpInterface op,
ArrayRef<Type> argTypes, bool isVariadic,
ArrayRef<Type> resultTypes);
inline void printFunctionSignature(OpAsmPrinter &p, FunctionOpInterface op,
ArrayRef<Type> argTypes, bool isVariadic,
ArrayRef<Type> resultTypes) {
call_interface_impl::printFunctionSignature(p, op, argTypes, isVariadic,
resultTypes, &op->getRegion(0),
/*printEmptyResult=*/false);
}

/// Prints the list of function prefixed with the "attributes" keyword. The
/// attributes with names listed in "elided" as well as those used by the
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Interfaces/FunctionInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ include "mlir/Interfaces/CallInterfaces.td"
//===----------------------------------------------------------------------===//

def FunctionOpInterface : OpInterface<"FunctionOpInterface", [
Symbol, CallableOpInterface
Symbol, CallableOpInterface, ArgumentAttributesOpInterface
]> {
let cppNamespace = "::mlir";
let description = [{
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/Async/IR/Async.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ void FuncOp::build(OpBuilder &builder, OperationState &state, StringRef name,
if (argAttrs.empty())
return;
assert(type.getNumInputs() == argAttrs.size());
function_interface_impl::addArgAndResultAttrs(
call_interface_impl::addArgAndResultAttrs(
builder, state, argAttrs, /*resultAttrs=*/std::nullopt,
getArgAttrsAttrName(state.name), getResAttrsAttrName(state.name));
}
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/EmitC/IR/EmitC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ void FuncOp::build(OpBuilder &builder, OperationState &state, StringRef name,
if (argAttrs.empty())
return;
assert(type.getNumInputs() == argAttrs.size());
function_interface_impl::addArgAndResultAttrs(
call_interface_impl::addArgAndResultAttrs(
builder, state, argAttrs, /*resultAttrs=*/std::nullopt,
getArgAttrsAttrName(state.name), getResAttrsAttrName(state.name));
}
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/Func/IR/FuncOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ void FuncOp::build(OpBuilder &builder, OperationState &state, StringRef name,
if (argAttrs.empty())
return;
assert(type.getNumInputs() == argAttrs.size());
function_interface_impl::addArgAndResultAttrs(
call_interface_impl::addArgAndResultAttrs(
builder, state, argAttrs, /*resultAttrs=*/std::nullopt,
getArgAttrsAttrName(state.name), getResAttrsAttrName(state.name));
}
Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1487,7 +1487,7 @@ ParseResult GPUFuncOp::parse(OpAsmParser &parser, OperationState &result) {
result.addAttribute(getFunctionTypeAttrName(result.name),
TypeAttr::get(type));

function_interface_impl::addArgAndResultAttrs(
call_interface_impl::addArgAndResultAttrs(
builder, result, entryArgs, resultAttrs, getArgAttrsAttrName(result.name),
getResAttrsAttrName(result.name));

Expand Down
4 changes: 2 additions & 2 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2510,7 +2510,7 @@ void LLVMFuncOp::build(OpBuilder &builder, OperationState &result,

assert(llvm::cast<LLVMFunctionType>(type).getNumParams() == argAttrs.size() &&
"expected as many argument attribute lists as arguments");
function_interface_impl::addArgAndResultAttrs(
call_interface_impl::addArgAndResultAttrs(
builder, result, argAttrs, /*resultAttrs=*/std::nullopt,
getArgAttrsAttrName(result.name), getResAttrsAttrName(result.name));
}
Expand Down Expand Up @@ -2636,7 +2636,7 @@ ParseResult LLVMFuncOp::parse(OpAsmParser &parser, OperationState &result) {

if (failed(parser.parseOptionalAttrDictWithKeyword(result.attributes)))
return failure();
function_interface_impl::addArgAndResultAttrs(
call_interface_impl::addArgAndResultAttrs(
parser.getBuilder(), result, entryArgs, resultAttrs,
getArgAttrsAttrName(result.name), getResAttrsAttrName(result.name));

Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ ParseResult spirv::FuncOp::parse(OpAsmParser &parser, OperationState &result) {

// Add the attributes to the function arguments.
assert(resultAttrs.size() == resultTypes.size());
function_interface_impl::addArgAndResultAttrs(
call_interface_impl::addArgAndResultAttrs(
builder, result, entryArgs, resultAttrs, getArgAttrsAttrName(result.name),
getResAttrsAttrName(result.name));

Expand Down
2 changes: 1 addition & 1 deletion mlir/lib/Dialect/Shape/IR/Shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1297,7 +1297,7 @@ void FuncOp::build(OpBuilder &builder, OperationState &state, StringRef name,
if (argAttrs.empty())
return;
assert(type.getNumInputs() == argAttrs.size());
function_interface_impl::addArgAndResultAttrs(
call_interface_impl::addArgAndResultAttrs(
builder, state, argAttrs, /*resultAttrs=*/std::nullopt,
getArgAttrsAttrName(state.name), getResAttrsAttrName(state.name));
}
Expand Down
21 changes: 5 additions & 16 deletions mlir/lib/Interfaces/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set(LLVM_OPTIONAL_SOURCES
CallImplementation.cpp
CallInterfaces.cpp
CastInterfaces.cpp
ControlFlowInterfaces.cpp
Expand All @@ -24,8 +25,10 @@ set(LLVM_OPTIONAL_SOURCES
)

function(add_mlir_interface_library name)
cmake_parse_arguments(ARG "" "" "EXTRA_SOURCE" ${ARGN})
add_mlir_library(MLIR${name}
${name}.cpp
${ARG_EXTRA_SOURCE}

ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Interfaces
Expand All @@ -39,28 +42,14 @@ function(add_mlir_interface_library name)
endfunction(add_mlir_interface_library)


add_mlir_interface_library(CallInterfaces)
add_mlir_interface_library(CallInterfaces EXTRA_SOURCE CallImplementation.cpp)
add_mlir_interface_library(CastInterfaces)
add_mlir_interface_library(ControlFlowInterfaces)
add_mlir_interface_library(CopyOpInterface)
add_mlir_interface_library(DataLayoutInterfaces)
add_mlir_interface_library(DerivedAttributeOpInterface)
add_mlir_interface_library(DestinationStyleOpInterface)

add_mlir_library(MLIRFunctionInterfaces
FunctionInterfaces.cpp
FunctionImplementation.cpp

ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Interfaces

DEPENDS
MLIRFunctionInterfacesIncGen

LINK_LIBS PUBLIC
MLIRIR
)

add_mlir_interface_library(FunctionInterfaces EXTRA_SOURCE FunctionImplementation.cpp)
add_mlir_interface_library(InferIntRangeInterface)
add_mlir_interface_library(InferTypeOpInterface)

Expand Down
Loading
Loading