14 #ifndef MLIR_IR_OPERATIONSUPPORT_H 15 #define MLIR_IR_OPERATIONSUPPORT_H 24 #include "llvm/ADT/BitmaskEnum.h" 25 #include "llvm/ADT/PointerUnion.h" 26 #include "llvm/Support/PointerLikeTypeTraits.h" 27 #include "llvm/Support/TrailingObjects.h" 38 class MutableOperandRangeRange;
40 struct OperationState;
42 class OpAsmParserResult;
45 class OperandRangeRange;
52 class RewritePatternSet;
56 template <
typename ValueRangeT>
66 llvm::unique_function<void(RewritePatternSet &, MLIRContext *) const>;
69 using HasTraitFn = llvm::unique_function<bool(TypeID) const>;
71 llvm::unique_function<ParseResult(OpAsmParser &, OperationState &) const>;
73 llvm::unique_function<void(Operation *, OpAsmPrinter &, StringRef) const>;
75 llvm::unique_function<LogicalResult(Operation *) const>;
77 llvm::unique_function<LogicalResult(Operation *) const>;
86 : name(name), dialect(nullptr), interfaceMap(
llvm::None) {}
138 template <
template <
typename T>
class Trait>
bool hasTrait()
const {
139 return hasTrait(TypeID::get<Trait>());
142 return isRegistered() &&
impl->hasTraitFn(traitID);
149 return mightHaveTrait(TypeID::get<Trait>());
152 return !isRegistered() ||
impl->hasTraitFn(traitID);
159 return impl->interfaceMap.lookup<T>();
164 return hasInterface(TypeID::get<T>());
167 return impl->interfaceMap.contains(interfaceID);
173 template <
typename T>
175 return mightHaveInterface(TypeID::get<T>());
178 return !isRegistered() || hasInterface(interfaceID);
184 return isRegistered() ?
impl->dialect :
impl->name.getReferencedDialect();
188 StringRef getDialectNamespace()
const;
191 StringRef
stripDialect()
const {
return getStringRef().split(
'.').second; }
199 void print(raw_ostream &os)
const;
207 const_cast<Impl *>(reinterpret_cast<const Impl *>(pointer)));
251 template <
typename T>
253 insert(T::getOperationName(), dialect, TypeID::get<T>(),
254 T::getParseAssemblyFn(), T::getPrintAssemblyFn(),
255 T::getVerifyInvariantsFn(), T::getVerifyRegionInvariantsFn(),
256 T::getFoldHookFn(), T::getGetCanonicalizationPatternsFn(),
257 T::getInterfaceMap(), T::getHasTraitFn(), T::getAttributeNames());
282 return impl->parseAssemblyFn;
287 StringRef defaultDialect)
const {
288 return impl->printAssemblyFn(op, p, defaultDialect);
295 return impl->verifyInvariantsFn(op);
298 return impl->verifyRegionInvariantsFn(op);
322 return impl->foldHookFn(op, operands, results);
329 return impl->getCanonicalizationPatternsFn(results, context);
334 template <
typename... Models>
336 impl->interfaceMap.insert<Models...>();
340 template <
template <
typename T>
class Trait>
bool hasTrait()
const {
341 return hasTrait(TypeID::get<Trait>());
364 return impl->attributeNames;
371 const_cast<Impl *>(reinterpret_cast<const Impl *>(pointer)));
382 OperationName::getRegisteredInfo()
const {
396 template <
typename IteratorT,
typename NameT>
399 for (
auto it = first; it != last; ++it)
400 if (it->getName() == name)
402 return {last,
false};
409 template <
typename IteratorT>
412 ptrdiff_t length = std::distance(first, last);
415 ptrdiff_t half = length / 2;
416 IteratorT mid = first + half;
417 int compare = mid->getName().strref().compare(name);
420 length = length - half - 1;
421 }
else if (compare > 0) {
427 return {first,
false};
433 template <
typename IteratorT>
436 constexpr
unsigned kSmallAttributeList = 16;
437 if (std::distance(first, last) > kSmallAttributeList)
444 template <
typename IteratorT,
typename NameT>
446 std::pair<IteratorT, bool> result =
findAttrSorted(first, last, name);
447 return result.second ? result.first->getValue() :
Attribute();
452 template <
typename IteratorT,
typename NameT>
455 std::pair<IteratorT, bool> result =
findAttrSorted(first, last, name);
481 return !(*
this == other);
484 return attrs == other.attrs;
488 void append(StringRef name,
Attribute attr);
499 template <
typename RangeT>
501 append(std::begin(newAttributes), std::end(newAttributes));
505 template <
typename IteratorT,
506 typename = std::enable_if_t<std::is_convertible<
507 typename std::iterator_traits<IteratorT>::iterator_category,
508 std::input_iterator_tag>
::value>>
509 void append(IteratorT inStart, IteratorT inEnd) {
512 dictionarySorted.setPointerAndInt(
nullptr,
false);
513 attrs.append(inStart, inEnd);
521 assign(range.begin(), range.end());
524 bool empty()
const {
return attrs.empty(); }
540 DictionaryAttr getDictionary(
MLIRContext *context)
const;
576 bool isSorted()
const {
return dictionarySorted.getInt(); }
582 template <
typename AttrListT,
typename NameT>
583 static auto findAttr(AttrListT &attrs, NameT name) {
584 return attrs.isSorted()
595 mutable llvm::PointerIntPair<Attribute, 1, bool> dictionarySorted;
634 types.append(newTypes.begin(), newTypes.end());
636 template <
typename RangeT>
637 std::enable_if_t<!std::is_convertible<RangeT, ArrayRef<Type>>
::value>
639 types.append(newTypes.begin(), newTypes.end());
644 addAttribute(StringAttr::get(getContext(), name), attr);
649 attributes.append(name, attr);
654 attributes.append(newAttributes);
668 void addRegion(std::unique_ptr<Region> &®ion);
698 void setOperands(
Operation *owner,
unsigned start,
unsigned length,
702 void eraseOperands(
unsigned start,
unsigned length);
706 void eraseOperands(
const BitVector &eraseIndices);
712 unsigned size() {
return numOperands; }
720 unsigned capacity : 31;
723 unsigned isStorageDynamic : 1;
725 unsigned numOperands;
747 OpPrintingFlags &elideLargeElementsAttrs(int64_t largeElementLimit = 16);
770 bool shouldElideElementsAttr(ElementsAttr attr)
const;
776 bool shouldPrintDebugInfo()
const;
779 bool shouldPrintDebugInfoPrettyForm()
const;
782 bool shouldPrintGenericOpForm()
const;
785 bool shouldAssumeVerified()
const;
788 bool shouldUseLocalScope()
const;
791 bool shouldPrintValueUsers()
const;
799 bool printDebugInfoFlag : 1;
800 bool printDebugInfoPrettyFormFlag : 1;
803 bool printGenericOpFormFlag : 1;
806 bool assumeVerifiedFlag : 1;
809 bool printLocalScope : 1;
812 bool printValueUsersFlag : 1;
824 OperandRange, OpOperand *, Value, Value, Value> {
826 using RangeBaseT::RangeBaseT;
836 unsigned getBeginOperandIndex()
const;
845 return object + index;
848 static Value dereference_iterator(
OpOperand *
object, ptrdiff_t index) {
849 return object[index].get();
862 :
public llvm::indexed_accessor_range<
863 OperandRangeRange, std::pair<OpOperand *, Attribute>, OperandRange,
864 OperandRange, OperandRange> {
865 using OwnerT = std::pair<OpOperand *, Attribute>;
868 OperandRange, OperandRange>;
871 using RangeBaseT::RangeBaseT;
879 OperandRangeRange(OperandRange operands,
Attribute operandSegments);
882 OperandRange join()
const;
886 static OperandRange dereference(
const OwnerT &
object, ptrdiff_t index);
913 slice(
unsigned subStart,
unsigned subLen,
926 void erase(
unsigned subStart,
unsigned subLen = 1);
932 unsigned size()
const {
return length; }
935 bool empty()
const {
return size() == 0; }
954 void updateLength(
unsigned newLength);
961 unsigned start, length;
974 :
public llvm::indexed_accessor_range<
975 MutableOperandRangeRange,
976 std::pair<MutableOperandRange, NamedAttribute>, MutableOperandRange,
977 MutableOperandRange, MutableOperandRange> {
978 using OwnerT = std::pair<MutableOperandRange, NamedAttribute>;
982 MutableOperandRange>;
985 using RangeBaseT::RangeBaseT;
989 MutableOperandRangeRange(
const MutableOperandRange &operands,
994 MutableOperandRange join()
const;
1001 static MutableOperandRange dereference(
const OwnerT &
object, ptrdiff_t index);
1013 ResultRange, detail::OpResultImpl *, OpResult, OpResult, OpResult> {
1015 using RangeBaseT::RangeBaseT;
1044 return llvm::all_of(*
this,
1050 template <
typename ValuesT>
1053 assert(static_cast<size_t>(std::distance(values.begin(), values.end())) ==
1055 "expected 'values' to correspond 1-1 with the number of results");
1057 for (
auto it : llvm::zip(*
this, values))
1058 std::get<0>(it).replaceAllUsesWith(std::get<1>(it));
1085 return offset_base(
object, index);
1095 :
public llvm::iterator_facade_base<UseIterator, std::forward_iterator_tag,
1102 using llvm::iterator_facade_base<
UseIterator, std::forward_iterator_tag,
1108 bool operator==(
const UseIterator &rhs)
const {
return use == rhs.use; }
1109 bool operator!=(
const UseIterator &rhs)
const {
return !(*
this == rhs); }
1112 void skipOverResultsWithNoUsers();
1115 ResultRange::iterator it, endIt;
1131 PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>,
1132 Value, Value, Value> {
1139 using RangeBaseT::RangeBaseT;
1141 template <
typename Arg,
1142 typename =
typename std::enable_if_t<
1143 std::is_constructible<ArrayRef<Value>, Arg>
::value &&
1167 static OwnerT offset_base(
const OwnerT &owner, ptrdiff_t index);
1169 static Value dereference_iterator(
const OwnerT &owner, ptrdiff_t index);
1186 IgnoreLocations = 1,
1188 LLVM_MARK_AS_BITMASK_ENUM( IgnoreLocations)
1200 Flags flags = Flags::None);
1218 Flags flags = Flags::None);
1269 struct PointerLikeTypeTraits<
mlir::OperationName> {
1276 static constexpr
int NumLowBitsAvailable =
1277 PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
1280 struct PointerLikeTypeTraits<
mlir::RegisteredOperationName>
1281 :
public PointerLikeTypeTraits<mlir::OperationName> {
bool use_empty() const
Returns true if no results in this range have uses.
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
static unsigned getHashValue(mlir::OperationName val)
This class contains a list of basic blocks and a link to the parent operation it is attached to...
This class provides an abstraction for a range of TypeRange.
OperationName(Impl *impl)
ValueRange(const Value &value)
void print(raw_ostream &os) const
StringRef stripDialect() const
Return the operation name with dialect name stripped, if it has one.
bool isRegistered() const
Return if this operation is registered.
FoldHookFn foldHookFn
Internal callback hooks provided by the op implementation.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
Operation is a basic unit of execution within MLIR.
bool hasTrait() const
Returns true if the operation has a particular trait.
SmallVector< Block *, 1 > successors
Successors of this operation and their respective operands.
const_iterator begin() const
static mlir::OperationName getEmptyKey()
void * getAsOpaquePointer() const
Represent the operation name as an opaque pointer.
This is a value defined by a result of an operation.
bool operator==(const UseIterator &rhs) const
Block represents an ordered list of Operations.
SmallVectorImpl< NamedAttribute >::const_iterator const_iterator
void reserve(size_type N)
OpResultImpl * getNextResultAtOffset(intptr_t offset)
Returns the next operation result at offset after this result.
StringAttr getIdentifier() const
Return the name of this operation as a StringAttr.
bool hasInterface() const
Returns true if this operation has the given interface registered to it.
GetCanonicalizationPatternsFn getCanonicalizationPatternsFn
bool mightHaveInterface() const
Returns true if the operation might have the provided interface.
This class implements the result iterators for the Operation class.
LogicalResult verifyRegionInvariants(Operation *op) const
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
Enable Bitmask enums for OperationEquivalence::Flags.
type_range getTypes() const
T::Concept * getInterface() const
Returns an instance of the concept object for the given interface if it was registered to this operat...
An iterator over the users of an IRObject.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it...
bool mightHaveTrait(TypeID traitID) const
static mlir::RegisteredOperationName getEmptyKey()
An inlay hint that for a type annotation.
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &) const > ParseAssemblyFn
static constexpr const bool value
bool hasInterface(TypeID interfaceID) const
SmallVector< Value, 4 > operands
bool operator==(const OperationName &rhs) const
This class provides an efficient unique identifier for a specific C++ type.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
void getCanonicalizationPatterns(RewritePatternSet &results, MLIRContext *context) const
This hook returns any canonicalization pattern rewrites that the operation supports, for use by the canonicalization pass.
static OperationName getFromOpaquePointer(const void *pointer)
NamedAttribute represents a combination of a name and an Attribute value.
void append(IteratorT inStart, IteratorT inEnd)
Add a range of named attributes.
bool hasTrait() const
Returns true if the operation was registered with a particular trait, e.g.
Operation * getOwner() const
Returns the owning operation.
This class provides utilities for computing if two operations are equivalent.
std::enable_if_t<!std::is_convertible< ValuesT, Operation * >::value > replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this range with the provided 'values'.
StringRef getStringRef() const
Return the name of this operation. This always succeeds.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
This class implements iteration on the types of a given range of values.
This class represents an efficient way to signal success or failure.
Optional< NamedAttribute > getNamedAttrFromSortedRange(IteratorT first, IteratorT last, NameT name)
Get an attribute from a sorted range of named attributes.
This class represents a contiguous range of mutable operand ranges, e.g.
This class provides an efficient mapping between a given Interface type, and a particular implementat...
llvm::unique_function< LogicalResult(Operation *) const > VerifyInvariantsFn
VerifyRegionInvariantsFn verifyRegionInvariantsFn
static mlir::OperationName getFromVoidPointer(void *P)
MLIRContext * getContext() const
Return the context this attribute belongs to.
static void * getAsVoidPointer(mlir::OperationName I)
llvm::unique_function< void(Operation *, OpAsmPrinter &, StringRef) const > PrintAssemblyFn
const_iterator end() const
Attributes are known-constant values of operations.
detail::InterfaceMap interfaceMap
A map of interfaces that were registered to this operation.
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
void addAttributes(ArrayRef< NamedAttribute > newAttributes)
Add an array of named attributes.
VerifyInvariantsFn verifyInvariantsFn
bool mightHaveInterface(TypeID interfaceID) const
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
bool operator!=(const OperationName &rhs) const
static mlir::RegisteredOperationName getFromVoidPointer(void *P)
TypeID getTypeID() const
Return the unique identifier of the derived Op class.
ValueRange(ArrayRef< BlockArgument > values)
This class provides an abstraction over the various different ranges of value types.
OpOperand & operator*() const
void addTypes(ArrayRef< Type > newTypes)
void append(RangeT &&newAttributes)
Add an array of named attributes.
bool operator!=(const UseIterator &rhs) const
This class represents a type erased version of an operation.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
LogicalResult foldHook(Operation *op, ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results) const
This hook implements a generalized folder for this operation.
This class provides a mutable adaptor for a range of operands.
TypeID typeID
The unique identifier of the derived Op class.
This represents an operation in an abstracted form, suitable for use with the builder APIs...
static RegisteredOperationName getFromOpaquePointer(const void *pointer)
Represent the operation name as an opaque pointer.
This class represents a contiguous range of operand ranges, e.g.
static llvm::hash_code directHashValue(Value v)
Helper that can be used with computeHash above to ignore operation operands/result mapping...
ValueRange(iterator_range< ResultRange::iterator > values)
bool operator!=(const NamedAttrList &other) const
friend MLIRContextImpl
Allow access to the Impl struct.
llvm::unique_function< void(RewritePatternSet &, MLIRContext *) const > GetCanonicalizationPatternsFn
static bool isEqual(mlir::OperationName lhs, mlir::OperationName rhs)
std::pair< IteratorT, bool > findAttrSorted(IteratorT first, IteratorT last, StringAttr name)
StringAttr lookups on large attribute lists will switch to string binary search.
void addSuccessors(Block *successor)
static mlir::RegisteredOperationName getTombstoneKey()
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
ParseAssemblyFn parseAssemblyFn
void addAttribute(StringRef name, Attribute attr)
Add an attribute with the specified name.
bool use_empty() const
Returns true if this value has no uses.
ValueRange(iterator_range< OperandRange::iterator > values)
std::pair< IteratorT, bool > findAttrUnsorted(IteratorT first, IteratorT last, NameT name)
Unsorted string search or identifier lookups are linear scans.
static LogicalResult exactValueMatch(Value lhs, Value rhs)
Helper that can be used with isEquivalentTo above to ignore operation operands/result mapping...
This class implements a use iterator for a range of operation results.
This class implements iteration on the types of a given range of values.
unsigned size()
Return the number of operands held in the storage.
static llvm::hash_code ignoreHashValue(Value)
Helper that can be used with computeHash above to ignore operation operands/result mapping...
MLIRContext * getContext() const
Get the context held by this operation state.
bool operator==(const NamedAttrList &other) const
StringAttr name
The name of the operation.
void pop_back()
Pop last element from list.
bool hasTrait(TypeID traitID) const
Returns true if the operation has a particular trait.
Set of flags used to control the behavior of the various IR print methods (e.g.
llvm::unique_function< LogicalResult(Operation *) const > VerifyRegionInvariantsFn
void printAssembly(Operation *op, OpAsmPrinter &p, StringRef defaultDialect) const
This hook implements the AsmPrinter for this operation.
std::enable_if_t<!std::is_convertible< RangeT, ArrayRef< Type > >::value > addTypes(RangeT &&newTypes)
raw_ostream & operator<<(raw_ostream &os, OperationName info)
unsigned size() const
Returns the current size of the range.
type_range getTypes() const
static bool hasTrait(TypeID traitID)
Returns true if this given Trait ID matches the IDs of any of the provided trait types Traits...
static void insert(Dialect &dialect)
Register a new operation in a Dialect object.
SmallVectorImpl< NamedAttribute >::iterator iterator
MLIRContext is the top-level object for a collection of MLIR operations.
This class represents an operand of an operation.
This class provides an abstraction over the different types of ranges over Blocks.
ArrayRef< StringAttr > getAttributeNames() const
Return the list of cached attribute names registered to this operation.
bool mightHaveTrait() const
Returns true if the operation might have the provided trait.
static LogicalResult ignoreValueEquivalence(Value lhs, Value rhs)
Helper that can be used with isEquivalentTo above to ignore operation operands/result mapping...
void append(NamedAttribute attr)
Append the given named attribute.
bool empty() const
Returns if the current range is empty.
This class implements the operand iterators for the Operation class.
This class provides the implementation for an operation result.
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context...
std::pair< unsigned, NamedAttribute > OperandSegment
A pair of a named attribute corresponding to an operand segment attribute, and the index within that ...
static llvm::hash_code computeHash(SymbolOpInterface symbolOp)
Computes a hash code to represent symbolOp based on all its attributes except for the symbol name...
llvm::unique_function< LogicalResult(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) const > FoldHookFn
Dialect * dialect
This is the dialect that this operation belongs to.
TypeRangeRange getTypes() const
Returns the range of types of the values within this range.
MutableArrayRef< OpOperand > getOperands()
Get the operation operands held by the storage.
llvm::hash_code hash_value(OperationName arg)
void append(StringAttr name, Attribute attr)
Add an attribute with the specified name.
SmallVector< std::unique_ptr< Region >, 1 > regions
Regions that the op will hold.
bool hasTrait(TypeID traitID) const
Value operator[](unsigned index) const
Returns the value at the given index.
Attribute getAttrFromSortedRange(IteratorT first, IteratorT last, NameT name)
Get an attribute from a sorted range of named attributes.
This is a "type erased" representation of a registered operation.
Dialect & getDialect() const
Return the dialect this operation is registered to.
OpOperand * operator->() const
LogicalResult verifyInvariants(Operation *op) const
These hooks implement the verifiers for this operation.
int compare(Fraction x, Fraction y)
Three-way comparison between two fractions.
ValueRange(const std::initializer_list< Value > &values)
void addAttribute(StringAttr name, Attribute attr)
Add an attribute with the specified name.
This class represents success/failure for parsing-like operations that find it important to chain tog...
static mlir::OperationName getTombstoneKey()
llvm::unique_function< bool(TypeID) const > HasTraitFn
This class provides an abstraction over the different types of ranges over Values.
Impl * impl
The internal implementation of the operation name.
void assign(ArrayRef< NamedAttribute > range)
Replaces the attributes with new list of attributes.
ArrayRef< StringAttr > attributeNames
A list of attribute names registered to this operation in StringAttr form.
PrintAssemblyFn printAssemblyFn
bool isRegistered() const
The following fields are only populated when the operation is registered.
static MappingLevel & operator++(MappingLevel &mappingLevel)
Bounded increment on MappingLevel.
void attachInterface()
Attach the given models as implementations of the corresponding interfaces for the concrete operation...
OpPrintingFlags(llvm::NoneType)
const ParseAssemblyFn & getParseAssemblyFn() const
Return the static hook for parsing this operation assembly.
type_range getTypes() const
SmallVector< Type, 4 > types
Types of the results of this operation.
This class handles the management of operation operands.