MLIR 24.0.0git
Operation.h
Go to the documentation of this file.
1//===- Operation.h - MLIR Operation Class -----------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the Operation class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef MLIR_IR_OPERATION_H
14#define MLIR_IR_OPERATION_H
15
16#include "mlir/IR/Block.h"
18#include "mlir/IR/Diagnostics.h"
20#include "mlir/IR/Region.h"
21#include <optional>
22
23namespace mlir {
24namespace detail {
25/// This is a "tag" used for mapping the properties storage in
26/// llvm::TrailingObjects.
27enum class OpProperties : char {};
28} // namespace detail
29
30/// Operation is the basic unit of execution within MLIR.
31///
32/// The following documentations are recommended to understand this class:
33/// - https://mlir.llvm.org/docs/LangRef/#operations
34/// - https://mlir.llvm.org/docs/Tutorials/UnderstandingTheIRStructure/
35///
36/// An Operation is defined first by its name, which is a unique string. The
37/// name is interpreted so that if it contains a '.' character, the part before
38/// is the dialect name this operation belongs to, and everything that follows
39/// is this operation name within the dialect.
40///
41/// An Operation defines zero or more SSA `Value` that we refer to as the
42/// Operation results. This array of Value is actually stored in memory before
43/// the Operation itself in reverse order. That is for an Operation with 3
44/// results we allocate the following memory layout:
45///
46/// [Result2, Result1, Result0, Operation]
47/// ^ this is where `Operation*` pointer points to.
48///
49/// A consequence of this is that this class must be heap allocated, which is
50/// handled by the various `create` methods. Each result contains:
51/// - one pointer to the first use (see `OpOperand`)
52/// - the type of the SSA Value this result defines.
53/// - the index for this result in the array.
54/// The results are defined as subclass of `ValueImpl`, and more precisely as
55/// the only two subclasses of `OpResultImpl`: `InlineOpResult` and
56/// `OutOfLineOpResult`. The former is used for the first 5 results and the
57/// latter for the subsequent ones. They differ in how they store their index:
58/// the first 5 results only need 3 bits and thus are packed with the Type
59/// pointer, while the subsequent one have an extra `unsigned` value and thus
60/// need more space.
61///
62/// An Operation also has zero or more operands: these are uses of SSA Value,
63/// which can be the results of other operations or Block arguments. Each of
64/// these uses is an instance of `OpOperand`. This optional array is initially
65/// tail allocated with the operation class itself, but can be dynamically moved
66/// out-of-line in a dynamic allocation as needed.
67///
68/// An Operation may optionally contain one or multiple Regions, stored in a
69/// tail allocated array. Each `Region` is a list of Blocks. Each `Block` is
70/// itself a list of Operations. This structure is effectively forming a tree.
71///
72/// Some operations like branches also refer to other Block, in which case they
73/// would have an array of `BlockOperand`.
74///
75/// An Operation may optionally contain a "Properties" object: this is a
76/// pre-defined C++ object with a fixed size. This object is owned by the
77/// operation and deleted with the operation. It can be converted to an
78/// Attribute on demand, or loaded from an Attribute.
79///
80///
81/// Finally an Operation also contain an optional `DictionaryAttr`, a Location,
82/// and a pointer to its parent Block (if any).
83class alignas(8) Operation final
84 : public llvm::ilist_node_with_parent<Operation, Block>,
85 private llvm::TrailingObjects<Operation, detail::OperandStorage,
86 detail::OpProperties, BlockOperand, Region,
87 OpOperand> {
88public:
89 /// Create a new Operation with the specific fields. This constructor
90 /// populates the provided attribute list with default attributes if
91 /// necessary.
92 static Operation *create(Location location, OperationName name,
93 TypeRange resultTypes, ValueRange operands,
94 NamedAttrList &&attributes, PropertyRef properties,
95 BlockRange successors, unsigned numRegions);
96
97 /// Create a new Operation with the specific fields. This constructor uses an
98 /// existing attribute dictionary to avoid uniquing a list of attributes.
99 static Operation *create(Location location, OperationName name,
100 TypeRange resultTypes, ValueRange operands,
101 DictionaryAttr attributes, PropertyRef properties,
102 BlockRange successors, unsigned numRegions);
103
104 /// Create a new Operation from the fields stored in `state`.
105 static Operation *create(const OperationState &state);
106
107 /// Create a new Operation with the specific fields.
108 static Operation *create(Location location, OperationName name,
109 TypeRange resultTypes, ValueRange operands,
110 NamedAttrList &&attributes, PropertyRef properties,
111 BlockRange successors = {},
112 RegionRange regions = {});
113
114 /// The name of an operation is the key identifier for it.
115 OperationName getName() { return name; }
116
117 /// If this operation has a registered operation description, return it.
118 /// Otherwise return std::nullopt.
119 std::optional<RegisteredOperationName> getRegisteredInfo() {
120 return getName().getRegisteredInfo();
121 }
122
123 /// Returns true if this operation has a registered operation description,
124 /// otherwise false.
125 bool isRegistered() { return getName().isRegistered(); }
126
127 /// Remove this operation from its parent block and delete it.
128 void erase();
129
130 /// Remove the operation from its parent block, but don't delete it.
131 void remove();
132
133 /// Class encompassing various options related to cloning an operation. Users
134 /// of this class should pass it to Operation's 'clone' methods.
135 /// Current options include:
136 /// * Whether cloning should recursively traverse into the regions of the
137 /// operation or not.
138 /// * Whether cloning should also clone the operands of the operation.
139 /// * Whether to use different result types or clone them.
141 public:
142 /// Default constructs an option with all flags set to false. That means all
143 /// parts of an operation that may optionally not be cloned, are not cloned.
144 CloneOptions();
145
146 /// Constructs an instance with the options set accordingly.
148 std::optional<SmallVector<Type>> resultTypes);
149
150 /// Returns an instance such that all elements of the operation are cloned.
151 /// This is the default when using the clone method and clones all parts of
152 /// the operation.
153 static CloneOptions all();
154
155 /// Configures whether cloning should traverse into any of the regions of
156 /// the operation. If set to true, the operation's regions are recursively
157 /// cloned. If set to false, cloned operations will have the same number of
158 /// regions, but they will be empty.
159 /// Cloning of nested operations in the operation's regions are currently
160 /// unaffected by other flags.
161 CloneOptions &cloneRegions(bool enable = true);
162
163 /// Returns whether regions of the operation should be cloned as well.
164 bool shouldCloneRegions() const { return cloneRegionsFlag; }
165
166 /// Configures whether operation' operands should be cloned. Otherwise the
167 /// resulting clones will simply have zero operands.
168 CloneOptions &cloneOperands(bool enable = true);
169
170 /// Returns whether operands should be cloned as well.
171 bool shouldCloneOperands() const { return cloneOperandsFlag; }
172
173 /// Configures different result types to use for the cloned operation.
174 /// If an empty optional, the result types are cloned from the original
175 /// operation.
176 CloneOptions &withResultTypes(std::optional<SmallVector<Type>> resultTypes);
177
178 /// Returns true if the results are cloned from the operation.
179 bool shouldCloneResults() const { return !resultTypes.has_value(); }
180
181 /// Returns the result types that should be used for the created operation
182 /// or `defaultResultTypes` if none were set.
183 TypeRange resultTypesOr(TypeRange defaultResultTypes) const {
184 if (resultTypes)
185 return *resultTypes;
186 return defaultResultTypes;
187 }
188
189 private:
190 /// Whether regions should be cloned.
191 bool cloneRegionsFlag : 1;
192 /// Whether operands should be cloned.
193 bool cloneOperandsFlag : 1;
194 /// New result types to use in the cloned operation.
195 std::optional<SmallVector<Type>> resultTypes;
196 };
197
198 /// Create a deep copy of this operation, remapping any operands that use
199 /// values outside of the operation using the map that is provided (leaving
200 /// them alone if no entry is present). Replaces references to cloned
201 /// sub-operations to the corresponding operation that is copied, and adds
202 /// those mappings to the map.
203 /// Optionally, one may configure what parts of the operation to clone using
204 /// the options parameter. If parts of the operation (e.g. results or regions)
205 /// are not cloned, they will not appear in the mapper.
206 ///
207 /// Calling this method from multiple threads is generally safe if through the
208 /// process of cloning no new uses of 'Value's from outside the operation are
209 /// created. Cloning an isolated-from-above operation with no operands, such
210 /// as top level function operations, is therefore always safe. Using the
211 /// mapper, it is possible to avoid adding uses to outside operands by
212 /// remapping them to 'Value's owned by the caller thread.
213 Operation *clone(IRMapping &mapper,
214 const CloneOptions &options = CloneOptions::all());
215 Operation *clone(const CloneOptions &options = CloneOptions::all());
216
217 /// Create a partial copy of this operation without traversing into attached
218 /// regions. The new operation will have the same number of regions as the
219 /// original one, but they will be left empty.
220 /// Operands are remapped using `mapper` (if present), and `mapper` is updated
221 /// to contain the results.
223
224 /// Create a partial copy of this operation without traversing into attached
225 /// regions. The new operation will have the same number of regions as the
226 /// original one, but they will be left empty.
228
229 /// Returns the operation block that contains this operation.
230 Block *getBlock() { return block; }
231
232 /// Return the context this operation is associated with.
233 MLIRContext *getContext() { return location->getContext(); }
234
235 /// Return the dialect this operation is associated with, or nullptr if the
236 /// associated dialect is not loaded.
238
239 /// The source location the operation was defined or derived from.
240 Location getLoc() { return location; }
241
242 /// Set the source location the operation was defined or derived from.
243 void setLoc(Location loc) { location = loc; }
244
245 /// Returns the region to which the instruction belongs. Returns nullptr if
246 /// the instruction is unlinked.
247 Region *getParentRegion() { return block ? block->getParent() : nullptr; }
248
249 /// Returns the closest surrounding operation that contains this operation
250 /// or nullptr if this is a top-level operation.
251 Operation *getParentOp() { return block ? block->getParentOp() : nullptr; }
252
253 /// Return the closest surrounding parent operation that is of type 'OpTy'.
254 template <typename OpTy>
256 auto *op = this;
257 while ((op = op->getParentOp()))
258 if (auto parentOp = dyn_cast<OpTy>(op))
259 return parentOp;
260 return OpTy();
261 }
262 template <typename... OpTy>
263 std::enable_if_t<(sizeof...(OpTy) > 1), Operation *> getParentOfType() {
264 auto *op = this;
265 while ((op = op->getParentOp()))
266 if (isa<OpTy...>(op))
267 return op;
268 return nullptr;
269 }
270
271 /// Returns the closest surrounding parent operation with trait `Trait`.
272 template <template <typename T> class Trait>
273 Operation *getParentWithTrait() {
274 Operation *op = this;
275 while ((op = op->getParentOp()))
276 if (op->hasTrait<Trait>())
277 return op;
278 return nullptr;
279 }
280
281 /// Return true if this operation is a proper ancestor of the `other`
282 /// operation.
283 bool isProperAncestor(Operation *other);
284
285 /// Return true if this operation is an ancestor of the `other` operation. An
286 /// operation is considered as its own ancestor, use `isProperAncestor` to
287 /// avoid this.
288 bool isAncestor(Operation *other) {
289 return this == other || isProperAncestor(other);
290 }
291
292 /// Replace any uses of 'from' with 'to' within this operation.
293 void replaceUsesOfWith(Value from, Value to);
294
295 /// Replace all uses of results of this operation with the provided 'values'.
296 template <typename ValuesT>
297 void replaceAllUsesWith(ValuesT &&values) {
298 getResults().replaceAllUsesWith(std::forward<ValuesT>(values));
299 }
300
301 /// Replace uses of results of this operation with the provided `values` if
302 /// the given callback returns true.
303 template <typename ValuesT>
304 void replaceUsesWithIf(ValuesT &&values,
305 function_ref<bool(OpOperand &)> shouldReplace) {
306 getResults().replaceUsesWithIf(std::forward<ValuesT>(values),
307 shouldReplace);
308 }
309
310 /// Destroys this operation and its subclass data.
311 void destroy();
312
313 /// This drops all operand uses from this operation, which is an essential
314 /// step in breaking cyclic dependencies between references when they are to
315 /// be deleted.
316 void dropAllReferences();
317
318 /// Drop uses of all values defined by this operation or its nested regions.
320
321 /// Unlink this operation from its current block and insert it right before
322 /// `existingOp` which may be in the same or another block in the same
323 /// function.
324 void moveBefore(Operation *existingOp);
325
326 /// Unlink this operation from its current block and insert it right before
327 /// `iterator` in the specified block.
328 void moveBefore(Block *block, llvm::iplist<Operation>::iterator iterator);
329
330 /// Unlink this operation from its current block and insert it right after
331 /// `existingOp` which may be in the same or another block in the same
332 /// function.
333 void moveAfter(Operation *existingOp);
334
335 /// Unlink this operation from its current block and insert it right after
336 /// `iterator` in the specified block.
337 void moveAfter(Block *block, llvm::iplist<Operation>::iterator iterator);
338
339 /// Given an operation 'other' that is within the same parent block, return
340 /// whether the current operation is before 'other' in the operation list
341 /// of the parent block.
342 /// Note: This function has an average complexity of O(1), but worst case may
343 /// take O(N) where N is the number of operations within the parent block.
344 bool isBeforeInBlock(Operation *other);
345
346 void print(raw_ostream &os, const OpPrintingFlags &flags = {});
347 void print(raw_ostream &os, AsmState &state);
348 void dump();
349
350 // Dump pretty printed IR. This method is helpful for better readability if
351 // the Operation is not verified because it won't disable custom printers to
352 // fall back to the generic one.
353 LLVM_DUMP_METHOD void dumpPretty();
354
355 //===--------------------------------------------------------------------===//
356 // Operands
357 //===--------------------------------------------------------------------===//
358
359 /// Replace the current operands of this operation with the ones provided in
360 /// 'operands'.
361 void setOperands(ValueRange operands);
362
363 /// Replace the operands beginning at 'start' and ending at 'start' + 'length'
364 /// with the ones provided in 'operands'. 'operands' may be smaller or larger
365 /// than the range pointed to by 'start'+'length'.
366 void setOperands(unsigned start, unsigned length, ValueRange operands);
367
368 /// Insert the given operands into the operand list at the given 'index'.
369 void insertOperands(unsigned index, ValueRange operands);
370
371 unsigned getNumOperands() {
372 return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().size() : 0;
373 }
374
375 Value getOperand(unsigned idx) { return getOpOperand(idx).get(); }
376 void setOperand(unsigned idx, Value value) {
377 return getOpOperand(idx).set(value);
378 }
379
380 /// Erase the operand at position `idx`.
381 void eraseOperand(unsigned idx) { eraseOperands(idx); }
382
383 /// Erase the operands starting at position `idx` and ending at position
384 /// 'idx'+'length'.
385 void eraseOperands(unsigned idx, unsigned length = 1) {
386 getOperandStorage().eraseOperands(idx, length);
387 }
388
389 /// Erases the operands that have their corresponding bit set in
390 /// `eraseIndices` and removes them from the operand list.
391 void eraseOperands(const BitVector &eraseIndices) {
392 getOperandStorage().eraseOperands(eraseIndices);
393 }
394
395 // Support operand iteration.
397 using operand_iterator = operand_range::iterator;
398
401
402 /// Returns an iterator on the underlying Value's.
405 return OperandRange(operands.data(), operands.size());
406 }
407
409 return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().getOperands()
411 }
412
413 OpOperand &getOpOperand(unsigned idx) {
414 return getOperandStorage().getOperands()[idx];
415 }
416
417 // Support operand type iteration.
423
424 //===--------------------------------------------------------------------===//
425 // Results
426 //===--------------------------------------------------------------------===//
427
428 /// Return the number of results held by this operation.
429 unsigned getNumResults() { return numResults; }
430
431 /// Get the 'idx'th result of this operation.
432 OpResult getResult(unsigned idx) { return OpResult(getOpResultImpl(idx)); }
433
434 /// Support result iteration.
436 using result_iterator = result_range::iterator;
437
441 return numResults == 0 ? result_range(nullptr, 0)
442 : result_range(getInlineOpResult(0), numResults);
443 }
444
446 OpResult getOpResult(unsigned idx) { return getResult(idx); }
447
448 /// Support result type iteration.
454
455 //===--------------------------------------------------------------------===//
456 // Attributes
457 //===--------------------------------------------------------------------===//
458
459 // Operations may optionally carry a list of attributes that associate
460 // constants to names. Attributes may be dynamically added and removed over
461 // the lifetime of an operation.
462
463 /// Access an inherent attribute by name: returns an empty optional if there
464 /// is no inherent attribute with this name.
465 ///
466 /// This method is available as a transient facility in the migration process
467 /// to use Properties instead.
468 std::optional<Attribute> getInherentAttr(StringRef name);
469
470 /// Set an inherent attribute by name.
471 ///
472 /// This method is available as a transient facility in the migration process
473 /// to use Properties instead.
474 void setInherentAttr(StringAttr name, Attribute value);
475
476 /// Access a discardable attribute by name, returns a null Attribute if the
477 /// discardable attribute does not exist.
478 Attribute getDiscardableAttr(StringRef name) { return attrs.get(name); }
479
480 /// Access a discardable attribute by name, returns a null Attribute if the
481 /// discardable attribute does not exist.
482 Attribute getDiscardableAttr(StringAttr name) { return attrs.get(name); }
483
484 /// Access a discardable attribute by name and cast it to `AttrClass`.
485 template <typename AttrClass>
486 AttrClass getDiscardableAttrOfType(StringRef name) {
487 return llvm::dyn_cast_or_null<AttrClass>(getDiscardableAttr(name));
488 }
489 template <typename AttrClass>
490 AttrClass getDiscardableAttrOfType(StringAttr name) {
491 return llvm::dyn_cast_or_null<AttrClass>(getDiscardableAttr(name));
492 }
493
494 /// Return true if this operation has a discardable attribute with the
495 /// provided name.
496 bool hasDiscardableAttr(StringRef name) { return bool(attrs.get(name)); }
497 bool hasDiscardableAttr(StringAttr name) { return bool(attrs.get(name)); }
498 template <typename AttrClass, typename NameT>
499 bool hasDiscardableAttrOfType(NameT &&name) {
500 return static_cast<bool>(
501 getDiscardableAttrOfType<AttrClass>(std::forward<NameT>(name)));
502 }
503
504 /// Set a discardable attribute by name.
505 void setDiscardableAttr(StringAttr name, Attribute value) {
506 NamedAttrList attributes(attrs);
507 if (attributes.set(name, value) != value)
508 attrs = attributes.getDictionary(getContext());
509 }
510 void setDiscardableAttr(StringRef name, Attribute value) {
511 setDiscardableAttr(StringAttr::get(getContext(), name), value);
512 }
513
514 /// Remove the discardable attribute with the specified name if it exists.
515 /// Return the attribute that was erased, or nullptr if there was no attribute
516 /// with such name.
518 NamedAttrList attributes(attrs);
519 Attribute removedAttr = attributes.erase(name);
520 if (removedAttr)
521 attrs = attributes.getDictionary(getContext());
522 return removedAttr;
523 }
525 return removeDiscardableAttr(StringAttr::get(getContext(), name));
526 }
527
528 /// Return a range of all of discardable attributes on this operation. Note
529 /// that for unregistered operations that are not storing inherent attributes
530 /// as properties, all attributes are considered discardable.
532 std::optional<RegisteredOperationName> opName = getRegisteredInfo();
533 ArrayRef<StringAttr> attributeNames =
534 opName ? getRegisteredInfo()->getAttributeNames()
536 return llvm::make_filter_range(
537 attrs.getValue(),
538 [this, attributeNames](const NamedAttribute attribute) {
539 return getPropertiesStorage() ||
540 !llvm::is_contained(attributeNames, attribute.getName());
541 });
542 }
543
544 /// Return all of the discardable attributes on this operation as a
545 /// DictionaryAttr.
548 return attrs;
549 return DictionaryAttr::get(getContext(),
550 llvm::to_vector(getDiscardableAttrs()));
551 }
552
553 /// Return all attributes that are not stored as properties.
554 DictionaryAttr getRawDictionaryAttrs() { return attrs; }
555
556 /// Return all of the attributes on this operation.
558
559 /// Return all of the attributes on this operation as a DictionaryAttr.
560 DictionaryAttr getAttrDictionary();
561
562 /// Set the attributes from a dictionary on this operation.
563 /// These methods are expensive: if the dictionary only contains discardable
564 /// attributes, `setDiscardableAttrs` is more efficient.
565 void setAttrs(DictionaryAttr newAttrs);
566 void setAttrs(ArrayRef<NamedAttribute> newAttrs);
567 /// Set the discardable attribute dictionary on this operation.
568 void setDiscardableAttrs(DictionaryAttr newAttrs) {
569 assert(newAttrs && "expected valid attribute dictionary");
570 attrs = newAttrs;
571 }
573 setDiscardableAttrs(DictionaryAttr::get(getContext(), newAttrs));
574 }
575
576 /// Return the specified attribute if present, null otherwise.
577 /// These methods are expensive: if the dictionary only contains discardable
578 /// attributes, `getDiscardableAttr` is more efficient.
579 Attribute getAttr(StringAttr name) {
581 if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
582 return *inherentAttr;
583 }
584 return attrs.get(name);
585 }
586 Attribute getAttr(StringRef name) {
588 if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
589 return *inherentAttr;
590 }
591 return attrs.get(name);
592 }
593
594 template <typename AttrClass>
595 AttrClass getAttrOfType(StringAttr name) {
596 return llvm::dyn_cast_or_null<AttrClass>(getAttr(name));
597 }
598 template <typename AttrClass>
599 AttrClass getAttrOfType(StringRef name) {
600 return llvm::dyn_cast_or_null<AttrClass>(getAttr(name));
601 }
602
603 /// Return true if the operation has an attribute with the provided name,
604 /// false otherwise.
605 bool hasAttr(StringAttr name) {
607 if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
608 return (bool)*inherentAttr;
609 }
610 return attrs.contains(name);
611 }
612 bool hasAttr(StringRef name) {
614 if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
615 return (bool)*inherentAttr;
616 }
617 return attrs.contains(name);
618 }
619 template <typename AttrClass, typename NameT>
620 bool hasAttrOfType(NameT &&name) {
621 return static_cast<bool>(
622 getAttrOfType<AttrClass>(std::forward<NameT>(name)));
623 }
624
625 /// If the an attribute exists with the specified name, change it to the new
626 /// value. Otherwise, add a new attribute with the specified name/value.
627 void setAttr(StringAttr name, Attribute value) {
629 if (getInherentAttr(name)) {
630 setInherentAttr(name, value);
631 return;
632 }
633 }
634 NamedAttrList attributes(attrs);
635 if (attributes.set(name, value) != value)
636 attrs = attributes.getDictionary(getContext());
637 }
638 void setAttr(StringRef name, Attribute value) {
639 setAttr(StringAttr::get(getContext(), name), value);
640 }
641
642 /// Remove the attribute with the specified name if it exists. Return the
643 /// attribute that was erased, or nullptr if there was no attribute with such
644 /// name.
645 Attribute removeAttr(StringAttr name) {
647 if (std::optional<Attribute> inherentAttr = getInherentAttr(name)) {
648 setInherentAttr(name, {});
649 return *inherentAttr;
650 }
651 }
652 NamedAttrList attributes(attrs);
653 Attribute removedAttr = attributes.erase(name);
654 if (removedAttr)
655 attrs = attributes.getDictionary(getContext());
656 return removedAttr;
657 }
658 Attribute removeAttr(StringRef name) {
659 return removeAttr(StringAttr::get(getContext(), name));
660 }
661
662 /// A utility iterator that filters out non-dialect attributes.
663 class dialect_attr_iterator
664 : public llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
665 bool (*)(NamedAttribute)> {
666 static bool filter(NamedAttribute attr) {
667 // Dialect attributes are prefixed by the dialect name, like operations.
668 return attr.getName().strref().count('.');
669 }
670
671 explicit dialect_attr_iterator(ArrayRef<NamedAttribute>::iterator it,
673 : llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
674 bool (*)(NamedAttribute)>(it, end, &filter) {}
675
676 // Allow access to the constructor.
677 friend Operation;
678 };
680
681 /// Return a range corresponding to the dialect attributes for this operation.
683 auto attrs = getAttrs();
684 return {dialect_attr_iterator(attrs.begin(), attrs.end()),
685 dialect_attr_iterator(attrs.end(), attrs.end())};
686 }
688 auto attrs = getAttrs();
689 return dialect_attr_iterator(attrs.begin(), attrs.end());
690 }
692 auto attrs = getAttrs();
693 return dialect_attr_iterator(attrs.end(), attrs.end());
694 }
695
696 /// Set the dialect attributes for this operation, and preserve all inherent.
697 template <typename DialectAttrT>
698 void setDialectAttrs(DialectAttrT &&dialectAttrs) {
699 NamedAttrList attrs;
700 attrs.append(std::begin(dialectAttrs), std::end(dialectAttrs));
701 for (auto attr : getAttrs())
702 if (!attr.getName().strref().contains('.'))
703 attrs.push_back(attr);
704 setAttrs(attrs.getDictionary(getContext()));
705 }
706
707 /// Sets default attributes on unset attributes.
710 name.populateDefaultAttrs(attrs);
711 setAttrs(attrs.getDictionary(getContext()));
712 }
713
714 //===--------------------------------------------------------------------===//
715 // Blocks
716 //===--------------------------------------------------------------------===//
717
718 /// Returns the number of regions held by this operation.
719 unsigned getNumRegions() { return numRegions; }
720
721 /// Returns the regions held by this operation.
723 // Check the count first, as computing the trailing objects can be slow.
724 if (numRegions == 0)
726
727 return getTrailingObjects<Region>(numRegions);
728 }
729
730 /// Returns the region held by this operation at position 'index'.
731 Region &getRegion(unsigned index) {
732 assert(index < numRegions && "invalid region index");
733 return getRegions()[index];
734 }
735
736 //===--------------------------------------------------------------------===//
737 // Successors
738 //===--------------------------------------------------------------------===//
739
741 return getTrailingObjects<BlockOperand>(numSuccs);
742 }
743
744 // Successor iteration.
745 using succ_iterator = SuccessorRange::iterator;
749
750 bool hasSuccessors() { return numSuccs != 0; }
751 unsigned getNumSuccessors() { return numSuccs; }
752
754 assert(index < getNumSuccessors());
755 return getBlockOperands()[index].get();
756 }
757 void setSuccessor(Block *block, unsigned index);
758
759 //===--------------------------------------------------------------------===//
760 // Accessors for various properties of operations
761 //===--------------------------------------------------------------------===//
762
763 /// Attempt to fold this operation with the specified constant operand values
764 /// - the elements in "operands" will correspond directly to the operands of
765 /// the operation, but may be null if non-constant.
766 ///
767 /// If folding was successful, this function returns "success".
768 /// * If this operation was modified in-place (but not folded away),
769 /// `results` is empty.
770 /// * Otherwise, `results` is filled with the folded results.
771 /// If folding was unsuccessful, this function returns "failure".
772 LogicalResult fold(ArrayRef<Attribute> operands,
774
775 /// Attempt to fold this operation.
776 ///
777 /// If folding was successful, this function returns "success".
778 /// * If this operation was modified in-place (but not folded away),
779 /// `results` is empty.
780 /// * Otherwise, `results` is filled with the folded results.
781 /// If folding was unsuccessful, this function returns "failure".
782 LogicalResult fold(SmallVectorImpl<OpFoldResult> &results);
783
784 /// Returns true if `InterfaceT` has been promised by the dialect or
785 /// implemented.
786 template <typename InterfaceT>
788 return name.hasPromiseOrImplementsInterface<InterfaceT>();
789 }
790
791 /// Returns true if the operation was registered with a particular trait, e.g.
792 /// hasTrait<OperandsAreSignlessIntegerLike>().
793 template <template <typename T> class Trait>
794 bool hasTrait() {
795 return name.hasTrait<Trait>();
796 }
797
798 /// Returns true if the operation *might* have the provided trait. This
799 /// means that either the operation is unregistered, or it was registered with
800 /// the provide trait.
801 template <template <typename T> class Trait>
803 return name.mightHaveTrait<Trait>();
804 }
805
806 //===--------------------------------------------------------------------===//
807 // Operation Walkers
808 //===--------------------------------------------------------------------===//
809
810 /// Walk the operation by calling the callback for each nested operation
811 /// (including this one), block or region, depending on the callback provided.
812 /// The order in which regions, blocks and operations at the same nesting
813 /// level are visited (e.g., lexicographical or reverse lexicographical order)
814 /// is determined by 'Iterator'. The walk order for enclosing regions, blocks
815 /// and operations with respect to their nested ones is specified by 'Order'
816 /// (post-order by default). A callback on a block or operation is allowed to
817 /// erase that block or operation if either:
818 /// * the walk is in post-order, or
819 /// * the walk is in pre-order and the walk is skipped after the erasure.
820 ///
821 /// The callback method can take any of the following forms:
822 /// void(Operation*) : Walk all operations opaquely.
823 /// * op->walk([](Operation *nestedOp) { ...});
824 /// void(OpT) : Walk all operations of the given derived type.
825 /// * op->walk([](ReturnOp returnOp) { ...});
826 /// WalkResult(Operation*|OpT) : Walk operations, but allow for
827 /// interruption/skipping.
828 /// * op->walk([](... op) {
829 /// // Skip the walk of this op based on some invariant.
830 /// if (some_invariant)
831 /// return WalkResult::skip();
832 /// // Interrupt, i.e cancel, the walk based on some invariant.
833 /// if (another_invariant)
834 /// return WalkResult::interrupt();
835 /// return WalkResult::advance();
836 /// });
837 template <WalkOrder Order = WalkOrder::PostOrder,
838 typename Iterator = ForwardIterator, typename FnT,
839 typename RetT = detail::walkResultType<FnT>>
840 std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 1,
841 RetT>
842 walk(FnT &&callback) {
843 return detail::walk<Order, Iterator>(this, std::forward<FnT>(callback));
844 }
845
846 /// Generic walker with a stage aware callback. Walk the operation by calling
847 /// the callback for each nested operation (including this one) N+1 times,
848 /// where N is the number of regions attached to that operation.
849 ///
850 /// The callback method can take any of the following forms:
851 /// void(Operation *, const WalkStage &) : Walk all operation opaquely
852 /// * op->walk([](Operation *nestedOp, const WalkStage &stage) { ...});
853 /// void(OpT, const WalkStage &) : Walk all operations of the given derived
854 /// type.
855 /// * op->walk([](ReturnOp returnOp, const WalkStage &stage) { ...});
856 /// WalkResult(Operation*|OpT, const WalkStage &stage) : Walk operations,
857 /// but allow for interruption/skipping.
858 /// * op->walk([](... op, const WalkStage &stage) {
859 /// // Skip the walk of this op based on some invariant.
860 /// if (some_invariant)
861 /// return WalkResult::skip();
862 /// // Interrupt, i.e cancel, the walk based on some invariant.
863 /// if (another_invariant)
864 /// return WalkResult::interrupt();
865 /// return WalkResult::advance();
866 /// });
867 template <typename FnT, typename RetT = detail::walkResultType<FnT>>
868 std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 2,
869 RetT>
870 walk(FnT &&callback) {
871 return detail::walk(this, std::forward<FnT>(callback));
872 }
873
874 //===--------------------------------------------------------------------===//
875 // Uses
876 //===--------------------------------------------------------------------===//
877
878 /// Drop all uses of results of this operation.
879 void dropAllUses() {
881 result.dropAllUses();
882 }
883
886
889
890 /// Returns a range of all uses, which is useful for iterating over all uses.
892
893 /// Returns true if this operation has exactly one use.
894 bool hasOneUse() { return llvm::hasSingleElement(getUses()); }
895
896 /// Returns true if this operation has no uses.
897 bool use_empty() { return getResults().use_empty(); }
898
899 /// Returns true if the results of this operation are used outside of the
900 /// given block.
902 return llvm::any_of(getOpResults(), [block](OpResult result) {
903 return result.isUsedOutsideOfBlock(block);
904 });
905 }
906
907 //===--------------------------------------------------------------------===//
908 // Users
909 //===--------------------------------------------------------------------===//
910
913
916
917 /// Returns a range of all users.
919
920 //===--------------------------------------------------------------------===//
921 // Other
922 //===--------------------------------------------------------------------===//
923
924 /// Emit an error with the op name prefixed, like "'dim' op " which is
925 /// convenient for verifiers.
926 InFlightDiagnostic emitOpError(const Twine &message = {});
927
928 /// Emit an error about fatal conditions with this operation, reporting up to
929 /// any diagnostic handlers that may be listening.
930 InFlightDiagnostic emitError(const Twine &message = {});
931
932 /// Emit a warning about this operation, reporting up to any diagnostic
933 /// handlers that may be listening.
934 InFlightDiagnostic emitWarning(const Twine &message = {});
935
936 /// Emit a remark about this operation, reporting up to any diagnostic
937 /// handlers that may be listening.
938 InFlightDiagnostic emitRemark(const Twine &message = {});
939
940 /// Returns the properties storage size.
942 return ((int)propertiesStorageSize) * 8;
943 }
944
945 /// Return a generic (but typed) reference to the property type storage.
947 if (propertiesStorageSize)
948 return PropertyRef(name.getOpPropertiesTypeID(),
950 return {};
951 }
952
954 if (propertiesStorageSize)
955 return PropertyRef(
956 name.getOpPropertiesTypeID(),
957 reinterpret_cast<void *>(const_cast<detail::OpProperties *>(
958 getTrailingObjects<detail::OpProperties>())));
959 return {};
960 }
961
962 /// Returns a pointer to the properties storage (if it exists) with no type
963 /// information.
965 return reinterpret_cast<void *>(const_cast<detail::OpProperties *>(
966 getTrailingObjects<detail::OpProperties>()));
967 }
968
969 /// Return the properties converted to an attribute.
970 /// This is expensive, and mostly useful when dealing with unregistered
971 /// operation. Returns an empty attribute if no properties are present.
973
974 /// Set the properties from the provided attribute.
975 /// This is an expensive operation that can fail if the attribute is not
976 /// matching the expectations of the properties for this operation. This is
977 /// mostly useful for unregistered operations or used when parsing the
978 /// generic format. An optional diagnostic emitter can be passed in for richer
979 /// errors, if none is passed then behavior is undefined in error case.
980 LogicalResult
983
984 /// Copy properties from an existing other properties object. The two objects
985 /// must be the same type.
987
988 /// Compute a hash for the op properties (if any).
989 llvm::hash_code hashProperties();
990
991private:
992 //===--------------------------------------------------------------------===//
993 // Ordering
994 //===--------------------------------------------------------------------===//
995
996 /// This value represents an invalid index ordering for an operation within a
997 /// block.
998 static constexpr unsigned kInvalidOrderIdx = -1;
999
1000 /// This value represents the stride to use when computing a new order for an
1001 /// operation.
1002 static constexpr unsigned kOrderStride = 5;
1003
1004 /// Update the order index of this operation if necessary,
1005 /// potentially recomputing the order of the parent block.
1006 void updateOrderIfNecessary();
1007
1008 /// Returns true if this operation has a valid order.
1009 bool hasValidOrder() { return orderIndex != kInvalidOrderIdx; }
1010
1011private:
1012 Operation(Location location, OperationName name, unsigned numResults,
1013 unsigned numSuccessors, unsigned numRegions,
1014 int propertiesStorageSize, DictionaryAttr attributes,
1015 PropertyRef properties, bool hasOperandStorage);
1016
1017 // Operations are deleted through the destroy() member because they are
1018 // allocated with malloc.
1019 ~Operation();
1020
1021 /// Returns the additional size necessary for allocating the given objects
1022 /// before an Operation in-memory.
1023 static size_t prefixAllocSize(unsigned numOutOfLineResults,
1024 unsigned numInlineResults) {
1025 return sizeof(detail::OutOfLineOpResult) * numOutOfLineResults +
1026 sizeof(detail::InlineOpResult) * numInlineResults;
1027 }
1028 /// Returns the additional size allocated before this Operation in-memory.
1029 size_t prefixAllocSize() {
1030 unsigned numResults = getNumResults();
1031 unsigned numOutOfLineResults = OpResult::getNumTrailing(numResults);
1032 unsigned numInlineResults = OpResult::getNumInline(numResults);
1033 return prefixAllocSize(numOutOfLineResults, numInlineResults);
1034 }
1035
1036 /// Returns the operand storage object.
1037 detail::OperandStorage &getOperandStorage() {
1038 assert(hasOperandStorage && "expected operation to have operand storage");
1039 return *getTrailingObjects<detail::OperandStorage>();
1040 }
1041
1042 /// Returns a pointer to the use list for the given out-of-line result.
1043 detail::OutOfLineOpResult *getOutOfLineOpResult(unsigned resultNumber) {
1044 // Out-of-line results are stored in reverse order after (before in memory)
1045 // the inline results.
1046 return reinterpret_cast<detail::OutOfLineOpResult *>(getInlineOpResult(
1048 ++resultNumber;
1049 }
1050
1051 /// Returns a pointer to the use list for the given inline result.
1052 detail::InlineOpResult *getInlineOpResult(unsigned resultNumber) {
1053 // Inline results are stored in reverse order before the operation in
1054 // memory.
1055 return reinterpret_cast<detail::InlineOpResult *>(this) - ++resultNumber;
1056 }
1057
1058 /// Returns a pointer to the use list for the given result, which may be
1059 /// either inline or out-of-line.
1060 detail::OpResultImpl *getOpResultImpl(unsigned resultNumber) {
1061 assert(resultNumber < getNumResults() &&
1062 "Result number is out of range for operation");
1063 unsigned maxInlineResults = detail::OpResultImpl::getMaxInlineResults();
1064 if (resultNumber < maxInlineResults)
1065 return getInlineOpResult(resultNumber);
1066 return getOutOfLineOpResult(resultNumber - maxInlineResults);
1067 }
1068
1069 /// Provide a 'getParent' method for ilist_node_with_parent methods.
1070 /// We mark it as a const function because ilist_node_with_parent specifically
1071 /// requires a 'getParent() const' method. Once ilist_node removes this
1072 /// constraint, we should drop the const to fit the rest of the MLIR const
1073 /// model.
1074 Block *getParent() const { return block; }
1075
1076 /// Expose a few methods explicitly for the debugger to call for
1077 /// visualization.
1078#ifndef NDEBUG
1079 LLVM_DUMP_METHOD operand_range debug_getOperands() { return getOperands(); }
1080 LLVM_DUMP_METHOD result_range debug_getResults() { return getResults(); }
1081 LLVM_DUMP_METHOD SuccessorRange debug_getSuccessors() {
1082 return getSuccessors();
1083 }
1084 LLVM_DUMP_METHOD MutableArrayRef<Region> debug_getRegions() {
1085 return getRegions();
1086 }
1087#endif
1088
1089 /// The operation block that contains this operation.
1090 Block *block = nullptr;
1091
1092 /// This holds information about the source location the operation was defined
1093 /// or derived from.
1094 Location location;
1095
1096 /// Relative order of this operation in its parent block. Used for
1097 /// O(1) local dominance checks between operations.
1098 mutable unsigned orderIndex = 0;
1099
1100 const unsigned numResults;
1101 const unsigned numSuccs;
1102 const unsigned numRegions : 23;
1103
1104 /// This bit signals whether this operation has an operand storage or not. The
1105 /// operand storage may be elided for operations that are known to never have
1106 /// operands.
1107 bool hasOperandStorage : 1;
1108
1109 /// The size of the storage for properties (if any), divided by 8: since the
1110 /// Properties storage will always be rounded up to the next multiple of 8 we
1111 /// save some bits here.
1112 unsigned char propertiesStorageSize : 8;
1113 /// This is the maximum size we support to allocate properties inline with an
1114 /// operation: this must match the bitwidth above.
1115 static constexpr int64_t propertiesCapacity = 8 * 256;
1116
1117 /// This holds the name of the operation.
1118 OperationName name;
1119
1120 /// This holds general named attributes for the operation.
1121 DictionaryAttr attrs;
1122
1123 // allow ilist_traits access to 'block' field.
1124 friend struct llvm::ilist_traits<Operation>;
1125
1126 // allow block to access the 'orderIndex' field.
1127 friend class Block;
1128
1129 // allow value to access the 'ResultStorage' methods.
1130 friend class Value;
1131
1132 // allow ilist_node_with_parent to access the 'getParent' method.
1133 friend class llvm::ilist_node_with_parent<Operation, Block>;
1134
1135 // This stuff is used by the TrailingObjects template.
1136 friend llvm::TrailingObjects<Operation, detail::OperandStorage,
1138 OpOperand>;
1139 size_t numTrailingObjects(OverloadToken<detail::OperandStorage>) const {
1140 return hasOperandStorage ? 1 : 0;
1141 }
1142 size_t numTrailingObjects(OverloadToken<BlockOperand>) const {
1143 return numSuccs;
1144 }
1145 size_t numTrailingObjects(OverloadToken<Region>) const { return numRegions; }
1146 size_t numTrailingObjects(OverloadToken<detail::OpProperties>) const {
1147 return getPropertiesStorageSize();
1148 }
1149};
1150
1152 const_cast<Operation &>(op).print(os, OpPrintingFlags().useLocalScope());
1153 return os;
1154}
1155
1156/// A wrapper class that allows for printing an operation with a set of flags,
1157/// useful to act as a "stream modifier" to customize printing an operation
1158/// with a stream using the operator<< overload, e.g.:
1159/// llvm::dbgs() << OpWithFlags(op, OpPrintingFlags().skipRegions());
1160/// This always prints the operation with the local scope, to avoid introducing
1161/// spurious newlines in the stream.
1163public:
1165 : op(op), theFlags(flags) {}
1166 OpPrintingFlags &flags() { return theFlags; }
1167 const OpPrintingFlags &flags() const { return theFlags; }
1168 Operation *getOperation() const { return op; }
1169
1170private:
1171 Operation *op;
1172 OpPrintingFlags theFlags;
1174};
1175
1177 opWithFlags.flags().useLocalScope();
1178 opWithFlags.op->print(os, opWithFlags.flags());
1179 return os;
1180}
1181
1182/// A wrapper class that allows for printing an operation with a custom
1183/// AsmState, useful to act as a "stream modifier" to customize printing an
1184/// operation with a stream using the operator<< overload, e.g.:
1185/// llvm::dbgs() << OpWithState(op, OpPrintingFlags().skipRegions());
1187public:
1188 OpWithState(Operation *op, AsmState &state) : op(op), theState(state) {}
1189
1190private:
1191 Operation *op;
1192 AsmState &theState;
1193 friend raw_ostream &operator<<(raw_ostream &os, const OpWithState &op);
1194};
1195
1197 const OpWithState &opWithState) {
1198 opWithState.op->print(os, const_cast<OpWithState &>(opWithState).theState);
1199 return os;
1200}
1201
1202} // namespace mlir
1203
1204namespace llvm {
1205/// Cast from an (const) Operation * to a derived operation type.
1206template <typename T>
1208 : public ValueFromPointerCast<T, ::mlir::Operation,
1209 CastInfo<T, ::mlir::Operation *>> {
1210 static bool isPossible(::mlir::Operation *op) { return T::classof(op); }
1211};
1212template <typename T>
1213struct CastInfo<T, const ::mlir::Operation *>
1214 : public ConstStrippingForwardingCast<T, const ::mlir::Operation *,
1215 CastInfo<T, ::mlir::Operation *>> {};
1216
1217/// Cast from an (const) Operation & to a derived operation type.
1218template <typename T>
1220 : public NullableValueCastFailed<T>,
1221 public DefaultDoCastIfPossible<T, ::mlir::Operation &,
1222 CastInfo<T, ::mlir::Operation>> {
1223 // Provide isPossible here because here we have the const-stripping from
1224 // ConstStrippingCast.
1225 static bool isPossible(::mlir::Operation &val) { return T::classof(&val); }
1226 static T doCast(::mlir::Operation &val) { return T(&val); }
1227};
1228template <typename T>
1229struct CastInfo<T, const ::mlir::Operation>
1230 : public ConstStrippingForwardingCast<T, const ::mlir::Operation,
1231 CastInfo<T, ::mlir::Operation>> {};
1232
1233/// Cast (const) Operation * to itself. This is helpful to avoid SFINAE in
1234/// templated implementations that should work on both base and derived
1235/// operation types.
1236template <>
1238 : public NullableValueCastFailed<::mlir::Operation *>,
1240 ::mlir::Operation *, ::mlir::Operation *,
1241 CastInfo<::mlir::Operation *, ::mlir::Operation *>> {
1242 static bool isPossible(::mlir::Operation *op) { return true; }
1243 static ::mlir::Operation *doCast(::mlir::Operation *op) { return op; }
1244};
1245template <>
1248 const ::mlir::Operation *, const ::mlir::Operation *,
1249 CastInfo<::mlir::Operation *, ::mlir::Operation *>> {};
1250} // namespace llvm
1251
1252#endif // MLIR_IR_OPERATION_H
static llvm::ManagedStatic< PassManagerOptions > options
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
This class provides management for the lifetime of the state used when printing the IR.
Definition AsmState.h:542
Attributes are known-constant values of operations.
Definition Attributes.h:25
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.
Definition Block.h:33
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition Dialect.h:38
This is a utility class for mapping one set of IR entities to another.
Definition IRMapping.h:26
IRValueT get() const
Return the current value being used by this operand.
void set(IRValueT newValue)
Set the current value being used by this operand.
This class represents a diagnostic that is inflight and set to be reported.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
DictionaryAttr getDictionary(MLIRContext *context) const
Return a dictionary attribute for the underlying dictionary.
Attribute erase(StringAttr name)
Erase the attribute with the given name from the list.
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
Attribute set(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
NamedAttribute represents a combination of a name and an Attribute value.
Definition Attributes.h:164
StringAttr getName() const
Return the name of the attribute.
This class represents an operand of an operation.
Definition Value.h:254
Set of flags used to control the behavior of the various IR print methods (e.g.
OpPrintingFlags & useLocalScope(bool enable=true)
Use local scope when printing the operation.
This is a value defined by a result of an operation.
Definition Value.h:454
A wrapper class that allows for printing an operation with a set of flags, useful to act as a "stream...
Definition Operation.h:1162
OpWithFlags(Operation *op, OpPrintingFlags flags={})
Definition Operation.h:1164
friend raw_ostream & operator<<(raw_ostream &os, OpWithFlags op)
Definition Operation.h:1176
const OpPrintingFlags & flags() const
Definition Operation.h:1167
Operation * getOperation() const
Definition Operation.h:1168
OpPrintingFlags & flags()
Definition Operation.h:1166
A wrapper class that allows for printing an operation with a custom AsmState, useful to act as a "str...
Definition Operation.h:1186
OpWithState(Operation *op, AsmState &state)
Definition Operation.h:1188
friend raw_ostream & operator<<(raw_ostream &os, const OpWithState &op)
Definition Operation.h:1196
This class implements the operand iterators for the Operation class.
Definition ValueRange.h:44
type_range getTypes() const
ValueTypeRange< OperandRange > type_range
Definition ValueRange.h:50
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Definition ValueRange.h:49
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context,...
std::optional< RegisteredOperationName > getRegisteredInfo() const
If this operation is registered, returns the registered information, std::nullopt otherwise.
bool isRegistered() const
Return if this operation is registered.
Class encompassing various options related to cloning an operation.
Definition Operation.h:140
bool shouldCloneResults() const
Returns true if the results are cloned from the operation.
Definition Operation.h:179
bool shouldCloneRegions() const
Returns whether regions of the operation should be cloned as well.
Definition Operation.h:164
CloneOptions()
Default constructs an option with all flags set to false.
static CloneOptions all()
Returns an instance such that all elements of the operation are cloned.
bool shouldCloneOperands() const
Returns whether operands should be cloned as well.
Definition Operation.h:171
TypeRange resultTypesOr(TypeRange defaultResultTypes) const
Returns the result types that should be used for the created operation or defaultResultTypes if none ...
Definition Operation.h:183
CloneOptions & cloneRegions(bool enable=true)
Configures whether cloning should traverse into any of the regions of the operation.
CloneOptions & withResultTypes(std::optional< SmallVector< Type > > resultTypes)
Configures different result types to use for the cloned operation.
CloneOptions & cloneOperands(bool enable=true)
Configures whether operation' operands should be cloned.
A utility iterator that filters out non-dialect attributes.
Definition Operation.h:665
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
PropertyRef getPropertiesStorage()
Return a generic (but typed) reference to the property type storage.
Definition Operation.h:946
AttrClass getAttrOfType(StringRef name)
Definition Operation.h:599
void setLoc(Location loc)
Set the source location the operation was defined or derived from.
Definition Operation.h:243
bool hasDiscardableAttrOfType(NameT &&name)
Definition Operation.h:499
void setInherentAttr(StringAttr name, Attribute value)
Set an inherent attribute by name.
void eraseOperands(const BitVector &eraseIndices)
Erases the operands that have their corresponding bit set in eraseIndices and removes them from the o...
Definition Operation.h:391
Attribute getDiscardableAttr(StringRef name)
Access a discardable attribute by name, returns a null Attribute if the discardable attribute does no...
Definition Operation.h:478
void replaceUsesOfWith(Value from, Value to)
Replace any uses of 'from' with 'to' within this operation.
PropertyRef getPropertiesStorage() const
Definition Operation.h:953
void copyProperties(PropertyRef rhs)
Copy properties from an existing other properties object.
MutableArrayRef< BlockOperand > getBlockOperands()
Definition Operation.h:740
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
ResultRange result_range
Support result iteration.
Definition Operation.h:435
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
Definition Operation.h:237
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Attempt to fold this operation with the specified constant operand values.
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==2, RetT > walk(FnT &&callback)
Generic walker with a stage aware callback.
Definition Operation.h:870
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
Definition Operation.h:731
bool use_empty()
Returns true if this operation has no uses.
Definition Operation.h:897
Value getOperand(unsigned idx)
Definition Operation.h:375
std::enable_if_t<(sizeof...(OpTy) > 1), Operation * > getParentOfType()
Definition Operation.h:263
OpResult getOpResult(unsigned idx)
Definition Operation.h:446
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Definition Operation.h:794
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.
Definition Operation.h:879
AttrClass getAttrOfType(StringAttr name)
Definition Operation.h:595
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
Definition Operation.h:579
bool hasAttr(StringRef name)
Definition Operation.h:612
operand_range::type_range operand_type_range
Definition Operation.h:419
bool hasAttrOfType(NameT &&name)
Definition Operation.h:620
void setOperand(unsigned idx, Value value)
Definition Operation.h:376
void setAttrs(DictionaryAttr newAttrs)
Set the attributes from a dictionary on this operation.
bool hasAttr(StringAttr name)
Return true if the operation has an attribute with the provided name, false otherwise.
Definition Operation.h:605
unsigned getNumSuccessors()
Definition Operation.h:751
bool isBeforeInBlock(Operation *other)
Given an operation 'other' that is within the same parent block, return whether the current operation...
result_iterator result_begin()
Definition Operation.h:438
void eraseOperands(unsigned idx, unsigned length=1)
Erase the operands starting at position idx and ending at position 'idx'+'length'.
Definition Operation.h:385
void dropAllReferences()
This drops all operand uses from this operation, which is an essential step in breaking cyclic depend...
bool isRegistered()
Returns true if this operation has a registered operation description, otherwise false.
Definition Operation.h:125
InFlightDiagnostic emitWarning(const Twine &message={})
Emit a warning about this operation, reporting up to any diagnostic handlers that may be listening.
result_range::iterator result_iterator
Definition Operation.h:436
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
Definition Operation.h:557
operand_iterator operand_begin()
Definition Operation.h:399
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
Definition Operation.h:802
result_range::use_iterator use_iterator
Definition Operation.h:884
bool hasOneUse()
Returns true if this operation has exactly one use.
Definition Operation.h:894
dialect_attr_iterator dialect_attr_begin()
Definition Operation.h:687
Attribute getAttr(StringRef name)
Definition Operation.h:586
Block * getBlock()
Returns the operation block that contains this operation.
Definition Operation.h:230
user_iterator user_end()
Definition Operation.h:915
void setDiscardableAttr(StringAttr name, Attribute value)
Set a discardable attribute by name.
Definition Operation.h:505
Attribute removeAttr(StringRef name)
Definition Operation.h:658
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition Operation.h:432
use_iterator use_begin()
Definition Operation.h:887
std::optional< Attribute > getInherentAttr(StringRef name)
Access an inherent attribute by name: returns an empty optional if there is no inherent attribute wit...
Operation * getParentWithTrait()
Returns the closest surrounding parent operation with trait Trait.
Definition Operation.h:273
operand_range::type_iterator operand_type_iterator
Definition Operation.h:418
operand_type_iterator operand_type_end()
Definition Operation.h:421
Attribute removeDiscardableAttr(StringRef name)
Definition Operation.h:524
result_range::type_range result_type_range
Definition Operation.h:450
unsigned getNumRegions()
Returns the number of regions held by this operation.
Definition Operation.h:719
void setDialectAttrs(DialectAttrT &&dialectAttrs)
Set the dialect attributes for this operation, and preserve all inherent.
Definition Operation.h:698
Location getLoc()
The source location the operation was defined or derived from.
Definition Operation.h:240
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Definition Operation.h:251
void replaceUsesWithIf(ValuesT &&values, function_ref< bool(OpOperand &)> shouldReplace)
Replace uses of results of this operation with the provided values if the given callback returns true...
Definition Operation.h:304
MutableArrayRef< OpOperand > getOpOperands()
Definition Operation.h:408
std::optional< RegisteredOperationName > getRegisteredInfo()
If this operation has a registered operation description, return it.
Definition Operation.h:119
void eraseOperand(unsigned idx)
Erase the operand at position idx.
Definition Operation.h:381
bool hasPromiseOrImplementsInterface() const
Returns true if InterfaceT has been promised by the dialect or implemented.
Definition Operation.h:787
DictionaryAttr getRawDictionaryAttrs()
Return all attributes that are not stored as properties.
Definition Operation.h:554
void dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
iterator_range< user_iterator > user_range
Definition Operation.h:912
iterator_range< dialect_attr_iterator > dialect_attr_range
Definition Operation.h:679
unsigned getNumOperands()
Definition Operation.h:371
result_type_iterator result_type_end()
Definition Operation.h:452
Attribute getPropertiesAsAttribute()
Return the properties converted to an attribute.
OperandRange operand_range
Definition Operation.h:396
void populateDefaultAttrs()
Sets default attributes on unset attributes.
Definition Operation.h:708
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
ValueUserIterator< use_iterator, OpOperand > user_iterator
Definition Operation.h:911
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition Operation.h:255
result_range::type_iterator result_type_iterator
Support result type iteration.
Definition Operation.h:449
operand_iterator operand_end()
Definition Operation.h:400
Attribute getDiscardableAttr(StringAttr name)
Access a discardable attribute by name, returns a null Attribute if the discardable attribute does no...
Definition Operation.h:482
bool isUsedOutsideOfBlock(Block *block)
Returns true if the results of this operation are used outside of the given block.
Definition Operation.h:901
result_type_iterator result_type_begin()
Definition Operation.h:451
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
Definition Operation.h:627
void destroy()
Destroys this operation and its subclass data.
bool hasDiscardableAttr(StringRef name)
Return true if this operation has a discardable attribute with the provided name.
Definition Operation.h:496
auto getDiscardableAttrs()
Return a range of all of discardable attributes on this operation.
Definition Operation.h:531
OperationName getName()
The name of an operation is the key identifier for it.
Definition Operation.h:115
DictionaryAttr getDiscardableAttrDictionary()
Return all of the discardable attributes on this operation as a DictionaryAttr.
Definition Operation.h:546
void remove()
Remove the operation from its parent block, but don't delete it.
void print(raw_ostream &os, const OpPrintingFlags &flags={})
void setDiscardableAttrs(ArrayRef< NamedAttribute > newAttrs)
Definition Operation.h:572
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
Definition Operation.h:682
LogicalResult setPropertiesFromAttribute(Attribute attr, function_ref< InFlightDiagnostic()> emitError)
Set the properties from the provided attribute.
bool hasSuccessors()
Definition Operation.h:750
operand_type_range getOperandTypes()
Definition Operation.h:422
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
Definition Operation.h:722
result_iterator result_end()
Definition Operation.h:439
AttrClass getDiscardableAttrOfType(StringAttr name)
Definition Operation.h:490
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.
Definition Operation.cpp:65
friend class Block
Definition Operation.h:1127
result_type_range getResultTypes()
Definition Operation.h:453
Attribute removeDiscardableAttr(StringAttr name)
Remove the discardable attribute with the specified name if it exists.
Definition Operation.h:517
LLVM_DUMP_METHOD void dumpPretty()
void setDiscardableAttr(StringRef name, Attribute value)
Definition Operation.h:510
operand_range getOperands()
Returns an iterator on the underlying Value's.
Definition Operation.h:403
void setSuccessor(Block *block, unsigned index)
void moveBefore(Operation *existingOp)
Unlink this operation from its current block and insert it right before existingOp which may be in th...
bool isAncestor(Operation *other)
Return true if this operation is an ancestor of the other operation.
Definition Operation.h:288
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided 'values'.
Definition Operation.h:297
void setOperands(ValueRange operands)
Replace the current operands of this operation with the ones provided in 'operands'.
result_range::use_range use_range
Definition Operation.h:885
bool hasDiscardableAttr(StringAttr name)
Definition Operation.h:497
void * getRawPropertiesStorageUnsafe()
Returns a pointer to the properties storage (if it exists) with no type information.
Definition Operation.h:964
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
Definition Operation.h:842
AttrClass getDiscardableAttrOfType(StringRef name)
Access a discardable attribute by name and cast it to AttrClass.
Definition Operation.h:486
Block * getSuccessor(unsigned index)
Definition Operation.h:753
user_range getUsers()
Returns a range of all users.
Definition Operation.h:918
SuccessorRange getSuccessors()
Definition Operation.h:748
result_range getOpResults()
Definition Operation.h:445
result_range getResults()
Definition Operation.h:440
int getPropertiesStorageSize() const
Returns the properties storage size.
Definition Operation.h:941
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.
Definition Operation.h:247
Attribute removeAttr(StringAttr name)
Remove the attribute with the specified name if it exists.
Definition Operation.h:645
SuccessorRange::iterator succ_iterator
Definition Operation.h:745
dialect_attr_iterator dialect_attr_end()
Definition Operation.h:691
bool isProperAncestor(Operation *other)
Return true if this operation is a proper ancestor of the other operation.
OpOperand & getOpOperand(unsigned idx)
Definition Operation.h:413
use_range getUses()
Returns a range of all uses, which is useful for iterating over all uses.
Definition Operation.h:891
void setAttr(StringRef name, Attribute value)
Definition Operation.h:638
MLIRContext * getContext()
Return the context this operation is associated with.
Definition Operation.h:233
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening.
operand_range::iterator operand_iterator
Definition Operation.h:397
user_iterator user_begin()
Definition Operation.h:914
friend class Value
Definition Operation.h:1130
void setDiscardableAttrs(DictionaryAttr newAttrs)
Set the discardable attribute dictionary on this operation.
Definition Operation.h:568
void moveAfter(Operation *existingOp)
Unlink this operation from its current block and insert it right after existingOp which may be in the...
llvm::hash_code hashProperties()
Compute a hash for the op properties (if any).
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
succ_iterator successor_end()
Definition Operation.h:747
use_iterator use_end()
Definition Operation.h:888
void erase()
Remove this operation from its parent block and delete it.
succ_iterator successor_begin()
Definition Operation.h:746
unsigned getNumResults()
Return the number of results held by this operation.
Definition Operation.h:429
operand_type_iterator operand_type_begin()
Definition Operation.h:420
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.
Definition Region.h:378
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition Region.h:26
This class implements the result iterators for the Operation class.
Definition ValueRange.h:248
std::enable_if_t<!std::is_convertible< ValuesT, Operation * >::value > replaceUsesWithIf(ValuesT &&values, function_ref< bool(OpOperand &)> shouldReplace)
Replace uses of results of this range with the provided 'values' if the given callback returns true.
Definition ValueRange.h:304
use_range getUses() const
Returns a range of all uses of results within this range, which is useful for iterating over all uses...
bool use_empty() const
Returns true if no results in this range have uses.
Definition ValueRange.h:278
ValueTypeRange< ResultRange > type_range
Definition ValueRange.h:259
use_iterator use_begin() const
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Definition ValueRange.h:258
use_iterator use_end() const
type_range getTypes() const
iterator_range< use_iterator > use_range
Definition ValueRange.h:269
UseIterator use_iterator
Definition ValueRange.h:268
std::enable_if_t<!std::is_convertible< ValuesT, Operation * >::value > replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this range with the provided 'values'.
Definition ValueRange.h:287
This class implements the successor iterators for Block.
This class provides an abstraction over the various different ranges of value types.
Definition TypeRange.h:40
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:389
An iterator over the users of an IRObject.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
static unsigned getMaxInlineResults()
Returns the maximum number of results that can be stored inline.
Definition Value.h:377
This class handles the management of operation operands.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition CallGraph.h:227
AttrTypeReplacer.
void walk(Operation *op, function_ref< void(Region *)> callback, WalkOrder order)
Walk all of the regions, blocks, or operations nested under (and including) the given operation.
Definition Visitors.h:102
OpProperties
This is a "tag" used for mapping the properties storage in llvm::TrailingObjects.
Definition Operation.h:27
decltype(walk(nullptr, std::declval< FnT >())) walkResultType
Utility to provide the return type of a templated walk method.
Definition Visitors.h:433
Include the generated interface declarations.
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
WalkOrder
Traversal order for region, block and operation walk utilities.
Definition Visitors.h:28
llvm::function_ref< Fn > function_ref
Definition LLVM.h:147
static T doCast(::mlir::Operation &val)
Definition Operation.h:1226
static bool isPossible(::mlir::Operation &val)
Definition Operation.h:1225
static bool isPossible(::mlir::Operation *op)
Definition Operation.h:1210
::mlir::Operation * doCast(::mlir::Operation *op)
Definition Operation.h:1243
This iterator enumerates the elements in "forward" order.
Definition Visitors.h:31
This represents an operation in an abstracted form, suitable for use with the builder APIs.