13#ifndef MLIR_IR_OPERATION_H
14#define MLIR_IR_OPERATION_H
21#include "llvm/ADT/Twine.h"
84class alignas(8) Operation final
85 :
public llvm::ilist_node_with_parent<Operation, Block>,
86 private llvm::TrailingObjects<Operation, detail::OperandStorage,
87 detail::OpProperties, BlockOperand, Region,
103 DictionaryAttr attributes,
105 unsigned numRegions);
190 return defaultResultTypes;
195 bool cloneRegionsFlag : 1;
197 bool cloneOperandsFlag : 1;
199 std::optional<SmallVector<Type>> resultTypes;
258 template <
typename OpTy>
261 while ((op = op->getParentOp()))
262 if (
auto parentOp = dyn_cast<OpTy>(op))
266 template <
typename... OpTy>
269 while ((op = op->getParentOp()))
270 if (isa<OpTy...>(op))
276 template <
template <
typename T>
class Trait>
278 Operation *op =
this;
300 template <
typename ValuesT>
307 template <
typename ValuesT>
332 void moveBefore(
Block *block, llvm::iplist<Operation>::iterator iterator);
341 void moveAfter(
Block *block, llvm::iplist<Operation>::iterator iterator);
376 return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().size() : 0;
390 getOperandStorage().eraseOperands(idx, length);
396 getOperandStorage().eraseOperands(eraseIndices);
413 return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().getOperands()
418 return getOperandStorage().getOperands()[idx];
491 if (attributes.
set(name, value) != value)
520 return llvm::make_filter_range(
523 return getPropertiesStorage() ||
524 !llvm::is_contained(attributeNames, attribute.getName());
549 void setAttrs(DictionaryAttr newAttrs);
553 assert(newAttrs &&
"expected valid attribute dictionary");
566 return *inherentAttr;
568 return attrs.get(name);
573 return *inherentAttr;
575 return attrs.get(name);
578 template <
typename AttrClass>
580 return llvm::dyn_cast_or_null<AttrClass>(
getAttr(name));
582 template <
typename AttrClass>
584 return llvm::dyn_cast_or_null<AttrClass>(
getAttr(name));
592 return (
bool)*inherentAttr;
594 return attrs.contains(name);
599 return (
bool)*inherentAttr;
601 return attrs.contains(name);
603 template <
typename AttrClass,
typename NameT>
605 return static_cast<bool>(
619 if (attributes.
set(name, value) != value)
633 return *inherentAttr;
647 class dialect_attr_iterator
648 :
public llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
649 bool (*)(NamedAttribute)> {
652 return attr.
getName().strref().count(
'.');
657 : llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
681 template <
typename DialectAttrT>
684 attrs.
append(std::begin(dialectAttrs), std::end(dialectAttrs));
686 if (!attr.getName().strref().contains(
'.'))
687 attrs.push_back(attr);
694 name.populateDefaultAttrs(attrs);
711 return getTrailingObjects<Region>(numRegions);
716 assert(
index < numRegions &&
"invalid region index");
725 return getTrailingObjects<BlockOperand>(numSuccs);
770 template <
typename InterfaceT>
772 return name.hasPromiseOrImplementsInterface<InterfaceT>();
777 template <
template <
typename T>
class Trait>
779 return name.hasTrait<Trait>();
785 template <
template <
typename T>
class Trait>
787 return name.mightHaveTrait<Trait>();
824 std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 1,
851 template <
typename FnT,
typename RetT = detail::walkResultType<FnT>>
852 std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 2,
887 return result.isUsedOutsideOfBlock(block);
914 InFlightDiagnostic
emitError(
const Twine &message = {});
918 InFlightDiagnostic
emitWarning(
const Twine &message = {});
922 InFlightDiagnostic
emitRemark(
const Twine &message = {});
926 return ((
int)propertiesStorageSize) * 8;
930 if (propertiesStorageSize)
935 if (propertiesStorageSize)
937 getTrailingObjects<detail::OpProperties>()))};
944 reinterpret_cast<void *
>(getTrailingObjects<detail::OpProperties>())};
976 static constexpr unsigned kInvalidOrderIdx = -1;
980 static constexpr unsigned kOrderStride = 5;
984 void updateOrderIfNecessary();
987 bool hasValidOrder() {
return orderIndex != kInvalidOrderIdx; }
990 Operation(Location location, OperationName name,
unsigned numResults,
991 unsigned numSuccessors,
unsigned numRegions,
992 int propertiesStorageSize, DictionaryAttr attributes,
993 OpaqueProperties properties,
bool hasOperandStorage);
1001 static size_t prefixAllocSize(
unsigned numOutOfLineResults,
1002 unsigned numInlineResults) {
1003 return sizeof(detail::OutOfLineOpResult) * numOutOfLineResults +
1004 sizeof(detail::InlineOpResult) * numInlineResults;
1007 size_t prefixAllocSize() {
1009 unsigned numOutOfLineResults = OpResult::getNumTrailing(numResults);
1010 unsigned numInlineResults = OpResult::getNumInline(numResults);
1011 return prefixAllocSize(numOutOfLineResults, numInlineResults);
1015 detail::OperandStorage &getOperandStorage() {
1016 assert(hasOperandStorage &&
"expected operation to have operand storage");
1017 return *getTrailingObjects<detail::OperandStorage>();
1021 detail::OutOfLineOpResult *getOutOfLineOpResult(
unsigned resultNumber) {
1024 return reinterpret_cast<detail::OutOfLineOpResult *
>(getInlineOpResult(
1030 detail::InlineOpResult *getInlineOpResult(
unsigned resultNumber) {
1033 return reinterpret_cast<detail::InlineOpResult *
>(
this) - ++resultNumber;
1038 detail::OpResultImpl *getOpResultImpl(
unsigned resultNumber) {
1040 "Result number is out of range for operation");
1042 if (resultNumber < maxInlineResults)
1043 return getInlineOpResult(resultNumber);
1044 return getOutOfLineOpResult(resultNumber - maxInlineResults);
1052 Block *getParent()
const {
return block; }
1059 LLVM_DUMP_METHOD SuccessorRange debug_getSuccessors() {
1062 LLVM_DUMP_METHOD MutableArrayRef<Region> debug_getRegions() {
1068 Block *block =
nullptr;
1076 mutable unsigned orderIndex = 0;
1078 const unsigned numResults;
1079 const unsigned numSuccs;
1080 const unsigned numRegions : 23;
1085 bool hasOperandStorage : 1;
1090 unsigned char propertiesStorageSize : 8;
1093 static constexpr int64_t propertiesCapacity = 8 * 256;
1099 DictionaryAttr attrs;
1102 friend struct llvm::ilist_traits<Operation>;
1111 friend class llvm::ilist_node_with_parent<Operation,
Block>;
1117 size_t numTrailingObjects(OverloadToken<detail::OperandStorage>)
const {
1118 return hasOperandStorage ? 1 : 0;
1120 size_t numTrailingObjects(OverloadToken<BlockOperand>)
const {
1123 size_t numTrailingObjects(OverloadToken<Region>)
const {
return numRegions; }
1124 size_t numTrailingObjects(OverloadToken<detail::OpProperties>)
const {
1143 : op(op), theFlags(
flags) {}
1156 opWithFlags.op->
print(os, opWithFlags.
flags());
1176 opWithState.op->
print(os,
const_cast<OpWithState &
>(opWithState).theState);
1184template <
typename T>
1187 CastInfo<T, ::mlir::Operation *>> {
1190template <
typename T>
1193 CastInfo<T, ::mlir::Operation *>> {};
1196template <
typename T>
1200 CastInfo<T, ::mlir::Operation>> {
1206template <
typename T>
1209 CastInfo<T, ::mlir::Operation>> {};
1218 ::mlir::Operation *, ::mlir::Operation *,
1219 CastInfo<::mlir::Operation *, ::mlir::Operation *>> {
1226 const ::mlir::Operation *, const ::mlir::Operation *,
1227 CastInfo<::mlir::Operation *, ::mlir::Operation *>> {};
static llvm::ManagedStatic< PassManagerOptions > options
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
This class provides management for the lifetime of the state used when printing the IR.
Attributes are known-constant values of operations.
A block operand represents an operand that holds a reference to a Block, e.g.
This class provides an abstraction over the different types of ranges over Blocks.
Block represents an ordered list of Operations.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
This is a utility class for mapping one set of IR entities to another.
IRValueT get() const
Return the current value being used by this operand.
void set(IRValueT newValue)
Set the current value being used by this operand.
This class represents a diagnostic that is inflight and set to be reported.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
DictionaryAttr getDictionary(MLIRContext *context) const
Return a dictionary attribute for the underlying dictionary.
Attribute erase(StringAttr name)
Erase the attribute with the given name from the list.
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
Attribute set(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
NamedAttribute represents a combination of a name and an Attribute value.
StringAttr getName() const
Return the name of the attribute.
This class represents an operand of an operation.
Set of flags used to control the behavior of the various IR print methods (e.g.
OpPrintingFlags & useLocalScope(bool enable=true)
Use local scope when printing the operation.
This is a value defined by a result of an operation.
A wrapper class that allows for printing an operation with a set of flags, useful to act as a "stream...
OpWithFlags(Operation *op, OpPrintingFlags flags={})
friend raw_ostream & operator<<(raw_ostream &os, OpWithFlags op)
const OpPrintingFlags & flags() const
Operation * getOperation() const
OpPrintingFlags & flags()
A wrapper class that allows for printing an operation with a custom AsmState, useful to act as a "str...
OpWithState(Operation *op, AsmState &state)
friend raw_ostream & operator<<(raw_ostream &os, const OpWithState &op)
Simple wrapper around a void* in order to express generically how to pass in op properties through AP...
This class implements the operand iterators for the Operation class.
type_range getTypes() const
ValueTypeRange< OperandRange > type_range
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context,...
std::optional< RegisteredOperationName > getRegisteredInfo() const
If this operation is registered, returns the registered information, std::nullopt otherwise.
bool isRegistered() const
Return if this operation is registered.
Class encompassing various options related to cloning an operation.
bool shouldCloneResults() const
Returns true if the results are cloned from the operation.
bool shouldCloneRegions() const
Returns whether regions of the operation should be cloned as well.
CloneOptions()
Default constructs an option with all flags set to false.
static CloneOptions all()
Returns an instance such that all elements of the operation are cloned.
bool shouldCloneOperands() const
Returns whether operands should be cloned as well.
TypeRange resultTypesOr(TypeRange defaultResultTypes) const
Returns the result types that should be used for the created operation or defaultResultTypes if none ...
CloneOptions & cloneRegions(bool enable=true)
Configures whether cloning should traverse into any of the regions of the operation.
CloneOptions & withResultTypes(std::optional< SmallVector< Type > > resultTypes)
Configures different result types to use for the cloned operation.
CloneOptions & cloneOperands(bool enable=true)
Configures whether operation' operands should be cloned.
A utility iterator that filters out non-dialect attributes.
Operation is the basic unit of execution within MLIR.
AttrClass getAttrOfType(StringRef name)
void setLoc(Location loc)
Set the source location the operation was defined or derived from.
void setInherentAttr(StringAttr name, Attribute value)
Set an inherent attribute by name.
void eraseOperands(const BitVector &eraseIndices)
Erases the operands that have their corresponding bit set in eraseIndices and removes them from the o...
Attribute getDiscardableAttr(StringRef name)
Access a discardable attribute by name, returns a null Attribute if the discardable attribute does no...
void replaceUsesOfWith(Value from, Value to)
Replace any uses of 'from' with 'to' within this operation.
MutableArrayRef< BlockOperand > getBlockOperands()
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
ResultRange result_range
Support result iteration.
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Attempt to fold this operation with the specified constant operand values.
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==2, RetT > walk(FnT &&callback)
Generic walker with a stage aware callback.
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
bool use_empty()
Returns true if this operation has no uses.
Value getOperand(unsigned idx)
std::enable_if_t<(sizeof...(OpTy) > 1), Operation * > getParentOfType()
OpResult getOpResult(unsigned idx)
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Operation * cloneWithoutRegions()
Create a partial copy of this operation without traversing into attached regions.
void insertOperands(unsigned index, ValueRange operands)
Insert the given operands into the operand list at the given 'index'.
void dropAllUses()
Drop all uses of results of this operation.
AttrClass getAttrOfType(StringAttr name)
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
bool hasAttr(StringRef name)
operand_range::type_range operand_type_range
bool hasAttrOfType(NameT &&name)
void setOperand(unsigned idx, Value value)
void setAttrs(DictionaryAttr newAttrs)
Set the attributes from a dictionary on this operation.
bool hasAttr(StringAttr name)
Return true if the operation has an attribute with the provided name, false otherwise.
OpaqueProperties getPropertiesStorage() const
unsigned getNumSuccessors()
bool isBeforeInBlock(Operation *other)
Given an operation 'other' that is within the same parent block, return whether the current operation...
result_iterator result_begin()
void eraseOperands(unsigned idx, unsigned length=1)
Erase the operands starting at position idx and ending at position 'idx'+'length'.
void dropAllReferences()
This drops all operand uses from this operation, which is an essential step in breaking cyclic depend...
bool isRegistered()
Returns true if this operation has a registered operation description, otherwise false.
InFlightDiagnostic emitWarning(const Twine &message={})
Emit a warning about this operation, reporting up to any diagnostic handlers that may be listening.
result_range::iterator result_iterator
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
operand_iterator operand_begin()
OpaqueProperties getPropertiesStorageUnsafe()
Returns the properties storage without checking whether properties are present.
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
result_range::use_iterator use_iterator
bool hasOneUse()
Returns true if this operation has exactly one use.
dialect_attr_iterator dialect_attr_begin()
Attribute getAttr(StringRef name)
Block * getBlock()
Returns the operation block that contains this operation.
void setDiscardableAttr(StringAttr name, Attribute value)
Set a discardable attribute by name.
Attribute removeAttr(StringRef name)
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
std::optional< Attribute > getInherentAttr(StringRef name)
Access an inherent attribute by name: returns an empty optional if there is no inherent attribute wit...
Operation * getParentWithTrait()
Returns the closest surrounding parent operation with trait Trait.
operand_range::type_iterator operand_type_iterator
operand_type_iterator operand_type_end()
Attribute removeDiscardableAttr(StringRef name)
result_range::type_range result_type_range
unsigned getNumRegions()
Returns the number of regions held by this operation.
void setDialectAttrs(DialectAttrT &&dialectAttrs)
Set the dialect attributes for this operation, and preserve all inherent.
Location getLoc()
The source location the operation was defined or derived from.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
void replaceUsesWithIf(ValuesT &&values, function_ref< bool(OpOperand &)> shouldReplace)
Replace uses of results of this operation with the provided values if the given callback returns true...
MutableArrayRef< OpOperand > getOpOperands()
std::optional< RegisteredOperationName > getRegisteredInfo()
If this operation has a registered operation description, return it.
void eraseOperand(unsigned idx)
Erase the operand at position idx.
bool hasPromiseOrImplementsInterface() const
Returns true if InterfaceT has been promised by the dialect or implemented.
DictionaryAttr getRawDictionaryAttrs()
Return all attributes that are not stored as properties.
void dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
iterator_range< user_iterator > user_range
iterator_range< dialect_attr_iterator > dialect_attr_range
unsigned getNumOperands()
result_type_iterator result_type_end()
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, NamedAttrList &&attributes, OpaqueProperties properties, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
Attribute getPropertiesAsAttribute()
Return the properties converted to an attribute.
OperandRange operand_range
void populateDefaultAttrs()
Sets default attributes on unset attributes.
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
ValueUserIterator< use_iterator, OpOperand > user_iterator
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
result_range::type_iterator result_type_iterator
Support result type iteration.
operand_iterator operand_end()
Attribute getDiscardableAttr(StringAttr name)
Access a discardable attribute by name, returns a null Attribute if the discardable attribute does no...
bool isUsedOutsideOfBlock(Block *block)
Returns true if the results of this operation are used outside of the given block.
result_type_iterator result_type_begin()
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
void destroy()
Destroys this operation and its subclass data.
auto getDiscardableAttrs()
Return a range of all of discardable attributes on this operation.
OperationName getName()
The name of an operation is the key identifier for it.
DictionaryAttr getDiscardableAttrDictionary()
Return all of the discardable attributes on this operation as a DictionaryAttr.
void remove()
Remove the operation from its parent block, but don't delete it.
void print(raw_ostream &os, const OpPrintingFlags &flags={})
void setDiscardableAttrs(ArrayRef< NamedAttribute > newAttrs)
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
LogicalResult setPropertiesFromAttribute(Attribute attr, function_ref< InFlightDiagnostic()> emitError)
Set the properties from the provided attribute.
operand_type_range getOperandTypes()
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
result_iterator result_end()
result_type_range getResultTypes()
Attribute removeDiscardableAttr(StringAttr name)
Remove the discardable attribute with the specified name if it exists.
LLVM_DUMP_METHOD void dumpPretty()
void setDiscardableAttr(StringRef name, Attribute value)
operand_range getOperands()
Returns an iterator on the underlying Value's.
void setSuccessor(Block *block, unsigned index)
void moveBefore(Operation *existingOp)
Unlink this operation from its current block and insert it right before existingOp which may be in th...
bool isAncestor(Operation *other)
Return true if this operation is an ancestor of the other operation.
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided 'values'.
void setOperands(ValueRange operands)
Replace the current operands of this operation with the ones provided in 'operands'.
result_range::use_range use_range
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
Block * getSuccessor(unsigned index)
user_range getUsers()
Returns a range of all users.
SuccessorRange getSuccessors()
result_range getOpResults()
result_range getResults()
int getPropertiesStorageSize() const
Returns the properties storage size.
Operation * clone(IRMapping &mapper, const CloneOptions &options=CloneOptions::all())
Create a deep copy of this operation, remapping any operands that use values outside of the operation...
Region * getParentRegion()
Returns the region to which the instruction belongs.
Attribute removeAttr(StringAttr name)
Remove the attribute with the specified name if it exists.
SuccessorRange::iterator succ_iterator
dialect_attr_iterator dialect_attr_end()
bool isProperAncestor(Operation *other)
Return true if this operation is a proper ancestor of the other operation.
OpOperand & getOpOperand(unsigned idx)
use_range getUses()
Returns a range of all uses, which is useful for iterating over all uses.
void setAttr(StringRef name, Attribute value)
MLIRContext * getContext()
Return the context this operation is associated with.
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening.
operand_range::iterator operand_iterator
user_iterator user_begin()
void setDiscardableAttrs(DictionaryAttr newAttrs)
Set the discardable attribute dictionary on this operation.
void moveAfter(Operation *existingOp)
Unlink this operation from its current block and insert it right after existingOp which may be in the...
llvm::hash_code hashProperties()
Compute a hash for the op properties (if any).
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
succ_iterator successor_end()
OpaqueProperties getPropertiesStorage()
Returns the properties storage.
void erase()
Remove this operation from its parent block and delete it.
void copyProperties(OpaqueProperties rhs)
Copy properties from an existing other properties object.
succ_iterator successor_begin()
unsigned getNumResults()
Return the number of results held by this operation.
operand_type_iterator operand_type_begin()
This class provides an abstraction over the different types of ranges over Regions.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class implements the result iterators for the Operation class.
std::enable_if_t<!std::is_convertible< ValuesT, Operation * >::value > replaceUsesWithIf(ValuesT &&values, function_ref< bool(OpOperand &)> shouldReplace)
Replace uses of results of this range with the provided 'values' if the given callback returns true.
use_range getUses() const
Returns a range of all uses of results within this range, which is useful for iterating over all uses...
bool use_empty() const
Returns true if no results in this range have uses.
ValueTypeRange< ResultRange > type_range
use_iterator use_begin() const
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
use_iterator use_end() const
type_range getTypes() const
iterator_range< use_iterator > use_range
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'.
This class implements the successor iterators for Block.
This class provides an abstraction over the various different ranges of value types.
This class provides an abstraction over the different types of ranges over Values.
An iterator over the users of an IRObject.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
static unsigned getMaxInlineResults()
Returns the maximum number of results that can be stored inline.
This class handles the management of operation operands.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
void walk(Operation *op, function_ref< void(Region *)> callback, WalkOrder order)
Walk all of the regions, blocks, or operations nested under (and including) the given operation.
OpProperties
This is a "tag" used for mapping the properties storage in llvm::TrailingObjects.
decltype(walk(nullptr, std::declval< FnT >())) walkResultType
Utility to provide the return type of a templated walk method.
Include the generated interface declarations.
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
WalkOrder
Traversal order for region, block and operation walk utilities.
llvm::function_ref< Fn > function_ref
static T doCast(::mlir::Operation &val)
static bool isPossible(::mlir::Operation &val)
static bool isPossible(::mlir::Operation *op)
::mlir::Operation * doCast(::mlir::Operation *op)
static bool isPossible(::mlir::Operation *op)
This iterator enumerates the elements in "forward" order.
This represents an operation in an abstracted form, suitable for use with the builder APIs.