17 #include "llvm/ADT/StringExtras.h"
38 unsigned numRegions = regions.size();
40 std::move(attributes), successors, numRegions);
41 for (
unsigned i = 0; i < numRegions; ++i)
51 unsigned numRegions) {
55 return create(location, name, resultTypes, operands,
56 attributes.getDictionary(location.
getContext()), successors,
64 DictionaryAttr attributes,
BlockRange successors,
65 unsigned numRegions) {
66 assert(llvm::all_of(resultTypes, [](
Type t) {
return t; }) &&
67 "unexpected null result type");
70 unsigned numTrailingResults = OpResult::getNumTrailing(resultTypes.size());
71 unsigned numInlineResults = OpResult::getNumInline(resultTypes.size());
72 unsigned numSuccessors = successors.size();
73 unsigned numOperands = operands.size();
74 unsigned numResults = resultTypes.size();
78 bool needsOperandStorage =
85 totalSizeToAlloc<detail::OperandStorage, BlockOperand, Region, OpOperand>(
86 needsOperandStorage ? 1 : 0, numSuccessors, numRegions, numOperands);
87 size_t prefixByteSize = llvm::alignTo(
88 Operation::prefixAllocSize(numTrailingResults, numInlineResults),
90 char *mallocMem =
reinterpret_cast<char *
>(malloc(byteSize + prefixByteSize));
91 void *rawMem = mallocMem + prefixByteSize;
95 ::new (rawMem)
Operation(location, name, numResults, numSuccessors,
96 numRegions, attributes, needsOperandStorage);
99 "unexpected successors in a non-terminator operation");
102 auto resultTypeIt = resultTypes.begin();
103 for (
unsigned i = 0; i < numInlineResults; ++i, ++resultTypeIt)
105 for (
unsigned i = 0; i < numTrailingResults; ++i, ++resultTypeIt) {
106 new (op->getOutOfLineOpResult(i))
111 for (
unsigned i = 0; i != numRegions; ++i)
115 if (needsOperandStorage) {
117 op, op->getTrailingObjects<
OpOperand>(), operands);
122 for (
unsigned i = 0; i != numSuccessors; ++i)
123 new (&blockOperands[i])
BlockOperand(op, successors[i]);
129 unsigned numSuccessors,
unsigned numRegions,
130 DictionaryAttr attributes,
bool hasOperandStorage)
131 : location(location), numResults(numResults), numSuccs(numSuccessors),
132 numRegions(numRegions), hasOperandStorage(hasOperandStorage), name(name),
134 assert(attributes &&
"unexpected null attribute dictionary");
137 llvm::report_fatal_error(
139 " created with unregistered dialect. If this is intended, please call "
140 "allowUnregisteredDialects() on the MLIRContext, or use "
141 "-allow-unregistered-dialect with the MLIR tool used.");
147 Operation::~Operation() {
148 assert(block ==
nullptr &&
"operation destroyed but still in a block");
153 emitOpError(
"operation destroyed but still has uses");
155 diag.attachNote(user->getLoc()) <<
"- use: " << *user <<
"\n";
157 llvm::report_fatal_error(
"operation destroyed but still has uses");
161 if (hasOperandStorage)
166 successor.~BlockOperand();
177 char *rawMem =
reinterpret_cast<char *
>(
this) -
178 llvm::alignTo(prefixAllocSize(),
alignof(
Operation));
197 if (operand.get() == from)
204 if (LLVM_LIKELY(hasOperandStorage))
205 return getOperandStorage().
setOperands(
this, operands);
206 assert(operands.empty() &&
"setting operands without an operand storage");
215 "invalid operand range specified");
216 if (LLVM_LIKELY(hasOperandStorage))
217 return getOperandStorage().
setOperands(
this, start, length, operands);
218 assert(operands.empty() &&
"setting operands without an operand storage");
223 if (LLVM_LIKELY(hasOperandStorage))
225 assert(operands.empty() &&
"inserting operands without an operand storage");
236 if (
getContext()->shouldPrintOpOnDiagnostic()) {
238 .append(
"see current operation: ")
248 if (
getContext()->shouldPrintOpOnDiagnostic())
249 diag.attachNote(
getLoc()) <<
"see current operation: " << *
this;
257 if (
getContext()->shouldPrintOpOnDiagnostic())
258 diag.attachNote(
getLoc()) <<
"see current operation: " << *
this;
266 constexpr
unsigned Operation::kInvalidOrderIdx;
267 constexpr
unsigned Operation::kOrderStride;
275 assert(block &&
"Operations without parent blocks have no order.");
276 assert(other && other->block == block &&
277 "Expected other operation to have the same parent block.");
284 updateOrderIfNecessary();
285 other->updateOrderIfNecessary();
288 return orderIndex < other->orderIndex;
293 void Operation::updateOrderIfNecessary() {
294 assert(block &&
"expected valid parent");
304 assert(blockFront != blockBack &&
"expected more than one operation");
307 if (
this == blockBack) {
309 if (!prevNode->hasValidOrder())
313 orderIndex = prevNode->orderIndex + kOrderStride;
319 if (
this == blockFront) {
321 if (!nextNode->hasValidOrder())
324 if (nextNode->orderIndex == 0)
329 if (nextNode->orderIndex <= kOrderStride)
330 orderIndex = (nextNode->orderIndex / 2);
332 orderIndex = kOrderStride;
338 Operation *prevNode = getPrevNode(), *nextNode = getNextNode();
339 if (!prevNode->hasValidOrder() || !nextNode->hasValidOrder())
341 unsigned prevOrder = prevNode->orderIndex, nextOrder = nextNode->orderIndex;
344 if (prevOrder + 1 == nextOrder)
346 orderIndex = prevOrder + ((nextOrder - prevOrder) / 2);
353 auto llvm::ilist_detail::SpecificNodeAccess<
354 typename llvm::ilist_detail::compute_node_options<
356 return NodeAccess::getNodePtr<OptionsT>(n);
359 auto llvm::ilist_detail::SpecificNodeAccess<
360 typename llvm::ilist_detail::compute_node_options<
362 ->
const node_type * {
363 return NodeAccess::getNodePtr<OptionsT>(n);
366 auto llvm::ilist_detail::SpecificNodeAccess<
367 typename llvm::ilist_detail::compute_node_options<
369 return NodeAccess::getValuePtr<OptionsT>(n);
372 auto llvm::ilist_detail::SpecificNodeAccess<
373 typename llvm::ilist_detail::compute_node_options<
376 return NodeAccess::getValuePtr<OptionsT>(n);
383 Block *llvm::ilist_traits<::mlir::Operation>::getContainingBlock() {
385 iplist<Operation> *anchor(
static_cast<iplist<Operation> *
>(
this));
386 return reinterpret_cast<Block *
>(
reinterpret_cast<char *
>(anchor) - offset);
392 assert(!op->
getBlock() &&
"already in an operation block!");
393 op->block = getContainingBlock();
396 op->orderIndex = Operation::kInvalidOrderIdx;
402 assert(op->block &&
"not already in an operation block!");
410 Block *curParent = getContainingBlock();
417 if (curParent == otherList.getContainingBlock())
421 for (; first != last; ++first)
422 first->block = curParent;
429 parent->getOperations().erase(
this);
437 parent->getOperations().remove(
this);
450 llvm::iplist<Operation>::iterator iterator) {
464 llvm::iplist<Operation>::iterator iterator) {
465 assert(iterator != block->
end() &&
"cannot move after end of block");
477 region.dropAllReferences();
489 for (
auto &block : region)
515 return interface->fold(
this, operands, results);
529 : cloneRegionsFlag(false), cloneOperandsFlag(false) {}
532 : cloneRegionsFlag(cloneRegions), cloneOperandsFlag(cloneOperands) {}
539 cloneRegionsFlag = enable;
544 cloneOperandsFlag = enable;
571 if (
options.shouldCloneOperands()) {
585 mapper.
map(
this, newOp);
588 if (
options.shouldCloneRegions()) {
589 for (
unsigned i = 0; i != numRegions; ++i)
614 return (*parseFn)(parser, result);
622 printOpName(op, p, defaultDialect);
632 StringRef defaultDialect) {
634 if (name.startswith((defaultDialect +
".").str()) && name.count(
'.') == 1)
635 name = name.drop_front(defaultDialect.size() + 1);
642 return getOperation()->emitError(message);
648 return getOperation()->emitOpError(message);
654 return getOperation()->emitWarning(message);
660 return getOperation()->emitRemark(message);
670 if (argumentOp && op->
getName() == argumentOp->getName()) {
683 if (argumentOp && op->
getName() == argumentOp->getName()) {
693 return op->
emitOpError() <<
"requires zero operands";
699 return op->
emitOpError() <<
"requires a single operand";
704 unsigned numOperands) {
706 return op->
emitOpError() <<
"expected " << numOperands
713 unsigned numOperands) {
716 <<
"expected " << numOperands <<
" or more operands, but found "
724 if (
auto vec = type.
dyn_cast<VectorType>())
725 return vec.getElementType();
753 if (!type.isSignlessIntOrIndex())
754 return op->
emitOpError() <<
"requires an integer or index type";
777 return op->
emitOpError() <<
"requires all operands to have the same type";
783 return op->
emitOpError() <<
"requires zero regions";
794 unsigned numRegions) {
796 return op->
emitOpError() <<
"expected " << numRegions <<
" regions";
801 unsigned numRegions) {
803 return op->
emitOpError() <<
"expected " << numRegions <<
" or more regions";
809 return op->
emitOpError() <<
"requires zero results";
820 unsigned numOperands) {
822 return op->
emitOpError() <<
"expected " << numOperands <<
" results";
827 unsigned numOperands) {
830 <<
"expected " << numOperands <<
" or more results";
839 return op->
emitOpError() <<
"requires the same shape for all operands";
854 <<
"requires the same shape for all operands and results";
864 for (
auto operand : llvm::drop_begin(op->
getOperands(), 1)) {
866 return op->
emitOpError(
"requires the same element type for all operands");
881 for (
auto result : llvm::drop_begin(op->
getResults(), 1)) {
884 "requires the same element type for all operands and results");
891 "requires the same element type for all operands and results");
905 if (
auto rankedType = dyn_cast<RankedTensorType>(type))
906 encoding = rankedType.getEncoding();
911 <<
"requires the same type for all operands and results";
913 if (
auto rankedType = dyn_cast<RankedTensorType>(resultType);
914 encoding != rankedType.getEncoding())
916 <<
"requires the same encoding for all operands and results";
922 <<
"requires the same type for all operands and results";
924 if (
auto rankedType = dyn_cast<RankedTensorType>(opType);
925 encoding != rankedType.getEncoding())
927 <<
"requires the same encoding for all operands and results";
935 if (!block || &block->
back() != op)
936 return op->
emitOpError(
"must be the last operation in the parent block");
945 if (succ->getParent() != parent)
946 return op->
emitError(
"reference to block defined in another region");
952 return op->
emitOpError(
"requires 0 successors but found ")
960 return op->
emitOpError(
"requires 1 successor but found ")
966 unsigned numSuccessors) {
969 << numSuccessors <<
" successors but found "
975 unsigned numSuccessors) {
978 << numSuccessors <<
" successors but found "
987 bool isBoolType = elementType.isInteger(1);
989 return op->
emitOpError() <<
"requires a bool result type";
998 return op->
emitOpError() <<
"requires a floating point type";
1007 return op->
emitOpError() <<
"requires an integer or index type";
1013 StringRef valueGroupName,
1014 size_t expectedCount) {
1017 return op->
emitOpError(
"requires dense i32 array attribute '")
1021 if (llvm::any_of(sizes, [](int32_t element) {
return element < 0; }))
1023 << attrName <<
"' attribute cannot have negative elements";
1026 std::accumulate(sizes.begin(), sizes.end(), 0,
1027 [](
unsigned all, int32_t one) { return all + one; });
1029 if (totalCount != expectedCount)
1031 << valueGroupName <<
" count (" << expectedCount
1032 <<
") does not match with the total size (" << totalCount
1033 <<
") specified in attribute '" << attrName <<
"'";
1038 StringRef attrName) {
1043 StringRef attrName) {
1052 if (region.getNumArguments() != 0) {
1055 << region.getRegionNumber() <<
" should have no arguments";
1056 return op->
emitOpError(
"region should have no arguments");
1063 auto isMappableType = [](
Type type) {
1066 auto resultMappableTypes = llvm::to_vector<1>(
1068 auto operandMappableTypes = llvm::to_vector<2>(
1073 if (resultMappableTypes.empty() && operandMappableTypes.empty())
1076 if (!resultMappableTypes.empty() && operandMappableTypes.empty())
1077 return op->
emitOpError(
"if a result is non-scalar, then at least one "
1078 "operand must be non-scalar");
1080 assert(!operandMappableTypes.empty());
1082 if (resultMappableTypes.empty())
1083 return op->
emitOpError(
"if an operand is non-scalar, then there must be at "
1084 "least one non-scalar result");
1088 "if an operand is non-scalar, then all results must be non-scalar");
1091 llvm::concat<Type>(operandMappableTypes, resultMappableTypes));
1092 TypeID expectedBaseTy = types.front().getTypeID();
1093 if (!llvm::all_of(types,
1096 return op->
emitOpError() <<
"all non-scalar operands/results must have the "
1097 "same shape and base type";
1107 "Intended to check IsolatedFromAbove ops");
1113 for (
auto ®ion : isolatedOp->
getRegions()) {
1114 pendingRegions.push_back(®ion);
1117 while (!pendingRegions.empty()) {
1118 for (
Operation &op : pendingRegions.pop_back_val()->getOps()) {
1119 for (
Value operand : op.getOperands()) {
1122 auto *operandRegion = operand.getParentRegion();
1124 return op.emitError(
"operation's operand is unlinked");
1125 if (!region.isAncestor(operandRegion)) {
1126 return op.emitOpError(
"using value defined outside the region")
1127 .attachNote(isolatedOp->
getLoc())
1128 <<
"required by region isolation constraints";
1135 if (op.getNumRegions() &&
1137 for (
Region &subRegion : op.getRegions())
1138 pendingRegions.push_back(&subRegion);
1161 if (operands.empty())
1167 foldResults.append(operands.begin(), operands.end());
1178 if (resultTypes.empty())
1180 <<
"expected at least one result for cast operation";
1183 if (!areCastCompatible(operandTypes, resultTypes)) {
1185 if (operandTypes.empty())
1187 else if (llvm::size(operandTypes) == 1)
1188 diag <<
" " << *operandTypes.begin();
1190 diag <<
"s " << operandTypes;
1191 return diag <<
" and result type" << (resultTypes.size() == 1 ?
" " :
"s ")
1192 << resultTypes <<
" are cast incompatible";
1218 builder.
insert(buildTerminatorOp(builder, loc));
static LogicalResult verifyTerminatorSuccessors(Operation *op)
static Type getTensorOrVectorElementType(Type type)
If this is a vector type, or a tensor type, return the scalar element type that it is built around,...
static std::string diag(const llvm::Value &value)
static llvm::ManagedStatic< PassManagerOptions > options
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
virtual SMLoc getNameLoc() const =0
Return the location of the original name token.
virtual raw_ostream & getStream() const
Return the raw output stream used by this printer.
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.
void recomputeOpOrder()
Recomputes the ordering of child operations within the block.
bool isOpOrderValid()
Returns true if the ordering of the child operations is valid, false otherwise.
void dropAllDefinedValueUses()
This drops all uses of values defined in this block or in the blocks of nested regions wherever the u...
void invalidateOpOrder()
Invalidates the current ordering of operations.
OpListType & getOperations()
static OpListType Block::* getSublistAccess(Operation *)
Returns pointer to member of operation list.
This class is a general helper class for creating context-global objects like types,...
MLIRContext * getContext() const
Define a fold interface to allow for dialects to control specific aspects of the folding behavior for...
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
virtual std::optional< ParseOpHook > getParseOperationHook(StringRef opName) const
Return the hook to parse an operation registered to this dialect, if any.
virtual llvm::unique_function< void(Operation *, OpAsmPrinter &printer)> getOperationPrinter(Operation *op) const
Print an operation registered to this dialect.
This is a utility class for mapping one set of IR entities to another.
auto lookupOrDefault(T from) const
Lookup a mapped value within the map.
void map(Value from, Value to)
Inserts a new mapping for 'from' to 'to'.
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 * getContext() const
Return the context this location is uniqued in.
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.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
virtual void printGenericOp(Operation *op, bool printOpName=true)=0
Print the entire operation with the default generic assembly form.
RAII guard to reset the insertion point of the builder when destroyed.
This class helps build Operations.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes=std::nullopt, ArrayRef< Location > locs=std::nullopt)
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
Operation * insert(Operation *op)
Insert the given operation at the current insertion point and return it.
This class represents a single result from folding an operation.
This class represents an operand of an operation.
Set of flags used to control the behavior of the various IR print methods (e.g.
static void printOpName(Operation *op, OpAsmPrinter &p, StringRef defaultDialect)
Print an operation name, eliding the dialect prefix if necessary.
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
InFlightDiagnostic emitWarning(const Twine &message={})
Emit a warning about this operation, reporting up to any diagnostic handlers that may be listening.
static ParseResult parse(OpAsmParser &parser, OperationState &result)
Parse the custom form of an operation.
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening.
void print(raw_ostream &os, OpPrintingFlags flags=std::nullopt)
Print the operation to the given stream.
This class provides the API for ops that are known to be isolated from above.
This class provides the API for ops that are known to be terminators.
This class provides the API for ops that are known to have no SSA operand.
This class implements the operand iterators for the Operation class.
type_range getTypes() const
StringRef getStringRef() const
Return the name of this operation. This always succeeds.
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,...
LogicalResult foldHook(Operation *op, ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results) const
This hook implements a generalized folder for this operation.
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.
CloneOptions()
Default constructs an option with all flags set to false.
static CloneOptions all()
Returns an instance with all flags set to true.
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.
Operation is the basic unit of execution within MLIR.
void replaceUsesOfWith(Value from, Value to)
Replace any uses of 'from' with 'to' within this operation.
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Attempt to fold this operation with the specified constant operand values.
bool use_empty()
Returns true if this operation has no uses.
Value getOperand(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)
unsigned getNumSuccessors()
bool isBeforeInBlock(Operation *other)
Given an operation 'other' that is within the same parent block, return whether the current operation...
void dropAllReferences()
This drops all operand uses from this operation, which is an essential step in breaking cyclic depend...
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...
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
MLIRContext * getContext()
Return the context this operation is associated with.
unsigned getNumRegions()
Returns the number of regions held by this operation.
Location getLoc()
The source location the operation was defined or derived from.
void dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
unsigned getNumOperands()
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.
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.
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
void destroy()
Destroys this operation and its subclass data.
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.
MutableArrayRef< BlockOperand > getBlockOperands()
operand_type_range getOperandTypes()
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...
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()
Region * getParentRegion()
Returns the region to which the instruction belongs.
result_range getResults()
bool isProperAncestor(Operation *other)
Return true if this operation is a proper ancestor of the other operation.
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening.
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.
void erase()
Remove this operation from its parent block and delete it.
unsigned getNumResults()
Return the number of results held by this operation.
This class represents success/failure for parsing-like operations that find it important to chain tog...
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.
void cloneInto(Region *dest, IRMapping &mapper)
Clone the internal blocks from this region into dest.
void takeBody(Region &other)
Takes body of another region (that region will have no body after this operation completes).
This class implements the result iterators for the Operation class.
type_range getTypes() const
Tensor types represent multi-dimensional arrays, and have two variants: RankedTensorType and Unranked...
This class provides an efficient unique identifier for a specific C++ type.
This class provides an abstraction over the various different ranges of value types.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
TypeID getTypeID()
Return a unique identifier for the concrete type.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Type getType() const
Return the type of this value.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
This class handles the management of operation operands.
void setOperands(Operation *owner, ValueRange values)
Replace the operands contained in the storage with the ones provided in 'values'.
This class provides the implementation for an operation result whose index cannot be represented "inl...
OpFoldResult foldIdempotent(Operation *op)
LogicalResult verifyResultsAreFloatLike(Operation *op)
LogicalResult verifyAtLeastNResults(Operation *op, unsigned numOperands)
LogicalResult verifyIsIdempotent(Operation *op)
LogicalResult verifyOperandsAreSignlessIntegerLike(Operation *op)
LogicalResult verifyNOperands(Operation *op, unsigned numOperands)
LogicalResult verifyNoRegionArguments(Operation *op)
LogicalResult verifyResultsAreSignlessIntegerLike(Operation *op)
LogicalResult verifyIsInvolution(Operation *op)
LogicalResult verifyOperandsAreFloatLike(Operation *op)
LogicalResult verifyZeroRegions(Operation *op)
LogicalResult verifyNSuccessors(Operation *op, unsigned numSuccessors)
LogicalResult verifyOperandSizeAttr(Operation *op, StringRef sizeAttrName)
LogicalResult verifyAtLeastNRegions(Operation *op, unsigned numRegions)
LogicalResult verifyValueSizeAttr(Operation *op, StringRef attrName, StringRef valueGroupName, size_t expectedCount)
LogicalResult verifyZeroResults(Operation *op)
LogicalResult verifySameOperandsAndResultType(Operation *op)
LogicalResult verifySameOperandsShape(Operation *op)
LogicalResult verifyAtLeastNSuccessors(Operation *op, unsigned numSuccessors)
LogicalResult verifyIsTerminator(Operation *op)
LogicalResult verifyAtLeastNOperands(Operation *op, unsigned numOperands)
LogicalResult verifyZeroOperands(Operation *op)
LogicalResult verifyElementwise(Operation *op)
LogicalResult verifyOneRegion(Operation *op)
LogicalResult verifyOneOperand(Operation *op)
LogicalResult verifyIsIsolatedFromAbove(Operation *op)
Check for any values used by operations regions attached to the specified "IsIsolatedFromAbove" opera...
LogicalResult verifyZeroSuccessors(Operation *op)
LogicalResult verifySameOperandsElementType(Operation *op)
LogicalResult verifyOneSuccessor(Operation *op)
LogicalResult verifySameOperandsAndResultElementType(Operation *op)
OpFoldResult foldInvolution(Operation *op)
LogicalResult verifyResultsAreBoolLike(Operation *op)
LogicalResult verifyNResults(Operation *op, unsigned numOperands)
LogicalResult verifyResultSizeAttr(Operation *op, StringRef sizeAttrName)
LogicalResult verifyNRegions(Operation *op, unsigned numRegions)
LogicalResult verifyOneResult(Operation *op)
LogicalResult verifySameTypeOperands(Operation *op)
LogicalResult verifySameOperandsAndResultShape(Operation *op)
bool hasElementwiseMappableTraits(Operation *op)
Together, Elementwise, Scalarizable, Vectorizable, and Tensorizable provide an easy way for scalar op...
LogicalResult foldCastInterfaceOp(Operation *op, ArrayRef< Attribute > attrOperands, SmallVectorImpl< OpFoldResult > &foldResults)
Attempt to fold the given cast operation.
LogicalResult verifyCastInterfaceOp(Operation *op, function_ref< bool(TypeRange, TypeRange)> areCastCompatible)
Attempt to verify the given cast operation.
void ensureRegionTerminator(Region ®ion, OpBuilder &builder, Location loc, function_ref< Operation *(OpBuilder &, Location)> buildTerminatorOp)
Insert an operation, generated by buildTerminatorOp, at the end of the region's only block if it does...
This header declares functions that assit transformations in the MemRef dialect.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
LogicalResult verifyCompatibleShapes(TypeRange types1, TypeRange types2)
Returns success if the given two arrays have the same number of elements and each pair wise entries h...
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Type getElementTypeOrSelf(Type type)
Return the element type or return the type itself.
InFlightDiagnostic emitRemark(Location loc)
Utility method to emit a remark message using this location.
LogicalResult verifyCompatibleShape(ArrayRef< int64_t > shape1, ArrayRef< int64_t > shape2)
Returns success if the given two shapes are compatible.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
void removeNodeFromList(Operation *op)
This is a trait method invoked when an operation is removed from a block.
void transferNodesFromList(ilist_traits< Operation > &otherList, op_iterator first, op_iterator last)
This is a trait method invoked when an operation is moved from one block to another.
void addNodeToList(Operation *op)
This is a trait method invoked when an operation is added to a block.
static void deleteNode(Operation *op)
simple_ilist< Operation >::iterator op_iterator
This class represents an efficient way to signal success or failure.
This trait tags element-wise ops on vectors or tensors.
This trait tags Elementwise operatons that can be systematically scalarized.
This trait tags Elementwise operatons that can be systematically tensorized.
This trait tags Elementwise operatons that can be systematically vectorized.
This represents an operation in an abstracted form, suitable for use with the builder APIs.
SmallVector< Block *, 1 > successors
Successors of this operation and their respective operands.
SmallVector< Value, 4 > operands
SmallVector< std::unique_ptr< Region >, 1 > regions
Regions that the op will hold.
MLIRContext * getContext() const
Get the context held by this operation state.
SmallVector< Type, 4 > types
Types of the results of this operation.
This class provides the implementation for an operation result whose index can be represented "inline...