21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/Support/ErrorHandling.h"
39 assert(!state.properties);
43 assert(
result.succeeded() &&
"invalid properties in op creation");
54 unsigned numRegions = regions.size();
56 create(location, name, resultTypes, operands, std::move(attributes),
57 properties, successors, numRegions);
58 for (
unsigned i = 0; i < numRegions; ++i)
72 return create(location, name, resultTypes, operands,
73 attributes.getDictionary(location.getContext()), properties,
74 successors, numRegions);
83 assert(llvm::all_of(resultTypes, [](
Type t) {
return t; }) &&
84 "unexpected null result type");
87 unsigned numTrailingResults = OpResult::getNumTrailing(resultTypes.size());
88 unsigned numInlineResults = OpResult::getNumInline(resultTypes.size());
89 unsigned numSuccessors = successors.size();
90 unsigned numOperands = operands.size();
91 unsigned numResults = resultTypes.size();
92 int opPropertiesAllocSize = llvm::alignTo<8>(name.getOpPropertyByteSize());
96 bool needsOperandStorage =
105 needsOperandStorage ? 1 : 0, opPropertiesAllocSize, numSuccessors,
106 numRegions, numOperands);
107 size_t prefixByteSize = llvm::alignTo(
108 Operation::prefixAllocSize(numTrailingResults, numInlineResults),
110 char *mallocMem =
reinterpret_cast<char *
>(malloc(byteSize + prefixByteSize));
111 void *rawMem = mallocMem + prefixByteSize;
114 Operation *op = ::new (rawMem) Operation(
115 location, name, numResults, numSuccessors, numRegions,
116 opPropertiesAllocSize, attributes, properties, needsOperandStorage);
119 "unexpected successors in a non-terminator operation");
122 auto resultTypeIt = resultTypes.begin();
123 for (
unsigned i = 0; i < numInlineResults; ++i, ++resultTypeIt)
125 for (
unsigned i = 0; i < numTrailingResults; ++i, ++resultTypeIt) {
126 new (op->getOutOfLineOpResult(i))
131 for (
unsigned i = 0; i != numRegions; ++i)
135 if (needsOperandStorage) {
137 op, op->getTrailingObjects<
OpOperand>(), operands);
142 for (
unsigned i = 0; i != numSuccessors; ++i)
143 new (&blockOperands[i])
BlockOperand(op, successors[i]);
152 unsigned numSuccessors,
unsigned numRegions,
153 int fullPropertiesStorageSize, DictionaryAttr attributes,
155 : location(location), numResults(numResults), numSuccs(numSuccessors),
156 numRegions(numRegions), hasOperandStorage(hasOperandStorage),
157 propertiesStorageSize((fullPropertiesStorageSize + 7) / 8), name(name) {
158 assert(attributes &&
"unexpected null attribute dictionary");
159 assert(fullPropertiesStorageSize <= propertiesCapacity &&
160 "Properties size overflow");
163 llvm::report_fatal_error(
165 " created with unregistered dialect. If this is intended, please call "
166 "allowUnregisteredDialects() on the MLIRContext, or use "
167 "-allow-unregistered-dialect with the MLIR tool used.");
169 if (fullPropertiesStorageSize)
175Operation::~Operation() {
176 assert(block ==
nullptr &&
"operation destroyed but still in a block");
181 emitOpError(
"operation destroyed but still has uses");
183 diag.attachNote(user->getLoc()) <<
"- use: " << *user <<
"\n";
185 llvm::report_fatal_error(
"operation destroyed but still has uses");
189 if (hasOperandStorage)
190 getOperandStorage().~OperandStorage();
194 successor.~BlockOperand();
199 if (propertiesStorageSize)
207 char *rawMem =
reinterpret_cast<char *
>(
this) -
208 llvm::alignTo(prefixAllocSize(),
alignof(Operation));
227 if (operand.get() == from)
234 if (LLVM_LIKELY(hasOperandStorage))
235 return getOperandStorage().setOperands(
this, operands);
236 assert(operands.empty() &&
"setting operands without an operand storage");
245 "invalid operand range specified");
246 if (LLVM_LIKELY(hasOperandStorage))
247 return getOperandStorage().setOperands(
this, start, length, operands);
248 assert(operands.empty() &&
"setting operands without an operand storage");
253 if (LLVM_LIKELY(hasOperandStorage))
255 assert(operands.empty() &&
"inserting operands without an operand storage");
266 if (
getContext()->shouldPrintOpOnDiagnostic()) {
268 .append(
"see current operation: ")
278 if (
getContext()->shouldPrintOpOnDiagnostic())
279 diag.attachNote(
getLoc()) <<
"see current operation: " << *
this;
287 if (
getContext()->shouldPrintOpOnDiagnostic())
288 diag.attachNote(
getLoc()) <<
"see current operation: " << *
this;
302 assert(newAttrs &&
"expected valid attribute dictionary");
307 discardableAttrs.reserve(newAttrs.size());
312 discardableAttrs.push_back(attr);
314 if (discardableAttrs.size() != newAttrs.size())
315 newAttrs = DictionaryAttr::get(
getContext(), discardableAttrs);
324 discardableAttrs.reserve(newAttrs.size());
329 discardableAttrs.push_back(attr);
331 attrs = DictionaryAttr::get(
getContext(), discardableAttrs);
334 attrs = DictionaryAttr::get(
getContext(), newAttrs);
347 if (LLVM_UNLIKELY(!info))
349 return info->getOpPropertiesAsAttribute(
this);
354 if (LLVM_UNLIKELY(!info)) {
358 return info->setOpPropertiesFromAttribute(
380 assert(block &&
"Operations without parent blocks have no order.");
381 assert(other && other->block == block &&
382 "Expected other operation to have the same parent block.");
385 if (!block->isOpOrderValid()) {
386 block->recomputeOpOrder();
389 updateOrderIfNecessary();
390 other->updateOrderIfNecessary();
393 return orderIndex < other->orderIndex;
398void Operation::updateOrderIfNecessary() {
399 assert(block &&
"expected valid parent");
402 if (hasValidOrder() || llvm::hasSingleElement(*block))
409 assert(blockFront != blockBack &&
"expected more than one operation");
412 if (
this == blockBack) {
414 if (!prevNode->hasValidOrder())
418 orderIndex = prevNode->orderIndex + kOrderStride;
424 if (
this == blockFront) {
426 if (!nextNode->hasValidOrder())
429 if (nextNode->orderIndex == 0)
434 if (nextNode->orderIndex <= kOrderStride)
435 orderIndex = (nextNode->orderIndex / 2);
437 orderIndex = kOrderStride;
443 Operation *prevNode = getPrevNode(), *nextNode = getNextNode();
444 if (!prevNode->hasValidOrder() || !nextNode->hasValidOrder())
445 return block->recomputeOpOrder();
446 unsigned prevOrder = prevNode->orderIndex, nextOrder = nextNode->orderIndex;
449 if (prevOrder + 1 == nextOrder)
450 return block->recomputeOpOrder();
451 orderIndex = prevOrder + ((nextOrder - prevOrder) / 2);
458auto llvm::ilist_detail::SpecificNodeAccess<
459 llvm::ilist_detail::compute_node_options<::mlir::Operation>::type>::
460 getNodePtr(pointer n) -> node_type * {
461 return NodeAccess::getNodePtr<OptionsT>(n);
464auto llvm::ilist_detail::SpecificNodeAccess<
465 llvm::ilist_detail::compute_node_options<::mlir::Operation>::type>::
466 getNodePtr(const_pointer n) ->
const node_type * {
467 return NodeAccess::getNodePtr<OptionsT>(n);
470auto llvm::ilist_detail::SpecificNodeAccess<
471 llvm::ilist_detail::compute_node_options<::mlir::Operation>::type>::
472 getValuePtr(node_type *n) -> pointer {
473 return NodeAccess::getValuePtr<OptionsT>(n);
476auto llvm::ilist_detail::SpecificNodeAccess<
477 llvm::ilist_detail::compute_node_options<::mlir::Operation>::type>::
478 getValuePtr(
const node_type *n) -> const_pointer {
479 return NodeAccess::getValuePtr<OptionsT>(n);
486Block *llvm::ilist_traits<::mlir::Operation>::getContainingBlock() {
488 iplist<Operation> *anchor(
static_cast<iplist<Operation> *
>(
this));
489 return reinterpret_cast<Block *
>(
reinterpret_cast<char *
>(anchor) - offset);
495 assert(!op->
getBlock() &&
"already in an operation block!");
496 op->block = getContainingBlock();
499 op->orderIndex = Operation::kInvalidOrderIdx;
505 assert(op->block &&
"not already in an operation block!");
513 Block *curParent = getContainingBlock();
520 if (curParent == otherList.getContainingBlock())
524 for (; first != last; ++first)
525 first->block = curParent;
532 parent->getOperations().erase(
this);
540 parent->getOperations().remove(
this);
553 llvm::iplist<Operation>::iterator iterator) {
555 "cannot move an operation that isn't contained in a block");
556 block->getOperations().splice(iterator,
getBlock()->getOperations(),
569 llvm::iplist<Operation>::iterator iterator) {
570 assert(iterator != block->end() &&
"cannot move after end of block");
582 region.dropAllReferences();
594 for (
auto &block : region)
595 block.dropAllDefinedValueUses();
611 for (
auto [ofr, opResult] : llvm::zip_equal(results, op->
getResults())) {
612 if (
auto value = dyn_cast<Value>(ofr)) {
613 if (value.getType() != opResult.getType()) {
614 op->
emitOpError() <<
"folder produced a value of incorrect type: "
616 <<
", expected: " << opResult.getType();
617 assert(
false &&
"incorrect fold result type");
629 if (succeeded(name.foldHook(
this, operands, results))) {
641 auto *
interface = dyn_cast<DialectFoldInterface>(dialect);
645 LogicalResult status = interface->fold(
this, operands, results);
647 if (succeeded(status))
659 return fold(constants, results);
673 : cloneRegionsFlag(
false), cloneOperandsFlag(
false),
674 resultTypes(std::nullopt) {}
680 resultTypes(std::move(resultTypes)) {}
683 return CloneOptions().cloneRegions().cloneOperands().withResultTypes(
688 cloneRegionsFlag = enable;
693 cloneOperandsFlag = enable;
699 this->resultTypes = std::move(resultTypes);
726 if (
options.shouldCloneOperands()) {
741 mapper.
map(
this, newOp);
744 if (
options.shouldCloneRegions()) {
745 for (
unsigned i = 0; i != numRegions; ++i)
750 if (
options.shouldCloneResults())
769 if (
auto parseFn =
result.name.getDialect()->getParseOperationHook(
770 result.name.getStringRef()))
771 return (*parseFn)(parser,
result);
789 StringRef defaultDialect) {
791 if (name.starts_with((defaultDialect +
".").str()) && name.count(
'.') == 1)
792 name = name.drop_front(defaultDialect.size() + 1);
812 auto dictAttr = dyn_cast_or_null<::mlir::DictionaryAttr>(properties);
813 if (dictAttr && !elidedProps.empty()) {
815 llvm::SmallDenseSet<StringRef> elidedAttrsSet(elidedProps.begin(),
819 return !elidedAttrsSet.contains(attr.
getName().strref());
821 if (!filteredAttrs.empty()) {
829 p <<
"<" << properties <<
">";
870 return !
static_cast<bool>(operands[std::distance(operandsBegin, &o)]);
872 auto *firstConstantIt = llvm::find_if_not(op->
getOpOperands(), isNonConstant);
873 auto *newConstantIt = std::stable_partition(
876 return success(firstConstantIt != newConstantIt);
882 if (argumentOp && op->
getName() == argumentOp->getName()) {
895 if (argumentOp && op->
getName() == argumentOp->getName()) {
897 return argumentOp->getOperand(0);
905 return op->
emitOpError() <<
"requires zero operands";
911 return op->
emitOpError() <<
"requires a single operand";
916 unsigned numOperands) {
918 return op->
emitOpError() <<
"expected " << numOperands
925 unsigned numOperands) {
928 <<
"expected " << numOperands <<
" or more operands, but found "
936 if (
auto vec = llvm::dyn_cast<VectorType>(type))
937 return vec.getElementType();
940 if (
auto tensor = llvm::dyn_cast<TensorType>(type))
965 if (!type.isSignlessIntOrIndex())
966 return op->
emitOpError() <<
"requires an integer or index type";
974 if (!llvm::isa<FloatType>(type))
989 return op->
emitOpError() <<
"requires all operands to have the same type";
995 return op->
emitOpError() <<
"requires zero regions";
1001 return op->
emitOpError() <<
"requires one region";
1006 unsigned numRegions) {
1008 return op->
emitOpError() <<
"expected " << numRegions <<
" regions";
1013 unsigned numRegions) {
1015 return op->
emitOpError() <<
"expected " << numRegions <<
" or more regions";
1021 return op->
emitOpError() <<
"requires zero results";
1027 return op->
emitOpError() <<
"requires one result";
1032 unsigned numOperands) {
1034 return op->
emitOpError() <<
"expected " << numOperands <<
" results";
1039 unsigned numOperands) {
1042 <<
"expected " << numOperands <<
" or more results";
1051 return op->
emitOpError() <<
"requires the same shape for all operands";
1066 <<
"requires the same shape for all operands and results";
1076 for (
auto operand : llvm::drop_begin(op->
getOperands(), 1)) {
1078 return op->
emitOpError(
"requires the same element type for all operands");
1096 "requires the same element type for all operands and results");
1103 "requires the same element type for all operands and results");
1117 if (
auto rankedType = dyn_cast<RankedTensorType>(type))
1118 encoding = rankedType.getEncoding();
1123 <<
"requires the same type for all operands and results";
1125 if (
auto rankedType = dyn_cast<RankedTensorType>(resultType);
1126 encoding != rankedType.getEncoding())
1128 <<
"requires the same encoding for all operands and results";
1134 <<
"requires the same type for all operands and results";
1136 if (
auto rankedType = dyn_cast<RankedTensorType>(opType);
1137 encoding != rankedType.getEncoding())
1139 <<
"requires the same encoding for all operands and results";
1150 auto hasRank = [](
const Type type) {
1151 if (
auto shapedType = dyn_cast<ShapedType>(type))
1152 return shapedType.hasRank();
1157 auto rankedOperandTypes =
1159 auto rankedResultTypes =
1163 if (rankedOperandTypes.empty() && rankedResultTypes.empty())
1167 auto getRank = [](
const Type type) {
1168 return cast<ShapedType>(type).getRank();
1171 auto rank = !rankedOperandTypes.empty() ? getRank(*rankedOperandTypes.begin())
1172 : getRank(*rankedResultTypes.begin());
1174 for (
const auto type : rankedOperandTypes) {
1175 if (rank != getRank(type)) {
1176 return op->
emitOpError(
"operands don't have matching ranks");
1180 for (
const auto type : rankedResultTypes) {
1181 if (rank != getRank(type)) {
1182 return op->
emitOpError(
"result type has different rank than operands");
1192 if (!block || &block->
back() != op)
1193 return op->
emitOpError(
"must be the last operation in the parent block");
1202 if (succ->getParent() != parent)
1203 return op->
emitError(
"reference to block defined in another region");
1209 return op->
emitOpError(
"requires 0 successors but found ")
1217 return op->
emitOpError(
"requires 1 successor but found ")
1223 unsigned numSuccessors) {
1226 << numSuccessors <<
" successors but found "
1232 unsigned numSuccessors) {
1235 << numSuccessors <<
" successors but found "
1244 bool isBoolType = elementType.isInteger(1);
1246 return op->
emitOpError() <<
"requires a bool result type";
1255 return op->
emitOpError() <<
"requires a floating point type";
1264 return op->
emitOpError() <<
"requires an integer or index type";
1270 StringRef valueGroupName,
1271 size_t expectedCount) {
1274 return op->
emitOpError(
"requires dense i32 array attribute '")
1278 if (llvm::any_of(sizes, [](int32_t element) {
return element < 0; }))
1280 << attrName <<
"' attribute cannot have negative elements";
1282 size_t totalCount = llvm::sum_of(sizes,
size_t(0));
1283 if (totalCount != expectedCount)
1285 << valueGroupName <<
" count (" << expectedCount
1286 <<
") does not match with the total size (" << totalCount
1287 <<
") specified in attribute '" << attrName <<
"'";
1292 StringRef attrName) {
1297 StringRef attrName) {
1306 if (region.getNumArguments() != 0) {
1309 << region.getRegionNumber() <<
" should have no arguments";
1310 return op->
emitOpError(
"region should have no arguments");
1317 auto isMappableType = llvm::IsaPred<VectorType, TensorType>;
1318 auto resultMappableTypes =
1320 auto operandMappableTypes =
1325 if (resultMappableTypes.empty() && operandMappableTypes.empty())
1328 if (!resultMappableTypes.empty() && operandMappableTypes.empty())
1329 return op->
emitOpError(
"if a result is non-scalar, then at least one "
1330 "operand must be non-scalar");
1332 assert(!operandMappableTypes.empty());
1334 if (resultMappableTypes.empty())
1335 return op->
emitOpError(
"if an operand is non-scalar, then there must be at "
1336 "least one non-scalar result");
1340 "if an operand is non-scalar, then all results must be non-scalar");
1343 llvm::concat<Type>(operandMappableTypes, resultMappableTypes));
1344 TypeID expectedBaseTy = types.front().getTypeID();
1345 if (!llvm::all_of(types,
1348 return op->
emitOpError() <<
"all non-scalar operands/results must have the "
1349 "same shape and base type";
1359 "Intended to check IsolatedFromAbove ops");
1365 for (
auto ®ion : isolatedOp->
getRegions()) {
1366 pendingRegions.push_back(®ion);
1369 while (!pendingRegions.empty()) {
1370 for (
Operation &op : pendingRegions.pop_back_val()->getOps()) {
1371 for (
Value operand : op.getOperands()) {
1374 auto *operandRegion = operand.getParentRegion();
1376 return op.emitError(
"operation's operand is unlinked");
1377 if (!region.isAncestor(operandRegion)) {
1378 return op.emitOpError(
"using value defined outside the region")
1379 .attachNote(isolatedOp->
getLoc())
1380 <<
"required by region isolation constraints";
1387 if (op.getNumRegions() &&
1389 for (
Region &subRegion : op.getRegions())
1390 pendingRegions.push_back(&subRegion);
1424 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 void checkFoldResultTypes(Operation *op, SmallVectorImpl< OpFoldResult > &results)
Assert that the folded results (in case of values) have the same type as the results of the given op.
static std::string diag(const llvm::Value &value)
false
Parses a map_entries map type from a string format back into its numeric 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 ParseResult parseOptionalLess()=0
Parse a '<' token if present.
virtual ParseResult parseGreater()=0
Parse a '>' token.
virtual ParseResult parseAttribute(Attribute &result, Type type={})=0
Parse an arbitrary attribute of a given type and return it in result.
virtual raw_ostream & getStream() const
Return the raw output stream used by this printer.
virtual void printNamedAttribute(NamedAttribute attr)
Print the given named attribute.
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.
void invalidateOpOrder()
Invalidates the current ordering of operations.
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
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
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...
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.
NamedAttribute represents a combination of a name and an Attribute value.
StringAttr getName() const
Return the name of the attribute.
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.
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes={}, ArrayRef< Location > locs={})
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
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.
Operation * getOperation()
Return the operation that this refers to.
static void genericPrintProperties(OpAsmPrinter &p, Attribute properties, ArrayRef< StringRef > elidedProps={})
Print the properties as a Attribute with names not included within 'elidedProps'.
void print(raw_ostream &os, OpPrintingFlags flags={})
Print the operation to the given stream.
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 genericParseProperties(OpAsmParser &parser, Attribute &result)
Parse properties as a Attribute.
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.
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.
void populateInherentAttrs(Operation *op, NamedAttrList &attrs) const
StringRef getStringRef() const
Return the name of this operation. This always succeeds.
void setInherentAttr(Operation *op, StringAttr name, Attribute value) const
std::optional< Attribute > getInherentAttr(Operation *op, StringRef name) const
Lookup an inherent attribute by name, this method isn't recommended and may be removed in the future.
void initOpProperties(PropertyRef storage, PropertyRef init) const
Initialize the op properties.
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 such that all elements of the operation are cloned.
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.
Operation is the basic unit of execution within MLIR.
PropertyRef getPropertiesStorage()
Return a generic (but typed) reference to the property type storage.
void setInherentAttr(StringAttr name, Attribute value)
Set an inherent attribute by name.
void replaceUsesOfWith(Value from, Value to)
Replace any uses of 'from' with 'to' within this operation.
void copyProperties(PropertyRef rhs)
Copy properties from an existing other properties object.
MutableArrayRef< BlockOperand > getBlockOperands()
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
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.
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)
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)
void setAttrs(DictionaryAttr newAttrs)
Set the attributes from a dictionary on this operation.
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.
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
Block * getBlock()
Returns the operation block that contains this operation.
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...
unsigned getNumRegions()
Returns the number of regions held by this operation.
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...
MutableArrayRef< OpOperand > getOpOperands()
std::optional< RegisteredOperationName > getRegisteredInfo()
If this operation has a registered operation description, return it.
void dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
unsigned getNumOperands()
Attribute getPropertiesAsAttribute()
Return the properties converted to an attribute.
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...
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.
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.
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, NamedAttrList &&attributes, PropertyRef properties, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
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()
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.
bool isProperAncestor(Operation *other)
Return true if this operation is a proper ancestor of the other operation.
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.
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.
void erase()
Remove this operation from its parent block and delete it.
unsigned getNumResults()
Return the number of results held by this operation.
Type-safe wrapper around a void* for passing properties, including the properties structs of operatio...
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 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.
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 foldCommutative(Operation *op, ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
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 verifySameOperandsAndResultRank(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...
OpProperties
This is a "tag" used for mapping the properties storage in llvm::TrailingObjects.
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...
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
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.
Type getElementTypeOrSelf(Type type)
Return the element type or return the type itself.
detail::DenseArrayAttrImpl< int32_t > DenseI32ArrayAttr
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.
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
llvm::function_ref< Fn > function_ref
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)
::mlir::Operation Operation
simple_ilist< Operation >::iterator op_iterator
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
MLIRContext * getContext() const
Get the context held by this operation state.
SmallVector< std::unique_ptr< Region >, 1 > regions
Regions that the op will hold.
Attribute propertiesAttr
This Attribute is used to opaquely construct the properties of the operation.
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...