[mlir][Types][NFC] Move all of the builtin Type classes to BuiltinTypes.h

This is part of a larger refactoring the better congregates the builtin structures under the BuiltinDialect. This also removes the problematic "standard" naming that clashes with the "standard" dialect, which is not defined within IR/. A temporary forward is placed in StandardTypes.h to allow time for downstream users to replaced references.

Differential Revision: https://reviews.llvm.org/D92435
This commit is contained in:
River Riddle 2020-12-03 17:22:29 -08:00
parent e66c2e259f
commit 09f7a55fad
122 changed files with 1138 additions and 1130 deletions

View File

@ -1,8 +1,8 @@
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Identifier.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OperationSupport.h"
#include "mlir/IR/StandardTypes.h"
mlir::MLIRContext Context;

View File

@ -13,7 +13,7 @@
#ifndef FORTRAN_LOWER_MANGLER_H
#define FORTRAN_LOWER_MANGLER_H
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "llvm/ADT/StringRef.h"
#include <string>

View File

@ -13,7 +13,7 @@
#include "flang/Semantics/tools.h"
#include "flang/Semantics/type.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#undef QUOTE
#undef TODO

View File

@ -19,8 +19,8 @@
#include "flang/Lower/ConvertType.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/ADT/SmallVector.h"
#include <functional>

View File

@ -370,7 +370,7 @@ constants must be created as SSA values before being used in other operations.
`llvm.mlir.constant` creates such values for scalars and vectors. It has a
mandatory `value` attribute, which may be an integer, floating point attribute;
dense or sparse attribute containing integers or floats. The type of the
attribute is one of the corresponding MLIR standard types. It may be omitted for
attribute is one of the corresponding MLIR builtin types. It may be omitted for
`i64` and `f64` types that are implied. The operation produces a new SSA value
of the specified LLVM IR dialect type. The type of that value _must_ correspond
to the attribute type converted to LLVM IR.

View File

@ -159,7 +159,7 @@ instructions are represented in the SPIR-V dialect:
#### Model types with MLIR custom types
* Types are represented using MLIR standard types and SPIR-V dialect specific
* Types are represented using MLIR builtin types and SPIR-V dialect specific
types. There are no type declaration ops in the SPIR-V dialect. More
discussions can be found in the [Types](#types) section later.
@ -247,9 +247,9 @@ encode them directly in the dialect-specific type.
Theoretically we can define all SPIR-V types using MLIR extensible type system,
but other than representational purity, it does not buy us more. Instead, we
need to maintain the code and invest in pretty printing them. So we prefer to
use builtin/standard types if possible.
use builtin types if possible.
The SPIR-V dialect reuses standard integer, float, and vector types:
The SPIR-V dialect reuses builtin integer, float, and vector types:
Specification | Dialect
:----------------------------------: | :-------------------------------:
@ -1005,10 +1005,10 @@ register other legality constraints into the returned `SPIRVConversionTarget`.
### `SPIRVTypeConverter`
The `mlir::SPIRVTypeConverter` derives from `mlir::TypeConverter` and provides
type conversion for standard types to SPIR-V types conforming to the [target
environment](#target-environment) it is constructed with. If the required
extension/capability for the resultant type is not available in the given
target environment, `convertType()` will return a null type.
type conversion for builtin types to SPIR-V types conforming to the
[target environment](#target-environment) it is constructed with. If the
required extension/capability for the resultant type is not available in the
given target environment, `convertType()` will return a null type.
Standard scalar types are converted to their corresponding SPIR-V scalar types.

View File

@ -702,7 +702,7 @@ defines the relation between the region results and the operation results.
Each value in MLIR has a type defined by the type system below. There are a
number of primitive types (like integers) and also aggregate types for tensors
and memory buffers. MLIR [standard types](#standard-types) do not include
and memory buffers. MLIR [builtin types](#builtin-types) do not include
structures, arrays, or dictionaries.
MLIR has an open type system (i.e. there is no fixed list of types), and types
@ -710,7 +710,7 @@ may have application-specific semantics. For example, MLIR supports a set of
[dialect types](#dialect-types).
```
type ::= type-alias | dialect-type | standard-type
type ::= type-alias | dialect-type | builtin-type
type-list-no-parens ::= type (`,` type)*
type-list-parens ::= `(` `)`
@ -807,13 +807,13 @@ characters.
See [here](Tutorials/DefiningAttributesAndTypes.md) to learn how to define dialect types.
### Standard Types
### Builtin Types
Standard types are a core set of [dialect types](#dialect-types) that are
defined in a builtin dialect and thus available to all users of MLIR.
Builtin types are a core set of [dialect types](#dialect-types) that are defined
in a builtin dialect and thus available to all users of MLIR.
```
standard-type ::= complex-type
builtin-type ::= complex-type
| float-type
| function-type
| index-type

View File

@ -439,23 +439,23 @@ understand. When types of a dialect are:
* In operations of other dialects
- For standard/builtin operations, only standard/builtin types are
allowed. This restriction allows for operations to clearly understand
the invariants that they are working under.
- For standard/builtin operations, only builtin types are allowed. This
restriction allows for operations to clearly understand the invariants
that they are working under.
- Outside of standard/builtin operations, dialects are expected to verify
the allowable operation types per operation.
* In types of other dialects
- For standard/builtin types, these types are allowed to contain types
from other dialects. This simplifies the type system and removes the
need for dialects to redefine all of the standard aggregate types, e.g.
tensor, as well as the memref type. Dialects are expected to verify that
a specific type is valid within a standard type, e.g. if a type can be
an element of a tensor.
- For builtin types, these types are allowed to contain types from other
dialects. This simplifies the type system and removes the need for
dialects to redefine all of the builtin aggregate types, e.g. tensor, as
well as the memref type. Dialects are expected to verify that a specific
type is valid within a builtin type, e.g. if a type can be an element of
a tensor.
- For dialect types, the dialect is expected to verify any type
invariants, e.g. if the standard tensor type can contain a specific type
of that dialect.
invariants, e.g. if the tensor type can contain a specific type of that
dialect.
#### Separating builtin and standard types

View File

@ -292,4 +292,4 @@ the shape function. The reference implementation is general and can support the
arbitrary computations needed to specify output shapes.
[InferTypeOpInterface]: https://github.com/llvm/llvm-project/tree/master/mlir/include/mlir/Interfaces/InferTypeOpInterface.td
[ShapedType]: https://github.com/llvm/llvm-project/tree/master/mlir/include/mlir/IR/StandardTypes.h
[ShapedType]: https://github.com/llvm/llvm-project/tree/master/mlir/include/mlir/IR/BuiltinTypes.h

View File

@ -14,8 +14,8 @@
#include "toy/Dialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
using namespace mlir;
using namespace mlir::toy;

View File

@ -18,8 +18,8 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Verifier.h"
#include "llvm/ADT/STLExtras.h"

View File

@ -14,8 +14,8 @@
#include "toy/Dialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
using namespace mlir;
using namespace mlir::toy;

View File

@ -18,8 +18,8 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Verifier.h"
#include "llvm/ADT/STLExtras.h"

View File

@ -15,8 +15,8 @@
#define MLIR_TUTORIAL_TOY_DIALECT_H_
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "toy/ShapeInferenceInterface.h"

View File

@ -14,8 +14,8 @@
#include "toy/Dialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Transforms/InliningUtils.h"
using namespace mlir;

View File

@ -18,8 +18,8 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Verifier.h"
#include "llvm/ADT/STLExtras.h"

View File

@ -15,8 +15,8 @@
#define MLIR_TUTORIAL_TOY_DIALECT_H_
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "toy/ShapeInferenceInterface.h"

View File

@ -14,8 +14,8 @@
#include "toy/Dialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Transforms/InliningUtils.h"
using namespace mlir;

View File

@ -18,8 +18,8 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Verifier.h"
#include "llvm/ADT/STLExtras.h"

View File

@ -15,8 +15,8 @@
#define MLIR_TUTORIAL_TOY_DIALECT_H_
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "toy/ShapeInferenceInterface.h"

View File

@ -14,8 +14,8 @@
#include "toy/Dialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Transforms/InliningUtils.h"
using namespace mlir;

View File

@ -18,8 +18,8 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Verifier.h"
#include "llvm/ADT/STLExtras.h"

View File

@ -15,8 +15,8 @@
#define MLIR_TUTORIAL_TOY_DIALECT_H_
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "toy/ShapeInferenceInterface.h"

View File

@ -14,9 +14,9 @@
#include "toy/Dialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Transforms/InliningUtils.h"
using namespace mlir;

View File

@ -18,8 +18,8 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Verifier.h"
#include "llvm/ADT/STLExtras.h"

View File

@ -1,4 +1,4 @@
//===-- mlir-c/StandardTypes.h - C API for MLIR Standard types ----*- C -*-===//
//===-- mlir-c/BuiltinTypes.h - C API for MLIR Builtin types ------*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM
// Exceptions.
@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_C_STANDARDTYPES_H
#define MLIR_C_STANDARDTYPES_H
#ifndef MLIR_C_BUILTINTYPES_H
#define MLIR_C_BUILTINTYPES_H
#include "mlir-c/AffineMap.h"
#include "mlir-c/IR.h"
@ -316,4 +316,4 @@ MLIR_CAPI_EXPORTED MlirType mlirFunctionTypeGetResult(MlirType type,
}
#endif
#endif // MLIR_C_STANDARDTYPES_H
#endif // MLIR_C_BUILTINTYPES_H

View File

@ -89,7 +89,7 @@ public:
/// Promote the bare pointers in 'values' that resulted from memrefs to
/// descriptors. 'stdTypes' holds the types of 'values' before the conversion
/// to the LLVM-IR dialect (i.e., MemRefType, or any other Standard type).
/// to the LLVM-IR dialect (i.e., MemRefType, or any other builtin type).
void promoteBarePtrsToDescriptors(ConversionPatternRewriter &rewriter,
Location loc, ArrayRef<Type> stdTypes,
SmallVectorImpl<Value> &values);

View File

@ -14,8 +14,8 @@
#define MLIR_DIALECT_AFFINE_IR_AFFINEMEMORYOPDIALECT_H_
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"
namespace mlir {
#include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h.inc"

View File

@ -18,9 +18,9 @@
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/LoopLikeInterface.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"

View File

@ -15,10 +15,10 @@
#define MLIR_DIALECT_ASYNC_IR_ASYNC_H
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"

View File

@ -16,7 +16,7 @@
#define MLIR_DIALECT_COMMONFOLDERS_H
#include "mlir/IR/Attributes.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"

View File

@ -15,11 +15,11 @@
#define MLIR_DIALECT_GPU_GPUDIALECT_H
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/FunctionSupport.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"

View File

@ -18,8 +18,8 @@
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinDialect.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/TypeUtilities.h"
#include "mlir/IR/Types.h"
#include "mlir/Interfaces/CopyOpInterface.h"

View File

@ -13,8 +13,8 @@
#include "mlir/Dialect/Utils/StructuredOpsUtils.h"
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Support/LLVM.h"
namespace mlir {

View File

@ -11,9 +11,9 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Types.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "llvm/Support/MathExtras.h"

View File

@ -11,9 +11,9 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Types.h"
#include "llvm/Support/MathExtras.h"

View File

@ -10,7 +10,7 @@
#define MLIR_DIALECT_QUANT_UNIFORMSUPPORT_H_
#include "mlir/Dialect/Quant/QuantTypes.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Types.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"

View File

@ -21,7 +21,7 @@
namespace mlir {
/// Type conversion from standard types to SPIR-V types for shader interface.
/// Type conversion from builtin types to SPIR-V types for shader interface.
///
/// Non-32-bit scalar types require special hardware support that may not exist
/// on all GPUs. This is reflected in SPIR-V as that non-32-bit scalar types

View File

@ -13,9 +13,9 @@
#ifndef MLIR_DIALECT_SPIRV_SPIRVTYPES_H_
#define MLIR_DIALECT_SPIRV_SPIRVTYPES_H_
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/TypeSupport.h"
#include "mlir/IR/Types.h"

View File

@ -15,9 +15,9 @@
#define MLIR_DIALECT_STANDARDOPS_IR_OPS_H
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/CallInterfaces.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"

View File

@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
// This header file define utilities that operate on standard types and are
// This header file define utilities that operate on builtin types and are
// useful across multiple dialects that use structured ops abstractions. These
// abstractions consist of define custom operations that encode and transport
// information about their semantics (e.g. type of iterators like parallel,

View File

@ -15,9 +15,9 @@
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "mlir/Interfaces/VectorInterfaces.h"
#include "mlir/Interfaces/ViewLikeInterface.h"

View File

@ -16,7 +16,7 @@
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Types.h"
namespace mlir {

View File

@ -20,7 +20,9 @@ class FileLineColLoc;
class Type;
class PrimitiveType;
class IntegerType;
class FloatType;
class FunctionType;
class IndexType;
class MemRefType;
class VectorType;
class RankedTensorType;

View File

@ -0,0 +1,821 @@
//===- BuiltinTypes.h - MLIR Builtin Type Classes ---------------*- 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
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_IR_BUILTINTYPES_H
#define MLIR_IR_BUILTINTYPES_H
#include "mlir/IR/Types.h"
namespace llvm {
struct fltSemantics;
} // namespace llvm
namespace mlir {
class AffineExpr;
class AffineMap;
class FloatType;
class Identifier;
class IndexType;
class IntegerType;
class Location;
class MLIRContext;
class TypeRange;
namespace detail {
struct BaseMemRefTypeStorage;
struct ComplexTypeStorage;
struct FunctionTypeStorage;
struct IntegerTypeStorage;
struct MemRefTypeStorage;
struct OpaqueTypeStorage;
struct RankedTensorTypeStorage;
struct ShapedTypeStorage;
struct TupleTypeStorage;
struct UnrankedMemRefTypeStorage;
struct UnrankedTensorTypeStorage;
struct VectorTypeStorage;
} // namespace detail
//===----------------------------------------------------------------------===//
// ComplexType
//===----------------------------------------------------------------------===//
/// The 'complex' type represents a complex number with a parameterized element
/// type, which is composed of a real and imaginary value of that element type.
///
/// The element must be a floating point or integer scalar type.
///
class ComplexType
: public Type::TypeBase<ComplexType, Type, detail::ComplexTypeStorage> {
public:
using Base::Base;
/// Get or create a ComplexType with the provided element type.
static ComplexType get(Type elementType);
/// Get or create a ComplexType with the provided element type. This emits
/// and error at the specified location and returns null if the element type
/// isn't supported.
static ComplexType getChecked(Type elementType, Location location);
/// Verify the construction of an integer type.
static LogicalResult verifyConstructionInvariants(Location loc,
Type elementType);
Type getElementType();
};
//===----------------------------------------------------------------------===//
// IndexType
//===----------------------------------------------------------------------===//
/// Index is a special integer-like type with unknown platform-dependent bit
/// width.
class IndexType : public Type::TypeBase<IndexType, Type, TypeStorage> {
public:
using Base::Base;
/// Get an instance of the IndexType.
static IndexType get(MLIRContext *context);
/// Storage bit width used for IndexType by internal compiler data structures.
static constexpr unsigned kInternalStorageBitWidth = 64;
};
//===----------------------------------------------------------------------===//
// IntegerType
//===----------------------------------------------------------------------===//
/// Integer types can have arbitrary bitwidth up to a large fixed limit.
class IntegerType
: public Type::TypeBase<IntegerType, Type, detail::IntegerTypeStorage> {
public:
using Base::Base;
/// Signedness semantics.
enum SignednessSemantics : uint32_t {
Signless, /// No signedness semantics
Signed, /// Signed integer
Unsigned, /// Unsigned integer
};
/// Get or create a new IntegerType of the given width within the context.
/// The created IntegerType is signless (i.e., no signedness semantics).
/// Assume the width is within the allowed range and assert on failures. Use
/// getChecked to handle failures gracefully.
static IntegerType get(unsigned width, MLIRContext *context);
/// Get or create a new IntegerType of the given width within the context.
/// The created IntegerType has signedness semantics as indicated via
/// `signedness`. Assume the width is within the allowed range and assert on
/// failures. Use getChecked to handle failures gracefully.
static IntegerType get(unsigned width, SignednessSemantics signedness,
MLIRContext *context);
/// Get or create a new IntegerType of the given width within the context,
/// defined at the given, potentially unknown, location. The created
/// IntegerType is signless (i.e., no signedness semantics). If the width is
/// outside the allowed range, emit errors and return a null type.
static IntegerType getChecked(unsigned width, Location location);
/// Get or create a new IntegerType of the given width within the context,
/// defined at the given, potentially unknown, location. The created
/// IntegerType has signedness semantics as indicated via `signedness`. If the
/// width is outside the allowed range, emit errors and return a null type.
static IntegerType getChecked(unsigned width, SignednessSemantics signedness,
Location location);
/// Verify the construction of an integer type.
static LogicalResult
verifyConstructionInvariants(Location loc, unsigned width,
SignednessSemantics signedness);
/// Return the bitwidth of this integer type.
unsigned getWidth() const;
/// Return the signedness semantics of this integer type.
SignednessSemantics getSignedness() const;
/// Return true if this is a signless integer type.
bool isSignless() const { return getSignedness() == Signless; }
/// Return true if this is a signed integer type.
bool isSigned() const { return getSignedness() == Signed; }
/// Return true if this is an unsigned integer type.
bool isUnsigned() const { return getSignedness() == Unsigned; }
/// Integer representation maximal bitwidth.
static constexpr unsigned kMaxWidth = 4096;
};
//===----------------------------------------------------------------------===//
// FloatType
//===----------------------------------------------------------------------===//
class FloatType : public Type {
public:
using Type::Type;
// Convenience factories.
static FloatType getBF16(MLIRContext *ctx);
static FloatType getF16(MLIRContext *ctx);
static FloatType getF32(MLIRContext *ctx);
static FloatType getF64(MLIRContext *ctx);
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(Type type);
/// Return the bitwidth of this float type.
unsigned getWidth();
/// Return the floating semantics of this float type.
const llvm::fltSemantics &getFloatSemantics();
};
//===----------------------------------------------------------------------===//
// BFloat16Type
class BFloat16Type
: public Type::TypeBase<BFloat16Type, FloatType, TypeStorage> {
public:
using Base::Base;
/// Return an instance of the bfloat16 type.
static BFloat16Type get(MLIRContext *context);
};
inline FloatType FloatType::getBF16(MLIRContext *ctx) {
return BFloat16Type::get(ctx);
}
//===----------------------------------------------------------------------===//
// Float16Type
class Float16Type : public Type::TypeBase<Float16Type, FloatType, TypeStorage> {
public:
using Base::Base;
/// Return an instance of the float16 type.
static Float16Type get(MLIRContext *context);
};
inline FloatType FloatType::getF16(MLIRContext *ctx) {
return Float16Type::get(ctx);
}
//===----------------------------------------------------------------------===//
// Float32Type
class Float32Type : public Type::TypeBase<Float32Type, FloatType, TypeStorage> {
public:
using Base::Base;
/// Return an instance of the float32 type.
static Float32Type get(MLIRContext *context);
};
inline FloatType FloatType::getF32(MLIRContext *ctx) {
return Float32Type::get(ctx);
}
//===----------------------------------------------------------------------===//
// Float64Type
class Float64Type : public Type::TypeBase<Float64Type, FloatType, TypeStorage> {
public:
using Base::Base;
/// Return an instance of the float64 type.
static Float64Type get(MLIRContext *context);
};
inline FloatType FloatType::getF64(MLIRContext *ctx) {
return Float64Type::get(ctx);
}
//===----------------------------------------------------------------------===//
// FunctionType
//===----------------------------------------------------------------------===//
/// Function types map from a list of inputs to a list of results.
class FunctionType
: public Type::TypeBase<FunctionType, Type, detail::FunctionTypeStorage> {
public:
using Base::Base;
static FunctionType get(TypeRange inputs, TypeRange results,
MLIRContext *context);
/// Input types.
unsigned getNumInputs() const;
Type getInput(unsigned i) const { return getInputs()[i]; }
ArrayRef<Type> getInputs() const;
/// Result types.
unsigned getNumResults() const;
Type getResult(unsigned i) const { return getResults()[i]; }
ArrayRef<Type> getResults() const;
/// Returns a new function type without the specified arguments and results.
FunctionType getWithoutArgsAndResults(ArrayRef<unsigned> argIndices,
ArrayRef<unsigned> resultIndices);
};
//===----------------------------------------------------------------------===//
// NoneType
//===----------------------------------------------------------------------===//
/// NoneType is a unit type, i.e. a type with exactly one possible value, where
/// its value does not have a defined dynamic representation.
class NoneType : public Type::TypeBase<NoneType, Type, TypeStorage> {
public:
using Base::Base;
/// Get an instance of the NoneType.
static NoneType get(MLIRContext *context);
};
//===----------------------------------------------------------------------===//
// OpaqueType
//===----------------------------------------------------------------------===//
/// Opaque types represent types of non-registered dialects. These are types
/// represented in their raw string form, and can only usefully be tested for
/// type equality.
class OpaqueType
: public Type::TypeBase<OpaqueType, Type, detail::OpaqueTypeStorage> {
public:
using Base::Base;
/// Get or create a new OpaqueType with the provided dialect and string data.
static OpaqueType get(Identifier dialect, StringRef typeData,
MLIRContext *context);
/// Get or create a new OpaqueType with the provided dialect and string data.
/// If the given identifier is not a valid namespace for a dialect, then a
/// null type is returned.
static OpaqueType getChecked(Identifier dialect, StringRef typeData,
MLIRContext *context, Location location);
/// Returns the dialect namespace of the opaque type.
Identifier getDialectNamespace() const;
/// Returns the raw type data of the opaque type.
StringRef getTypeData() const;
/// Verify the construction of an opaque type.
static LogicalResult verifyConstructionInvariants(Location loc,
Identifier dialect,
StringRef typeData);
};
//===----------------------------------------------------------------------===//
// ShapedType
//===----------------------------------------------------------------------===//
/// This is a common base class between Vector, UnrankedTensor, RankedTensor,
/// and MemRef types because they share behavior and semantics around shape,
/// rank, and fixed element type. Any type with these semantics should inherit
/// from ShapedType.
class ShapedType : public Type {
public:
using ImplType = detail::ShapedTypeStorage;
using Type::Type;
// TODO: merge these two special values in a single one used everywhere.
// Unfortunately, uses of `-1` have crept deep into the codebase now and are
// hard to track.
static constexpr int64_t kDynamicSize = -1;
static constexpr int64_t kDynamicStrideOrOffset =
std::numeric_limits<int64_t>::min();
/// Return the element type.
Type getElementType() const;
/// If an element type is an integer or a float, return its width. Otherwise,
/// abort.
unsigned getElementTypeBitWidth() const;
/// If it has static shape, return the number of elements. Otherwise, abort.
int64_t getNumElements() const;
/// If this is a ranked type, return the rank. Otherwise, abort.
int64_t getRank() const;
/// Whether or not this is a ranked type. Memrefs, vectors and ranked tensors
/// have a rank, while unranked tensors do not.
bool hasRank() const;
/// If this is a ranked type, return the shape. Otherwise, abort.
ArrayRef<int64_t> getShape() const;
/// If this is unranked type or any dimension has unknown size (<0), it
/// doesn't have static shape. If all dimensions have known size (>= 0), it
/// has static shape.
bool hasStaticShape() const;
/// If this has a static shape and the shape is equal to `shape` return true.
bool hasStaticShape(ArrayRef<int64_t> shape) const;
/// If this is a ranked type, return the number of dimensions with dynamic
/// size. Otherwise, abort.
int64_t getNumDynamicDims() const;
/// If this is ranked type, return the size of the specified dimension.
/// Otherwise, abort.
int64_t getDimSize(unsigned idx) const;
/// Returns true if this dimension has a dynamic size (for ranked types);
/// aborts for unranked types.
bool isDynamicDim(unsigned idx) const;
/// Returns the position of the dynamic dimension relative to just the dynamic
/// dimensions, given its `index` within the shape.
unsigned getDynamicDimIndex(unsigned index) const;
/// Get the total amount of bits occupied by a value of this type. This does
/// not take into account any memory layout or widening constraints, e.g. a
/// vector<3xi57> is reported to occupy 3x57=171 bit, even though in practice
/// it will likely be stored as in a 4xi64 vector register. Fail an assertion
/// if the size cannot be computed statically, i.e. if the type has a dynamic
/// shape or if its elemental type does not have a known bit width.
int64_t getSizeInBits() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(Type type);
/// Whether the given dimension size indicates a dynamic dimension.
static constexpr bool isDynamic(int64_t dSize) {
return dSize == kDynamicSize;
}
static constexpr bool isDynamicStrideOrOffset(int64_t dStrideOrOffset) {
return dStrideOrOffset == kDynamicStrideOrOffset;
}
};
//===----------------------------------------------------------------------===//
// VectorType
//===----------------------------------------------------------------------===//
/// Vector types represent multi-dimensional SIMD vectors, and have a fixed
/// known constant shape with one or more dimension.
class VectorType
: public Type::TypeBase<VectorType, ShapedType, detail::VectorTypeStorage> {
public:
using Base::Base;
/// Get or create a new VectorType of the provided shape and element type.
/// Assumes the arguments define a well-formed VectorType.
static VectorType get(ArrayRef<int64_t> shape, Type elementType);
/// Get or create a new VectorType of the provided shape and element type
/// declared at the given, potentially unknown, location. If the VectorType
/// defined by the arguments would be ill-formed, emit errors and return
/// nullptr-wrapping type.
static VectorType getChecked(ArrayRef<int64_t> shape, Type elementType,
Location location);
/// Verify the construction of a vector type.
static LogicalResult verifyConstructionInvariants(Location loc,
ArrayRef<int64_t> shape,
Type elementType);
/// Returns true of the given type can be used as an element of a vector type.
/// In particular, vectors can consist of integer or float primitives.
static bool isValidElementType(Type t) {
return t.isa<IntegerType, FloatType>();
}
ArrayRef<int64_t> getShape() const;
};
//===----------------------------------------------------------------------===//
// TensorType
//===----------------------------------------------------------------------===//
/// Tensor types represent multi-dimensional arrays, and have two variants:
/// RankedTensorType and UnrankedTensorType.
class TensorType : public ShapedType {
public:
using ShapedType::ShapedType;
/// Return true if the specified element type is ok in a tensor.
static bool isValidElementType(Type type);
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(Type type);
};
//===----------------------------------------------------------------------===//
// RankedTensorType
/// Ranked tensor types represent multi-dimensional arrays that have a shape
/// with a fixed number of dimensions. Each shape element can be a non-negative
/// integer or unknown (represented by -1).
class RankedTensorType
: public Type::TypeBase<RankedTensorType, TensorType,
detail::RankedTensorTypeStorage> {
public:
using Base::Base;
/// Get or create a new RankedTensorType of the provided shape and element
/// type. Assumes the arguments define a well-formed type.
static RankedTensorType get(ArrayRef<int64_t> shape, Type elementType);
/// Get or create a new RankedTensorType of the provided shape and element
/// type declared at the given, potentially unknown, location. If the
/// RankedTensorType defined by the arguments would be ill-formed, emit errors
/// and return a nullptr-wrapping type.
static RankedTensorType getChecked(ArrayRef<int64_t> shape, Type elementType,
Location location);
/// Verify the construction of a ranked tensor type.
static LogicalResult verifyConstructionInvariants(Location loc,
ArrayRef<int64_t> shape,
Type elementType);
ArrayRef<int64_t> getShape() const;
};
//===----------------------------------------------------------------------===//
// UnrankedTensorType
/// Unranked tensor types represent multi-dimensional arrays that have an
/// unknown shape.
class UnrankedTensorType
: public Type::TypeBase<UnrankedTensorType, TensorType,
detail::UnrankedTensorTypeStorage> {
public:
using Base::Base;
/// Get or create a new UnrankedTensorType of the provided shape and element
/// type. Assumes the arguments define a well-formed type.
static UnrankedTensorType get(Type elementType);
/// Get or create a new UnrankedTensorType of the provided shape and element
/// type declared at the given, potentially unknown, location. If the
/// UnrankedTensorType defined by the arguments would be ill-formed, emit
/// errors and return a nullptr-wrapping type.
static UnrankedTensorType getChecked(Type elementType, Location location);
/// Verify the construction of a unranked tensor type.
static LogicalResult verifyConstructionInvariants(Location loc,
Type elementType);
ArrayRef<int64_t> getShape() const { return llvm::None; }
};
//===----------------------------------------------------------------------===//
// BaseMemRefType
//===----------------------------------------------------------------------===//
/// Base MemRef for Ranked and Unranked variants
class BaseMemRefType : public ShapedType {
public:
using ImplType = detail::BaseMemRefTypeStorage;
using ShapedType::ShapedType;
/// Return true if the specified element type is ok in a memref.
static bool isValidElementType(Type type) {
return type.isIntOrIndexOrFloat() || type.isa<VectorType, ComplexType>();
}
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(Type type);
/// Returns the memory space in which data referred to by this memref resides.
unsigned getMemorySpace() const;
};
//===----------------------------------------------------------------------===//
// MemRefType
/// MemRef types represent a region of memory that have a shape with a fixed
/// number of dimensions. Each shape element can be a non-negative integer or
/// unknown (represented by -1). MemRef types also have an affine map
/// composition, represented as an array AffineMap pointers.
class MemRefType : public Type::TypeBase<MemRefType, BaseMemRefType,
detail::MemRefTypeStorage> {
public:
/// This is a builder type that keeps local references to arguments. Arguments
/// that are passed into the builder must out-live the builder.
class Builder {
public:
// Build from another MemRefType.
explicit Builder(MemRefType other)
: shape(other.getShape()), elementType(other.getElementType()),
affineMaps(other.getAffineMaps()),
memorySpace(other.getMemorySpace()) {}
// Build from scratch.
Builder(ArrayRef<int64_t> shape, Type elementType)
: shape(shape), elementType(elementType), affineMaps(), memorySpace(0) {
}
Builder &setShape(ArrayRef<int64_t> newShape) {
shape = newShape;
return *this;
}
Builder &setElementType(Type newElementType) {
elementType = newElementType;
return *this;
}
Builder &setAffineMaps(ArrayRef<AffineMap> newAffineMaps) {
affineMaps = newAffineMaps;
return *this;
}
Builder &setMemorySpace(unsigned newMemorySpace) {
memorySpace = newMemorySpace;
return *this;
}
operator MemRefType() {
return MemRefType::get(shape, elementType, affineMaps, memorySpace);
}
private:
ArrayRef<int64_t> shape;
Type elementType;
ArrayRef<AffineMap> affineMaps;
unsigned memorySpace;
};
using Base::Base;
/// Get or create a new MemRefType based on shape, element type, affine
/// map composition, and memory space. Assumes the arguments define a
/// well-formed MemRef type. Use getChecked to gracefully handle MemRefType
/// construction failures.
static MemRefType get(ArrayRef<int64_t> shape, Type elementType,
ArrayRef<AffineMap> affineMapComposition = {},
unsigned memorySpace = 0);
/// Get or create a new MemRefType based on shape, element type, affine
/// map composition, and memory space declared at the given location.
/// If the location is unknown, the last argument should be an instance of
/// UnknownLoc. If the MemRefType defined by the arguments would be
/// ill-formed, emits errors (to the handler registered with the context or to
/// the error stream) and returns nullptr.
static MemRefType getChecked(ArrayRef<int64_t> shape, Type elementType,
ArrayRef<AffineMap> affineMapComposition,
unsigned memorySpace, Location location);
ArrayRef<int64_t> getShape() const;
/// Returns an array of affine map pointers representing the memref affine
/// map composition.
ArrayRef<AffineMap> getAffineMaps() const;
// TODO: merge these two special values in a single one used everywhere.
// Unfortunately, uses of `-1` have crept deep into the codebase now and are
// hard to track.
static int64_t getDynamicStrideOrOffset() {
return ShapedType::kDynamicStrideOrOffset;
}
private:
/// Get or create a new MemRefType defined by the arguments. If the resulting
/// type would be ill-formed, return nullptr. If the location is provided,
/// emit detailed error messages.
static MemRefType getImpl(ArrayRef<int64_t> shape, Type elementType,
ArrayRef<AffineMap> affineMapComposition,
unsigned memorySpace, Optional<Location> location);
using Base::getImpl;
};
//===----------------------------------------------------------------------===//
// UnrankedMemRefType
/// Unranked MemRef type represent multi-dimensional MemRefs that
/// have an unknown rank.
class UnrankedMemRefType
: public Type::TypeBase<UnrankedMemRefType, BaseMemRefType,
detail::UnrankedMemRefTypeStorage> {
public:
using Base::Base;
/// Get or create a new UnrankedMemRefType of the provided element
/// type and memory space
static UnrankedMemRefType get(Type elementType, unsigned memorySpace);
/// Get or create a new UnrankedMemRefType of the provided element
/// type and memory space declared at the given, potentially unknown,
/// location. If the UnrankedMemRefType defined by the arguments would be
/// ill-formed, emit errors and return a nullptr-wrapping type.
static UnrankedMemRefType getChecked(Type elementType, unsigned memorySpace,
Location location);
/// Verify the construction of a unranked memref type.
static LogicalResult verifyConstructionInvariants(Location loc,
Type elementType,
unsigned memorySpace);
ArrayRef<int64_t> getShape() const { return llvm::None; }
};
//===----------------------------------------------------------------------===//
// TupleType
//===----------------------------------------------------------------------===//
/// Tuple types represent a collection of other types. Note: This type merely
/// provides a common mechanism for representing tuples in MLIR. It is up to
/// dialect authors to provides operations for manipulating them, e.g.
/// extract_tuple_element. When possible, users should prefer multi-result
/// operations in the place of tuples.
class TupleType
: public Type::TypeBase<TupleType, Type, detail::TupleTypeStorage> {
public:
using Base::Base;
/// Get or create a new TupleType with the provided element types. Assumes the
/// arguments define a well-formed type.
static TupleType get(TypeRange elementTypes, MLIRContext *context);
/// Get or create an empty tuple type.
static TupleType get(MLIRContext *context);
/// Return the elements types for this tuple.
ArrayRef<Type> getTypes() const;
/// Accumulate the types contained in this tuple and tuples nested within it.
/// Note that this only flattens nested tuples, not any other container type,
/// e.g. a tuple<i32, tensor<i32>, tuple<f32, tuple<i64>>> is flattened to
/// (i32, tensor<i32>, f32, i64)
void getFlattenedTypes(SmallVectorImpl<Type> &types);
/// Return the number of held types.
size_t size() const;
/// Iterate over the held elements.
using iterator = ArrayRef<Type>::iterator;
iterator begin() const { return getTypes().begin(); }
iterator end() const { return getTypes().end(); }
/// Return the element type at index 'index'.
Type getType(size_t index) const {
assert(index < size() && "invalid index for tuple type");
return getTypes()[index];
}
};
//===----------------------------------------------------------------------===//
// Deferred Method Definitions
//===----------------------------------------------------------------------===//
inline bool BaseMemRefType::classof(Type type) {
return type.isa<MemRefType, UnrankedMemRefType>();
}
inline bool FloatType::classof(Type type) {
return type.isa<BFloat16Type, Float16Type, Float32Type, Float64Type>();
}
inline bool ShapedType::classof(Type type) {
return type.isa<RankedTensorType, VectorType, UnrankedTensorType,
UnrankedMemRefType, MemRefType>();
}
inline bool TensorType::classof(Type type) {
return type.isa<RankedTensorType, UnrankedTensorType>();
}
//===----------------------------------------------------------------------===//
// Type Utilities
//===----------------------------------------------------------------------===//
/// Returns the strides of the MemRef if the layout map is in strided form.
/// MemRefs with layout maps in strided form include:
/// 1. empty or identity layout map, in which case the stride information is
/// the canonical form computed from sizes;
/// 2. single affine map layout of the form `K + k0 * d0 + ... kn * dn`,
/// where K and ki's are constants or symbols.
///
/// A stride specification is a list of integer values that are either static
/// or dynamic (encoded with getDynamicStrideOrOffset()). Strides encode the
/// distance in the number of elements between successive entries along a
/// particular dimension. For example, `memref<42x16xf32, (64 * d0 + d1)>`
/// specifies a view into a non-contiguous memory region of `42` by `16` `f32`
/// elements in which the distance between two consecutive elements along the
/// outer dimension is `1` and the distance between two consecutive elements
/// along the inner dimension is `64`.
///
/// Returns whether a simple strided form can be extracted from the composition
/// of the layout map.
///
/// The convention is that the strides for dimensions d0, .. dn appear in
/// order to make indexing intuitive into the result.
LogicalResult getStridesAndOffset(MemRefType t,
SmallVectorImpl<int64_t> &strides,
int64_t &offset);
LogicalResult getStridesAndOffset(MemRefType t,
SmallVectorImpl<AffineExpr> &strides,
AffineExpr &offset);
/// Given a list of strides (in which MemRefType::getDynamicStrideOrOffset()
/// represents a dynamic value), return the single result AffineMap which
/// represents the linearized strided layout map. Dimensions correspond to the
/// offset followed by the strides in order. Symbols are inserted for each
/// dynamic dimension in order. A stride cannot take value `0`.
///
/// Examples:
/// =========
///
/// 1. For offset: 0 strides: ?, ?, 1 return
/// (i, j, k)[M, N]->(M * i + N * j + k)
///
/// 2. For offset: 3 strides: 32, ?, 16 return
/// (i, j, k)[M]->(3 + 32 * i + M * j + 16 * k)
///
/// 3. For offset: ? strides: ?, ?, ? return
/// (i, j, k)[off, M, N, P]->(off + M * i + N * j + P * k)
AffineMap makeStridedLinearLayoutMap(ArrayRef<int64_t> strides, int64_t offset,
MLIRContext *context);
/// Return a version of `t` with identity layout if it can be determined
/// statically that the layout is the canonical contiguous strided layout.
/// Otherwise pass `t`'s layout into `simplifyAffineMap` and return a copy of
/// `t` with simplified layout.
MemRefType canonicalizeStridedLayout(MemRefType t);
/// Return a version of `t` with a layout that has all dynamic offset and
/// strides. This is used to erase the static layout.
MemRefType eraseStridedLayout(MemRefType t);
/// Given MemRef `sizes` that are either static or dynamic, returns the
/// canonical "contiguous" strides AffineExpr. Strides are multiplicative and
/// once a dynamic dimension is encountered, all canonical strides become
/// dynamic and need to be encoded with a different symbol.
/// For canonical strides expressions, the offset is always 0 and and fastest
/// varying stride is always `1`.
///
/// Examples:
/// - memref<3x4x5xf32> has canonical stride expression
/// `20*exprs[0] + 5*exprs[1] + exprs[2]`.
/// - memref<3x?x5xf32> has canonical stride expression
/// `s0*exprs[0] + 5*exprs[1] + exprs[2]`.
/// - memref<3x4x?xf32> has canonical stride expression
/// `s1*exprs[0] + s0*exprs[1] + exprs[2]`.
AffineExpr makeCanonicalStridedLayoutExpr(ArrayRef<int64_t> sizes,
ArrayRef<AffineExpr> exprs,
MLIRContext *context);
/// Return the result of makeCanonicalStrudedLayoutExpr for the common case
/// where `exprs` is {d0, d1, .., d_(sizes.size()-1)}
AffineExpr makeCanonicalStridedLayoutExpr(ArrayRef<int64_t> sizes,
MLIRContext *context);
/// Return true if the layout for `t` is compatible with strided semantics.
bool isStrided(MemRefType t);
} // end namespace mlir
#endif // MLIR_IR_BUILTINTYPES_H

View File

@ -14,6 +14,7 @@
#ifndef MLIR_IR_FUNCTIONSUPPORT_H
#define MLIR_IR_FUNCTIONSUPPORT_H
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "llvm/ADT/SmallString.h"

View File

@ -15,8 +15,8 @@
#ifndef MLIR_MATCHERS_H
#define MLIR_MATCHERS_H
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"
namespace mlir {

View File

@ -13,6 +13,7 @@
#ifndef MLIR_IR_OPIMPLEMENTATION_H
#define MLIR_IR_OPIMPLEMENTATION_H
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectInterface.h"
#include "mlir/IR/OpDefinition.h"
#include "llvm/ADT/Twine.h"

View File

@ -9,747 +9,8 @@
#ifndef MLIR_IR_STANDARDTYPES_H
#define MLIR_IR_STANDARDTYPES_H
#include "mlir/IR/Types.h"
namespace llvm {
struct fltSemantics;
} // namespace llvm
namespace mlir {
class AffineExpr;
class AffineMap;
class FloatType;
class IndexType;
class IntegerType;
class Location;
class MLIRContext;
namespace detail {
struct IntegerTypeStorage;
struct ShapedTypeStorage;
struct VectorTypeStorage;
struct RankedTensorTypeStorage;
struct UnrankedTensorTypeStorage;
struct BaseMemRefTypeStorage;
struct MemRefTypeStorage;
struct UnrankedMemRefTypeStorage;
struct ComplexTypeStorage;
struct TupleTypeStorage;
} // namespace detail
//===----------------------------------------------------------------------===//
// ComplexType
//===----------------------------------------------------------------------===//
/// The 'complex' type represents a complex number with a parameterized element
/// type, which is composed of a real and imaginary value of that element type.
///
/// The element must be a floating point or integer scalar type.
///
class ComplexType
: public Type::TypeBase<ComplexType, Type, detail::ComplexTypeStorage> {
public:
using Base::Base;
/// Get or create a ComplexType with the provided element type.
static ComplexType get(Type elementType);
/// Get or create a ComplexType with the provided element type. This emits
/// and error at the specified location and returns null if the element type
/// isn't supported.
static ComplexType getChecked(Type elementType, Location location);
/// Verify the construction of an integer type.
static LogicalResult verifyConstructionInvariants(Location loc,
Type elementType);
Type getElementType();
};
//===----------------------------------------------------------------------===//
// IndexType
//===----------------------------------------------------------------------===//
/// Index is a special integer-like type with unknown platform-dependent bit
/// width.
class IndexType : public Type::TypeBase<IndexType, Type, TypeStorage> {
public:
using Base::Base;
/// Get an instance of the IndexType.
static IndexType get(MLIRContext *context);
/// Storage bit width used for IndexType by internal compiler data structures.
static constexpr unsigned kInternalStorageBitWidth = 64;
};
//===----------------------------------------------------------------------===//
// IntegerType
//===----------------------------------------------------------------------===//
/// Integer types can have arbitrary bitwidth up to a large fixed limit.
class IntegerType
: public Type::TypeBase<IntegerType, Type, detail::IntegerTypeStorage> {
public:
using Base::Base;
/// Signedness semantics.
enum SignednessSemantics : uint32_t {
Signless, /// No signedness semantics
Signed, /// Signed integer
Unsigned, /// Unsigned integer
};
/// Get or create a new IntegerType of the given width within the context.
/// The created IntegerType is signless (i.e., no signedness semantics).
/// Assume the width is within the allowed range and assert on failures. Use
/// getChecked to handle failures gracefully.
static IntegerType get(unsigned width, MLIRContext *context);
/// Get or create a new IntegerType of the given width within the context.
/// The created IntegerType has signedness semantics as indicated via
/// `signedness`. Assume the width is within the allowed range and assert on
/// failures. Use getChecked to handle failures gracefully.
static IntegerType get(unsigned width, SignednessSemantics signedness,
MLIRContext *context);
/// Get or create a new IntegerType of the given width within the context,
/// defined at the given, potentially unknown, location. The created
/// IntegerType is signless (i.e., no signedness semantics). If the width is
/// outside the allowed range, emit errors and return a null type.
static IntegerType getChecked(unsigned width, Location location);
/// Get or create a new IntegerType of the given width within the context,
/// defined at the given, potentially unknown, location. The created
/// IntegerType has signedness semantics as indicated via `signedness`. If the
/// width is outside the allowed range, emit errors and return a null type.
static IntegerType getChecked(unsigned width, SignednessSemantics signedness,
Location location);
/// Verify the construction of an integer type.
static LogicalResult
verifyConstructionInvariants(Location loc, unsigned width,
SignednessSemantics signedness);
/// Return the bitwidth of this integer type.
unsigned getWidth() const;
/// Return the signedness semantics of this integer type.
SignednessSemantics getSignedness() const;
/// Return true if this is a signless integer type.
bool isSignless() const { return getSignedness() == Signless; }
/// Return true if this is a signed integer type.
bool isSigned() const { return getSignedness() == Signed; }
/// Return true if this is an unsigned integer type.
bool isUnsigned() const { return getSignedness() == Unsigned; }
/// Integer representation maximal bitwidth.
static constexpr unsigned kMaxWidth = 4096;
};
//===----------------------------------------------------------------------===//
// FloatType
//===----------------------------------------------------------------------===//
class FloatType : public Type {
public:
using Type::Type;
// Convenience factories.
static FloatType getBF16(MLIRContext *ctx);
static FloatType getF16(MLIRContext *ctx);
static FloatType getF32(MLIRContext *ctx);
static FloatType getF64(MLIRContext *ctx);
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(Type type);
/// Return the bitwidth of this float type.
unsigned getWidth();
/// Return the floating semantics of this float type.
const llvm::fltSemantics &getFloatSemantics();
};
//===----------------------------------------------------------------------===//
// BFloat16Type
class BFloat16Type
: public Type::TypeBase<BFloat16Type, FloatType, TypeStorage> {
public:
using Base::Base;
/// Return an instance of the bfloat16 type.
static BFloat16Type get(MLIRContext *context);
};
inline FloatType FloatType::getBF16(MLIRContext *ctx) {
return BFloat16Type::get(ctx);
}
//===----------------------------------------------------------------------===//
// Float16Type
class Float16Type : public Type::TypeBase<Float16Type, FloatType, TypeStorage> {
public:
using Base::Base;
/// Return an instance of the float16 type.
static Float16Type get(MLIRContext *context);
};
inline FloatType FloatType::getF16(MLIRContext *ctx) {
return Float16Type::get(ctx);
}
//===----------------------------------------------------------------------===//
// Float32Type
class Float32Type : public Type::TypeBase<Float32Type, FloatType, TypeStorage> {
public:
using Base::Base;
/// Return an instance of the float32 type.
static Float32Type get(MLIRContext *context);
};
inline FloatType FloatType::getF32(MLIRContext *ctx) {
return Float32Type::get(ctx);
}
//===----------------------------------------------------------------------===//
// Float64Type
class Float64Type : public Type::TypeBase<Float64Type, FloatType, TypeStorage> {
public:
using Base::Base;
/// Return an instance of the float64 type.
static Float64Type get(MLIRContext *context);
};
inline FloatType FloatType::getF64(MLIRContext *ctx) {
return Float64Type::get(ctx);
}
//===----------------------------------------------------------------------===//
// NoneType
//===----------------------------------------------------------------------===//
/// NoneType is a unit type, i.e. a type with exactly one possible value, where
/// its value does not have a defined dynamic representation.
class NoneType : public Type::TypeBase<NoneType, Type, TypeStorage> {
public:
using Base::Base;
/// Get an instance of the NoneType.
static NoneType get(MLIRContext *context);
};
//===----------------------------------------------------------------------===//
// ShapedType
//===----------------------------------------------------------------------===//
/// This is a common base class between Vector, UnrankedTensor, RankedTensor,
/// and MemRef types because they share behavior and semantics around shape,
/// rank, and fixed element type. Any type with these semantics should inherit
/// from ShapedType.
class ShapedType : public Type {
public:
using ImplType = detail::ShapedTypeStorage;
using Type::Type;
// TODO: merge these two special values in a single one used everywhere.
// Unfortunately, uses of `-1` have crept deep into the codebase now and are
// hard to track.
static constexpr int64_t kDynamicSize = -1;
static constexpr int64_t kDynamicStrideOrOffset =
std::numeric_limits<int64_t>::min();
/// Return the element type.
Type getElementType() const;
/// If an element type is an integer or a float, return its width. Otherwise,
/// abort.
unsigned getElementTypeBitWidth() const;
/// If it has static shape, return the number of elements. Otherwise, abort.
int64_t getNumElements() const;
/// If this is a ranked type, return the rank. Otherwise, abort.
int64_t getRank() const;
/// Whether or not this is a ranked type. Memrefs, vectors and ranked tensors
/// have a rank, while unranked tensors do not.
bool hasRank() const;
/// If this is a ranked type, return the shape. Otherwise, abort.
ArrayRef<int64_t> getShape() const;
/// If this is unranked type or any dimension has unknown size (<0), it
/// doesn't have static shape. If all dimensions have known size (>= 0), it
/// has static shape.
bool hasStaticShape() const;
/// If this has a static shape and the shape is equal to `shape` return true.
bool hasStaticShape(ArrayRef<int64_t> shape) const;
/// If this is a ranked type, return the number of dimensions with dynamic
/// size. Otherwise, abort.
int64_t getNumDynamicDims() const;
/// If this is ranked type, return the size of the specified dimension.
/// Otherwise, abort.
int64_t getDimSize(unsigned idx) const;
/// Returns true if this dimension has a dynamic size (for ranked types);
/// aborts for unranked types.
bool isDynamicDim(unsigned idx) const;
/// Returns the position of the dynamic dimension relative to just the dynamic
/// dimensions, given its `index` within the shape.
unsigned getDynamicDimIndex(unsigned index) const;
/// Get the total amount of bits occupied by a value of this type. This does
/// not take into account any memory layout or widening constraints, e.g. a
/// vector<3xi57> is reported to occupy 3x57=171 bit, even though in practice
/// it will likely be stored as in a 4xi64 vector register. Fail an assertion
/// if the size cannot be computed statically, i.e. if the type has a dynamic
/// shape or if its elemental type does not have a known bit width.
int64_t getSizeInBits() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(Type type);
/// Whether the given dimension size indicates a dynamic dimension.
static constexpr bool isDynamic(int64_t dSize) {
return dSize == kDynamicSize;
}
static constexpr bool isDynamicStrideOrOffset(int64_t dStrideOrOffset) {
return dStrideOrOffset == kDynamicStrideOrOffset;
}
};
//===----------------------------------------------------------------------===//
// VectorType
//===----------------------------------------------------------------------===//
/// Vector types represent multi-dimensional SIMD vectors, and have a fixed
/// known constant shape with one or more dimension.
class VectorType
: public Type::TypeBase<VectorType, ShapedType, detail::VectorTypeStorage> {
public:
using Base::Base;
/// Get or create a new VectorType of the provided shape and element type.
/// Assumes the arguments define a well-formed VectorType.
static VectorType get(ArrayRef<int64_t> shape, Type elementType);
/// Get or create a new VectorType of the provided shape and element type
/// declared at the given, potentially unknown, location. If the VectorType
/// defined by the arguments would be ill-formed, emit errors and return
/// nullptr-wrapping type.
static VectorType getChecked(ArrayRef<int64_t> shape, Type elementType,
Location location);
/// Verify the construction of a vector type.
static LogicalResult verifyConstructionInvariants(Location loc,
ArrayRef<int64_t> shape,
Type elementType);
/// Returns true of the given type can be used as an element of a vector type.
/// In particular, vectors can consist of integer or float primitives.
static bool isValidElementType(Type t) {
return t.isa<IntegerType, FloatType>();
}
ArrayRef<int64_t> getShape() const;
};
//===----------------------------------------------------------------------===//
// TensorType
//===----------------------------------------------------------------------===//
/// Tensor types represent multi-dimensional arrays, and have two variants:
/// RankedTensorType and UnrankedTensorType.
class TensorType : public ShapedType {
public:
using ShapedType::ShapedType;
/// Return true if the specified element type is ok in a tensor.
static bool isValidElementType(Type type);
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(Type type);
};
//===----------------------------------------------------------------------===//
// RankedTensorType
/// Ranked tensor types represent multi-dimensional arrays that have a shape
/// with a fixed number of dimensions. Each shape element can be a non-negative
/// integer or unknown (represented by -1).
class RankedTensorType
: public Type::TypeBase<RankedTensorType, TensorType,
detail::RankedTensorTypeStorage> {
public:
using Base::Base;
/// Get or create a new RankedTensorType of the provided shape and element
/// type. Assumes the arguments define a well-formed type.
static RankedTensorType get(ArrayRef<int64_t> shape, Type elementType);
/// Get or create a new RankedTensorType of the provided shape and element
/// type declared at the given, potentially unknown, location. If the
/// RankedTensorType defined by the arguments would be ill-formed, emit errors
/// and return a nullptr-wrapping type.
static RankedTensorType getChecked(ArrayRef<int64_t> shape, Type elementType,
Location location);
/// Verify the construction of a ranked tensor type.
static LogicalResult verifyConstructionInvariants(Location loc,
ArrayRef<int64_t> shape,
Type elementType);
ArrayRef<int64_t> getShape() const;
};
//===----------------------------------------------------------------------===//
// UnrankedTensorType
/// Unranked tensor types represent multi-dimensional arrays that have an
/// unknown shape.
class UnrankedTensorType
: public Type::TypeBase<UnrankedTensorType, TensorType,
detail::UnrankedTensorTypeStorage> {
public:
using Base::Base;
/// Get or create a new UnrankedTensorType of the provided shape and element
/// type. Assumes the arguments define a well-formed type.
static UnrankedTensorType get(Type elementType);
/// Get or create a new UnrankedTensorType of the provided shape and element
/// type declared at the given, potentially unknown, location. If the
/// UnrankedTensorType defined by the arguments would be ill-formed, emit
/// errors and return a nullptr-wrapping type.
static UnrankedTensorType getChecked(Type elementType, Location location);
/// Verify the construction of a unranked tensor type.
static LogicalResult verifyConstructionInvariants(Location loc,
Type elementType);
ArrayRef<int64_t> getShape() const { return llvm::None; }
};
//===----------------------------------------------------------------------===//
// BaseMemRefType
//===----------------------------------------------------------------------===//
/// Base MemRef for Ranked and Unranked variants
class BaseMemRefType : public ShapedType {
public:
using ImplType = detail::BaseMemRefTypeStorage;
using ShapedType::ShapedType;
/// Return true if the specified element type is ok in a memref.
static bool isValidElementType(Type type) {
return type.isIntOrIndexOrFloat() || type.isa<VectorType, ComplexType>();
}
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(Type type);
/// Returns the memory space in which data referred to by this memref resides.
unsigned getMemorySpace() const;
};
//===----------------------------------------------------------------------===//
// MemRefType
/// MemRef types represent a region of memory that have a shape with a fixed
/// number of dimensions. Each shape element can be a non-negative integer or
/// unknown (represented by -1). MemRef types also have an affine map
/// composition, represented as an array AffineMap pointers.
class MemRefType : public Type::TypeBase<MemRefType, BaseMemRefType,
detail::MemRefTypeStorage> {
public:
/// This is a builder type that keeps local references to arguments. Arguments
/// that are passed into the builder must out-live the builder.
class Builder {
public:
// Build from another MemRefType.
explicit Builder(MemRefType other)
: shape(other.getShape()), elementType(other.getElementType()),
affineMaps(other.getAffineMaps()),
memorySpace(other.getMemorySpace()) {}
// Build from scratch.
Builder(ArrayRef<int64_t> shape, Type elementType)
: shape(shape), elementType(elementType), affineMaps(), memorySpace(0) {
}
Builder &setShape(ArrayRef<int64_t> newShape) {
shape = newShape;
return *this;
}
Builder &setElementType(Type newElementType) {
elementType = newElementType;
return *this;
}
Builder &setAffineMaps(ArrayRef<AffineMap> newAffineMaps) {
affineMaps = newAffineMaps;
return *this;
}
Builder &setMemorySpace(unsigned newMemorySpace) {
memorySpace = newMemorySpace;
return *this;
}
operator MemRefType() {
return MemRefType::get(shape, elementType, affineMaps, memorySpace);
}
private:
ArrayRef<int64_t> shape;
Type elementType;
ArrayRef<AffineMap> affineMaps;
unsigned memorySpace;
};
using Base::Base;
/// Get or create a new MemRefType based on shape, element type, affine
/// map composition, and memory space. Assumes the arguments define a
/// well-formed MemRef type. Use getChecked to gracefully handle MemRefType
/// construction failures.
static MemRefType get(ArrayRef<int64_t> shape, Type elementType,
ArrayRef<AffineMap> affineMapComposition = {},
unsigned memorySpace = 0);
/// Get or create a new MemRefType based on shape, element type, affine
/// map composition, and memory space declared at the given location.
/// If the location is unknown, the last argument should be an instance of
/// UnknownLoc. If the MemRefType defined by the arguments would be
/// ill-formed, emits errors (to the handler registered with the context or to
/// the error stream) and returns nullptr.
static MemRefType getChecked(ArrayRef<int64_t> shape, Type elementType,
ArrayRef<AffineMap> affineMapComposition,
unsigned memorySpace, Location location);
ArrayRef<int64_t> getShape() const;
/// Returns an array of affine map pointers representing the memref affine
/// map composition.
ArrayRef<AffineMap> getAffineMaps() const;
// TODO: merge these two special values in a single one used everywhere.
// Unfortunately, uses of `-1` have crept deep into the codebase now and are
// hard to track.
static int64_t getDynamicStrideOrOffset() {
return ShapedType::kDynamicStrideOrOffset;
}
private:
/// Get or create a new MemRefType defined by the arguments. If the resulting
/// type would be ill-formed, return nullptr. If the location is provided,
/// emit detailed error messages.
static MemRefType getImpl(ArrayRef<int64_t> shape, Type elementType,
ArrayRef<AffineMap> affineMapComposition,
unsigned memorySpace, Optional<Location> location);
using Base::getImpl;
};
//===----------------------------------------------------------------------===//
// UnrankedMemRefType
/// Unranked MemRef type represent multi-dimensional MemRefs that
/// have an unknown rank.
class UnrankedMemRefType
: public Type::TypeBase<UnrankedMemRefType, BaseMemRefType,
detail::UnrankedMemRefTypeStorage> {
public:
using Base::Base;
/// Get or create a new UnrankedMemRefType of the provided element
/// type and memory space
static UnrankedMemRefType get(Type elementType, unsigned memorySpace);
/// Get or create a new UnrankedMemRefType of the provided element
/// type and memory space declared at the given, potentially unknown,
/// location. If the UnrankedMemRefType defined by the arguments would be
/// ill-formed, emit errors and return a nullptr-wrapping type.
static UnrankedMemRefType getChecked(Type elementType, unsigned memorySpace,
Location location);
/// Verify the construction of a unranked memref type.
static LogicalResult verifyConstructionInvariants(Location loc,
Type elementType,
unsigned memorySpace);
ArrayRef<int64_t> getShape() const { return llvm::None; }
};
//===----------------------------------------------------------------------===//
// TupleType
//===----------------------------------------------------------------------===//
/// Tuple types represent a collection of other types. Note: This type merely
/// provides a common mechanism for representing tuples in MLIR. It is up to
/// dialect authors to provides operations for manipulating them, e.g.
/// extract_tuple_element. When possible, users should prefer multi-result
/// operations in the place of tuples.
class TupleType
: public Type::TypeBase<TupleType, Type, detail::TupleTypeStorage> {
public:
using Base::Base;
/// Get or create a new TupleType with the provided element types. Assumes the
/// arguments define a well-formed type.
static TupleType get(TypeRange elementTypes, MLIRContext *context);
/// Get or create an empty tuple type.
static TupleType get(MLIRContext *context);
/// Return the elements types for this tuple.
ArrayRef<Type> getTypes() const;
/// Accumulate the types contained in this tuple and tuples nested within it.
/// Note that this only flattens nested tuples, not any other container type,
/// e.g. a tuple<i32, tensor<i32>, tuple<f32, tuple<i64>>> is flattened to
/// (i32, tensor<i32>, f32, i64)
void getFlattenedTypes(SmallVectorImpl<Type> &types);
/// Return the number of held types.
size_t size() const;
/// Iterate over the held elements.
using iterator = ArrayRef<Type>::iterator;
iterator begin() const { return getTypes().begin(); }
iterator end() const { return getTypes().end(); }
/// Return the element type at index 'index'.
Type getType(size_t index) const {
assert(index < size() && "invalid index for tuple type");
return getTypes()[index];
}
};
//===----------------------------------------------------------------------===//
// Deferred Method Definitions
//===----------------------------------------------------------------------===//
inline bool BaseMemRefType::classof(Type type) {
return type.isa<MemRefType, UnrankedMemRefType>();
}
inline bool FloatType::classof(Type type) {
return type.isa<BFloat16Type, Float16Type, Float32Type, Float64Type>();
}
inline bool ShapedType::classof(Type type) {
return type.isa<RankedTensorType, VectorType, UnrankedTensorType,
UnrankedMemRefType, MemRefType>();
}
inline bool TensorType::classof(Type type) {
return type.isa<RankedTensorType, UnrankedTensorType>();
}
//===----------------------------------------------------------------------===//
// Type Utilities
//===----------------------------------------------------------------------===//
/// Returns the strides of the MemRef if the layout map is in strided form.
/// MemRefs with layout maps in strided form include:
/// 1. empty or identity layout map, in which case the stride information is
/// the canonical form computed from sizes;
/// 2. single affine map layout of the form `K + k0 * d0 + ... kn * dn`,
/// where K and ki's are constants or symbols.
///
/// A stride specification is a list of integer values that are either static
/// or dynamic (encoded with getDynamicStrideOrOffset()). Strides encode the
/// distance in the number of elements between successive entries along a
/// particular dimension. For example, `memref<42x16xf32, (64 * d0 + d1)>`
/// specifies a view into a non-contiguous memory region of `42` by `16` `f32`
/// elements in which the distance between two consecutive elements along the
/// outer dimension is `1` and the distance between two consecutive elements
/// along the inner dimension is `64`.
///
/// Returns whether a simple strided form can be extracted from the composition
/// of the layout map.
///
/// The convention is that the strides for dimensions d0, .. dn appear in
/// order to make indexing intuitive into the result.
LogicalResult getStridesAndOffset(MemRefType t,
SmallVectorImpl<int64_t> &strides,
int64_t &offset);
LogicalResult getStridesAndOffset(MemRefType t,
SmallVectorImpl<AffineExpr> &strides,
AffineExpr &offset);
/// Given a list of strides (in which MemRefType::getDynamicStrideOrOffset()
/// represents a dynamic value), return the single result AffineMap which
/// represents the linearized strided layout map. Dimensions correspond to the
/// offset followed by the strides in order. Symbols are inserted for each
/// dynamic dimension in order. A stride cannot take value `0`.
///
/// Examples:
/// =========
///
/// 1. For offset: 0 strides: ?, ?, 1 return
/// (i, j, k)[M, N]->(M * i + N * j + k)
///
/// 2. For offset: 3 strides: 32, ?, 16 return
/// (i, j, k)[M]->(3 + 32 * i + M * j + 16 * k)
///
/// 3. For offset: ? strides: ?, ?, ? return
/// (i, j, k)[off, M, N, P]->(off + M * i + N * j + P * k)
AffineMap makeStridedLinearLayoutMap(ArrayRef<int64_t> strides, int64_t offset,
MLIRContext *context);
/// Return a version of `t` with identity layout if it can be determined
/// statically that the layout is the canonical contiguous strided layout.
/// Otherwise pass `t`'s layout into `simplifyAffineMap` and return a copy of
/// `t` with simplified layout.
MemRefType canonicalizeStridedLayout(MemRefType t);
/// Return a version of `t` with a layout that has all dynamic offset and
/// strides. This is used to erase the static layout.
MemRefType eraseStridedLayout(MemRefType t);
/// Given MemRef `sizes` that are either static or dynamic, returns the
/// canonical "contiguous" strides AffineExpr. Strides are multiplicative and
/// once a dynamic dimension is encountered, all canonical strides become
/// dynamic and need to be encoded with a different symbol.
/// For canonical strides expressions, the offset is always 0 and and fastest
/// varying stride is always `1`.
///
/// Examples:
/// - memref<3x4x5xf32> has canonical stride expression
/// `20*exprs[0] + 5*exprs[1] + exprs[2]`.
/// - memref<3x?x5xf32> has canonical stride expression
/// `s0*exprs[0] + 5*exprs[1] + exprs[2]`.
/// - memref<3x4x?xf32> has canonical stride expression
/// `s1*exprs[0] + s0*exprs[1] + exprs[2]`.
AffineExpr makeCanonicalStridedLayoutExpr(ArrayRef<int64_t> sizes,
ArrayRef<AffineExpr> exprs,
MLIRContext *context);
/// Return the result of makeCanonicalStrudedLayoutExpr for the common case
/// where `exprs` is {d0, d1, .., d_(sizes.size()-1)}
AffineExpr makeCanonicalStridedLayoutExpr(ArrayRef<int64_t> sizes,
MLIRContext *context);
/// Return true if the layout for `t` is compatible with strided semantics.
bool isStrided(MemRefType t);
} // end namespace mlir
/// TODO: Remove this file when all references have been replaced by
/// BuiltinTypes.h.
#include "mlir/IR/BuiltinTypes.h"
#endif // MLIR_IR_STANDARDTYPES_H

View File

@ -15,19 +15,6 @@
#include "llvm/Support/PointerLikeTypeTraits.h"
namespace mlir {
class FloatType;
class Identifier;
class IndexType;
class IntegerType;
class MLIRContext;
class TypeStorage;
class TypeRange;
namespace detail {
struct FunctionTypeStorage;
struct OpaqueTypeStorage;
} // namespace detail
/// Instances of the Type class are uniqued, have an immutable identifier and an
/// optional mutable component. They wrap a pointer to the storage object owned
/// by MLIRContext. Therefore, instances of Type are passed around by value.
@ -226,67 +213,9 @@ private:
};
//===----------------------------------------------------------------------===//
// FunctionType
// Type Utils
//===----------------------------------------------------------------------===//
/// Function types map from a list of inputs to a list of results.
class FunctionType
: public Type::TypeBase<FunctionType, Type, detail::FunctionTypeStorage> {
public:
using Base::Base;
static FunctionType get(TypeRange inputs, TypeRange results,
MLIRContext *context);
/// Input types.
unsigned getNumInputs() const;
Type getInput(unsigned i) const { return getInputs()[i]; }
ArrayRef<Type> getInputs() const;
/// Result types.
unsigned getNumResults() const;
Type getResult(unsigned i) const { return getResults()[i]; }
ArrayRef<Type> getResults() const;
/// Returns a new function type without the specified arguments and results.
FunctionType getWithoutArgsAndResults(ArrayRef<unsigned> argIndices,
ArrayRef<unsigned> resultIndices);
};
//===----------------------------------------------------------------------===//
// OpaqueType
//===----------------------------------------------------------------------===//
/// Opaque types represent types of non-registered dialects. These are types
/// represented in their raw string form, and can only usefully be tested for
/// type equality.
class OpaqueType
: public Type::TypeBase<OpaqueType, Type, detail::OpaqueTypeStorage> {
public:
using Base::Base;
/// Get or create a new OpaqueType with the provided dialect and string data.
static OpaqueType get(Identifier dialect, StringRef typeData,
MLIRContext *context);
/// Get or create a new OpaqueType with the provided dialect and string data.
/// If the given identifier is not a valid namespace for a dialect, then a
/// null type is returned.
static OpaqueType getChecked(Identifier dialect, StringRef typeData,
MLIRContext *context, Location location);
/// Returns the dialect namespace of the opaque type.
Identifier getDialectNamespace() const;
/// Returns the raw type data of the opaque type.
StringRef getTypeData() const;
/// Verify the construction of an opaque type.
static LogicalResult verifyConstructionInvariants(Location loc,
Identifier dialect,
StringRef typeData);
};
// Make Type hashable.
inline ::llvm::hash_code hash_value(Type arg) {
return ::llvm::hash_value(arg.impl);

View File

@ -14,8 +14,8 @@
#define MLIR_INTERFACES_VECTORINTERFACES_H
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"
/// Include the generated interface declarations.
#include "mlir/Interfaces/VectorInterfaces.h.inc"

View File

@ -14,8 +14,8 @@
#define MLIR_INTERFACES_VIEWLIKEINTERFACE_H_
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
namespace mlir {
/// Auxiliary range data structure to unpack the offset, size and stride

View File

@ -12,9 +12,9 @@
#include "PybindUtils.h"
#include "mlir-c/Bindings/Python/Interop.h"
#include "mlir-c/BuiltinTypes.h"
#include "mlir-c/Registration.h"
#include "mlir-c/StandardAttributes.h"
#include "mlir-c/StandardTypes.h"
#include "llvm/ADT/SmallVector.h"
#include <pybind11/stl.h>
@ -1923,7 +1923,7 @@ public:
} // namespace
//------------------------------------------------------------------------------
// Standard type subclasses.
// Builtin type subclasses.
//------------------------------------------------------------------------------
namespace {
@ -3105,7 +3105,7 @@ void mlir::python::populateIRSubmodule(py::module &m) {
return printAccum.join();
});
// Standard type bindings.
// Builtin type bindings.
PyIntegerType::bind(m);
PyIndexType::bind(m);
PyBF16Type::bind(m);

View File

@ -1,4 +1,4 @@
//===- StandardTypes.cpp - C Interface to MLIR Standard Types -------------===//
//===- BuiltinTypes.cpp - C Interface to MLIR Builtin Types ---------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@ -6,13 +6,13 @@
//
//===----------------------------------------------------------------------===//
#include "mlir-c/StandardTypes.h"
#include "mlir-c/BuiltinTypes.h"
#include "mlir-c/AffineMap.h"
#include "mlir-c/IR.h"
#include "mlir/CAPI/AffineMap.h"
#include "mlir/CAPI/IR.h"
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Types.h"
using namespace mlir;

View File

@ -2,11 +2,11 @@
add_mlir_public_c_api_library(MLIRCAPIIR
AffineExpr.cpp
AffineMap.cpp
BuiltinTypes.cpp
Diagnostics.cpp
IR.cpp
Pass.cpp
StandardAttributes.cpp
StandardTypes.cpp
Support.cpp
LINK_LIBS PUBLIC

View File

@ -11,7 +11,7 @@
#include "mlir/CAPI/IR.h"
#include "mlir/CAPI/Support.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
using namespace mlir;

View File

@ -22,7 +22,7 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/DataLayout.h"

View File

@ -23,7 +23,7 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
using namespace mlir;

View File

@ -26,10 +26,10 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Types.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Transforms/DialectConversion.h"

View File

@ -109,7 +109,7 @@ LLVMTypeConverter::LLVMTypeConverter(MLIRContext *ctx,
if (options.indexBitwidth == kDeriveIndexBitwidthFromDataLayout)
this->options.indexBitwidth = options.dataLayout.getPointerSizeInBits();
// Register conversions for the standard types.
// Register conversions for the builtin types.
addConversion([&](ComplexType type) { return convertComplexType(type); });
addConversion([&](FloatType type) { return convertFloatType(type); });
addConversion([&](FunctionType type) { return convertFunctionType(type); });
@ -430,7 +430,7 @@ Type LLVMTypeConverter::convertCallingConventionType(Type type) {
/// Promote the bare pointers in 'values' that resulted from memrefs to
/// descriptors. 'stdTypes' holds they types of 'values' before the conversion
/// to the LLVM-IR dialect (i.e., MemRefType, or any other Standard type).
/// to the LLVM-IR dialect (i.e., MemRefType, or any other builtin type).
void LLVMTypeConverter::promoteBarePtrsToDescriptors(
ConversionPatternRewriter &rewriter, Location loc, ArrayRef<Type> stdTypes,
SmallVectorImpl<Value> &values) {

View File

@ -647,8 +647,8 @@ LogicalResult ConstantCompositeOpPattern::matchAndRewrite(
}
// Unfortunately, we cannot use dialect-specific types for element
// attributes; element attributes only works with standard types. So we need
// to prepare another converted standard types for the destination elements
// attributes; element attributes only works with builtin types. So we need
// to prepare another converted builtin types for the destination elements
// attribute.
if (dstAttrType.isa<RankedTensorType>())
dstAttrType = RankedTensorType::get(dstAttrType.getShape(), dstElemType);

View File

@ -17,7 +17,7 @@
#include "mlir/Dialect/SPIRV/SPIRVDialect.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/Dialect/Vector/VectorOps.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
using namespace mlir;

View File

@ -13,7 +13,7 @@
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/Dialect/Vector/VectorOps.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/Target/LLVMIR/TypeTranslation.h"
#include "mlir/Transforms/DialectConversion.h"

View File

@ -17,11 +17,11 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/FunctionImplementation.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/ADT/TypeSwitch.h"
using namespace mlir;

View File

@ -14,10 +14,10 @@
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/FunctionImplementation.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/AsmParser/Parser.h"

View File

@ -17,10 +17,10 @@
#include "mlir/Dialect/LLVMIR/NVVMDialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/OperationSupport.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"

View File

@ -18,9 +18,9 @@
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"

View File

@ -12,9 +12,9 @@
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Parser.h"
#include "mlir/Support/LLVM.h"
#include "mlir/Transforms/InliningUtils.h"

View File

@ -9,8 +9,8 @@
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "mlir/Dialect/OpenACC/OpenACCOpsEnums.cpp.inc"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
using namespace mlir;
using namespace acc;

View File

@ -8,8 +8,8 @@
#include "mlir/Dialect/PDL/IR/PDL.h"
#include "mlir/Dialect/PDL/IR/PDLTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/InferTypeOpInterface.h"
#include "llvm/ADT/StringSwitch.h"

View File

@ -8,8 +8,8 @@
#include "mlir/Dialect/PDLInterp/IR/PDLInterp.h"
#include "mlir/Dialect/PDL/IR/PDLTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/StandardTypes.h"
using namespace mlir;
using namespace mlir::pdl_interp;

View File

@ -10,10 +10,10 @@
#include "TypeDetail.h"
#include "mlir/Dialect/Quant/QuantTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Matchers.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MathExtras.h"

View File

@ -10,8 +10,8 @@
#include "TypeDetail.h"
#include "mlir/Dialect/Quant/QuantOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MathExtras.h"

View File

@ -9,7 +9,7 @@
#ifndef TYPE_DETAIL_H_
#define TYPE_DETAIL_H_
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/TypeSupport.h"
#include "mlir/IR/Types.h"
#include "llvm/ADT/DenseMap.h"

View File

@ -8,9 +8,9 @@
#include "mlir/Dialect/Quant/QuantOps.h"
#include "mlir/Dialect/Quant/QuantTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Types.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/StringSwitch.h"

View File

@ -12,8 +12,8 @@
#include "mlir/Dialect/Quant/QuantizeUtils.h"
#include "mlir/Dialect/Quant/UniformSupport.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Matchers.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
using namespace mlir;

View File

@ -11,7 +11,7 @@
#include "mlir/Dialect/Quant/Passes.h"
#include "mlir/Dialect/Quant/QuantOps.h"
#include "mlir/Dialect/Quant/UniformSupport.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
using namespace mlir;

View File

@ -9,7 +9,7 @@
#include "mlir/Dialect/Quant/QuantizeUtils.h"
#include "mlir/Dialect/Quant/UniformSupport.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
using namespace mlir;
using namespace mlir::quant;

View File

@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/Quant/UniformSupport.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include <numeric>
using namespace mlir;

View File

@ -16,9 +16,9 @@
#include "mlir/Dialect/SPIRV/SPIRVTypes.h"
#include "mlir/Dialect/SPIRV/TargetAndABI.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Parser.h"
#include "mlir/Transforms/InliningUtils.h"
#include "llvm/ADT/DenseMap.h"

View File

@ -414,7 +414,7 @@ SPIRVTypeConverter::SPIRVTypeConverter(spirv::TargetEnvAttr targetAttr)
// All other cases failed. Then we cannot convert this type.
addConversion([](Type type) { return llvm::None; });
// Allow all SPIR-V dialect specific types. This assumes all standard types
// Allow all SPIR-V dialect specific types. This assumes all builtin types
// adopted in the SPIR-V dialect (i.e., IntegerType, FloatType, VectorType)
// were tried before.
//

View File

@ -19,9 +19,9 @@
#include "mlir/Dialect/SPIRV/TargetAndABI.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/FunctionImplementation.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Interfaces/CallInterfaces.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/bit.h"

View File

@ -13,8 +13,8 @@
#include "mlir/Dialect/SPIRV/SPIRVTypes.h"
#include "mlir/Dialect/SPIRV/SPIRVDialect.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Identifier.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"

View File

@ -11,9 +11,9 @@
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/Dialect/Traits.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Transforms/InliningUtils.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/TypeSwitch.h"

View File

@ -14,10 +14,10 @@
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Matchers.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/TypeUtilities.h"
#include "mlir/IR/Value.h"
#include "mlir/Support/MathExtras.h"

View File

@ -15,7 +15,7 @@
#include "mlir/Dialect/Tosa/IR/TosaOps.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/Dialect/Tosa/Utils/QuantUtils.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/Transforms/FoldUtils.h"
#include "mlir/Transforms/InliningUtils.h"
#include "mlir/Transforms/RegionUtils.h"

View File

@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/Traits.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/TypeUtilities.h"
#include "llvm/Support/FormatVariadic.h"

View File

@ -19,8 +19,8 @@
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/ExecutionEngine/ExecutionEngine.h"
#include "mlir/ExecutionEngine/OptUtils.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/InitAllDialects.h"
#include "mlir/Parser.h"
#include "mlir/Support/FileUtilities.h"

View File

@ -9,7 +9,7 @@
#include "mlir/IR/AffineMap.h"
#include "AffineMapDetail.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Support/MathExtras.h"
#include "llvm/ADT/SmallSet.h"

View File

@ -15,13 +15,13 @@
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/IR/IntegerSet.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"

View File

@ -15,10 +15,10 @@
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Identifier.h"
#include "mlir/IR/IntegerSet.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Support/StorageUniquer.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/PointerIntPair.h"

View File

@ -10,11 +10,11 @@
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/IntegerSet.h"
#include "mlir/IR/Matchers.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/SymbolTable.h"
#include "llvm/Support/raw_ostream.h"
using namespace mlir;

View File

@ -15,9 +15,9 @@
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/FunctionImplementation.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/StandardTypes.h"
#include "llvm/ADT/MapVector.h"
using namespace mlir;

View File

@ -1,4 +1,4 @@
//===- StandardTypes.cpp - MLIR Standard Type Classes ---------------------===//
//===- BuiltinTypes.cpp - MLIR Builtin Type Classes -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@ -6,97 +6,19 @@
//
//===----------------------------------------------------------------------===//
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "TypeDetail.h"
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Dialect.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/Twine.h"
using namespace mlir;
using namespace mlir::detail;
//===----------------------------------------------------------------------===//
// Type
//===----------------------------------------------------------------------===//
bool Type::isBF16() const { return isa<BFloat16Type>(); }
bool Type::isF16() const { return isa<Float16Type>(); }
bool Type::isF32() const { return isa<Float32Type>(); }
bool Type::isF64() const { return isa<Float64Type>(); }
bool Type::isIndex() const { return isa<IndexType>(); }
/// Return true if this is an integer type with the specified width.
bool Type::isInteger(unsigned width) const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.getWidth() == width;
return false;
}
bool Type::isSignlessInteger() const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isSignless();
return false;
}
bool Type::isSignlessInteger(unsigned width) const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isSignless() && intTy.getWidth() == width;
return false;
}
bool Type::isSignedInteger() const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isSigned();
return false;
}
bool Type::isSignedInteger(unsigned width) const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isSigned() && intTy.getWidth() == width;
return false;
}
bool Type::isUnsignedInteger() const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isUnsigned();
return false;
}
bool Type::isUnsignedInteger(unsigned width) const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isUnsigned() && intTy.getWidth() == width;
return false;
}
bool Type::isSignlessIntOrIndex() const {
return isSignlessInteger() || isa<IndexType>();
}
bool Type::isSignlessIntOrIndexOrFloat() const {
return isSignlessInteger() || isa<IndexType, FloatType>();
}
bool Type::isSignlessIntOrFloat() const {
return isSignlessInteger() || isa<FloatType>();
}
bool Type::isIntOrIndex() const { return isa<IntegerType>() || isIndex(); }
bool Type::isIntOrFloat() const { return isa<IntegerType, FloatType>(); }
bool Type::isIntOrIndexOrFloat() const { return isIntOrFloat() || isIndex(); }
unsigned Type::getIntOrFloatBitWidth() const {
assert(isIntOrFloat() && "only integers and floats have a bitwidth");
if (auto intType = dyn_cast<IntegerType>())
return intType.getWidth();
return cast<FloatType>().getWidth();
}
//===----------------------------------------------------------------------===//
/// ComplexType
//===----------------------------------------------------------------------===//
@ -170,6 +92,100 @@ const llvm::fltSemantics &FloatType::getFloatSemantics() {
llvm_unreachable("non-floating point type used");
}
//===----------------------------------------------------------------------===//
// FunctionType
//===----------------------------------------------------------------------===//
FunctionType FunctionType::get(TypeRange inputs, TypeRange results,
MLIRContext *context) {
return Base::get(context, inputs, results);
}
unsigned FunctionType::getNumInputs() const { return getImpl()->numInputs; }
ArrayRef<Type> FunctionType::getInputs() const {
return getImpl()->getInputs();
}
unsigned FunctionType::getNumResults() const { return getImpl()->numResults; }
ArrayRef<Type> FunctionType::getResults() const {
return getImpl()->getResults();
}
/// Helper to call a callback once on each index in the range
/// [0, `totalIndices`), *except* for the indices given in `indices`.
/// `indices` is allowed to have duplicates and can be in any order.
inline void iterateIndicesExcept(unsigned totalIndices,
ArrayRef<unsigned> indices,
function_ref<void(unsigned)> callback) {
llvm::BitVector skipIndices(totalIndices);
for (unsigned i : indices)
skipIndices.set(i);
for (unsigned i = 0; i < totalIndices; ++i)
if (!skipIndices.test(i))
callback(i);
}
/// Returns a new function type without the specified arguments and results.
FunctionType
FunctionType::getWithoutArgsAndResults(ArrayRef<unsigned> argIndices,
ArrayRef<unsigned> resultIndices) {
ArrayRef<Type> newInputTypes = getInputs();
SmallVector<Type, 4> newInputTypesBuffer;
if (!argIndices.empty()) {
unsigned originalNumArgs = getNumInputs();
iterateIndicesExcept(originalNumArgs, argIndices, [&](unsigned i) {
newInputTypesBuffer.emplace_back(getInput(i));
});
newInputTypes = newInputTypesBuffer;
}
ArrayRef<Type> newResultTypes = getResults();
SmallVector<Type, 4> newResultTypesBuffer;
if (!resultIndices.empty()) {
unsigned originalNumResults = getNumResults();
iterateIndicesExcept(originalNumResults, resultIndices, [&](unsigned i) {
newResultTypesBuffer.emplace_back(getResult(i));
});
newResultTypes = newResultTypesBuffer;
}
return get(newInputTypes, newResultTypes, getContext());
}
//===----------------------------------------------------------------------===//
// OpaqueType
//===----------------------------------------------------------------------===//
OpaqueType OpaqueType::get(Identifier dialect, StringRef typeData,
MLIRContext *context) {
return Base::get(context, dialect, typeData);
}
OpaqueType OpaqueType::getChecked(Identifier dialect, StringRef typeData,
MLIRContext *context, Location location) {
return Base::getChecked(location, dialect, typeData);
}
/// Returns the dialect namespace of the opaque type.
Identifier OpaqueType::getDialectNamespace() const {
return getImpl()->dialectNamespace;
}
/// Returns the raw type data of the opaque type.
StringRef OpaqueType::getTypeData() const { return getImpl()->typeData; }
/// Verify the construction of an opaque type.
LogicalResult OpaqueType::verifyConstructionInvariants(Location loc,
Identifier dialect,
StringRef typeData) {
if (!Dialect::isValidNamespace(dialect.strref()))
return emitError(loc, "invalid dialect namespace '") << dialect << "'";
return success();
}
//===----------------------------------------------------------------------===//
// ShapedType
//===----------------------------------------------------------------------===//

View File

@ -6,6 +6,7 @@ add_mlir_library(MLIRIR
Block.cpp
Builders.cpp
BuiltinDialect.cpp
BuiltinTypes.cpp
Diagnostics.cpp
Dialect.cpp
Dominance.cpp
@ -19,7 +20,6 @@ add_mlir_library(MLIRIR
PatternMatch.cpp
Region.cpp
RegionKindInterface.cpp
StandardTypes.cpp
SymbolTable.cpp
Types.cpp
TypeRange.cpp

View File

@ -8,10 +8,10 @@
#include "mlir/IR/Operation.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/TypeUtilities.h"
#include "mlir/Interfaces/FoldInterfaces.h"
#include <numeric>

View File

@ -13,9 +13,9 @@
#include "mlir/IR/OperationSupport.h"
#include "mlir/IR/Block.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/StandardTypes.h"
using namespace mlir;
//===----------------------------------------------------------------------===//

View File

@ -13,10 +13,10 @@
#define TYPEDETAIL_H_
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Identifier.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OperationSupport.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/TypeRange.h"
#include "llvm/ADT/bit.h"
#include "llvm/Support/TrailingObjects.h"

View File

@ -12,7 +12,7 @@
#include "mlir/IR/TypeUtilities.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Types.h"
#include "mlir/IR/Value.h"

View File

@ -6,13 +6,8 @@
//
//===----------------------------------------------------------------------===//
#include "mlir/IR/Types.h"
#include "TypeDetail.h"
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/Twine.h"
using namespace mlir;
using namespace mlir::detail;
@ -27,96 +22,77 @@ Dialect &Type::getDialect() const {
MLIRContext *Type::getContext() const { return getDialect().getContext(); }
//===----------------------------------------------------------------------===//
// FunctionType
//===----------------------------------------------------------------------===//
bool Type::isBF16() const { return isa<BFloat16Type>(); }
bool Type::isF16() const { return isa<Float16Type>(); }
bool Type::isF32() const { return isa<Float32Type>(); }
bool Type::isF64() const { return isa<Float64Type>(); }
FunctionType FunctionType::get(TypeRange inputs, TypeRange results,
MLIRContext *context) {
return Base::get(context, inputs, results);
bool Type::isIndex() const { return isa<IndexType>(); }
/// Return true if this is an integer type with the specified width.
bool Type::isInteger(unsigned width) const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.getWidth() == width;
return false;
}
unsigned FunctionType::getNumInputs() const { return getImpl()->numInputs; }
ArrayRef<Type> FunctionType::getInputs() const {
return getImpl()->getInputs();
bool Type::isSignlessInteger() const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isSignless();
return false;
}
unsigned FunctionType::getNumResults() const { return getImpl()->numResults; }
ArrayRef<Type> FunctionType::getResults() const {
return getImpl()->getResults();
bool Type::isSignlessInteger(unsigned width) const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isSignless() && intTy.getWidth() == width;
return false;
}
/// Helper to call a callback once on each index in the range
/// [0, `totalIndices`), *except* for the indices given in `indices`.
/// `indices` is allowed to have duplicates and can be in any order.
inline void iterateIndicesExcept(unsigned totalIndices,
ArrayRef<unsigned> indices,
function_ref<void(unsigned)> callback) {
llvm::BitVector skipIndices(totalIndices);
for (unsigned i : indices)
skipIndices.set(i);
for (unsigned i = 0; i < totalIndices; ++i)
if (!skipIndices.test(i))
callback(i);
bool Type::isSignedInteger() const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isSigned();
return false;
}
/// Returns a new function type without the specified arguments and results.
FunctionType
FunctionType::getWithoutArgsAndResults(ArrayRef<unsigned> argIndices,
ArrayRef<unsigned> resultIndices) {
ArrayRef<Type> newInputTypes = getInputs();
SmallVector<Type, 4> newInputTypesBuffer;
if (!argIndices.empty()) {
unsigned originalNumArgs = getNumInputs();
iterateIndicesExcept(originalNumArgs, argIndices, [&](unsigned i) {
newInputTypesBuffer.emplace_back(getInput(i));
});
newInputTypes = newInputTypesBuffer;
}
ArrayRef<Type> newResultTypes = getResults();
SmallVector<Type, 4> newResultTypesBuffer;
if (!resultIndices.empty()) {
unsigned originalNumResults = getNumResults();
iterateIndicesExcept(originalNumResults, resultIndices, [&](unsigned i) {
newResultTypesBuffer.emplace_back(getResult(i));
});
newResultTypes = newResultTypesBuffer;
}
return get(newInputTypes, newResultTypes, getContext());
bool Type::isSignedInteger(unsigned width) const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isSigned() && intTy.getWidth() == width;
return false;
}
//===----------------------------------------------------------------------===//
// OpaqueType
//===----------------------------------------------------------------------===//
OpaqueType OpaqueType::get(Identifier dialect, StringRef typeData,
MLIRContext *context) {
return Base::get(context, dialect, typeData);
bool Type::isUnsignedInteger() const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isUnsigned();
return false;
}
OpaqueType OpaqueType::getChecked(Identifier dialect, StringRef typeData,
MLIRContext *context, Location location) {
return Base::getChecked(location, dialect, typeData);
bool Type::isUnsignedInteger(unsigned width) const {
if (auto intTy = dyn_cast<IntegerType>())
return intTy.isUnsigned() && intTy.getWidth() == width;
return false;
}
/// Returns the dialect namespace of the opaque type.
Identifier OpaqueType::getDialectNamespace() const {
return getImpl()->dialectNamespace;
bool Type::isSignlessIntOrIndex() const {
return isSignlessInteger() || isa<IndexType>();
}
/// Returns the raw type data of the opaque type.
StringRef OpaqueType::getTypeData() const { return getImpl()->typeData; }
/// Verify the construction of an opaque type.
LogicalResult OpaqueType::verifyConstructionInvariants(Location loc,
Identifier dialect,
StringRef typeData) {
if (!Dialect::isValidNamespace(dialect.strref()))
return emitError(loc, "invalid dialect namespace '") << dialect << "'";
return success();
bool Type::isSignlessIntOrIndexOrFloat() const {
return isSignlessInteger() || isa<IndexType, FloatType>();
}
bool Type::isSignlessIntOrFloat() const {
return isSignlessInteger() || isa<FloatType>();
}
bool Type::isIntOrIndex() const { return isa<IntegerType>() || isIndex(); }
bool Type::isIntOrFloat() const { return isa<IntegerType, FloatType>(); }
bool Type::isIntOrIndexOrFloat() const { return isIntOrFloat() || isIndex(); }
unsigned Type::getIntOrFloatBitWidth() const {
assert(isIntOrFloat() && "only integers and floats have a bitwidth");
if (auto intType = dyn_cast<IntegerType>())
return intType.getWidth();
return cast<FloatType>().getWidth();
}

Some files were not shown because too many files have changed in this diff Show More