llvm/mlir/include/mlir/IR/BuiltinAttributes.h

//===- BuiltinAttributes.h - MLIR Builtin Attribute 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_BUILTINATTRIBUTES_H
#define MLIR_IR_BUILTINATTRIBUTES_H

#include "mlir/IR/BuiltinAttributeInterfaces.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/Sequence.h"
#include <complex>
#include <optional>

namespace mlir {
class AffineMap;
class AsmResourceBlob;
class BoolAttr;
class BuiltinDialect;
class DenseIntElementsAttr;
template <typename T>
struct DialectResourceBlobHandle;
class FlatSymbolRefAttr;
class FunctionType;
class IntegerSet;
class IntegerType;
class Location;
class Operation;
class RankedTensorType;

namespace detail {
struct DenseIntOrFPElementsAttrStorage;
struct DenseStringElementsAttrStorage;
struct StringAttrStorage;
} // namespace detail

//===----------------------------------------------------------------------===//
// Elements Attributes
//===----------------------------------------------------------------------===//

namespace detail {
/// Pair of raw pointer and a boolean flag of whether the pointer holds a splat,
DenseIterPtrAndSplat;

/// Impl iterator for indexed DenseElementsAttr iterators that records a data
/// pointer and data index that is adjusted for the case of a splat attribute.
template <typename ConcreteT, typename T, typename PointerT = T *,
          typename ReferenceT = T &>
class DenseElementIndexedIteratorImpl
    : public llvm::indexed_accessor_iterator<ConcreteT, DenseIterPtrAndSplat, T,
                                             PointerT, ReferenceT> {};

/// Type trait detector that checks if a given type T is a complex type.
template <typename T>
struct is_complex_t : public std::false_type {};
is_complex_t<std::complex<T>>;
} // namespace detail

/// An attribute that represents a reference to a dense vector or tensor
/// object.
class DenseElementsAttr : public Attribute {};

/// An attribute that represents a reference to a splat vector or tensor
/// constant, meaning all of the elements have the same value.
class SplatElementsAttr : public DenseElementsAttr {};

//===----------------------------------------------------------------------===//
// DenseResourceElementsAttr
//===----------------------------------------------------------------------===//

DenseResourceElementsHandle;

} // namespace mlir

//===----------------------------------------------------------------------===//
// Tablegen Attribute Declarations
//===----------------------------------------------------------------------===//

#define GET_ATTRDEF_CLASSES
#include "mlir/IR/BuiltinAttributes.h.inc"

//===----------------------------------------------------------------------===//
// C++ Attribute Declarations
//===----------------------------------------------------------------------===//

namespace mlir {
//===----------------------------------------------------------------------===//
// DenseArrayAttr

namespace detail {
/// Base class for DenseArrayAttr that is instantiated and specialized for each
/// supported element type below.
template <typename T>
class DenseArrayAttrImpl : public DenseArrayAttr {};

extern template class DenseArrayAttrImpl<bool>;
extern template class DenseArrayAttrImpl<int8_t>;
extern template class DenseArrayAttrImpl<int16_t>;
extern template class DenseArrayAttrImpl<int32_t>;
extern template class DenseArrayAttrImpl<int64_t>;
extern template class DenseArrayAttrImpl<float>;
extern template class DenseArrayAttrImpl<double>;
} // namespace detail

// Public name for all the supported DenseArrayAttr
DenseBoolArrayAttr;
DenseI8ArrayAttr;
DenseI16ArrayAttr;
DenseI32ArrayAttr;
DenseI64ArrayAttr;
DenseF32ArrayAttr;
DenseF64ArrayAttr;

//===----------------------------------------------------------------------===//
// DenseResourceElementsAttr

namespace detail {
/// Base class for DenseResourceElementsAttr that is instantiated and
/// specialized for each supported element type below.
template <typename T>
class DenseResourceElementsAttrBase : public DenseResourceElementsAttr {};

extern template class DenseResourceElementsAttrBase<bool>;
extern template class DenseResourceElementsAttrBase<int8_t>;
extern template class DenseResourceElementsAttrBase<int16_t>;
extern template class DenseResourceElementsAttrBase<int32_t>;
extern template class DenseResourceElementsAttrBase<int64_t>;
extern template class DenseResourceElementsAttrBase<uint8_t>;
extern template class DenseResourceElementsAttrBase<uint16_t>;
extern template class DenseResourceElementsAttrBase<uint32_t>;
extern template class DenseResourceElementsAttrBase<uint64_t>;
extern template class DenseResourceElementsAttrBase<float>;
extern template class DenseResourceElementsAttrBase<double>;
} // namespace detail

// Public names for all the supported DenseResourceElementsAttr.

DenseBoolResourceElementsAttr;
DenseI8ResourceElementsAttr;
DenseI16ResourceElementsAttr;
DenseI32ResourceElementsAttr;
DenseI64ResourceElementsAttr;
DenseUI8ResourceElementsAttr;
DenseUI16ResourceElementsAttr;
DenseUI32ResourceElementsAttr;
DenseUI64ResourceElementsAttr;
DenseF32ResourceElementsAttr;
DenseF64ResourceElementsAttr;

//===----------------------------------------------------------------------===//
// BoolAttr
//===----------------------------------------------------------------------===//

/// Special case of IntegerAttr to represent boolean integers, i.e., signless i1
/// integers.
class BoolAttr : public Attribute {};

//===----------------------------------------------------------------------===//
// FlatSymbolRefAttr
//===----------------------------------------------------------------------===//

/// A symbol reference with a reference path containing a single element. This
/// is used to refer to an operation within the current symbol table.
class FlatSymbolRefAttr : public SymbolRefAttr {};

//===----------------------------------------------------------------------===//
// DenseFPElementsAttr
//===----------------------------------------------------------------------===//

/// An attribute that represents a reference to a dense float vector or tensor
/// object. Each element is stored as a double.
class DenseFPElementsAttr : public DenseIntOrFPElementsAttr {};

//===----------------------------------------------------------------------===//
// DenseIntElementsAttr
//===----------------------------------------------------------------------===//

/// An attribute that represents a reference to a dense integer vector or tensor
/// object.
class DenseIntElementsAttr : public DenseIntOrFPElementsAttr {};

//===----------------------------------------------------------------------===//
// SparseElementsAttr
//===----------------------------------------------------------------------===//

template <typename T>
auto SparseElementsAttr::try_value_begin_impl(OverloadToken<T>) const
    -> FailureOr<iterator<T>> {}

//===----------------------------------------------------------------------===//
// DistinctAttr
//===----------------------------------------------------------------------===//

namespace detail {
struct DistinctAttrStorage;
class DistinctAttributeUniquer;
} // namespace detail

/// An attribute that associates a referenced attribute with a unique
/// identifier. Every call to the create function allocates a new distinct
/// attribute instance. The address of the attribute instance serves as a
/// temporary identifier. Similar to the names of SSA values, the final
/// identifiers are generated during pretty printing. This delayed numbering
/// ensures the printed identifiers are deterministic even if multiple distinct
/// attribute instances are created in-parallel.
///
/// Examples:
///
/// #distinct = distinct[0]<42.0 : f32>
/// #distinct1 = distinct[1]<42.0 : f32>
/// #distinct2 = distinct[2]<array<i32: 10, 42>>
///
/// NOTE: The distinct attribute cannot be defined using ODS since it uses a
/// custom distinct attribute uniquer that cannot be set from ODS.
class DistinctAttr
    : public detail::StorageUserBase<DistinctAttr, Attribute,
                                     detail::DistinctAttrStorage,
                                     detail::DistinctAttributeUniquer> {};

//===----------------------------------------------------------------------===//
// StringAttr
//===----------------------------------------------------------------------===//

/// Define comparisons for StringAttr against nullptr and itself to avoid the
/// StringRef overloads from being chosen when not desirable.
inline bool operator==(StringAttr lhs, std::nullptr_t) {}
inline bool operator!=(StringAttr lhs, std::nullptr_t) {}
inline bool operator==(StringAttr lhs, StringAttr rhs) {}
inline bool operator!=(StringAttr lhs, StringAttr rhs) {}

/// Allow direct comparison with StringRef.
inline bool operator==(StringAttr lhs, StringRef rhs) {}
inline bool operator!=(StringAttr lhs, StringRef rhs) {}
inline bool operator==(StringRef lhs, StringAttr rhs) {}
inline bool operator!=(StringRef lhs, StringAttr rhs) {}

} // namespace mlir

//===----------------------------------------------------------------------===//
// Attribute Utilities
//===----------------------------------------------------------------------===//

namespace mlir {

/// Given a list of strides (in which ShapedType::kDynamic
/// 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 is always positive.
///
/// 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);

} // namespace mlir

namespace llvm {

template <>
struct DenseMapInfo<mlir::StringAttr> : public DenseMapInfo<mlir::Attribute> {};
template <>
struct PointerLikeTypeTraits<mlir::StringAttr>
    : public PointerLikeTypeTraits<mlir::Attribute> {};

template <>
struct PointerLikeTypeTraits<mlir::IntegerAttr>
    : public PointerLikeTypeTraits<mlir::Attribute> {};

template <>
struct PointerLikeTypeTraits<mlir::SymbolRefAttr>
    : public PointerLikeTypeTraits<mlir::Attribute> {};

} // namespace llvm

#endif // MLIR_IR_BUILTINATTRIBUTES_H