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