//===- OperationSupport.h ---------------------------------------*- 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 a number of support types that Operation and related // classes build on top of. // //===----------------------------------------------------------------------===// #ifndef MLIR_IR_OPERATIONSUPPORT_H #define MLIR_IR_OPERATIONSUPPORT_H #include "mlir/IR/Attributes.h" #include "mlir/IR/BlockSupport.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Diagnostics.h" #include "mlir/IR/DialectRegistry.h" #include "mlir/IR/Location.h" #include "mlir/IR/TypeRange.h" #include "mlir/IR/Types.h" #include "mlir/IR/Value.h" #include "mlir/Support/InterfaceSupport.h" #include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/TrailingObjects.h" #include <memory> #include <optional> namespace llvm { class BitVector; } // namespace llvm namespace mlir { class Dialect; class DictionaryAttr; class ElementsAttr; struct EmptyProperties; class MutableOperandRangeRange; class NamedAttrList; class Operation; struct OperationState; class OpAsmParser; class OpAsmPrinter; class OperandRange; class OperandRangeRange; class OpFoldResult; class Pattern; class Region; class ResultRange; class RewritePattern; class RewritePatternSet; class Type; class Value; class ValueRange; template <typename ValueRangeT> class ValueTypeRange; //===----------------------------------------------------------------------===// // OpaqueProperties //===----------------------------------------------------------------------===// /// Simple wrapper around a void* in order to express generically how to pass /// in op properties through APIs. class OpaqueProperties { … }; //===----------------------------------------------------------------------===// // OperationName //===----------------------------------------------------------------------===// class OperationName { … }; inline raw_ostream &operator<<(raw_ostream &os, OperationName info) { … } // Make operation names hashable. inline llvm::hash_code hash_value(OperationName arg) { … } //===----------------------------------------------------------------------===// // RegisteredOperationName //===----------------------------------------------------------------------===// /// This is a "type erased" representation of a registered operation. This /// should only be used by things like the AsmPrinter and other things that need /// to be parameterized by generic operation hooks. Most user code should use /// the concrete operation types. class RegisteredOperationName : public OperationName { … }; inline std::optional<RegisteredOperationName> OperationName::getRegisteredInfo() const { … } //===----------------------------------------------------------------------===// // Attribute Dictionary-Like Interface //===----------------------------------------------------------------------===// /// Attribute collections provide a dictionary-like interface. Define common /// lookup functions. namespace impl { /// Unsorted string search or identifier lookups are linear scans. template <typename IteratorT, typename NameT> std::pair<IteratorT, bool> findAttrUnsorted(IteratorT first, IteratorT last, NameT name) { … } /// Using llvm::lower_bound requires an extra string comparison to check whether /// the returned iterator points to the found element or whether it indicates /// the lower bound. Skip this redundant comparison by checking if `compare == /// 0` during the binary search. template <typename IteratorT> std::pair<IteratorT, bool> findAttrSorted(IteratorT first, IteratorT last, StringRef name) { … } /// StringAttr lookups on large attribute lists will switch to string binary /// search. String binary searches become significantly faster than linear scans /// with the identifier when the attribute list becomes very large. template <typename IteratorT> std::pair<IteratorT, bool> findAttrSorted(IteratorT first, IteratorT last, StringAttr name) { … } /// Get an attribute from a sorted range of named attributes. Returns null if /// the attribute was not found. template <typename IteratorT, typename NameT> Attribute getAttrFromSortedRange(IteratorT first, IteratorT last, NameT name) { … } /// Get an attribute from a sorted range of named attributes. Returns /// std::nullopt if the attribute was not found. template <typename IteratorT, typename NameT> std::optional<NamedAttribute> getNamedAttrFromSortedRange(IteratorT first, IteratorT last, NameT name) { … } } // namespace impl //===----------------------------------------------------------------------===// // NamedAttrList //===----------------------------------------------------------------------===// /// NamedAttrList is array of NamedAttributes that tracks whether it is sorted /// and does some basic work to remain sorted. class NamedAttrList { … }; //===----------------------------------------------------------------------===// // OperationState //===----------------------------------------------------------------------===// /// This represents an operation in an abstracted form, suitable for use with /// the builder APIs. This object is a large and heavy weight object meant to /// be used as a temporary object on the stack. It is generally unwise to put /// this in a collection. struct OperationState { … }; //===----------------------------------------------------------------------===// // OperandStorage //===----------------------------------------------------------------------===// namespace detail { /// This class handles the management of operation operands. Operands are /// stored either in a trailing array, or a dynamically resizable vector. class alignas(8) OperandStorage { … }; } // namespace detail //===----------------------------------------------------------------------===// // OpPrintingFlags //===----------------------------------------------------------------------===// /// Set of flags used to control the behavior of the various IR print methods /// (e.g. Operation::Print). class OpPrintingFlags { … }; //===----------------------------------------------------------------------===// // Operation Equivalency //===----------------------------------------------------------------------===// /// This class provides utilities for computing if two operations are /// equivalent. struct OperationEquivalence { … }; /// Enable Bitmask enums for OperationEquivalence::Flags. LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(…); //===----------------------------------------------------------------------===// // OperationFingerPrint //===----------------------------------------------------------------------===// /// A unique fingerprint for a specific operation, and all of it's internal /// operations (if `includeNested` is set). class OperationFingerPrint { … }; } // namespace mlir namespace llvm { template <> struct DenseMapInfo<mlir::OperationName> { … }; template <> struct DenseMapInfo<mlir::RegisteredOperationName> : public DenseMapInfo<mlir::OperationName> { … }; template <> struct PointerLikeTypeTraits<mlir::OperationName> { … }; template <> struct PointerLikeTypeTraits<mlir::RegisteredOperationName> : public PointerLikeTypeTraits<mlir::OperationName> { … }; } // namespace llvm #endif