13 #ifndef MLIR_IR_OPERATION_H
14 #define MLIR_IR_OPERATION_H
21 #include "llvm/ADT/Twine.h"
73 :
public llvm::ilist_node_with_parent<Operation, Block>,
74 private llvm::TrailingObjects<Operation, detail::OperandStorage,
75 BlockOperand, Region, OpOperand> {
89 DictionaryAttr attributes,
BlockRange successors,
161 bool cloneRegionsFlag : 1;
163 bool cloneOperandsFlag : 1;
221 template <
typename OpTy>
224 while ((op = op->getParentOp()))
225 if (
auto parentOp = dyn_cast<OpTy>(op))
231 template <
template <
typename T>
class Trait>
255 template <
typename ValuesT>
262 template <
typename ValuesT>
287 void moveBefore(
Block *block, llvm::iplist<Operation>::iterator iterator);
296 void moveAfter(
Block *block, llvm::iplist<Operation>::iterator iterator);
326 return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().
size() : 0;
363 return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().
getOperands()
425 assert(newAttrs &&
"expected valid attribute dictionary");
436 template <
typename AttrClass>
440 template <
typename AttrClass>
447 bool hasAttr(StringAttr name) {
return attrs.contains(name); }
448 bool hasAttr(StringRef name) {
return attrs.contains(name); }
449 template <
typename AttrClass,
typename NameT>
451 return static_cast<bool>(
452 getAttrOfType<AttrClass>(std::forward<NameT>(name)));
459 if (attributes.
set(name, value) != value)
482 :
public llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
483 bool (*)(NamedAttribute)> {
486 return attr.
getName().strref().count(
'.');
491 : llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
515 template <
typename DialectAttrT>
518 attrs.
append(std::begin(dialectAttrs), std::end(dialectAttrs));
520 if (!attr.getName().strref().contains(
'.'))
545 auto *regions = getTrailingObjects<Region>();
546 return {regions, numRegions};
551 assert(index < numRegions &&
"invalid region index");
560 return {getTrailingObjects<BlockOperand>(), numSuccs};
591 template <
template <
typename T>
class Trait>
599 template <
template <
typename T>
class Trait>
638 std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 1,
641 return detail::walk<Order, Iterator>(
this, std::forward<FnT>(callback));
665 template <
typename FnT,
typename RetT = detail::walkResultType<FnT>>
666 std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 2,
679 result.dropAllUses();
728 InFlightDiagnostic
emitError(
const Twine &message = {});
732 InFlightDiagnostic
emitWarning(
const Twine &message = {});
736 InFlightDiagnostic
emitRemark(
const Twine &message = {});
745 static constexpr
unsigned kInvalidOrderIdx = -1;
749 static constexpr
unsigned kOrderStride = 5;
753 void updateOrderIfNecessary();
756 bool hasValidOrder() {
return orderIndex != kInvalidOrderIdx; }
759 Operation(Location location, OperationName name,
unsigned numResults,
760 unsigned numSuccessors,
unsigned numRegions,
761 DictionaryAttr attributes,
bool hasOperandStorage);
769 static size_t prefixAllocSize(
unsigned numOutOfLineResults,
770 unsigned numInlineResults) {
771 return sizeof(detail::OutOfLineOpResult) * numOutOfLineResults +
772 sizeof(detail::InlineOpResult) * numInlineResults;
775 size_t prefixAllocSize() {
777 unsigned numOutOfLineResults = OpResult::getNumTrailing(numResults);
778 unsigned numInlineResults = OpResult::getNumInline(numResults);
779 return prefixAllocSize(numOutOfLineResults, numInlineResults);
783 detail::OperandStorage &getOperandStorage() {
784 assert(hasOperandStorage &&
"expected operation to have operand storage");
785 return *getTrailingObjects<detail::OperandStorage>();
789 detail::OutOfLineOpResult *getOutOfLineOpResult(
unsigned resultNumber) {
792 return reinterpret_cast<detail::OutOfLineOpResult *
>(getInlineOpResult(
798 detail::InlineOpResult *getInlineOpResult(
unsigned resultNumber) {
801 return reinterpret_cast<detail::InlineOpResult *
>(
this) - ++resultNumber;
806 detail::OpResultImpl *getOpResultImpl(
unsigned resultNumber) {
808 if (resultNumber < maxInlineResults)
809 return getInlineOpResult(resultNumber);
810 return getOutOfLineOpResult(resultNumber - maxInlineResults);
818 Block *getParent()
const {
return block; }
825 LLVM_DUMP_METHOD SuccessorRange debug_getSuccessors() {
828 LLVM_DUMP_METHOD MutableArrayRef<Region> debug_getRegions() {
834 Block *block =
nullptr;
842 mutable unsigned orderIndex = 0;
844 const unsigned numResults;
845 const unsigned numSuccs;
846 const unsigned numRegions : 31;
851 bool hasOperandStorage : 1;
857 DictionaryAttr attrs;
860 friend struct llvm::ilist_traits<
Operation>;
874 size_t numTrailingObjects(OverloadToken<detail::OperandStorage>)
const {
875 return hasOperandStorage ? 1 : 0;
877 size_t numTrailingObjects(OverloadToken<BlockOperand>)
const {
880 size_t numTrailingObjects(OverloadToken<Region>)
const {
return numRegions; }
892 template <
typename T>
895 CastInfo<T, ::mlir::Operation *>> {
898 template <
typename T>
901 CastInfo<T, ::mlir::Operation *>> {};
904 template <
typename T>
908 CastInfo<T, ::mlir::Operation>> {
914 template <
typename T>
917 CastInfo<T, ::mlir::Operation>> {};
926 ::mlir::Operation *, ::mlir::Operation *,
927 CastInfo<::mlir::Operation *, ::mlir::Operation *>> {
934 const ::mlir::Operation *, const ::mlir::Operation *,
935 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.
U dyn_cast_or_null() const
MLIRContext * getContext() const
Return the context this attribute belongs to.
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.
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
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.
void push_back(NamedAttribute newAttribute)
Add an attribute with the specified name.
Attribute erase(StringAttr name)
Erase the attribute with the given name from the list.
Attribute set(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
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()
Use local scope when printing the operation.
This is a value defined by a result of an operation.
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.
bool hasTrait() const
Returns true if the operation was registered with a particular trait, e.g.
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 mightHaveTrait() const
Returns true if the operation might have the provided trait.
bool isRegistered() const
Return if this operation is registered.
void populateDefaultAttrs(NamedAttrList &attrs) const
This hook implements the method to populate defaults attributes that are unset.
Class encompassing various options related to cloning an 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 with all flags set to true.
bool shouldCloneOperands() const
Returns whether operands should be cloned as well.
CloneOptions & cloneRegions(bool enable=true)
Configures whether cloning should traverse into any of the regions of the 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 eraseOperands(const BitVector &eraseIndices)
Erases the operands that have their corresponding bit set in eraseIndices and removes them from the o...
void replaceUsesOfWith(Value from, Value to)
Replace any uses of 'from' with 'to' within this operation.
ResultRange result_range
Support result iteration.
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Attempt to fold this operation with the specified constant operand values.
void setAttrs(ArrayRef< NamedAttribute > newAttrs)
bool use_empty()
Returns true if this operation has no uses.
Value getOperand(unsigned idx)
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.
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
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)
OpOperand & getOpOperand(unsigned idx)
bool hasAttrOfType(NameT &&name)
void setOperand(unsigned idx, Value value)
Block * getSuccessor(unsigned index)
bool hasAttr(StringAttr name)
Return true if the operation has an attribute with the provided name, false otherwise.
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.
Operation * clone(IRMapping &mapper, CloneOptions options=CloneOptions::all())
Create a deep copy of this operation, remapping any operands that use values outside of the operation...
result_range::iterator result_iterator
void setAttrs(DictionaryAttr newAttrs)
Set the attribute dictionary on this operation.
operand_iterator operand_begin()
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
bool hasOneUse()
Returns true if this operation has exactly one use.
dialect_attr_iterator dialect_attr_begin()
Attribute getAttr(StringRef name)
Attribute removeAttr(StringRef name)
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
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),...
void print(raw_ostream &os, const OpPrintingFlags &flags=std::nullopt)
operand_type_iterator operand_type_end()
MLIRContext * getContext()
Return the context this operation is associated with.
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 dependent.
std::optional< RegisteredOperationName > getRegisteredInfo()
If this operation has a registered operation description, return it.
Location getLoc()
The source location the operation was defined or derived from.
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...
void eraseOperand(unsigned idx)
Erase the operand at position idx.
void dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
unsigned getNumOperands()
result_type_iterator result_type_end()
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, NamedAttrList &&attributes, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
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...
Block * getBlock()
Returns the operation block that contains this operation.
ValueUserIterator< use_iterator, OpOperand > user_iterator
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
operand_iterator operand_end()
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
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.
Operation * getParentWithTrait()
Returns the closest surrounding parent operation with trait Trait.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
void destroy()
Destroys this operation and its subclass data.
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
OperationName getName()
The name of an operation is the key identifier for it.
void remove()
Remove the operation from its parent block, but don't delete it.
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
MutableArrayRef< BlockOperand > getBlockOperands()
operand_type_range getOperandTypes()
result_iterator result_end()
MutableArrayRef< OpOperand > getOpOperands()
result_type_range getResultTypes()
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'.
user_range getUsers()
Returns a range of all users.
SuccessorRange getSuccessors()
result_range getOpResults()
Region * getParentRegion()
Returns the region to which the instruction belongs.
result_range getResults()
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.
use_range getUses()
Returns a range of all uses, which is useful for iterating over all uses.
void setAttr(StringRef name, Attribute value)
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 moveAfter(Operation *existingOp)
Unlink this operation from its current block and insert it right after existingOp which may be in the...
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()
void erase()
Remove this operation from its parent block and delete it.
succ_iterator successor_begin()
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.
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 a use iterator for a range of operation results.
This class implements the result iterators for the Operation class.
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
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.
type_range getTypes() const
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'.
iterator_range< use_iterator > use_range
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.
This class implements iteration on the types of a given range of values.
This class implements iteration on the types of a given range of 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...
bool isUsedOutsideOfBlock(Block *block)
Returns true if the value is used outside of the given block.
static unsigned getMaxInlineResults()
Returns the maximum number of results that can be stored inline.
This class handles the management of operation operands.
MutableArrayRef< OpOperand > getOperands()
Get the operation operands held by the storage.
void eraseOperands(unsigned start, unsigned length)
Erase the operands held by the storage within the given range.
unsigned size()
Return the number of operands held in the storage.
Include the generated interface declarations.
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.
decltype(walk(nullptr, std::declval< FnT >())) walkResultType
Utility to provide the return type of a templated walk method.
This header declares functions that assit transformations in the MemRef dialect.
WalkOrder
Traversal order for region, block and operation walk utilities.
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
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 class represents an efficient way to signal success or failure.
This represents an operation in an abstracted form, suitable for use with the builder APIs.