MLIR  14.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 
23 namespace mlir {
24 /// Operation is a basic unit of execution within MLIR. Operations can
25 /// be nested within `Region`s held by other operations effectively forming a
26 /// tree. Child operations are organized into operation blocks represented by a
27 /// 'Block' class.
28 class alignas(8) Operation final
29  : public llvm::ilist_node_with_parent<Operation, Block>,
30  private llvm::TrailingObjects<Operation, detail::OperandStorage,
31  BlockOperand, Region, OpOperand> {
32 public:
33  /// Create a new Operation with the specific fields.
34  static Operation *create(Location location, OperationName name,
35  TypeRange resultTypes, ValueRange operands,
36  ArrayRef<NamedAttribute> attributes,
37  BlockRange successors, unsigned numRegions);
38 
39  /// Overload of create that takes an existing DictionaryAttr to avoid
40  /// unnecessarily uniquing a list of attributes.
41  static Operation *create(Location location, OperationName name,
42  TypeRange resultTypes, ValueRange operands,
43  DictionaryAttr attributes, BlockRange successors,
44  unsigned numRegions);
45 
46  /// Create a new Operation from the fields stored in `state`.
47  static Operation *create(const OperationState &state);
48 
49  /// Create a new Operation with the specific fields.
50  static Operation *create(Location location, OperationName name,
51  TypeRange resultTypes, ValueRange operands,
52  DictionaryAttr attributes,
53  BlockRange successors = {},
54  RegionRange regions = {});
55 
56  /// The name of an operation is the key identifier for it.
57  OperationName getName() { return name; }
58 
59  /// If this operation has a registered operation description, return it.
60  /// Otherwise return None.
62  return getName().getRegisteredInfo();
63  }
64 
65  /// Returns true if this operation has a registered operation description,
66  /// otherwise false.
67  bool isRegistered() { return getName().isRegistered(); }
68 
69  /// Remove this operation from its parent block and delete it.
70  void erase();
71 
72  /// Remove the operation from its parent block, but don't delete it.
73  void remove();
74 
75  /// Create a deep copy of this operation, remapping any operands that use
76  /// values outside of the operation using the map that is provided (leaving
77  /// them alone if no entry is present). Replaces references to cloned
78  /// sub-operations to the corresponding operation that is copied, and adds
79  /// those mappings to the map.
81  Operation *clone();
82 
83  /// Create a partial copy of this operation without traversing into attached
84  /// regions. The new operation will have the same number of regions as the
85  /// original one, but they will be left empty.
86  /// Operands are remapped using `mapper` (if present), and `mapper` is updated
87  /// to contain the results.
89 
90  /// Create a partial copy of this operation without traversing into attached
91  /// regions. The new operation will have the same number of regions as the
92  /// original one, but they will be left empty.
94 
95  /// Returns the operation block that contains this operation.
96  Block *getBlock() { return block; }
97 
98  /// Return the context this operation is associated with.
99  MLIRContext *getContext() { return location->getContext(); }
100 
101  /// Return the dialect this operation is associated with, or nullptr if the
102  /// associated dialect is not loaded.
104 
105  /// The source location the operation was defined or derived from.
106  Location getLoc() { return location; }
107 
108  /// Set the source location the operation was defined or derived from.
109  void setLoc(Location loc) { location = loc; }
110 
111  /// Returns the region to which the instruction belongs. Returns nullptr if
112  /// the instruction is unlinked.
113  Region *getParentRegion() { return block ? block->getParent() : nullptr; }
114 
115  /// Returns the closest surrounding operation that contains this operation
116  /// or nullptr if this is a top-level operation.
117  Operation *getParentOp() { return block ? block->getParentOp() : nullptr; }
118 
119  /// Return the closest surrounding parent operation that is of type 'OpTy'.
120  template <typename OpTy> OpTy getParentOfType() {
121  auto *op = this;
122  while ((op = op->getParentOp()))
123  if (auto parentOp = dyn_cast<OpTy>(op))
124  return parentOp;
125  return OpTy();
126  }
127 
128  /// Returns the closest surrounding parent operation with trait `Trait`.
129  template <template <typename T> class Trait>
131  Operation *op = this;
132  while ((op = op->getParentOp()))
133  if (op->hasTrait<Trait>())
134  return op;
135  return nullptr;
136  }
137 
138  /// Return true if this operation is a proper ancestor of the `other`
139  /// operation.
140  bool isProperAncestor(Operation *other);
141 
142  /// Return true if this operation is an ancestor of the `other` operation. An
143  /// operation is considered as its own ancestor, use `isProperAncestor` to
144  /// avoid this.
145  bool isAncestor(Operation *other) {
146  return this == other || isProperAncestor(other);
147  }
148 
149  /// Replace any uses of 'from' with 'to' within this operation.
150  void replaceUsesOfWith(Value from, Value to);
151 
152  /// Replace all uses of results of this operation with the provided 'values'.
153  template <typename ValuesT>
154  void replaceAllUsesWith(ValuesT &&values) {
155  getResults().replaceAllUsesWith(std::forward<ValuesT>(values));
156  }
157 
158  /// Destroys this operation and its subclass data.
159  void destroy();
160 
161  /// This drops all operand uses from this operation, which is an essential
162  /// step in breaking cyclic dependences between references when they are to
163  /// be deleted.
164  void dropAllReferences();
165 
166  /// Drop uses of all values defined by this operation or its nested regions.
168 
169  /// Unlink this operation from its current block and insert it right before
170  /// `existingOp` which may be in the same or another block in the same
171  /// function.
172  void moveBefore(Operation *existingOp);
173 
174  /// Unlink this operation from its current block and insert it right before
175  /// `iterator` in the specified block.
176  void moveBefore(Block *block, llvm::iplist<Operation>::iterator iterator);
177 
178  /// Unlink this operation from its current block and insert it right after
179  /// `existingOp` which may be in the same or another block in the same
180  /// function.
181  void moveAfter(Operation *existingOp);
182 
183  /// Unlink this operation from its current block and insert it right after
184  /// `iterator` in the specified block.
185  void moveAfter(Block *block, llvm::iplist<Operation>::iterator iterator);
186 
187  /// Given an operation 'other' that is within the same parent block, return
188  /// whether the current operation is before 'other' in the operation list
189  /// of the parent block.
190  /// Note: This function has an average complexity of O(1), but worst case may
191  /// take O(N) where N is the number of operations within the parent block.
192  bool isBeforeInBlock(Operation *other);
193 
194  void print(raw_ostream &os, const OpPrintingFlags &flags = llvm::None);
195  void print(raw_ostream &os, AsmState &state,
196  const OpPrintingFlags &flags = llvm::None);
197  void dump();
198 
199  //===--------------------------------------------------------------------===//
200  // Operands
201  //===--------------------------------------------------------------------===//
202 
203  /// Replace the current operands of this operation with the ones provided in
204  /// 'operands'.
205  void setOperands(ValueRange operands);
206 
207  /// Replace the operands beginning at 'start' and ending at 'start' + 'length'
208  /// with the ones provided in 'operands'. 'operands' may be smaller or larger
209  /// than the range pointed to by 'start'+'length'.
210  void setOperands(unsigned start, unsigned length, ValueRange operands);
211 
212  /// Insert the given operands into the operand list at the given 'index'.
213  void insertOperands(unsigned index, ValueRange operands);
214 
215  unsigned getNumOperands() {
216  return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().size() : 0;
217  }
218 
219  Value getOperand(unsigned idx) { return getOpOperand(idx).get(); }
220  void setOperand(unsigned idx, Value value) {
221  return getOpOperand(idx).set(value);
222  }
223 
224  /// Erase the operand at position `idx`.
225  void eraseOperand(unsigned idx) { eraseOperands(idx); }
226 
227  /// Erase the operands starting at position `idx` and ending at position
228  /// 'idx'+'length'.
229  void eraseOperands(unsigned idx, unsigned length = 1) {
230  getOperandStorage().eraseOperands(idx, length);
231  }
232 
233  /// Erases the operands that have their corresponding bit set in
234  /// `eraseIndices` and removes them from the operand list.
235  void eraseOperands(const llvm::BitVector &eraseIndices) {
236  getOperandStorage().eraseOperands(eraseIndices);
237  }
238 
239  // Support operand iteration.
241  using operand_iterator = operand_range::iterator;
242 
245 
246  /// Returns an iterator on the underlying Value's.
249  return OperandRange(operands.data(), operands.size());
250  }
251 
253  return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().getOperands()
255  }
256 
257  OpOperand &getOpOperand(unsigned idx) {
258  return getOperandStorage().getOperands()[idx];
259  }
260 
261  // Support operand type iteration.
267 
268  //===--------------------------------------------------------------------===//
269  // Results
270  //===--------------------------------------------------------------------===//
271 
272  /// Return the number of results held by this operation.
273  unsigned getNumResults() { return numResults; }
274 
275  /// Get the 'idx'th result of this operation.
276  OpResult getResult(unsigned idx) { return OpResult(getOpResultImpl(idx)); }
277 
278  /// Support result iteration.
280  using result_iterator = result_range::iterator;
281 
282  result_iterator result_begin() { return getResults().begin(); }
283  result_iterator result_end() { return getResults().end(); }
285  return numResults == 0 ? result_range(nullptr, 0)
286  : result_range(getInlineOpResult(0), numResults);
287  }
288 
290  OpResult getOpResult(unsigned idx) { return getResult(idx); }
291 
292  /// Support result type iteration.
298 
299  //===--------------------------------------------------------------------===//
300  // Attributes
301  //===--------------------------------------------------------------------===//
302 
303  // Operations may optionally carry a list of attributes that associate
304  // constants to names. Attributes may be dynamically added and removed over
305  // the lifetime of an operation.
306 
307  /// Return all of the attributes on this operation.
308  ArrayRef<NamedAttribute> getAttrs() { return attrs.getValue(); }
309 
310  /// Return all of the attributes on this operation as a DictionaryAttr.
311  DictionaryAttr getAttrDictionary() { return attrs; }
312 
313  /// Set the attribute dictionary on this operation.
314  void setAttrs(DictionaryAttr newAttrs) {
315  assert(newAttrs && "expected valid attribute dictionary");
316  attrs = newAttrs;
317  }
319  setAttrs(DictionaryAttr::get(getContext(), newAttrs));
320  }
321 
322  /// Return the specified attribute if present, null otherwise.
323  Attribute getAttr(StringAttr name) { return attrs.get(name); }
324  Attribute getAttr(StringRef name) { return attrs.get(name); }
325 
326  template <typename AttrClass>
327  AttrClass getAttrOfType(StringAttr name) {
328  return getAttr(name).dyn_cast_or_null<AttrClass>();
329  }
330  template <typename AttrClass>
331  AttrClass getAttrOfType(StringRef name) {
332  return getAttr(name).dyn_cast_or_null<AttrClass>();
333  }
334 
335  /// Return true if the operation has an attribute with the provided name,
336  /// false otherwise.
337  bool hasAttr(StringAttr name) { return attrs.contains(name); }
338  bool hasAttr(StringRef name) { return attrs.contains(name); }
339  template <typename AttrClass, typename NameT>
340  bool hasAttrOfType(NameT &&name) {
341  return static_cast<bool>(
342  getAttrOfType<AttrClass>(std::forward<NameT>(name)));
343  }
344 
345  /// If the an attribute exists with the specified name, change it to the new
346  /// value. Otherwise, add a new attribute with the specified name/value.
347  void setAttr(StringAttr name, Attribute value) {
348  NamedAttrList attributes(attrs);
349  if (attributes.set(name, value) != value)
350  attrs = attributes.getDictionary(getContext());
351  }
352  void setAttr(StringRef name, Attribute value) {
353  setAttr(StringAttr::get(getContext(), name), value);
354  }
355 
356  /// Remove the attribute with the specified name if it exists. Return the
357  /// attribute that was erased, or nullptr if there was no attribute with such
358  /// name.
359  Attribute removeAttr(StringAttr name) {
360  NamedAttrList attributes(attrs);
361  Attribute removedAttr = attributes.erase(name);
362  if (removedAttr)
363  attrs = attributes.getDictionary(getContext());
364  return removedAttr;
365  }
366  Attribute removeAttr(StringRef name) {
367  return removeAttr(StringAttr::get(getContext(), name));
368  }
369 
370  /// A utility iterator that filters out non-dialect attributes.
372  : public llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
373  bool (*)(NamedAttribute)> {
374  static bool filter(NamedAttribute attr) {
375  // Dialect attributes are prefixed by the dialect name, like operations.
376  return attr.getName().strref().count('.');
377  }
378 
381  : llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
382  bool (*)(NamedAttribute)>(it, end, &filter) {}
383 
384  // Allow access to the constructor.
385  friend Operation;
386  };
388 
389  /// Return a range corresponding to the dialect attributes for this operation.
391  auto attrs = getAttrs();
392  return {dialect_attr_iterator(attrs.begin(), attrs.end()),
393  dialect_attr_iterator(attrs.end(), attrs.end())};
394  }
396  auto attrs = getAttrs();
397  return dialect_attr_iterator(attrs.begin(), attrs.end());
398  }
400  auto attrs = getAttrs();
401  return dialect_attr_iterator(attrs.end(), attrs.end());
402  }
403 
404  /// Set the dialect attributes for this operation, and preserve all dependent.
405  template <typename DialectAttrT>
406  void setDialectAttrs(DialectAttrT &&dialectAttrs) {
407  NamedAttrList attrs;
408  attrs.append(std::begin(dialectAttrs), std::end(dialectAttrs));
409  for (auto attr : getAttrs())
410  if (!attr.getName().strref().contains('.'))
411  attrs.push_back(attr);
413  }
414 
415  //===--------------------------------------------------------------------===//
416  // Blocks
417  //===--------------------------------------------------------------------===//
418 
419  /// Returns the number of regions held by this operation.
420  unsigned getNumRegions() { return numRegions; }
421 
422  /// Returns the regions held by this operation.
424  auto *regions = getTrailingObjects<Region>();
425  return {regions, numRegions};
426  }
427 
428  /// Returns the region held by this operation at position 'index'.
429  Region &getRegion(unsigned index) {
430  assert(index < numRegions && "invalid region index");
431  return getRegions()[index];
432  }
433 
434  //===--------------------------------------------------------------------===//
435  // Successors
436  //===--------------------------------------------------------------------===//
437 
439  return {getTrailingObjects<BlockOperand>(), numSuccs};
440  }
441 
442  // Successor iteration.
443  using succ_iterator = SuccessorRange::iterator;
447 
448  bool hasSuccessors() { return numSuccs != 0; }
449  unsigned getNumSuccessors() { return numSuccs; }
450 
451  Block *getSuccessor(unsigned index) {
452  assert(index < getNumSuccessors());
453  return getBlockOperands()[index].get();
454  }
455  void setSuccessor(Block *block, unsigned index);
456 
457  //===--------------------------------------------------------------------===//
458  // Accessors for various properties of operations
459  //===--------------------------------------------------------------------===//
460 
461  /// Attempt to fold this operation with the specified constant operand values
462  /// - the elements in "operands" will correspond directly to the operands of
463  /// the operation, but may be null if non-constant. If folding is successful,
464  /// this fills in the `results` vector. If not, `results` is unspecified.
467 
468  /// Returns true if the operation was registered with a particular trait, e.g.
469  /// hasTrait<OperandsAreSignlessIntegerLike>().
470  template <template <typename T> class Trait> bool hasTrait() {
471  return name.hasTrait<Trait>();
472  }
473 
474  /// Returns true if the operation *might* have the provided trait. This
475  /// means that either the operation is unregistered, or it was registered with
476  /// the provide trait.
477  template <template <typename T> class Trait> bool mightHaveTrait() {
478  return name.mightHaveTrait<Trait>();
479  }
480 
481  //===--------------------------------------------------------------------===//
482  // Operation Walkers
483  //===--------------------------------------------------------------------===//
484 
485  /// Walk the operation by calling the callback for each nested operation
486  /// (including this one), block or region, depending on the callback provided.
487  /// Regions, blocks and operations at the same nesting level are visited in
488  /// lexicographical order. The walk order for enclosing regions, blocks and
489  /// operations with respect to their nested ones is specified by 'Order'
490  /// (post-order by default). A callback on a block or operation is allowed to
491  /// erase that block or operation if either:
492  /// * the walk is in post-order, or
493  /// * the walk is in pre-order and the walk is skipped after the erasure.
494  ///
495  /// The callback method can take any of the following forms:
496  /// void(Operation*) : Walk all operations opaquely.
497  /// * op->walk([](Operation *nestedOp) { ...});
498  /// void(OpT) : Walk all operations of the given derived type.
499  /// * op->walk([](ReturnOp returnOp) { ...});
500  /// WalkResult(Operation*|OpT) : Walk operations, but allow for
501  /// interruption/skipping.
502  /// * op->walk([](... op) {
503  /// // Skip the walk of this op based on some invariant.
504  /// if (some_invariant)
505  /// return WalkResult::skip();
506  /// // Interrupt, i.e cancel, the walk based on some invariant.
507  /// if (another_invariant)
508  /// return WalkResult::interrupt();
509  /// return WalkResult::advance();
510  /// });
511  template <WalkOrder Order = WalkOrder::PostOrder, typename FnT,
512  typename RetT = detail::walkResultType<FnT>>
513  RetT walk(FnT &&callback) {
514  return detail::walk<Order>(this, std::forward<FnT>(callback));
515  }
516 
517  //===--------------------------------------------------------------------===//
518  // Uses
519  //===--------------------------------------------------------------------===//
520 
521  /// Drop all uses of results of this operation.
522  void dropAllUses() {
523  for (OpResult result : getOpResults())
524  result.dropAllUses();
525  }
526 
529 
532 
533  /// Returns a range of all uses, which is useful for iterating over all uses.
535 
536  /// Returns true if this operation has exactly one use.
537  bool hasOneUse() { return llvm::hasSingleElement(getUses()); }
538 
539  /// Returns true if this operation has no uses.
540  bool use_empty() { return getResults().use_empty(); }
541 
542  /// Returns true if the results of this operation are used outside of the
543  /// given block.
545  return llvm::any_of(getOpResults(), [block](OpResult result) {
546  return result.isUsedOutsideOfBlock(block);
547  });
548  }
549 
550  //===--------------------------------------------------------------------===//
551  // Users
552  //===--------------------------------------------------------------------===//
553 
556 
559 
560  /// Returns a range of all users.
561  user_range getUsers() { return {user_begin(), user_end()}; }
562 
563  //===--------------------------------------------------------------------===//
564  // Other
565  //===--------------------------------------------------------------------===//
566 
567  /// Emit an error with the op name prefixed, like "'dim' op " which is
568  /// convenient for verifiers.
569  InFlightDiagnostic emitOpError(const Twine &message = {});
570 
571  /// Emit an error about fatal conditions with this operation, reporting up to
572  /// any diagnostic handlers that may be listening.
573  InFlightDiagnostic emitError(const Twine &message = {});
574 
575  /// Emit a warning about this operation, reporting up to any diagnostic
576  /// handlers that may be listening.
577  InFlightDiagnostic emitWarning(const Twine &message = {});
578 
579  /// Emit a remark about this operation, reporting up to any diagnostic
580  /// handlers that may be listening.
581  InFlightDiagnostic emitRemark(const Twine &message = {});
582 
583 private:
584  //===--------------------------------------------------------------------===//
585  // Ordering
586  //===--------------------------------------------------------------------===//
587 
588  /// This value represents an invalid index ordering for an operation within a
589  /// block.
590  static constexpr unsigned kInvalidOrderIdx = -1;
591 
592  /// This value represents the stride to use when computing a new order for an
593  /// operation.
594  static constexpr unsigned kOrderStride = 5;
595 
596  /// Update the order index of this operation of this operation if necessary,
597  /// potentially recomputing the order of the parent block.
598  void updateOrderIfNecessary();
599 
600  /// Returns true if this operation has a valid order.
601  bool hasValidOrder() { return orderIndex != kInvalidOrderIdx; }
602 
603 private:
604  Operation(Location location, OperationName name, unsigned numResults,
605  unsigned numSuccessors, unsigned numRegions,
606  DictionaryAttr attributes, bool hasOperandStorage);
607 
608  // Operations are deleted through the destroy() member because they are
609  // allocated with malloc.
610  ~Operation();
611 
612  /// Returns the additional size necessary for allocating the given objects
613  /// before an Operation in-memory.
614  static size_t prefixAllocSize(unsigned numOutOfLineResults,
615  unsigned numInlineResults) {
616  return sizeof(detail::OutOfLineOpResult) * numOutOfLineResults +
617  sizeof(detail::InlineOpResult) * numInlineResults;
618  }
619  /// Returns the additional size allocated before this Operation in-memory.
620  size_t prefixAllocSize() {
621  unsigned numResults = getNumResults();
622  unsigned numOutOfLineResults = OpResult::getNumTrailing(numResults);
623  unsigned numInlineResults = OpResult::getNumInline(numResults);
624  return prefixAllocSize(numOutOfLineResults, numInlineResults);
625  }
626 
627  /// Returns the operand storage object.
628  detail::OperandStorage &getOperandStorage() {
629  assert(hasOperandStorage && "expected operation to have operand storage");
630  return *getTrailingObjects<detail::OperandStorage>();
631  }
632 
633  /// Returns a pointer to the use list for the given out-of-line result.
634  detail::OutOfLineOpResult *getOutOfLineOpResult(unsigned resultNumber) {
635  // Out-of-line results are stored in reverse order after (before in memory)
636  // the inline results.
637  return reinterpret_cast<detail::OutOfLineOpResult *>(getInlineOpResult(
639  ++resultNumber;
640  }
641 
642  /// Returns a pointer to the use list for the given inline result.
643  detail::InlineOpResult *getInlineOpResult(unsigned resultNumber) {
644  // Inline results are stored in reverse order before the operation in
645  // memory.
646  return reinterpret_cast<detail::InlineOpResult *>(this) - ++resultNumber;
647  }
648 
649  /// Returns a pointer to the use list for the given result, which may be
650  /// either inline or out-of-line.
651  detail::OpResultImpl *getOpResultImpl(unsigned resultNumber) {
652  unsigned maxInlineResults = detail::OpResultImpl::getMaxInlineResults();
653  if (resultNumber < maxInlineResults)
654  return getInlineOpResult(resultNumber);
655  return getOutOfLineOpResult(resultNumber - maxInlineResults);
656  }
657 
658  /// Provide a 'getParent' method for ilist_node_with_parent methods.
659  /// We mark it as a const function because ilist_node_with_parent specifically
660  /// requires a 'getParent() const' method. Once ilist_node removes this
661  /// constraint, we should drop the const to fit the rest of the MLIR const
662  /// model.
663  Block *getParent() const { return block; }
664 
665  /// The operation block that contains this operation.
666  Block *block = nullptr;
667 
668  /// This holds information about the source location the operation was defined
669  /// or derived from.
670  Location location;
671 
672  /// Relative order of this operation in its parent block. Used for
673  /// O(1) local dominance checks between operations.
674  mutable unsigned orderIndex = 0;
675 
676  const unsigned numResults;
677  const unsigned numSuccs;
678  const unsigned numRegions : 31;
679 
680  /// This bit signals whether this operation has an operand storage or not. The
681  /// operand storage may be elided for operations that are known to never have
682  /// operands.
683  bool hasOperandStorage : 1;
684 
685  /// This holds the name of the operation.
686  OperationName name;
687 
688  /// This holds general named attributes for the operation.
689  DictionaryAttr attrs;
690 
691  // allow ilist_traits access to 'block' field.
692  friend struct llvm::ilist_traits<Operation>;
693 
694  // allow block to access the 'orderIndex' field.
695  friend class Block;
696 
697  // allow value to access the 'ResultStorage' methods.
698  friend class Value;
699 
700  // allow ilist_node_with_parent to access the 'getParent' method.
701  friend class llvm::ilist_node_with_parent<Operation, Block>;
702 
703  // This stuff is used by the TrailingObjects template.
704  friend llvm::TrailingObjects<Operation, detail::OperandStorage, BlockOperand,
705  Region, OpOperand>;
706  size_t numTrailingObjects(OverloadToken<detail::OperandStorage>) const {
707  return hasOperandStorage ? 1 : 0;
708  }
709  size_t numTrailingObjects(OverloadToken<BlockOperand>) const {
710  return numSuccs;
711  }
712  size_t numTrailingObjects(OverloadToken<Region>) const { return numRegions; }
713 };
714 
715 inline raw_ostream &operator<<(raw_ostream &os, const Operation &op) {
716  const_cast<Operation &>(op).print(os, OpPrintingFlags().useLocalScope());
717  return os;
718 }
719 
720 } // end namespace mlir
721 
722 namespace llvm {
723 /// Provide isa functionality for operation casts.
724 template <typename T> struct isa_impl<T, ::mlir::Operation> {
725  static inline bool doit(const ::mlir::Operation &op) {
726  return T::classof(const_cast<::mlir::Operation *>(&op));
727  }
728 };
729 
730 /// Provide specializations for operation casts as the resulting T is value
731 /// typed.
732 template <typename T> struct cast_retty_impl<T, ::mlir::Operation *> {
733  using ret_type = T;
734 };
735 template <typename T> struct cast_retty_impl<T, ::mlir::Operation> {
736  using ret_type = T;
737 };
738 template <class T>
739 struct cast_convert_val<T, ::mlir::Operation, ::mlir::Operation> {
740  static T doit(::mlir::Operation &val) { return T(&val); }
741 };
742 template <class T>
743 struct cast_convert_val<T, ::mlir::Operation *, ::mlir::Operation *> {
744  static T doit(::mlir::Operation *val) { return T(val); }
745 };
746 } // end namespace llvm
747 
748 #endif // MLIR_IR_OPERATION_H
bool use_empty() const
Returns true if no results in this range have uses.
operand_range::iterator operand_iterator
Definition: Operation.h:241
void moveBefore(Operation *existingOp)
Unlink this operation from its current block and insert it right before existingOp which may be in th...
Definition: Operation.cpp:440
Include the generated interface declarations.
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, ArrayRef< NamedAttribute > attributes, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
Definition: Operation.cpp:27
This class contains a list of basic blocks and a link to the parent operation it is attached to...
Definition: Region.h:26
use_iterator use_begin() const
bool hasSuccessors()
Definition: Operation.h:448
bool isRegistered() const
Return if this operation is registered.
U dyn_cast_or_null() const
Definition: Attributes.h:123
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
Definition: Operation.h:423
void setAttrs(ArrayRef< NamedAttribute > newAttrs)
Definition: Operation.h:318
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
Definition: Block.cpp:30
bool isAncestor(Operation *other)
Return true if this operation is an ancestor of the other operation.
Definition: Operation.h:145
iterator_range< use_iterator > use_range
This is a value defined by a result of an operation.
Definition: Value.h:425
operand_range getOperands()
Returns an iterator on the underlying Value&#39;s.
Definition: Operation.h:247
use_range getUses()
Returns a range of all uses, which is useful for iterating over all uses.
Definition: Operation.h:534
unsigned getNumRegions()
Returns the number of regions held by this operation.
Definition: Operation.h:420
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:299
void setOperands(ValueRange operands)
Replace the current operands of this operation with the ones provided in &#39;operands&#39;.
Definition: Operation.cpp:200
Block represents an ordered list of Operations.
Definition: Block.h:29
bool hasOneUse()
Returns true if this operation has exactly one use.
Definition: Operation.h:537
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
Definition: Operation.h:308
Value getOperand(unsigned idx)
Definition: Operation.h:219
AttrClass getAttrOfType(StringAttr name)
Definition: Operation.h:327
bool isUsedOutsideOfBlock(Block *block)
Returns true if the results of this operation are used outside of the given block.
Definition: Operation.h:544
Attribute set(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
use_iterator use_begin()
Definition: Operation.h:530
unsigned getNumOperands()
Definition: Operation.h:215
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
Definition: Operation.h:477
A block operand represents an operand that holds a reference to a Block, e.g.
Definition: BlockSupport.h:30
operand_type_range getOperandTypes()
Definition: Operation.h:266
ValueTypeRange< ResultRange > type_range
Operation * getParentWithTrait()
Returns the closest surrounding parent operation with trait Trait.
Definition: Operation.h:130
bool isBeforeInBlock(Operation *other)
Given an operation &#39;other&#39; that is within the same parent block, return whether the current operation...
Definition: Operation.cpp:271
DictionaryAttr getDictionary(MLIRContext *context) const
Return a dictionary attribute for the underlying dictionary.
This class implements the result iterators for the Operation class.
bool hasAttr(StringRef name)
Definition: Operation.h:338
type_range getTypes() const
unsigned getNumSuccessors()
Definition: Operation.h:449
An iterator over the users of an IRObject.
Definition: UseDefLists.h:25
bool isRegistered()
Returns true if this operation has a registered operation description, otherwise false.
Definition: Operation.h:67
Attribute erase(StringAttr name)
Erase the attribute with the given name from the list.
Block * getBlock()
Returns the operation block that contains this operation.
Definition: Operation.h:96
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
void insertOperands(unsigned index, ValueRange operands)
Insert the given operands into the operand list at the given &#39;index&#39;.
Definition: Operation.cpp:219
void destroy()
Destroys this operation and its subclass data.
Definition: Operation.cpp:171
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type &#39;OpTy&#39;.
Definition: Operation.h:120
Region * getParent() const
Provide a &#39;getParent&#39; method for ilist_node_with_parent methods.
Definition: Block.cpp:26
static constexpr const bool value
void erase()
Remove this operation from its parent block and delete it.
Definition: Operation.cpp:424
void setSuccessor(Block *block, unsigned index)
Definition: Operation.cpp:490
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:140
MLIRContext * getContext()
Return the context this operation is associated with.
Definition: Operation.h:99
decltype(walk(nullptr, std::declval< FnT >())) walkResultType
Utility to provide the return type of a templated walk method.
Definition: Visitors.h:202
bool hasTrait() const
Returns true if the operation was registered with a particular trait, e.g.
user_iterator user_end()
Definition: Operation.h:558
MutableArrayRef< OpOperand > getOpOperands()
Definition: Operation.h:252
std::enable_if_t<!std::is_convertible< ValuesT, Operation * >::value > replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this range with the provided &#39;values&#39;.
AttrClass getAttrOfType(StringRef name)
Definition: Operation.h:331
void eraseOperands(unsigned idx, unsigned length=1)
Erase the operands starting at position idx and ending at position &#39;idx&#39;+&#39;length&#39;.
Definition: Operation.h:229
This class implements iteration on the types of a given range of values.
Definition: TypeRange.h:126
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
bool hasAttr(StringAttr name)
Return true if the operation has an attribute with the provided name, false otherwise.
Definition: Operation.h:337
succ_iterator successor_end()
Definition: Operation.h:445
Operation * clone()
Definition: Operation.cpp:574
Block * getSuccessor(unsigned index)
Definition: Operation.h:451
MLIRContext * getContext() const
Return the context this attribute belongs to.
Definition: Attributes.cpp:20
dialect_attr_iterator dialect_attr_begin()
Definition: Operation.h:395
void set(IRValueT newValue)
Set the current value being used by this operand.
Definition: UseDefLists.h:136
SuccessorRange::iterator succ_iterator
Definition: Operation.h:443
Attributes are known-constant values of operations.
Definition: Attributes.h:27
dialect_attr_iterator dialect_attr_end()
Definition: Operation.h:399
void eraseOperands(const llvm::BitVector &eraseIndices)
Erases the operands that have their corresponding bit set in eraseIndices and removes them from the o...
Definition: Operation.h:235
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Definition: Operation.h:470
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Definition: Operation.h:117
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided &#39;values&#39;.
Definition: Operation.h:154
ValueUserIterator< use_iterator, OpOperand > user_iterator
Definition: Operation.h:554
StringAttr getName() const
Return the name of the attribute.
Definition: Attributes.cpp:32
Attribute removeAttr(StringAttr name)
Remove the attribute with the specified name if it exists.
Definition: Operation.h:359
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:42
OpResult getResult(unsigned idx)
Get the &#39;idx&#39;th result of this operation.
Definition: Operation.h:276
succ_iterator successor_begin()
Definition: Operation.h:444
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:38
Optional< RegisteredOperationName > getRegisteredInfo() const
If this operation is registered, returns the registered information, None otherwise.
Location getLoc()
The source location the operation was defined or derived from.
Definition: Operation.h:106
RetT walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one)...
Definition: Operation.h:513
IRValueT get() const
Return the current value being used by this operand.
Definition: UseDefLists.h:133
This represents an operation in an abstracted form, suitable for use with the builder APIs...
MutableArrayRef< BlockOperand > getBlockOperands()
Definition: Operation.h:438
result_type_iterator result_type_end()
Definition: Operation.h:296
void dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
Definition: Operation.cpp:482
InFlightDiagnostic emitWarning(const Twine &message={})
Emit a warning about this operation, reporting up to any diagnostic handlers that may be listening...
Definition: Operation.cpp:243
bool hasAttrOfType(NameT &&name)
Definition: Operation.h:340
operand_type_iterator operand_type_begin()
Definition: Operation.h:264
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening...
Definition: Operation.cpp:252
result_range getOpResults()
Definition: Operation.h:289
void dropAllUses()
Drop all uses of results of this operation.
Definition: Operation.h:522
void setOperand(unsigned idx, Value value)
Definition: Operation.h:220
This class implements the successor iterators for Block.
Definition: BlockSupport.h:72
void print(raw_ostream &os, const OpPrintingFlags &flags=llvm::None)
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
Definition: Operation.h:311
bool use_empty()
Returns true if this operation has no uses.
Definition: Operation.h:540
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:84
operand_type_iterator operand_type_end()
Definition: Operation.h:265
This class implements a use iterator for a range of operation results.
This class implements iteration on the types of a given range of values.
Definition: Block.h:26
void eraseOperand(unsigned idx)
Erase the operand at position idx.
Definition: Operation.h:225
OpPrintingFlags & useLocalScope()
Use local scope when printing the operation.
Definition: AsmPrinter.cpp:202
unsigned size()
Return the number of operands held in the storage.
void dropAllReferences()
This drops all operand uses from this operation, which is an essential step in breaking cyclic depend...
Definition: Operation.cpp:469
void moveAfter(Operation *existingOp)
Unlink this operation from its current block and insert it right after existingOp which may be in the...
Definition: Operation.cpp:454
operand_iterator operand_begin()
Definition: Operation.h:243
SuccessorRange getSuccessors()
Definition: Operation.h:446
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
Definition: Operation.h:347
Set of flags used to control the behavior of the various IR print methods (e.g.
result_iterator result_end()
Definition: Operation.h:283
use_range getUses() const
Returns a range of all uses of results within this range, which is useful for iterating over all uses...
void setAttr(StringRef name, Attribute value)
Definition: Operation.h:352
result_type_iterator result_type_begin()
Definition: Operation.h:295
Attribute removeAttr(StringRef name)
Definition: Operation.h:366
void setLoc(Location loc)
Set the source location the operation was defined or derived from.
Definition: Operation.h:109
bool isUsedOutsideOfBlock(Block *block)
Returns true if the value is used outside of the given block.
Definition: Value.cpp:90
A utility iterator that filters out non-dialect attributes.
Definition: Operation.h:371
This class provides the implementation for an operation result whose index cannot be represented "inl...
Definition: Value.h:395
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
Definition: Operation.h:103
ValueTypeRange< OperandRange > type_range
OpOperand & getOpOperand(unsigned idx)
Definition: Operation.h:257
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
OpResult getOpResult(unsigned idx)
Definition: Operation.h:290
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
This class represents an operand of an operation.
Definition: Value.h:251
This class provides an abstraction over the different types of ranges over Blocks.
Definition: BlockSupport.h:104
This class provides an abstraction over the different types of ranges over Regions.
Definition: Region.h:316
void setDialectAttrs(DialectAttrT &&dialectAttrs)
Set the dialect attributes for this operation, and preserve all dependent.
Definition: Operation.h:406
bool mightHaveTrait() const
Returns true if the operation might have the provided trait.
This class implements the operand iterators for the Operation class.
This class provides the implementation for an operation result.
Definition: Value.h:349
result_range::iterator result_iterator
Definition: Operation.h:280
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context...
Region * getParentRegion()
Returns the region to which the instruction belongs.
Definition: Operation.h:113
Attribute getAttr(StringRef name)
Definition: Operation.h:324
use_iterator use_end() const
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Attempt to fold this operation with the specified constant operand values.
Definition: Operation.cpp:496
unsigned getNumResults()
Return the number of results held by this operation.
Definition: Operation.h:273
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
Definition: Operation.h:390
ResultRange result_range
Support result iteration.
Definition: Operation.h:279
MutableArrayRef< OpOperand > getOperands()
Get the operation operands held by the storage.
user_iterator user_begin()
Definition: Operation.h:557
static bool doit(const ::mlir::Operation &op)
Definition: Operation.h:725
operand_iterator operand_end()
Definition: Operation.h:244
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "&#39;dim&#39; op " which is convenient for verifiers...
Definition: Operation.cpp:518
Optional< RegisteredOperationName > getRegisteredInfo()
If this operation has a registered operation description, return it.
Definition: Operation.h:61
UseIterator use_iterator
OperationName getName()
The name of an operation is the key identifier for it.
Definition: Operation.h:57
WalkOrder
Traversal order for region, block and operation walk utilities.
Definition: Visitors.h:62
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:231
user_range getUsers()
Returns a range of all users.
Definition: Operation.h:561
void replaceUsesOfWith(Value from, Value to)
Replace any uses of &#39;from&#39; with &#39;to&#39; within this operation.
Definition: Operation.cpp:190
use_iterator use_end()
Definition: Operation.h:531
void setAttrs(DictionaryAttr newAttrs)
Set the attribute dictionary on this operation.
Definition: Operation.h:314
result_range getResults()
Definition: Operation.h:284
This class provides an abstraction over the different types of ranges over Values.
void push_back(NamedAttribute newAttribute)
Add an attribute with the specified name.
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
Definition: Operation.h:323
result_type_range getResultTypes()
Definition: Operation.h:297
bool isProperAncestor(Operation *other)
Return true if this operation is a proper ancestor of the other operation.
Definition: Operation.cpp:182
This class provides the implementation for an operation result whose index can be represented "inline...
Definition: Value.h:378
Region & getRegion(unsigned index)
Returns the region held by this operation at position &#39;index&#39;.
Definition: Operation.h:429
result_iterator result_begin()
Definition: Operation.h:282
void eraseOperands(unsigned start, unsigned length)
Erase the operands held by the storage within the given range.
This class provides management for the lifetime of the state used when printing the IR...
Definition: AsmState.h:36
Operation * cloneWithoutRegions()
Create a partial copy of this operation without traversing into attached regions. ...
Definition: Operation.cpp:554
type_range getTypes() const
static unsigned getMaxInlineResults()
Returns the maximum number of results that can be stored inline.
Definition: Value.h:371
This class handles the management of operation operands.