llvm/mlir/lib/Dialect/LLVMIR/IR/TypeDetail.h

//===- TypeDetail.h - Details of MLIR LLVM dialect types --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains implementation details, such as storage structures, of
// MLIR LLVM dialect types.
//
//===----------------------------------------------------------------------===//

#ifndef DIALECT_LLVMIR_IR_TYPEDETAIL_H
#define DIALECT_LLVMIR_IR_TYPEDETAIL_H

#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/TypeSupport.h"
#include "mlir/IR/Types.h"

#include "llvm/ADT/Bitfields.h"
#include "llvm/ADT/PointerIntPair.h"

namespace mlir {
namespace LLVM {
namespace detail {

//===----------------------------------------------------------------------===//
// LLVMStructTypeStorage.
//===----------------------------------------------------------------------===//

/// Type storage for LLVM structure types.
///
/// Structures are uniqued using:
/// - a bit indicating whether a struct is literal or identified;
/// - for identified structs, in addition to the bit:
///   - a string identifier;
/// - for literal structs, in addition to the bit:
///   - a list of contained types;
///   - a bit indicating whether the literal struct is packed.
///
/// Identified structures only have a mutable component consisting of:
///   - a list of contained types;
///   - a bit indicating whether the identified struct is packed;
///   - a bit indicating whether the identified struct is intentionally opaque;
///   - a bit indicating whether the identified struct has been initialized.
/// Uninitialized structs are considered opaque by the user, and can be mutated.
/// Initialized and still opaque structs cannot be mutated.
///
/// The struct storage consists of:
///   - immutable part:
///     - a pointer to the first element of the key (character for identified
///       structs, type for literal structs);
///     - the number of elements in the key packed together with bits indicating
///       whether a type is literal or identified, and the packedness bit for
///       literal structs only;
///   - mutable part:
///     - a pointer to the first contained type for identified structs only;
///     - the number of contained types packed together with bits of the mutable
///       component, for identified structs only.
struct LLVMStructTypeStorage : public TypeStorage {};
} // end namespace detail
} // end namespace LLVM

/// Allow walking and replacing the subelements of a LLVMStructTypeStorage key.
template <>
struct AttrTypeSubElementHandler<LLVM::detail::LLVMStructTypeStorage::Key> {};

namespace LLVM {
namespace detail {
//===----------------------------------------------------------------------===//
// LLVMTypeAndSizeStorage.
//===----------------------------------------------------------------------===//

/// Common storage used for LLVM dialect types that need an element type and a
/// number: arrays, fixed and scalable vectors. The actual semantics of the
/// type is defined by its kind.
struct LLVMTypeAndSizeStorage : public TypeStorage {};

} // namespace detail
} // namespace LLVM
} // namespace mlir

#endif // DIALECT_LLVMIR_IR_TYPEDETAIL_H