MLIR  15.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  /// Class encompassing various options related to cloning an operation. Users
76  /// of this class should pass it to Operation's 'clone' methods.
77  /// Current options include:
78  /// * Whether cloning should recursively traverse into the regions of the
79  /// operation or not.
80  /// * Whether cloning should also clone the operands of the operation.
81  class CloneOptions {
82  public:
83  /// Default constructs an option with all flags set to false. That means all
84  /// parts of an operation that may optionally not be cloned, are not cloned.
85  CloneOptions();
86 
87  /// Constructs an instance with the clone regions and clone operands flags
88  /// set accordingly.
90 
91  /// Returns an instance with all flags set to true. This is the default
92  /// when using the clone method and clones all parts of the operation.
93  static CloneOptions all();
94 
95  /// Configures whether cloning should traverse into any of the regions of
96  /// the operation. If set to true, the operation's regions are recursively
97  /// cloned. If set to false, cloned operations will have the same number of
98  /// regions, but they will be empty.
99  /// Cloning of nested operations in the operation's regions are currently
100  /// unaffected by other flags.
101  CloneOptions &cloneRegions(bool enable = true);
102 
103  /// Returns whether regions of the operation should be cloned as well.
104  bool shouldCloneRegions() const { return cloneRegionsFlag; }
105 
106  /// Configures whether operation' operands should be cloned. Otherwise the
107  /// resulting clones will simply have zero operands.
108  CloneOptions &cloneOperands(bool enable = true);
109 
110  /// Returns whether operands should be cloned as well.
111  bool shouldCloneOperands() const { return cloneOperandsFlag; }
112 
113  private:
114  /// Whether regions should be cloned.
115  bool cloneRegionsFlag : 1;
116  /// Whether operands should be cloned.
117  bool cloneOperandsFlag : 1;
118  };
119 
120  /// Create a deep copy of this operation, remapping any operands that use
121  /// values outside of the operation using the map that is provided (leaving
122  /// them alone if no entry is present). Replaces references to cloned
123  /// sub-operations to the corresponding operation that is copied, and adds
124  /// those mappings to the map.
125  /// Optionally, one may configure what parts of the operation to clone using
126  /// the options parameter.
127  ///
128  /// Calling this method from multiple threads is generally safe if through the
129  /// process of cloning no new uses of 'Value's from outside the operation are
130  /// created. Cloning an isolated-from-above operation with no operands, such
131  /// as top level function operations, is therefore always safe. Using the
132  /// mapper, it is possible to avoid adding uses to outside operands by
133  /// remapping them to 'Value's owned by the caller thread.
137 
138  /// Create a partial copy of this operation without traversing into attached
139  /// regions. The new operation will have the same number of regions as the
140  /// original one, but they will be left empty.
141  /// Operands are remapped using `mapper` (if present), and `mapper` is updated
142  /// to contain the results.
144 
145  /// Create a partial copy of this operation without traversing into attached
146  /// regions. The new operation will have the same number of regions as the
147  /// original one, but they will be left empty.
149 
150  /// Returns the operation block that contains this operation.
151  Block *getBlock() { return block; }
152 
153  /// Return the context this operation is associated with.
154  MLIRContext *getContext() { return location->getContext(); }
155 
156  /// Return the dialect this operation is associated with, or nullptr if the
157  /// associated dialect is not loaded.
159 
160  /// The source location the operation was defined or derived from.
161  Location getLoc() { return location; }
162 
163  /// Set the source location the operation was defined or derived from.
164  void setLoc(Location loc) { location = loc; }
165 
166  /// Returns the region to which the instruction belongs. Returns nullptr if
167  /// the instruction is unlinked.
168  Region *getParentRegion() { return block ? block->getParent() : nullptr; }
169 
170  /// Returns the closest surrounding operation that contains this operation
171  /// or nullptr if this is a top-level operation.
172  Operation *getParentOp() { return block ? block->getParentOp() : nullptr; }
173 
174  /// Return the closest surrounding parent operation that is of type 'OpTy'.
175  template <typename OpTy>
177  auto *op = this;
178  while ((op = op->getParentOp()))
179  if (auto parentOp = dyn_cast<OpTy>(op))
180  return parentOp;
181  return OpTy();
182  }
183 
184  /// Returns the closest surrounding parent operation with trait `Trait`.
185  template <template <typename T> class Trait>
187  Operation *op = this;
188  while ((op = op->getParentOp()))
189  if (op->hasTrait<Trait>())
190  return op;
191  return nullptr;
192  }
193 
194  /// Return true if this operation is a proper ancestor of the `other`
195  /// operation.
196  bool isProperAncestor(Operation *other);
197 
198  /// Return true if this operation is an ancestor of the `other` operation. An
199  /// operation is considered as its own ancestor, use `isProperAncestor` to
200  /// avoid this.
201  bool isAncestor(Operation *other) {
202  return this == other || isProperAncestor(other);
203  }
204 
205  /// Replace any uses of 'from' with 'to' within this operation.
206  void replaceUsesOfWith(Value from, Value to);
207 
208  /// Replace all uses of results of this operation with the provided 'values'.
209  template <typename ValuesT>
210  void replaceAllUsesWith(ValuesT &&values) {
211  getResults().replaceAllUsesWith(std::forward<ValuesT>(values));
212  }
213 
214  /// Destroys this operation and its subclass data.
215  void destroy();
216 
217  /// This drops all operand uses from this operation, which is an essential
218  /// step in breaking cyclic dependences between references when they are to
219  /// be deleted.
220  void dropAllReferences();
221 
222  /// Drop uses of all values defined by this operation or its nested regions.
224 
225  /// Unlink this operation from its current block and insert it right before
226  /// `existingOp` which may be in the same or another block in the same
227  /// function.
228  void moveBefore(Operation *existingOp);
229 
230  /// Unlink this operation from its current block and insert it right before
231  /// `iterator` in the specified block.
232  void moveBefore(Block *block, llvm::iplist<Operation>::iterator iterator);
233 
234  /// Unlink this operation from its current block and insert it right after
235  /// `existingOp` which may be in the same or another block in the same
236  /// function.
237  void moveAfter(Operation *existingOp);
238 
239  /// Unlink this operation from its current block and insert it right after
240  /// `iterator` in the specified block.
241  void moveAfter(Block *block, llvm::iplist<Operation>::iterator iterator);
242 
243  /// Given an operation 'other' that is within the same parent block, return
244  /// whether the current operation is before 'other' in the operation list
245  /// of the parent block.
246  /// Note: This function has an average complexity of O(1), but worst case may
247  /// take O(N) where N is the number of operations within the parent block.
248  bool isBeforeInBlock(Operation *other);
249 
250  void print(raw_ostream &os, const OpPrintingFlags &flags = llvm::None);
251  void print(raw_ostream &os, AsmState &state);
252  void dump();
253 
254  //===--------------------------------------------------------------------===//
255  // Operands
256  //===--------------------------------------------------------------------===//
257 
258  /// Replace the current operands of this operation with the ones provided in
259  /// 'operands'.
260  void setOperands(ValueRange operands);
261 
262  /// Replace the operands beginning at 'start' and ending at 'start' + 'length'
263  /// with the ones provided in 'operands'. 'operands' may be smaller or larger
264  /// than the range pointed to by 'start'+'length'.
265  void setOperands(unsigned start, unsigned length, ValueRange operands);
266 
267  /// Insert the given operands into the operand list at the given 'index'.
268  void insertOperands(unsigned index, ValueRange operands);
269 
270  unsigned getNumOperands() {
271  return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().size() : 0;
272  }
273 
274  Value getOperand(unsigned idx) { return getOpOperand(idx).get(); }
275  void setOperand(unsigned idx, Value value) {
276  return getOpOperand(idx).set(value);
277  }
278 
279  /// Erase the operand at position `idx`.
280  void eraseOperand(unsigned idx) { eraseOperands(idx); }
281 
282  /// Erase the operands starting at position `idx` and ending at position
283  /// 'idx'+'length'.
284  void eraseOperands(unsigned idx, unsigned length = 1) {
285  getOperandStorage().eraseOperands(idx, length);
286  }
287 
288  /// Erases the operands that have their corresponding bit set in
289  /// `eraseIndices` and removes them from the operand list.
290  void eraseOperands(const BitVector &eraseIndices) {
291  getOperandStorage().eraseOperands(eraseIndices);
292  }
293 
294  // Support operand iteration.
296  using operand_iterator = operand_range::iterator;
297 
300 
301  /// Returns an iterator on the underlying Value's.
304  return OperandRange(operands.data(), operands.size());
305  }
306 
308  return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().getOperands()
310  }
311 
312  OpOperand &getOpOperand(unsigned idx) {
313  return getOperandStorage().getOperands()[idx];
314  }
315 
316  // Support operand type iteration.
322 
323  //===--------------------------------------------------------------------===//
324  // Results
325  //===--------------------------------------------------------------------===//
326 
327  /// Return the number of results held by this operation.
328  unsigned getNumResults() { return numResults; }
329 
330  /// Get the 'idx'th result of this operation.
331  OpResult getResult(unsigned idx) { return OpResult(getOpResultImpl(idx)); }
332 
333  /// Support result iteration.
335  using result_iterator = result_range::iterator;
336 
337  result_iterator result_begin() { return getResults().begin(); }
338  result_iterator result_end() { return getResults().end(); }
340  return numResults == 0 ? result_range(nullptr, 0)
341  : result_range(getInlineOpResult(0), numResults);
342  }
343 
345  OpResult getOpResult(unsigned idx) { return getResult(idx); }
346 
347  /// Support result type iteration.
353 
354  //===--------------------------------------------------------------------===//
355  // Attributes
356  //===--------------------------------------------------------------------===//
357 
358  // Operations may optionally carry a list of attributes that associate
359  // constants to names. Attributes may be dynamically added and removed over
360  // the lifetime of an operation.
361 
362  /// Return all of the attributes on this operation.
363  ArrayRef<NamedAttribute> getAttrs() { return attrs.getValue(); }
364 
365  /// Return all of the attributes on this operation as a DictionaryAttr.
366  DictionaryAttr getAttrDictionary() { return attrs; }
367 
368  /// Set the attribute dictionary on this operation.
369  void setAttrs(DictionaryAttr newAttrs) {
370  assert(newAttrs && "expected valid attribute dictionary");
371  attrs = newAttrs;
372  }
374  setAttrs(DictionaryAttr::get(getContext(), newAttrs));
375  }
376 
377  /// Return the specified attribute if present, null otherwise.
378  Attribute getAttr(StringAttr name) { return attrs.get(name); }
379  Attribute getAttr(StringRef name) { return attrs.get(name); }
380 
381  template <typename AttrClass>
382  AttrClass getAttrOfType(StringAttr name) {
383  return getAttr(name).dyn_cast_or_null<AttrClass>();
384  }
385  template <typename AttrClass>
386  AttrClass getAttrOfType(StringRef name) {
387  return getAttr(name).dyn_cast_or_null<AttrClass>();
388  }
389 
390  /// Return true if the operation has an attribute with the provided name,
391  /// false otherwise.
392  bool hasAttr(StringAttr name) { return attrs.contains(name); }
393  bool hasAttr(StringRef name) { return attrs.contains(name); }
394  template <typename AttrClass, typename NameT>
395  bool hasAttrOfType(NameT &&name) {
396  return static_cast<bool>(
397  getAttrOfType<AttrClass>(std::forward<NameT>(name)));
398  }
399 
400  /// If the an attribute exists with the specified name, change it to the new
401  /// value. Otherwise, add a new attribute with the specified name/value.
402  void setAttr(StringAttr name, Attribute value) {
403  NamedAttrList attributes(attrs);
404  if (attributes.set(name, value) != value)
405  attrs = attributes.getDictionary(getContext());
406  }
407  void setAttr(StringRef name, Attribute value) {
408  setAttr(StringAttr::get(getContext(), name), value);
409  }
410 
411  /// Remove the attribute with the specified name if it exists. Return the
412  /// attribute that was erased, or nullptr if there was no attribute with such
413  /// name.
414  Attribute removeAttr(StringAttr name) {
415  NamedAttrList attributes(attrs);
416  Attribute removedAttr = attributes.erase(name);
417  if (removedAttr)
418  attrs = attributes.getDictionary(getContext());
419  return removedAttr;
420  }
421  Attribute removeAttr(StringRef name) {
422  return removeAttr(StringAttr::get(getContext(), name));
423  }
424 
425  /// A utility iterator that filters out non-dialect attributes.
427  : public llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
428  bool (*)(NamedAttribute)> {
429  static bool filter(NamedAttribute attr) {
430  // Dialect attributes are prefixed by the dialect name, like operations.
431  return attr.getName().strref().count('.');
432  }
433 
436  : llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
437  bool (*)(NamedAttribute)>(it, end, &filter) {}
438 
439  // Allow access to the constructor.
440  friend Operation;
441  };
443 
444  /// Return a range corresponding to the dialect attributes for this operation.
446  auto attrs = getAttrs();
447  return {dialect_attr_iterator(attrs.begin(), attrs.end()),
448  dialect_attr_iterator(attrs.end(), attrs.end())};
449  }
451  auto attrs = getAttrs();
452  return dialect_attr_iterator(attrs.begin(), attrs.end());
453  }
455  auto attrs = getAttrs();
456  return dialect_attr_iterator(attrs.end(), attrs.end());
457  }
458 
459  /// Set the dialect attributes for this operation, and preserve all dependent.
460  template <typename DialectAttrT>
461  void setDialectAttrs(DialectAttrT &&dialectAttrs) {
462  NamedAttrList attrs;
463  attrs.append(std::begin(dialectAttrs), std::end(dialectAttrs));
464  for (auto attr : getAttrs())
465  if (!attr.getName().strref().contains('.'))
466  attrs.push_back(attr);
468  }
469 
470  //===--------------------------------------------------------------------===//
471  // Blocks
472  //===--------------------------------------------------------------------===//
473 
474  /// Returns the number of regions held by this operation.
475  unsigned getNumRegions() { return numRegions; }
476 
477  /// Returns the regions held by this operation.
479  auto *regions = getTrailingObjects<Region>();
480  return {regions, numRegions};
481  }
482 
483  /// Returns the region held by this operation at position 'index'.
484  Region &getRegion(unsigned index) {
485  assert(index < numRegions && "invalid region index");
486  return getRegions()[index];
487  }
488 
489  //===--------------------------------------------------------------------===//
490  // Successors
491  //===--------------------------------------------------------------------===//
492 
494  return {getTrailingObjects<BlockOperand>(), numSuccs};
495  }
496 
497  // Successor iteration.
498  using succ_iterator = SuccessorRange::iterator;
502 
503  bool hasSuccessors() { return numSuccs != 0; }
504  unsigned getNumSuccessors() { return numSuccs; }
505 
506  Block *getSuccessor(unsigned index) {
507  assert(index < getNumSuccessors());
508  return getBlockOperands()[index].get();
509  }
510  void setSuccessor(Block *block, unsigned index);
511 
512  //===--------------------------------------------------------------------===//
513  // Accessors for various properties of operations
514  //===--------------------------------------------------------------------===//
515 
516  /// Attempt to fold this operation with the specified constant operand values
517  /// - the elements in "operands" will correspond directly to the operands of
518  /// the operation, but may be null if non-constant. If folding is successful,
519  /// this fills in the `results` vector. If not, `results` is unspecified.
522 
523  /// Returns true if the operation was registered with a particular trait, e.g.
524  /// hasTrait<OperandsAreSignlessIntegerLike>().
525  template <template <typename T> class Trait>
526  bool hasTrait() {
527  return name.hasTrait<Trait>();
528  }
529 
530  /// Returns true if the operation *might* have the provided trait. This
531  /// means that either the operation is unregistered, or it was registered with
532  /// the provide trait.
533  template <template <typename T> class Trait>
534  bool mightHaveTrait() {
535  return name.mightHaveTrait<Trait>();
536  }
537 
538  //===--------------------------------------------------------------------===//
539  // Operation Walkers
540  //===--------------------------------------------------------------------===//
541 
542  /// Walk the operation by calling the callback for each nested operation
543  /// (including this one), block or region, depending on the callback provided.
544  /// Regions, blocks and operations at the same nesting level are visited in
545  /// lexicographical order. The walk order for enclosing regions, blocks and
546  /// operations with respect to their nested ones is specified by 'Order'
547  /// (post-order by default). A callback on a block or operation is allowed to
548  /// erase that block or operation if either:
549  /// * the walk is in post-order, or
550  /// * the walk is in pre-order and the walk is skipped after the erasure.
551  ///
552  /// The callback method can take any of the following forms:
553  /// void(Operation*) : Walk all operations opaquely.
554  /// * op->walk([](Operation *nestedOp) { ...});
555  /// void(OpT) : Walk all operations of the given derived type.
556  /// * op->walk([](ReturnOp returnOp) { ...});
557  /// WalkResult(Operation*|OpT) : Walk operations, but allow for
558  /// interruption/skipping.
559  /// * op->walk([](... op) {
560  /// // Skip the walk of this op based on some invariant.
561  /// if (some_invariant)
562  /// return WalkResult::skip();
563  /// // Interrupt, i.e cancel, the walk based on some invariant.
564  /// if (another_invariant)
565  /// return WalkResult::interrupt();
566  /// return WalkResult::advance();
567  /// });
568  template <WalkOrder Order = WalkOrder::PostOrder, typename FnT,
569  typename RetT = detail::walkResultType<FnT>>
570  typename std::enable_if<
571  llvm::function_traits<std::decay_t<FnT>>::num_args == 1, RetT>::type
572  walk(FnT &&callback) {
573  return detail::walk<Order>(this, std::forward<FnT>(callback));
574  }
575 
576  /// Generic walker with a stage aware callback. Walk the operation by calling
577  /// the callback for each nested operation (including this one) N+1 times,
578  /// where N is the number of regions attached to that operation.
579  ///
580  /// The callback method can take any of the following forms:
581  /// void(Operation *, const WalkStage &) : Walk all operation opaquely
582  /// * op->walk([](Operation *nestedOp, const WalkStage &stage) { ...});
583  /// void(OpT, const WalkStage &) : Walk all operations of the given derived
584  /// type.
585  /// * op->walk([](ReturnOp returnOp, const WalkStage &stage) { ...});
586  /// WalkResult(Operation*|OpT, const WalkStage &stage) : Walk operations,
587  /// but allow for interruption/skipping.
588  /// * op->walk([](... op, const WalkStage &stage) {
589  /// // Skip the walk of this op based on some invariant.
590  /// if (some_invariant)
591  /// return WalkResult::skip();
592  /// // Interrupt, i.e cancel, the walk based on some invariant.
593  /// if (another_invariant)
594  /// return WalkResult::interrupt();
595  /// return WalkResult::advance();
596  /// });
597  template <typename FnT, typename RetT = detail::walkResultType<FnT>>
598  typename std::enable_if<
599  llvm::function_traits<std::decay_t<FnT>>::num_args == 2, RetT>::type
600  walk(FnT &&callback) {
601  return detail::walk(this, std::forward<FnT>(callback));
602  }
603 
604  //===--------------------------------------------------------------------===//
605  // Uses
606  //===--------------------------------------------------------------------===//
607 
608  /// Drop all uses of results of this operation.
609  void dropAllUses() {
610  for (OpResult result : getOpResults())
611  result.dropAllUses();
612  }
613 
616 
619 
620  /// Returns a range of all uses, which is useful for iterating over all uses.
622 
623  /// Returns true if this operation has exactly one use.
624  bool hasOneUse() { return llvm::hasSingleElement(getUses()); }
625 
626  /// Returns true if this operation has no uses.
627  bool use_empty() { return getResults().use_empty(); }
628 
629  /// Returns true if the results of this operation are used outside of the
630  /// given block.
632  return llvm::any_of(getOpResults(), [block](OpResult result) {
633  return result.isUsedOutsideOfBlock(block);
634  });
635  }
636 
637  //===--------------------------------------------------------------------===//
638  // Users
639  //===--------------------------------------------------------------------===//
640 
643 
646 
647  /// Returns a range of all users.
648  user_range getUsers() { return {user_begin(), user_end()}; }
649 
650  //===--------------------------------------------------------------------===//
651  // Other
652  //===--------------------------------------------------------------------===//
653 
654  /// Emit an error with the op name prefixed, like "'dim' op " which is
655  /// convenient for verifiers.
656  InFlightDiagnostic emitOpError(const Twine &message = {});
657 
658  /// Emit an error about fatal conditions with this operation, reporting up to
659  /// any diagnostic handlers that may be listening.
660  InFlightDiagnostic emitError(const Twine &message = {});
661 
662  /// Emit a warning about this operation, reporting up to any diagnostic
663  /// handlers that may be listening.
664  InFlightDiagnostic emitWarning(const Twine &message = {});
665 
666  /// Emit a remark about this operation, reporting up to any diagnostic
667  /// handlers that may be listening.
668  InFlightDiagnostic emitRemark(const Twine &message = {});
669 
670 private:
671  //===--------------------------------------------------------------------===//
672  // Ordering
673  //===--------------------------------------------------------------------===//
674 
675  /// This value represents an invalid index ordering for an operation within a
676  /// block.
677  static constexpr unsigned kInvalidOrderIdx = -1;
678 
679  /// This value represents the stride to use when computing a new order for an
680  /// operation.
681  static constexpr unsigned kOrderStride = 5;
682 
683  /// Update the order index of this operation of this operation if necessary,
684  /// potentially recomputing the order of the parent block.
685  void updateOrderIfNecessary();
686 
687  /// Returns true if this operation has a valid order.
688  bool hasValidOrder() { return orderIndex != kInvalidOrderIdx; }
689 
690 private:
691  Operation(Location location, OperationName name, unsigned numResults,
692  unsigned numSuccessors, unsigned numRegions,
693  DictionaryAttr attributes, bool hasOperandStorage);
694 
695  // Operations are deleted through the destroy() member because they are
696  // allocated with malloc.
697  ~Operation();
698 
699  /// Returns the additional size necessary for allocating the given objects
700  /// before an Operation in-memory.
701  static size_t prefixAllocSize(unsigned numOutOfLineResults,
702  unsigned numInlineResults) {
703  return sizeof(detail::OutOfLineOpResult) * numOutOfLineResults +
704  sizeof(detail::InlineOpResult) * numInlineResults;
705  }
706  /// Returns the additional size allocated before this Operation in-memory.
707  size_t prefixAllocSize() {
708  unsigned numResults = getNumResults();
709  unsigned numOutOfLineResults = OpResult::getNumTrailing(numResults);
710  unsigned numInlineResults = OpResult::getNumInline(numResults);
711  return prefixAllocSize(numOutOfLineResults, numInlineResults);
712  }
713 
714  /// Returns the operand storage object.
715  detail::OperandStorage &getOperandStorage() {
716  assert(hasOperandStorage && "expected operation to have operand storage");
717  return *getTrailingObjects<detail::OperandStorage>();
718  }
719 
720  /// Returns a pointer to the use list for the given out-of-line result.
721  detail::OutOfLineOpResult *getOutOfLineOpResult(unsigned resultNumber) {
722  // Out-of-line results are stored in reverse order after (before in memory)
723  // the inline results.
724  return reinterpret_cast<detail::OutOfLineOpResult *>(getInlineOpResult(
726  ++resultNumber;
727  }
728 
729  /// Returns a pointer to the use list for the given inline result.
730  detail::InlineOpResult *getInlineOpResult(unsigned resultNumber) {
731  // Inline results are stored in reverse order before the operation in
732  // memory.
733  return reinterpret_cast<detail::InlineOpResult *>(this) - ++resultNumber;
734  }
735 
736  /// Returns a pointer to the use list for the given result, which may be
737  /// either inline or out-of-line.
738  detail::OpResultImpl *getOpResultImpl(unsigned resultNumber) {
739  unsigned maxInlineResults = detail::OpResultImpl::getMaxInlineResults();
740  if (resultNumber < maxInlineResults)
741  return getInlineOpResult(resultNumber);
742  return getOutOfLineOpResult(resultNumber - maxInlineResults);
743  }
744 
745  /// Provide a 'getParent' method for ilist_node_with_parent methods.
746  /// We mark it as a const function because ilist_node_with_parent specifically
747  /// requires a 'getParent() const' method. Once ilist_node removes this
748  /// constraint, we should drop the const to fit the rest of the MLIR const
749  /// model.
750  Block *getParent() const { return block; }
751 
752  /// The operation block that contains this operation.
753  Block *block = nullptr;
754 
755  /// This holds information about the source location the operation was defined
756  /// or derived from.
757  Location location;
758 
759  /// Relative order of this operation in its parent block. Used for
760  /// O(1) local dominance checks between operations.
761  mutable unsigned orderIndex = 0;
762 
763  const unsigned numResults;
764  const unsigned numSuccs;
765  const unsigned numRegions : 31;
766 
767  /// This bit signals whether this operation has an operand storage or not. The
768  /// operand storage may be elided for operations that are known to never have
769  /// operands.
770  bool hasOperandStorage : 1;
771 
772  /// This holds the name of the operation.
773  OperationName name;
774 
775  /// This holds general named attributes for the operation.
776  DictionaryAttr attrs;
777 
778  // allow ilist_traits access to 'block' field.
779  friend struct llvm::ilist_traits<Operation>;
780 
781  // allow block to access the 'orderIndex' field.
782  friend class Block;
783 
784  // allow value to access the 'ResultStorage' methods.
785  friend class Value;
786 
787  // allow ilist_node_with_parent to access the 'getParent' method.
788  friend class llvm::ilist_node_with_parent<Operation, Block>;
789 
790  // This stuff is used by the TrailingObjects template.
791  friend llvm::TrailingObjects<Operation, detail::OperandStorage, BlockOperand,
792  Region, OpOperand>;
793  size_t numTrailingObjects(OverloadToken<detail::OperandStorage>) const {
794  return hasOperandStorage ? 1 : 0;
795  }
796  size_t numTrailingObjects(OverloadToken<BlockOperand>) const {
797  return numSuccs;
798  }
799  size_t numTrailingObjects(OverloadToken<Region>) const { return numRegions; }
800 };
801 
802 inline raw_ostream &operator<<(raw_ostream &os, const Operation &op) {
803  const_cast<Operation &>(op).print(os, OpPrintingFlags().useLocalScope());
804  return os;
805 }
806 
807 } // namespace mlir
808 
809 namespace llvm {
810 /// Cast from an (const) Operation * to a derived operation type.
811 template <typename T>
812 struct CastInfo<T, ::mlir::Operation *>
813  : public ValueFromPointerCast<T, ::mlir::Operation,
814  CastInfo<T, ::mlir::Operation *>> {
815  static bool isPossible(::mlir::Operation *op) { return T::classof(op); }
816 };
817 template <typename T>
818 struct CastInfo<T, const ::mlir::Operation *>
819  : public ConstStrippingForwardingCast<T, const ::mlir::Operation *,
820  CastInfo<T, ::mlir::Operation *>> {};
821 
822 /// Cast from an (const) Operation & to a derived operation type.
823 template <typename T>
824 struct CastInfo<T, ::mlir::Operation>
825  : public NullableValueCastFailed<T>,
826  public DefaultDoCastIfPossible<T, ::mlir::Operation &,
827  CastInfo<T, ::mlir::Operation>> {
828  // Provide isPossible here because here we have the const-stripping from
829  // ConstStrippingCast.
830  static bool isPossible(::mlir::Operation &val) { return T::classof(&val); }
831  static T doCast(::mlir::Operation &val) { return T(&val); }
832 };
833 template <typename T>
834 struct CastInfo<T, const ::mlir::Operation>
835  : public ConstStrippingForwardingCast<T, const ::mlir::Operation,
836  CastInfo<T, ::mlir::Operation>> {};
837 
838 /// Cast (const) Operation * to itself. This is helpful to avoid SFINAE in
839 /// templated implementations that should work on both base and derived
840 /// operation types.
841 template <>
842 struct CastInfo<::mlir::Operation *, ::mlir::Operation *>
843  : public NullableValueCastFailed<::mlir::Operation *>,
845  ::mlir::Operation *, ::mlir::Operation *,
846  CastInfo<::mlir::Operation *, ::mlir::Operation *>> {
847  static bool isPossible(::mlir::Operation *op) { return true; }
848  static ::mlir::Operation *doCast(::mlir::Operation *op) { return op; }
849 };
850 template <>
851 struct CastInfo<const ::mlir::Operation *, const ::mlir::Operation *>
853  const ::mlir::Operation *, const ::mlir::Operation *,
854  CastInfo<::mlir::Operation *, ::mlir::Operation *>> {};
855 } // namespace llvm
856 
857 #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:296
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
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
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:503
bool isRegistered() const
Return if this operation is registered.
U dyn_cast_or_null() const
Definition: Attributes.h:127
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:221
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:478
CloneOptions & cloneRegions(bool enable=true)
Configures whether cloning should traverse into any of the regions of the operation.
Definition: Operation.cpp:536
void setAttrs(ArrayRef< NamedAttribute > newAttrs)
Definition: Operation.h:373
bool isAncestor(Operation *other)
Return true if this operation is an ancestor of the other operation.
Definition: Operation.h:201
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:302
use_range getUses()
Returns a range of all uses, which is useful for iterating over all uses.
Definition: Operation.h:621
unsigned getNumRegions()
Returns the number of regions held by this operation.
Definition: Operation.h:475
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:311
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
CloneOptions()
Default constructs an option with all flags set to false.
Definition: Operation.cpp:526
bool hasOneUse()
Returns true if this operation has exactly one use.
Definition: Operation.h:624
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
Definition: Operation.h:363
Value getOperand(unsigned idx)
Definition: Operation.h:274
AttrClass getAttrOfType(StringAttr name)
Definition: Operation.h:382
bool isUsedOutsideOfBlock(Block *block)
Returns true if the results of this operation are used outside of the given block.
Definition: Operation.h:631
bool shouldCloneOperands() const
Returns whether operands should be cloned as well.
Definition: Operation.h:111
Attribute set(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
std::enable_if< llvm::function_traits< std::decay_t< FnT > >::num_args==2, RetT >::type walk(FnT &&callback)
Generic walker with a stage aware callback.
Definition: Operation.h:600
use_iterator use_begin()
Definition: Operation.h:617
unsigned getNumOperands()
Definition: Operation.h:270
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
Definition: Operation.h:534
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:321
ValueTypeRange< ResultRange > type_range
Operation * getParentWithTrait()
Returns the closest surrounding parent operation with trait Trait.
Definition: Operation.h:186
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:393
type_range getTypes() const
unsigned getNumSuccessors()
Definition: Operation.h:504
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:151
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
CloneOptions & cloneOperands(bool enable=true)
Configures whether operation&#39; operands should be cloned.
Definition: Operation.cpp:541
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:176
static bool isPossible(::mlir::Operation &val)
Definition: Operation.h:830
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:144
MLIRContext * getContext()
Return the context this operation is associated with.
Definition: Operation.h:154
decltype(walk(nullptr, std::declval< FnT >())) walkResultType
Utility to provide the return type of a templated walk method.
Definition: Visitors.h:319
bool hasTrait() const
Returns true if the operation was registered with a particular trait, e.g.
user_iterator user_end()
Definition: Operation.h:645
MutableArrayRef< OpOperand > getOpOperands()
Definition: Operation.h:307
static CloneOptions all()
Returns an instance with all flags set to true.
Definition: Operation.cpp:532
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:386
bool shouldCloneRegions() const
Returns whether regions of the operation should be cloned as well.
Definition: Operation.h:104
static bool isPossible(::mlir::Operation *op)
Definition: Operation.h:847
std::enable_if< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT >::type walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one)...
Definition: Operation.h:572
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:284
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:392
succ_iterator successor_end()
Definition: Operation.h:500
Block * getSuccessor(unsigned index)
Definition: Operation.h:506
MLIRContext * getContext() const
Return the context this attribute belongs to.
Definition: Attributes.cpp:20
dialect_attr_iterator dialect_attr_begin()
Definition: Operation.h:450
void set(IRValueT newValue)
Set the current value being used by this operand.
Definition: UseDefLists.h:136
SuccessorRange::iterator succ_iterator
Definition: Operation.h:498
Operation * clone(BlockAndValueMapping &mapper, CloneOptions options=CloneOptions::all())
Create a deep copy of this operation, remapping any operands that use values outside of the operation...
Definition: Operation.cpp:564
Attributes are known-constant values of operations.
Definition: Attributes.h:24
dialect_attr_iterator dialect_attr_end()
Definition: Operation.h:454
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Definition: Operation.h:526
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Definition: Operation.h:172
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided &#39;values&#39;.
Definition: Operation.h:210
ValueUserIterator< use_iterator, OpOperand > user_iterator
Definition: Operation.h:641
StringAttr getName() const
Return the name of the attribute.
Definition: Attributes.cpp:32
static T doCast(::mlir::Operation &val)
Definition: Operation.h:831
Attribute removeAttr(StringAttr name)
Remove the attribute with the specified name if it exists.
Definition: Operation.h:414
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
OpResult getResult(unsigned idx)
Get the &#39;idx&#39;th result of this operation.
Definition: Operation.h:331
succ_iterator successor_begin()
Definition: Operation.h:499
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:161
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:493
result_type_iterator result_type_end()
Definition: Operation.h:351
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:395
operand_type_iterator operand_type_begin()
Definition: Operation.h:319
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:344
void dropAllUses()
Drop all uses of results of this operation.
Definition: Operation.h:609
void setOperand(unsigned idx, Value value)
Definition: Operation.h:275
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:366
bool use_empty()
Returns true if this operation has no uses.
Definition: Operation.h:627
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:85
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:290
operand_type_iterator operand_type_end()
Definition: Operation.h:320
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
static llvm::ManagedStatic< PassManagerOptions > options
void eraseOperand(unsigned idx)
Erase the operand at position idx.
Definition: Operation.h:280
OpPrintingFlags & useLocalScope()
Use local scope when printing the operation.
Definition: AsmPrinter.cpp:233
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:298
SuccessorRange getSuccessors()
Definition: Operation.h:501
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
Definition: Operation.h:402
Set of flags used to control the behavior of the various IR print methods (e.g.
result_iterator result_end()
Definition: Operation.h:338
use_range getUses() const
Returns a range of all uses of results within this range, which is useful for iterating over all uses...
Class encompassing various options related to cloning an operation.
Definition: Operation.h:81
void setAttr(StringRef name, Attribute value)
Definition: Operation.h:407
result_type_iterator result_type_begin()
Definition: Operation.h:350
Attribute removeAttr(StringRef name)
Definition: Operation.h:421
void setLoc(Location loc)
Set the source location the operation was defined or derived from.
Definition: Operation.h:164
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:426
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.cpp:24
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:158
ValueTypeRange< OperandRange > type_range
OpOperand & getOpOperand(unsigned idx)
Definition: Operation.h:312
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
OpResult getOpResult(unsigned idx)
Definition: Operation.h:345
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:328
void setDialectAttrs(DialectAttrT &&dialectAttrs)
Set the dialect attributes for this operation, and preserve all dependent.
Definition: Operation.h:461
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
static bool isPossible(::mlir::Operation *op)
Definition: Operation.h:815
result_range::iterator result_iterator
Definition: Operation.h:335
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:168
Attribute getAttr(StringRef name)
Definition: Operation.h:379
use_iterator use_end() const
::mlir::Operation * doCast(::mlir::Operation *op)
Definition: Operation.h:848
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:328
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
Definition: Operation.h:445
ResultRange result_range
Support result iteration.
Definition: Operation.h:334
user_iterator user_begin()
Definition: Operation.h:644
operand_iterator operand_end()
Definition: Operation.h:299
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:648
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:618
void setAttrs(DictionaryAttr newAttrs)
Set the attribute dictionary on this operation.
Definition: Operation.h:369
result_range getResults()
Definition: Operation.h:339
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:378
result_type_range getResultTypes()
Definition: Operation.h:352
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:484
result_iterator result_begin()
Definition: Operation.h:337
This class provides management for the lifetime of the state used when printing the IR...
Definition: AsmState.h:345
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.