Skip to content

Commit

Permalink
[mlir] Add new SubElementAttr/SubElementType Interfaces
Browse files Browse the repository at this point in the history
These interfaces allow for a composite attribute or type to opaquely provide access to any held attributes or types. There are several intended use cases for this interface. The first of which is to allow the printer to create aliases for non-builtin dialect attributes and types. In the future, this interface will also be extended to allow for SymbolRefAttr to be placed on other entities aside from just DictionaryAttr and ArrayAttr.

To limit potential test breakages, this revision only adds the new interfaces to the builtin attributes/types that are currently hardcoded during AsmPrinter alias generation. In a followup the remaining builtin attributes/types, and non-builtin attributes/types can be extended to support it.

Differential Revision: https://reviews.llvm.org/D102945
  • Loading branch information
River707 committed Jun 11, 2021
1 parent f8a1d65 commit c42dd5d
Show file tree
Hide file tree
Showing 14 changed files with 365 additions and 44 deletions.
2 changes: 1 addition & 1 deletion mlir/include/mlir/IR/BuiltinAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#ifndef MLIR_IR_BUILTINATTRIBUTES_H
#define MLIR_IR_BUILTINATTRIBUTES_H

#include "mlir/IR/Attributes.h"
#include "SubElementInterfaces.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/Sequence.h"
#include <complex>
Expand Down
26 changes: 17 additions & 9 deletions mlir/include/mlir/IR/BuiltinAttributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@
#define BUILTIN_ATTRIBUTES

include "mlir/IR/BuiltinDialect.td"
include "mlir/IR/SubElementInterfaces.td"

// TODO: Currently the attributes defined in this file are prefixed with
// `Builtin_`. This is to differentiate the attributes here with the ones in
// OpBase.td. We should remove the definitions in OpBase.td, and repoint users
// to this file instead.

// Base class for Builtin dialect attributes.
class Builtin_Attr<string name, string baseCppClass = "::mlir::Attribute">
: AttrDef<Builtin_Dialect, name, [], baseCppClass> {
class Builtin_Attr<string name, list<Trait> traits = [],
string baseCppClass = "::mlir::Attribute">
: AttrDef<Builtin_Dialect, name, traits, baseCppClass> {
let mnemonic = ?;
}

Expand Down Expand Up @@ -62,7 +64,9 @@ def Builtin_AffineMapAttr : Builtin_Attr<"AffineMap"> {
// ArrayAttr
//===----------------------------------------------------------------------===//

def Builtin_ArrayAttr : Builtin_Attr<"Array"> {
def Builtin_ArrayAttr : Builtin_Attr<"Array", [
DeclareAttrInterfaceMethods<SubElementAttrInterface>
]> {
let summary = "A collection of other Attribute values";
let description = [{
Syntax:
Expand Down Expand Up @@ -133,7 +137,7 @@ def Builtin_ArrayAttr : Builtin_Attr<"Array"> {
//===----------------------------------------------------------------------===//

def Builtin_DenseIntOrFPElementsAttr
: Builtin_Attr<"DenseIntOrFPElements", "DenseElementsAttr"> {
: Builtin_Attr<"DenseIntOrFPElements", /*traits=*/[], "DenseElementsAttr"> {
let summary = "An Attribute containing a dense multi-dimensional array of "
"integer or floating-point values";
let description = [{
Expand Down Expand Up @@ -228,7 +232,7 @@ def Builtin_DenseIntOrFPElementsAttr
//===----------------------------------------------------------------------===//

def Builtin_DenseStringElementsAttr
: Builtin_Attr<"DenseStringElements", "DenseElementsAttr"> {
: Builtin_Attr<"DenseStringElements", /*traits=*/[], "DenseElementsAttr"> {
let summary = "An Attribute containing a dense multi-dimensional array of "
"strings";
let description = [{
Expand Down Expand Up @@ -277,7 +281,9 @@ def Builtin_DenseStringElementsAttr
// DictionaryAttr
//===----------------------------------------------------------------------===//

def Builtin_DictionaryAttr : Builtin_Attr<"Dictionary"> {
def Builtin_DictionaryAttr : Builtin_Attr<"Dictionary", [
DeclareAttrInterfaceMethods<SubElementAttrInterface>
]> {
let summary = "An dictionary of named Attribute values";
let description = [{
Syntax:
Expand Down Expand Up @@ -589,7 +595,7 @@ def Builtin_OpaqueAttr : Builtin_Attr<"Opaque"> {
//===----------------------------------------------------------------------===//

def Builtin_OpaqueElementsAttr
: Builtin_Attr<"OpaqueElements", "ElementsAttr"> {
: Builtin_Attr<"OpaqueElements", /*traits=*/[], "ElementsAttr"> {
let summary = "An opaque representation of a multi-dimensional array";
let description = [{
Syntax:
Expand Down Expand Up @@ -655,7 +661,7 @@ def Builtin_OpaqueElementsAttr
//===----------------------------------------------------------------------===//

def Builtin_SparseElementsAttr
: Builtin_Attr<"SparseElements", "ElementsAttr"> {
: Builtin_Attr<"SparseElements", /*traits=*/[], "ElementsAttr"> {
let summary = "An opaque representation of a multi-dimensional array";
let description = [{
Syntax:
Expand Down Expand Up @@ -892,7 +898,9 @@ def Builtin_SymbolRefAttr : Builtin_Attr<"SymbolRef"> {
// TypeAttr
//===----------------------------------------------------------------------===//

def Builtin_TypeAttr : Builtin_Attr<"Type"> {
def Builtin_TypeAttr : Builtin_Attr<"Type", [
DeclareAttrInterfaceMethods<SubElementAttrInterface>
]> {
let summary = "An Attribute containing a Type";
let description = [{
Syntax:
Expand Down
3 changes: 1 addition & 2 deletions mlir/include/mlir/IR/BuiltinTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
#ifndef MLIR_IR_BUILTINTYPES_H
#define MLIR_IR_BUILTINTYPES_H

#include "mlir/IR/Attributes.h"
#include "mlir/IR/Types.h"
#include "SubElementInterfaces.h"

namespace llvm {
struct fltSemantics;
Expand Down
37 changes: 27 additions & 10 deletions mlir/include/mlir/IR/BuiltinTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@

include "mlir/IR/BuiltinDialect.td"
include "mlir/IR/BuiltinTypeInterfaces.td"
include "mlir/IR/SubElementInterfaces.td"

// TODO: Currently the types defined in this file are prefixed with `Builtin_`.
// This is to differentiate the types here with the ones in OpBase.td. We should
// remove the definitions in OpBase.td, and repoint users to this file instead.

// Base class for Builtin dialect types.
class Builtin_Type<string name, string baseCppClass = "::mlir::Type">
: TypeDef<Builtin_Dialect, name, [], baseCppClass> {
class Builtin_Type<string name, list<Trait> traits = [],
string baseCppClass = "::mlir::Type">
: TypeDef<Builtin_Dialect, name, traits, baseCppClass> {
let mnemonic = ?;
}

Expand Down Expand Up @@ -66,7 +68,8 @@ def Builtin_Complex : Builtin_Type<"Complex"> {
//===----------------------------------------------------------------------===//

// Base class for Builtin dialect float types.
class Builtin_FloatType<string name> : Builtin_Type<name, "::mlir::FloatType"> {
class Builtin_FloatType<string name>
: Builtin_Type<name, /*traits=*/[], "::mlir::FloatType"> {
let extraClassDeclaration = [{
static }] # name # [{Type get(MLIRContext *context);
}];
Expand Down Expand Up @@ -118,7 +121,9 @@ def Builtin_Float128 : Builtin_FloatType<"Float128"> {
// FunctionType
//===----------------------------------------------------------------------===//

def Builtin_Function : Builtin_Type<"Function"> {
def Builtin_Function : Builtin_Type<"Function", [
DeclareTypeInterfaceMethods<SubElementTypeInterface>
]> {
let summary = "Map from a list of inputs to a list of results";
let description = [{
Syntax:
Expand Down Expand Up @@ -253,7 +258,9 @@ def Builtin_Integer : Builtin_Type<"Integer"> {
// MemRefType
//===----------------------------------------------------------------------===//

def Builtin_MemRef : Builtin_Type<"MemRef", "BaseMemRefType"> {
def Builtin_MemRef : Builtin_Type<"MemRef", [
DeclareTypeInterfaceMethods<SubElementTypeInterface>
], "BaseMemRefType"> {
let summary = "Shaped reference to a region of memory";
let description = [{
Syntax:
Expand Down Expand Up @@ -638,7 +645,9 @@ def Builtin_Opaque : Builtin_Type<"Opaque"> {
// RankedTensorType
//===----------------------------------------------------------------------===//

def Builtin_RankedTensor : Builtin_Type<"RankedTensor", "TensorType"> {
def Builtin_RankedTensor : Builtin_Type<"RankedTensor", [
DeclareTypeInterfaceMethods<SubElementTypeInterface>
], "TensorType"> {
let summary = "Multi-dimensional array with a fixed number of dimensions";
let description = [{
Syntax:
Expand Down Expand Up @@ -726,7 +735,9 @@ def Builtin_RankedTensor : Builtin_Type<"RankedTensor", "TensorType"> {
// TupleType
//===----------------------------------------------------------------------===//

def Builtin_Tuple : Builtin_Type<"Tuple"> {
def Builtin_Tuple : Builtin_Type<"Tuple", [
DeclareTypeInterfaceMethods<SubElementTypeInterface>
]> {
let summary = "Fixed-sized collection of other types";
let description = [{
Syntax:
Expand Down Expand Up @@ -793,7 +804,9 @@ def Builtin_Tuple : Builtin_Type<"Tuple"> {
// UnrankedMemRefType
//===----------------------------------------------------------------------===//

def Builtin_UnrankedMemRef : Builtin_Type<"UnrankedMemRef", "BaseMemRefType"> {
def Builtin_UnrankedMemRef : Builtin_Type<"UnrankedMemRef", [
DeclareTypeInterfaceMethods<SubElementTypeInterface>
], "BaseMemRefType"> {
let summary = "Shaped reference, with unknown rank, to a region of memory";
let description = [{
Syntax:
Expand Down Expand Up @@ -853,7 +866,9 @@ def Builtin_UnrankedMemRef : Builtin_Type<"UnrankedMemRef", "BaseMemRefType"> {
// UnrankedTensorType
//===----------------------------------------------------------------------===//

def Builtin_UnrankedTensor : Builtin_Type<"UnrankedTensor", "TensorType"> {
def Builtin_UnrankedTensor : Builtin_Type<"UnrankedTensor", [
DeclareTypeInterfaceMethods<SubElementTypeInterface>
], "TensorType"> {
let summary = "Multi-dimensional array with unknown dimensions";
let description = [{
Syntax:
Expand Down Expand Up @@ -890,7 +905,9 @@ def Builtin_UnrankedTensor : Builtin_Type<"UnrankedTensor", "TensorType"> {
// VectorType
//===----------------------------------------------------------------------===//

def Builtin_Vector : Builtin_Type<"Vector", "ShapedType"> {
def Builtin_Vector : Builtin_Type<"Vector", [
DeclareTypeInterfaceMethods<SubElementTypeInterface>
], "ShapedType"> {
let summary = "Multi-dimensional SIMD vector type";
let description = [{
Syntax:
Expand Down
7 changes: 7 additions & 0 deletions mlir/include/mlir/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ mlir_tablegen(BuiltinTypeInterfaces.h.inc -gen-type-interface-decls)
mlir_tablegen(BuiltinTypeInterfaces.cpp.inc -gen-type-interface-defs)
add_public_tablegen_target(MLIRBuiltinTypeInterfacesIncGen)

set(LLVM_TARGET_DEFINITIONS SubElementInterfaces.td)
mlir_tablegen(SubElementAttrInterfaces.h.inc -gen-attr-interface-decls)
mlir_tablegen(SubElementAttrInterfaces.cpp.inc -gen-attr-interface-defs)
mlir_tablegen(SubElementTypeInterfaces.h.inc -gen-type-interface-decls)
mlir_tablegen(SubElementTypeInterfaces.cpp.inc -gen-type-interface-defs)
add_public_tablegen_target(MLIRSubElementInterfacesIncGen)

set(LLVM_TARGET_DEFINITIONS TensorEncoding.td)
mlir_tablegen(TensorEncInterfaces.h.inc -gen-attr-interface-decls)
mlir_tablegen(TensorEncInterfaces.cpp.inc -gen-attr-interface-defs)
Expand Down
24 changes: 24 additions & 0 deletions mlir/include/mlir/IR/SubElementInterfaces.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===- SubElementInterfaces.h - Attr and Type SubElements -------*- 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 contains interfaces and utilities for querying the sub elements of
// an attribute or type.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_INTERFACES_SUBELEMENTINTERFACES_H
#define MLIR_INTERFACES_SUBELEMENTINTERFACES_H

#include "mlir/IR/Attributes.h"
#include "mlir/IR/Types.h"

/// Include the definitions of the sub elemnt interfaces.
#include "mlir/IR/SubElementAttrInterfaces.h.inc"
#include "mlir/IR/SubElementTypeInterfaces.h.inc"

#endif // MLIR_INTERFACES_SUBELEMENTINTERFACES_H
100 changes: 100 additions & 0 deletions mlir/include/mlir/IR/SubElementInterfaces.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//===-- SubElementInterfaces.td - Sub-Element Interfaces ---*- tablegen -*-===//
//
// 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 contains a set of interfaces that can be used to interface with
// sub-elements, e.g. held attributes and types, of a composite attribute or
// type.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_IR_SUBELEMENTINTERFACES_TD_
#define MLIR_IR_SUBELEMENTINTERFACES_TD_

include "mlir/IR/OpBase.td"

//===----------------------------------------------------------------------===//
// SubElementInterfaceBase
//===----------------------------------------------------------------------===//

class SubElementInterfaceBase<string interfaceName, string derivedValue> {
string cppNamespace = "::mlir";

list<InterfaceMethod> methods = [
InterfaceMethod<
/*desc=*/[{
Walk all of the immediately nested sub-attributes and sub-types. This
method does not recurse into sub elements.
}], "void", "walkImmediateSubElements",
(ins "llvm::function_ref<void(mlir::Attribute)>":$walkAttrsFn,
"llvm::function_ref<void(mlir::Type)>":$walkTypesFn)
>,
];

code extraClassDeclaration = [{
/// Walk all of the held sub-attributes.
void walkSubAttrs(llvm::function_ref<void(mlir::Attribute)> walkFn) {
walkSubElements(walkFn, /*walkTypesFn=*/[](mlir::Type) {});
}

/// Walk all of the held sub-types.
void walkSubTypes(llvm::function_ref<void(mlir::Type)> walkFn) {
walkSubElements(/*walkAttrsFn=*/[](mlir::Attribute) {}, walkFn);
}

/// Walk all of the held sub-attributes and sub-types.
void walkSubElements(llvm::function_ref<void(mlir::Attribute)> walkAttrsFn,
llvm::function_ref<void(mlir::Type)> walkTypesFn);
}];

code extraTraitClassDeclaration = [{
/// Walk all of the held sub-attributes.
void walkSubAttrs(llvm::function_ref<void(mlir::Attribute)> walkFn) {
walkSubElements(walkFn, /*walkTypesFn=*/[](mlir::Type) {});
}

/// Walk all of the held sub-types.
void walkSubTypes(llvm::function_ref<void(mlir::Type)> walkFn) {
walkSubElements(/*walkAttrsFn=*/[](mlir::Attribute) {}, walkFn);
}

/// Walk all of the held sub-attributes and sub-types.
void walkSubElements(llvm::function_ref<void(mlir::Attribute)> walkAttrsFn,
llvm::function_ref<void(mlir::Type)> walkTypesFn) {
}] # interfaceName # " interface(" # derivedValue # [{);
interface.walkSubElements(walkAttrsFn, walkTypesFn);
}
}];
}

//===----------------------------------------------------------------------===//
// SubElementAttrInterface
//===----------------------------------------------------------------------===//

def SubElementAttrInterface
: AttrInterface<"SubElementAttrInterface">,
SubElementInterfaceBase<"SubElementAttrInterface", "$_attr"> {
let description = [{
An interface used to query and manipulate sub-elements, such as sub-types
and sub-attributes of a composite attribute.
}];
}

//===----------------------------------------------------------------------===//
// SubElementTypeInterface
//===----------------------------------------------------------------------===//

def SubElementTypeInterface
: TypeInterface<"SubElementTypeInterface">,
SubElementInterfaceBase<"SubElementTypeInterface", "$_type"> {
let description = [{
An interface used to query and manipulate sub-elements, such as sub-types
and sub-attributes of a composite type.
}];
}

#endif // MLIR_IR_SUBELEMENTINTERFACES_TD_
Loading

0 comments on commit c42dd5d

Please sign in to comment.