llvm/mlir/include/mlir/IR/Value.h

//===- Value.h - Base of the SSA Value hierarchy ----------------*- 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 defines generic Value type and manipulation utilities.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_IR_VALUE_H
#define MLIR_IR_VALUE_H

#include "mlir/IR/Types.h"
#include "mlir/IR/UseDefLists.h"
#include "mlir/Support/LLVM.h"
#include "llvm/Support/PointerLikeTypeTraits.h"

namespace mlir {
class AsmState;
class Block;
class BlockArgument;
class Operation;
class OpOperand;
class OpPrintingFlags;
class OpResult;
class Region;
class Value;

//===----------------------------------------------------------------------===//
// Value
//===----------------------------------------------------------------------===//

namespace detail {

/// The base class for all derived Value classes. It contains all of the
/// components that are shared across Value classes.
class alignas(8) ValueImpl : public IRObjectWithUseList<OpOperand> {};
} // namespace detail

/// This class represents an instance of an SSA value in the MLIR system,
/// representing a computable value that has a type and a set of users. An SSA
/// value is either a BlockArgument or the result of an operation. Note: This
/// class has value-type semantics and is just a simple wrapper around a
/// ValueImpl that is either owner by a block(in the case of a BlockArgument) or
/// an Operation(in the case of an OpResult).
/// As most IR constructs, this isn't const-correct, but we keep method
/// consistent and as such method that immediately modify this Value aren't
/// marked `const` (include modifying the Value use-list).
class Value {};

inline raw_ostream &operator<<(raw_ostream &os, Value value) {}

//===----------------------------------------------------------------------===//
// OpOperand
//===----------------------------------------------------------------------===//

/// This class represents an operand of an operation. Instances of this class
/// contain a reference to a specific `Value`.
class OpOperand : public IROperand<OpOperand, Value> {};

//===----------------------------------------------------------------------===//
// BlockArgument
//===----------------------------------------------------------------------===//

namespace detail {
/// The internal implementation of a BlockArgument.
class BlockArgumentImpl : public ValueImpl {};
} // namespace detail

/// This class represents an argument of a Block.
class BlockArgument : public Value {};

//===----------------------------------------------------------------------===//
// OpResult
//===----------------------------------------------------------------------===//

namespace detail {
/// This class provides the implementation for an operation result.
class alignas(8) OpResultImpl : public ValueImpl {};

/// This class provides the implementation for an operation result whose index
/// can be represented "inline" in the underlying ValueImpl.
struct InlineOpResult : public OpResultImpl {};

/// This class provides the implementation for an operation result whose index
/// cannot be represented "inline", and thus requires an additional index field.
class OutOfLineOpResult : public OpResultImpl {};

/// Return the result number of this op result.
inline unsigned OpResultImpl::getResultNumber() const {}

/// TypedValue is a Value with a statically know type.
/// TypedValue can be null/empty
template <typename Ty>
struct TypedValue : Value {};

} // namespace detail

/// This is a value defined by a result of an operation.
class OpResult : public Value {};

/// Make Value hashable.
inline ::llvm::hash_code hash_value(Value arg) {}

TypedValue;

} // namespace mlir

namespace llvm {

template <>
struct DenseMapInfo<mlir::Value> {};
template <>
struct DenseMapInfo<mlir::BlockArgument> : public DenseMapInfo<mlir::Value> {};
template <>
struct DenseMapInfo<mlir::OpResult> : public DenseMapInfo<mlir::Value> {};
DenseMapInfo<mlir::detail::TypedValue<T>>;

/// Allow stealing the low bits of a value.
template <>
struct PointerLikeTypeTraits<mlir::Value> {};
template <>
struct PointerLikeTypeTraits<mlir::BlockArgument>
    : public PointerLikeTypeTraits<mlir::Value> {};
template <>
struct PointerLikeTypeTraits<mlir::OpResult>
    : public PointerLikeTypeTraits<mlir::Value> {};
PointerLikeTypeTraits<mlir::detail::TypedValue<T>>;

/// Add support for llvm style casts. We provide a cast between To and From if
/// From is mlir::Value or derives from it.
CastInfo<To, From, std::enable_if_t<std::is_same_v<mlir::Value, std::remove_const_t<From>> || std::is_base_of_v<mlir::Value, From>>>;

} // namespace llvm

#endif