//===- 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