21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/Support/ErrorHandling.h"
36 create(state.location, state.name, state.types, state.operands,
37 state.attributes.getDictionary(state.getContext()),
38 state.properties, state.successors, state.regions);
39 if (LLVM_UNLIKELY(state.propertiesAttr)) {
40 assert(!state.properties);
41 LogicalResult result =
44 assert(result.succeeded() &&
"invalid properties in op creation");
56 unsigned numRegions = regions.size();
58 create(location, name, resultTypes, operands, std::move(attributes),
59 properties, successors, numRegions);
60 for (
unsigned i = 0; i < numRegions; ++i)
71 unsigned numRegions) {
75 return create(location, name, resultTypes, operands,
76 attributes.getDictionary(location.
getContext()), properties,
77 successors, numRegions);
84 DictionaryAttr attributes,
86 unsigned numRegions) {
87 assert(llvm::all_of(resultTypes, [](
Type t) {
return t; }) &&
88 "unexpected null result type");
91 unsigned numTrailingResults = OpResult::getNumTrailing(resultTypes.size());
92 unsigned numInlineResults = OpResult::getNumInline(resultTypes.size());
93 unsigned numSuccessors = successors.size();
94 unsigned numOperands = operands.size();
95 unsigned numResults = resultTypes.size();
100 bool needsOperandStorage =
109 needsOperandStorage ? 1 : 0, opPropertiesAllocSize, numSuccessors,
110 numRegions, numOperands);
111 size_t prefixByteSize = llvm::alignTo(
112 Operation::prefixAllocSize(numTrailingResults, numInlineResults),
114 char *mallocMem =
reinterpret_cast<char *
>(malloc(byteSize + prefixByteSize));
115 void *rawMem = mallocMem + prefixByteSize;
119 location, name, numResults, numSuccessors, numRegions,
120 opPropertiesAllocSize, attributes, properties, needsOperandStorage);
123 "unexpected successors in a non-terminator operation");
126 auto resultTypeIt = resultTypes.begin();
127 for (
unsigned i = 0; i < numInlineResults; ++i, ++resultTypeIt)
129 for (
unsigned i = 0; i < numTrailingResults; ++i, ++resultTypeIt) {
130 new (op->getOutOfLineOpResult(i))
135 for (
unsigned i = 0; i != numRegions; ++i)
139 if (needsOperandStorage) {
141 op, op->getTrailingObjects<
OpOperand>(), operands);
146 for (
unsigned i = 0; i != numSuccessors; ++i)
147 new (&blockOperands[i])
BlockOperand(op, successors[i]);
156 unsigned numSuccessors,
unsigned numRegions,
157 int fullPropertiesStorageSize, DictionaryAttr attributes,
159 : location(location), numResults(numResults), numSuccs(numSuccessors),
160 numRegions(numRegions), hasOperandStorage(hasOperandStorage),
161 propertiesStorageSize((fullPropertiesStorageSize + 7) / 8), name(name) {
162 assert(attributes &&
"unexpected null attribute dictionary");
163 assert(fullPropertiesStorageSize <= propertiesCapacity &&
164 "Properties size overflow");
167 llvm::report_fatal_error(
169 " created with unregistered dialect. If this is intended, please call "
170 "allowUnregisteredDialects() on the MLIRContext, or use "
171 "-allow-unregistered-dialect with the MLIR tool used.");
173 if (fullPropertiesStorageSize)
179 Operation::~Operation() {
180 assert(block ==
nullptr &&
"operation destroyed but still in a block");
185 emitOpError(
"operation destroyed but still has uses");
187 diag.attachNote(user->getLoc()) <<
"- use: " << *user <<
"\n";
189 llvm::report_fatal_error(
"operation destroyed but still has uses");
193 if (hasOperandStorage)
198 successor.~BlockOperand();
203 if (propertiesStorageSize)
211 char *rawMem =
reinterpret_cast<char *
>(
this) -
212 llvm::alignTo(prefixAllocSize(),
alignof(
Operation));
231 if (operand.get() == from)
238 if (LLVM_LIKELY(hasOperandStorage))
239 return getOperandStorage().
setOperands(
this, operands);
240 assert(operands.empty() &&
"setting operands without an operand storage");
249 "invalid operand range specified");
250 if (LLVM_LIKELY(hasOperandStorage))
251 return getOperandStorage().
setOperands(
this, start, length, operands);
252 assert(operands.empty() &&
"setting operands without an operand storage");
257 if (LLVM_LIKELY(hasOperandStorage))
259 assert(operands.empty() &&
"inserting operands without an operand storage");
270 if (
getContext()->shouldPrintOpOnDiagnostic()) {
272 .append(
"see current operation: ")
282 if (
getContext()->shouldPrintOpOnDiagnostic())
283 diag.attachNote(
getLoc()) <<
"see current operation: " << *
this;
291 if (
getContext()->shouldPrintOpOnDiagnostic())
292 diag.attachNote(
getLoc()) <<
"see current operation: " << *
this;
306 assert(newAttrs &&
"expected valid attribute dictionary");
311 discardableAttrs.reserve(newAttrs.size());
316 discardableAttrs.push_back(attr);
318 if (discardableAttrs.size() != newAttrs.size())
328 discardableAttrs.reserve(newAttrs.size());
333 discardableAttrs.push_back(attr);
351 if (LLVM_UNLIKELY(!info))
353 return info->getOpPropertiesAsAttribute(
this);
358 if (LLVM_UNLIKELY(!info)) {
362 return info->setOpPropertiesFromAttribute(
378 constexpr
unsigned Operation::kInvalidOrderIdx;
379 constexpr
unsigned Operation::kOrderStride;
387 assert(block &&
"Operations without parent blocks have no order.");
388 assert(other && other->block == block &&
389 "Expected other operation to have the same parent block.");
396 updateOrderIfNecessary();
397 other->updateOrderIfNecessary();
400 return orderIndex < other->orderIndex;
405 void Operation::updateOrderIfNecessary() {
406 assert(block &&
"expected valid parent");
409 if (hasValidOrder() || llvm::hasSingleElement(*block))
416 assert(blockFront != blockBack &&
"expected more than one operation");
419 if (
this == blockBack) {
421 if (!prevNode->hasValidOrder())
425 orderIndex = prevNode->orderIndex + kOrderStride;
431 if (
this == blockFront) {
433 if (!nextNode->hasValidOrder())
436 if (nextNode->orderIndex == 0)
441 if (nextNode->orderIndex <= kOrderStride)
442 orderIndex = (nextNode->orderIndex / 2);
444 orderIndex = kOrderStride;
450 Operation *prevNode = getPrevNode(), *nextNode = getNextNode();
451 if (!prevNode->hasValidOrder() || !nextNode->hasValidOrder())
453 unsigned prevOrder = prevNode->orderIndex, nextOrder = nextNode->orderIndex;
456 if (prevOrder + 1 == nextOrder)
458 orderIndex = prevOrder + ((nextOrder - prevOrder) / 2);
465 auto llvm::ilist_detail::SpecificNodeAccess<
466 typename llvm::ilist_detail::compute_node_options<
468 return NodeAccess::getNodePtr<OptionsT>(n);
471 auto llvm::ilist_detail::SpecificNodeAccess<
472 typename llvm::ilist_detail::compute_node_options<
474 ->
const node_type * {
475 return NodeAccess::getNodePtr<OptionsT>(n);
478 auto llvm::ilist_detail::SpecificNodeAccess<
479 typename llvm::ilist_detail::compute_node_options<
481 return NodeAccess::getValuePtr<OptionsT>(n);
484 auto llvm::ilist_detail::SpecificNodeAccess<
485 typename llvm::ilist_detail::compute_node_options<
488 return NodeAccess::getValuePtr<OptionsT>(n);
495 Block *llvm::ilist_traits<::mlir::Operation>::getContainingBlock() {
497 iplist<Operation> *anchor(
static_cast<iplist<Operation> *
>(
this));
498 return reinterpret_cast<Block *
>(
reinterpret_cast<char *
>(anchor) - offset);
504 assert(!op->
getBlock() &&
"already in an operation block!");
505 op->block = getContainingBlock();
508 op->orderIndex = Operation::kInvalidOrderIdx;
514 assert(op->block &&
"not already in an operation block!");
522 Block *curParent = getContainingBlock();
529 if (curParent == otherList.getContainingBlock())
533 for (; first != last; ++first)
534 first->block = curParent;
541 parent->getOperations().erase(
this);
549 parent->getOperations().remove(
this);
562 llvm::iplist<Operation>::iterator iterator) {
576 llvm::iplist<Operation>::iterator iterator) {
577 assert(iterator != block->
end() &&
"cannot move after end of block");
601 for (
auto &block : region)
618 for (
auto [ofr, opResult] : llvm::zip_equal(results, op->
getResults())) {
619 if (
auto value = dyn_cast<Value>(ofr)) {
620 if (value.getType() != opResult.getType()) {
621 op->
emitOpError() <<
"folder produced a value of incorrect type: "
623 <<
", expected: " << opResult.getType();
624 assert(
false &&
"incorrect fold result type");
636 if (succeeded(name.
foldHook(
this, operands, results))) {
652 LogicalResult status = interface->fold(
this, operands, results);
654 if (succeeded(status))
666 return fold(constants, results);
680 : cloneRegionsFlag(false), cloneOperandsFlag(false) {}
683 : cloneRegionsFlag(cloneRegions), cloneOperandsFlag(cloneOperands) {}
690 cloneRegionsFlag = enable;
695 cloneOperandsFlag = enable;
722 if (
options.shouldCloneOperands()) {
736 mapper.
map(
this, newOp);
739 if (
options.shouldCloneRegions()) {
740 for (
unsigned i = 0; i != numRegions; ++i)
765 return (*parseFn)(parser, result);
773 printOpName(op, p, defaultDialect);
783 StringRef defaultDialect) {
785 if (name.starts_with((defaultDialect +
".").str()) && name.count(
'.') == 1)
786 name = name.drop_front(defaultDialect.size() + 1);
806 auto dictAttr = dyn_cast_or_null<::mlir::DictionaryAttr>(properties);
807 if (dictAttr && !elidedProps.empty()) {
809 llvm::SmallDenseSet<StringRef> elidedAttrsSet(elidedProps.begin(),
811 bool atLeastOneAttr = llvm::any_of(attrs, [&](
NamedAttribute attr) {
812 return !elidedAttrsSet.contains(attr.
getName().strref());
814 if (atLeastOneAttr) {
820 p <<
"<" << properties <<
">";
827 return getOperation()->emitError(message);
833 return getOperation()->emitOpError(message);
839 return getOperation()->emitWarning(message);
845 return getOperation()->emitRemark(message);
861 return !
static_cast<bool>(operands[std::distance(operandsBegin, &o)]);
863 auto *firstConstantIt = llvm::find_if_not(op->
getOpOperands(), isNonConstant);
864 auto *newConstantIt = std::stable_partition(
867 return success(firstConstantIt != newConstantIt);
873 if (argumentOp && op->
getName() == argumentOp->getName()) {
886 if (argumentOp && op->
getName() == argumentOp->getName()) {
896 return op->
emitOpError() <<
"requires zero operands";
902 return op->
emitOpError() <<
"requires a single operand";
907 unsigned numOperands) {
909 return op->
emitOpError() <<
"expected " << numOperands
916 unsigned numOperands) {
919 <<
"expected " << numOperands <<
" or more operands, but found "
927 if (
auto vec = llvm::dyn_cast<VectorType>(type))
928 return vec.getElementType();
931 if (
auto tensor = llvm::dyn_cast<TensorType>(type))
956 if (!type.isSignlessIntOrIndex())
957 return op->
emitOpError() <<
"requires an integer or index type";
965 if (!llvm::isa<FloatType>(type))
980 return op->
emitOpError() <<
"requires all operands to have the same type";
986 return op->
emitOpError() <<
"requires zero regions";
997 unsigned numRegions) {
999 return op->
emitOpError() <<
"expected " << numRegions <<
" regions";
1004 unsigned numRegions) {
1006 return op->
emitOpError() <<
"expected " << numRegions <<
" or more regions";
1012 return op->
emitOpError() <<
"requires zero results";
1018 return op->
emitOpError() <<
"requires one result";
1023 unsigned numOperands) {
1025 return op->
emitOpError() <<
"expected " << numOperands <<
" results";
1030 unsigned numOperands) {
1033 <<
"expected " << numOperands <<
" or more results";
1042 return op->
emitOpError() <<
"requires the same shape for all operands";
1057 <<
"requires the same shape for all operands and results";
1067 for (
auto operand : llvm::drop_begin(op->
getOperands(), 1)) {
1069 return op->
emitOpError(
"requires the same element type for all operands");
1084 for (
auto result : llvm::drop_begin(op->
getResults(), 1)) {
1087 "requires the same element type for all operands and results");
1094 "requires the same element type for all operands and results");
1108 if (
auto rankedType = dyn_cast<RankedTensorType>(type))
1109 encoding = rankedType.getEncoding();
1114 <<
"requires the same type for all operands and results";
1116 if (
auto rankedType = dyn_cast<RankedTensorType>(resultType);
1117 encoding != rankedType.getEncoding())
1119 <<
"requires the same encoding for all operands and results";
1125 <<
"requires the same type for all operands and results";
1127 if (
auto rankedType = dyn_cast<RankedTensorType>(opType);
1128 encoding != rankedType.getEncoding())
1130 <<
"requires the same encoding for all operands and results";
1141 auto hasRank = [](
const Type type) {
1142 if (
auto shapedType = dyn_cast<ShapedType>(type))
1143 return shapedType.hasRank();
1148 auto rankedOperandTypes =
1150 auto rankedResultTypes =
1154 if (rankedOperandTypes.empty() && rankedResultTypes.empty())
1158 auto getRank = [](
const Type type) {
1159 return cast<ShapedType>(type).getRank();
1162 auto rank = !rankedOperandTypes.empty() ? getRank(*rankedOperandTypes.begin())
1163 : getRank(*rankedResultTypes.begin());
1165 for (
const auto type : rankedOperandTypes) {
1166 if (rank != getRank(type)) {
1167 return op->
emitOpError(
"operands don't have matching ranks");
1171 for (
const auto type : rankedResultTypes) {
1172 if (rank != getRank(type)) {
1173 return op->
emitOpError(
"result type has different rank than operands");
1183 if (!block || &block->
back() != op)
1184 return op->
emitOpError(
"must be the last operation in the parent block");
1193 if (succ->getParent() != parent)
1194 return op->
emitError(
"reference to block defined in another region");
1200 return op->
emitOpError(
"requires 0 successors but found ")
1208 return op->
emitOpError(
"requires 1 successor but found ")
1214 unsigned numSuccessors) {
1217 << numSuccessors <<
" successors but found "
1223 unsigned numSuccessors) {
1226 << numSuccessors <<
" successors but found "
1235 bool isBoolType = elementType.isInteger(1);
1237 return op->
emitOpError() <<
"requires a bool result type";
1246 return op->
emitOpError() <<
"requires a floating point type";
1255 return op->
emitOpError() <<
"requires an integer or index type";
1261 StringRef valueGroupName,
1262 size_t expectedCount) {
1265 return op->
emitOpError(
"requires dense i32 array attribute '")
1269 if (llvm::any_of(sizes, [](int32_t element) {
return element < 0; }))
1271 << attrName <<
"' attribute cannot have negative elements";
1274 std::accumulate(sizes.begin(), sizes.end(), 0,
1275 [](
unsigned all, int32_t one) { return all + one; });
1277 if (totalCount != expectedCount)
1279 << valueGroupName <<
" count (" << expectedCount
1280 <<
") does not match with the total size (" << totalCount
1281 <<
") specified in attribute '" << attrName <<
"'";
1286 StringRef attrName) {
1291 StringRef attrName) {
1300 if (region.getNumArguments() != 0) {
1303 << region.getRegionNumber() <<
" should have no arguments";
1304 return op->
emitOpError(
"region should have no arguments");
1311 auto isMappableType = llvm::IsaPred<VectorType, TensorType>;
1312 auto resultMappableTypes = llvm::to_vector<1>(
1314 auto operandMappableTypes = llvm::to_vector<2>(
1319 if (resultMappableTypes.empty() && operandMappableTypes.empty())
1322 if (!resultMappableTypes.empty() && operandMappableTypes.empty())
1323 return op->
emitOpError(
"if a result is non-scalar, then at least one "
1324 "operand must be non-scalar");
1326 assert(!operandMappableTypes.empty());
1328 if (resultMappableTypes.empty())
1329 return op->
emitOpError(
"if an operand is non-scalar, then there must be at "
1330 "least one non-scalar result");
1334 "if an operand is non-scalar, then all results must be non-scalar");
1337 llvm::concat<Type>(operandMappableTypes, resultMappableTypes));
1338 TypeID expectedBaseTy = types.front().getTypeID();
1339 if (!llvm::all_of(types,
1342 return op->
emitOpError() <<
"all non-scalar operands/results must have the "
1343 "same shape and base type";
1353 "Intended to check IsolatedFromAbove ops");
1359 for (
auto ®ion : isolatedOp->
getRegions()) {
1360 pendingRegions.push_back(®ion);
1363 while (!pendingRegions.empty()) {
1364 for (
Operation &op : pendingRegions.pop_back_val()->getOps()) {
1368 auto *operandRegion = operand.getParentRegion();
1370 return op.
emitError(
"operation's operand is unlinked");
1371 if (!region.isAncestor(operandRegion)) {
1372 return op.
emitOpError(
"using value defined outside the region")
1374 <<
"required by region isolation constraints";
1384 pendingRegions.push_back(&subRegion);
1418 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)
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.
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.
Diagnostic & attachNote(std::optional< Location > noteLoc=std::nullopt)
Attaches a note to this diagnostic.
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.
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 printOptionalAttrDict(ArrayRef< NamedAttribute > attrs, ArrayRef< StringRef > elidedAttrs={})=0
If the specified operation has attributes, print out an attribute dictionary with their values.
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 genericPrintProperties(OpAsmPrinter &p, Attribute properties, ArrayRef< StringRef > elidedProps={})
Print the properties as a Attribute with names not included within 'elidedProps'.
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.
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.
Simple wrapper around a void* in order to express generically how to pass in op properties through AP...
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
bool hasTrait() const
Returns true if the operation was registered with a particular trait, e.g.
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.
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context,...
void initOpProperties(OpaqueProperties storage, OpaqueProperties init) const
Initialize the op properties.
llvm::hash_code hashOpProperties(OpaqueProperties properties) const
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.
void destroyOpProperties(OpaqueProperties properties) const
This hooks destroy the op properties.
int getOpPropertyByteSize() const
This hooks return the number of bytes to allocate for the op properties.
void copyOpProperties(OpaqueProperties lhs, OpaqueProperties rhs) const
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 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.
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
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)
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.
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.
std::optional< Attribute > getInherentAttr(StringRef name)
Access an inherent attribute by name: returns an empty optional if there is no inherent attribute wit...
MLIRContext * getContext()
Return the context this operation is associated with.
unsigned getNumRegions()
Returns the number of regions held by this operation.
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 dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
unsigned getNumOperands()
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.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
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.
LogicalResult setPropertiesFromAttribute(Attribute attr, function_ref< InFlightDiagnostic()> emitError)
Set the properties from the provided attribute.
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()
int getPropertiesStorageSize() const
Returns the properties storage size.
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...
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.
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.
unsigned getNumResults()
Return the number of results held by this operation.
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.
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 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.
InFlightDiagnostic emitRemark(Location loc)
Utility method to emit a remark message using this location.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
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.
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 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.
This class provides the implementation for an operation result whose index can be represented "inline...