MLIR  17.0.0git
Operation.h
Go to the documentation of this file.
1 //===- Operation.h - MLIR Operation Class -----------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the Operation class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_IR_OPERATION_H
14 #define MLIR_IR_OPERATION_H
15 
16 #include "mlir/IR/Block.h"
18 #include "mlir/IR/Diagnostics.h"
20 #include "mlir/IR/Region.h"
21 #include "llvm/ADT/Twine.h"
22 #include <optional>
23 
24 namespace mlir {
25 /// Operation is the basic unit of execution within MLIR.
26 ///
27 /// The following documentation are recommended to understand this class:
28 /// - https://mlir.llvm.org/docs/LangRef/#operations
29 /// - https://mlir.llvm.org/docs/Tutorials/UnderstandingTheIRStructure/
30 ///
31 /// An Operation is defined first by its name, which is a unique string. The
32 /// name is interpreted so that if it contains a '.' character, the part before
33 /// is the dialect name this operation belongs to, and everything that follows
34 /// is this operation name within the dialect.
35 ///
36 /// An Operation defines zero or more SSA `Value` that we refer to as the
37 /// Operation results. This array of Value is actually stored in memory before
38 /// the Operation itself in reverse order. That is for an Operation with 3
39 /// results we allocate the following memory layout:
40 ///
41 /// [Result2, Result1, Result0, Operation]
42 /// ^ this is where `Operation*` pointer points to.
43 ///
44 /// A consequence of this is that this class must be heap allocated, which is
45 /// handled by the various `create` methods. Each result contains:
46 /// - one pointer to the first use (see `OpOperand`)
47 /// - the type of the SSA Value this result defines.
48 /// - the index for this result in the array.
49 /// The results are defined as subclass of `ValueImpl`, and more precisely as
50 /// the only two subclasses of `OpResultImpl`: `InlineOpResult` and
51 /// `OutOfLineOpResult`. The former is used for the first 5 results and the
52 /// latter for the subsequent ones. They differ in how they store their index:
53 /// the first 5 results only need 3 bits and thus are packed with the Type
54 /// pointer, while the subsequent one have an extra `unsigned` value and thus
55 /// need more space.
56 ///
57 /// An Operation also has zero or more operands: these are uses of SSA Value,
58 /// which can be the results of other operations or Block arguments. Each of
59 /// these uses is an instance of `OpOperand`. This optional array is initially
60 /// tail allocated with the operation class itself, but can be dynamically moved
61 /// out-of-line in a dynamic allocation as needed.
62 ///
63 /// An Operation may contain optionally one or multiple Regions, stored in a
64 /// tail allocated array. Each `Region` is a list of Blocks. Each `Block` is
65 /// itself a list of Operations. This structure is effectively forming a tree.
66 ///
67 /// Some operations like branches also refer to other Block, in which case they
68 /// would have an array of `BlockOperand`.
69 ///
70 /// Finally an Operation also contain an optional `DictionaryAttr`, a Location,
71 /// and a pointer to its parent Block (if any).
72 class alignas(8) Operation final
73  : public llvm::ilist_node_with_parent<Operation, Block>,
74  private llvm::TrailingObjects<Operation, detail::OperandStorage,
75  BlockOperand, Region, OpOperand> {
76 public:
77  /// Create a new Operation with the specific fields. This constructor
78  /// populates the provided attribute list with default attributes if
79  /// necessary.
80  static Operation *create(Location location, OperationName name,
81  TypeRange resultTypes, ValueRange operands,
82  NamedAttrList &&attributes, BlockRange successors,
83  unsigned numRegions);
84 
85  /// Create a new Operation with the specific fields. This constructor uses an
86  /// existing attribute dictionary to avoid uniquing a list of attributes.
87  static Operation *create(Location location, OperationName name,
88  TypeRange resultTypes, ValueRange operands,
89  DictionaryAttr attributes, BlockRange successors,
90  unsigned numRegions);
91 
92  /// Create a new Operation from the fields stored in `state`.
93  static Operation *create(const OperationState &state);
94 
95  /// Create a new Operation with the specific fields.
96  static Operation *create(Location location, OperationName name,
97  TypeRange resultTypes, ValueRange operands,
98  NamedAttrList &&attributes,
99  BlockRange successors = {},
100  RegionRange regions = {});
101 
102  /// The name of an operation is the key identifier for it.
103  OperationName getName() { return name; }
104 
105  /// If this operation has a registered operation description, return it.
106  /// Otherwise return std::nullopt.
107  std::optional<RegisteredOperationName> getRegisteredInfo() {
108  return getName().getRegisteredInfo();
109  }
110 
111  /// Returns true if this operation has a registered operation description,
112  /// otherwise false.
113  bool isRegistered() { return getName().isRegistered(); }
114 
115  /// Remove this operation from its parent block and delete it.
116  void erase();
117 
118  /// Remove the operation from its parent block, but don't delete it.
119  void remove();
120 
121  /// Class encompassing various options related to cloning an operation. Users
122  /// of this class should pass it to Operation's 'clone' methods.
123  /// Current options include:
124  /// * Whether cloning should recursively traverse into the regions of the
125  /// operation or not.
126  /// * Whether cloning should also clone the operands of the operation.
127  class CloneOptions {
128  public:
129  /// Default constructs an option with all flags set to false. That means all
130  /// parts of an operation that may optionally not be cloned, are not cloned.
131  CloneOptions();
132 
133  /// Constructs an instance with the clone regions and clone operands flags
134  /// set accordingly.
136 
137  /// Returns an instance with all flags set to true. This is the default
138  /// when using the clone method and clones all parts of the operation.
139  static CloneOptions all();
140 
141  /// Configures whether cloning should traverse into any of the regions of
142  /// the operation. If set to true, the operation's regions are recursively
143  /// cloned. If set to false, cloned operations will have the same number of
144  /// regions, but they will be empty.
145  /// Cloning of nested operations in the operation's regions are currently
146  /// unaffected by other flags.
147  CloneOptions &cloneRegions(bool enable = true);
148 
149  /// Returns whether regions of the operation should be cloned as well.
150  bool shouldCloneRegions() const { return cloneRegionsFlag; }
151 
152  /// Configures whether operation' operands should be cloned. Otherwise the
153  /// resulting clones will simply have zero operands.
154  CloneOptions &cloneOperands(bool enable = true);
155 
156  /// Returns whether operands should be cloned as well.
157  bool shouldCloneOperands() const { return cloneOperandsFlag; }
158 
159  private:
160  /// Whether regions should be cloned.
161  bool cloneRegionsFlag : 1;
162  /// Whether operands should be cloned.
163  bool cloneOperandsFlag : 1;
164  };
165 
166  /// Create a deep copy of this operation, remapping any operands that use
167  /// values outside of the operation using the map that is provided (leaving
168  /// them alone if no entry is present). Replaces references to cloned
169  /// sub-operations to the corresponding operation that is copied, and adds
170  /// those mappings to the map.
171  /// Optionally, one may configure what parts of the operation to clone using
172  /// the options parameter.
173  ///
174  /// Calling this method from multiple threads is generally safe if through the
175  /// process of cloning no new uses of 'Value's from outside the operation are
176  /// created. Cloning an isolated-from-above operation with no operands, such
177  /// as top level function operations, is therefore always safe. Using the
178  /// mapper, it is possible to avoid adding uses to outside operands by
179  /// remapping them to 'Value's owned by the caller thread.
180  Operation *clone(IRMapping &mapper,
181  CloneOptions options = CloneOptions::all());
182  Operation *clone(CloneOptions options = CloneOptions::all());
183 
184  /// Create a partial copy of this operation without traversing into attached
185  /// regions. The new operation will have the same number of regions as the
186  /// original one, but they will be left empty.
187  /// Operands are remapped using `mapper` (if present), and `mapper` is updated
188  /// to contain the results.
190 
191  /// Create a partial copy of this operation without traversing into attached
192  /// regions. The new operation will have the same number of regions as the
193  /// original one, but they will be left empty.
195 
196  /// Returns the operation block that contains this operation.
197  Block *getBlock() { return block; }
198 
199  /// Return the context this operation is associated with.
200  MLIRContext *getContext() { return location->getContext(); }
201 
202  /// Return the dialect this operation is associated with, or nullptr if the
203  /// associated dialect is not loaded.
205 
206  /// The source location the operation was defined or derived from.
207  Location getLoc() { return location; }
208 
209  /// Set the source location the operation was defined or derived from.
210  void setLoc(Location loc) { location = loc; }
211 
212  /// Returns the region to which the instruction belongs. Returns nullptr if
213  /// the instruction is unlinked.
214  Region *getParentRegion() { return block ? block->getParent() : nullptr; }
215 
216  /// Returns the closest surrounding operation that contains this operation
217  /// or nullptr if this is a top-level operation.
218  Operation *getParentOp() { return block ? block->getParentOp() : nullptr; }
219 
220  /// Return the closest surrounding parent operation that is of type 'OpTy'.
221  template <typename OpTy>
223  auto *op = this;
224  while ((op = op->getParentOp()))
225  if (auto parentOp = dyn_cast<OpTy>(op))
226  return parentOp;
227  return OpTy();
228  }
229 
230  /// Returns the closest surrounding parent operation with trait `Trait`.
231  template <template <typename T> class Trait>
233  Operation *op = this;
234  while ((op = op->getParentOp()))
235  if (op->hasTrait<Trait>())
236  return op;
237  return nullptr;
238  }
239 
240  /// Return true if this operation is a proper ancestor of the `other`
241  /// operation.
242  bool isProperAncestor(Operation *other);
243 
244  /// Return true if this operation is an ancestor of the `other` operation. An
245  /// operation is considered as its own ancestor, use `isProperAncestor` to
246  /// avoid this.
247  bool isAncestor(Operation *other) {
248  return this == other || isProperAncestor(other);
249  }
250 
251  /// Replace any uses of 'from' with 'to' within this operation.
252  void replaceUsesOfWith(Value from, Value to);
253 
254  /// Replace all uses of results of this operation with the provided 'values'.
255  template <typename ValuesT>
256  void replaceAllUsesWith(ValuesT &&values) {
257  getResults().replaceAllUsesWith(std::forward<ValuesT>(values));
258  }
259 
260  /// Replace uses of results of this operation with the provided `values` if
261  /// the given callback returns true.
262  template <typename ValuesT>
263  void replaceUsesWithIf(ValuesT &&values,
264  function_ref<bool(OpOperand &)> shouldReplace) {
265  getResults().replaceUsesWithIf(std::forward<ValuesT>(values),
266  shouldReplace);
267  }
268 
269  /// Destroys this operation and its subclass data.
270  void destroy();
271 
272  /// This drops all operand uses from this operation, which is an essential
273  /// step in breaking cyclic dependences between references when they are to
274  /// be deleted.
275  void dropAllReferences();
276 
277  /// Drop uses of all values defined by this operation or its nested regions.
279 
280  /// Unlink this operation from its current block and insert it right before
281  /// `existingOp` which may be in the same or another block in the same
282  /// function.
283  void moveBefore(Operation *existingOp);
284 
285  /// Unlink this operation from its current block and insert it right before
286  /// `iterator` in the specified block.
287  void moveBefore(Block *block, llvm::iplist<Operation>::iterator iterator);
288 
289  /// Unlink this operation from its current block and insert it right after
290  /// `existingOp` which may be in the same or another block in the same
291  /// function.
292  void moveAfter(Operation *existingOp);
293 
294  /// Unlink this operation from its current block and insert it right after
295  /// `iterator` in the specified block.
296  void moveAfter(Block *block, llvm::iplist<Operation>::iterator iterator);
297 
298  /// Given an operation 'other' that is within the same parent block, return
299  /// whether the current operation is before 'other' in the operation list
300  /// of the parent block.
301  /// Note: This function has an average complexity of O(1), but worst case may
302  /// take O(N) where N is the number of operations within the parent block.
303  bool isBeforeInBlock(Operation *other);
304 
305  void print(raw_ostream &os, const OpPrintingFlags &flags = std::nullopt);
306  void print(raw_ostream &os, AsmState &state);
307  void dump();
308 
309  //===--------------------------------------------------------------------===//
310  // Operands
311  //===--------------------------------------------------------------------===//
312 
313  /// Replace the current operands of this operation with the ones provided in
314  /// 'operands'.
315  void setOperands(ValueRange operands);
316 
317  /// Replace the operands beginning at 'start' and ending at 'start' + 'length'
318  /// with the ones provided in 'operands'. 'operands' may be smaller or larger
319  /// than the range pointed to by 'start'+'length'.
320  void setOperands(unsigned start, unsigned length, ValueRange operands);
321 
322  /// Insert the given operands into the operand list at the given 'index'.
323  void insertOperands(unsigned index, ValueRange operands);
324 
325  unsigned getNumOperands() {
326  return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().size() : 0;
327  }
328 
329  Value getOperand(unsigned idx) { return getOpOperand(idx).get(); }
330  void setOperand(unsigned idx, Value value) {
331  return getOpOperand(idx).set(value);
332  }
333 
334  /// Erase the operand at position `idx`.
335  void eraseOperand(unsigned idx) { eraseOperands(idx); }
336 
337  /// Erase the operands starting at position `idx` and ending at position
338  /// 'idx'+'length'.
339  void eraseOperands(unsigned idx, unsigned length = 1) {
340  getOperandStorage().eraseOperands(idx, length);
341  }
342 
343  /// Erases the operands that have their corresponding bit set in
344  /// `eraseIndices` and removes them from the operand list.
345  void eraseOperands(const BitVector &eraseIndices) {
346  getOperandStorage().eraseOperands(eraseIndices);
347  }
348 
349  // Support operand iteration.
351  using operand_iterator = operand_range::iterator;
352 
355 
356  /// Returns an iterator on the underlying Value's.
359  return OperandRange(operands.data(), operands.size());
360  }
361 
363  return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().getOperands()
365  }
366 
367  OpOperand &getOpOperand(unsigned idx) {
368  return getOperandStorage().getOperands()[idx];
369  }
370 
371  // Support operand type iteration.
377 
378  //===--------------------------------------------------------------------===//
379  // Results
380  //===--------------------------------------------------------------------===//
381 
382  /// Return the number of results held by this operation.
383  unsigned getNumResults() { return numResults; }
384 
385  /// Get the 'idx'th result of this operation.
386  OpResult getResult(unsigned idx) { return OpResult(getOpResultImpl(idx)); }
387 
388  /// Support result iteration.
390  using result_iterator = result_range::iterator;
391 
392  result_iterator result_begin() { return getResults().begin(); }
393  result_iterator result_end() { return getResults().end(); }
395  return numResults == 0 ? result_range(nullptr, 0)
396  : result_range(getInlineOpResult(0), numResults);
397  }
398 
400  OpResult getOpResult(unsigned idx) { return getResult(idx); }
401 
402  /// Support result type iteration.
408 
409  //===--------------------------------------------------------------------===//
410  // Attributes
411  //===--------------------------------------------------------------------===//
412 
413  // Operations may optionally carry a list of attributes that associate
414  // constants to names. Attributes may be dynamically added and removed over
415  // the lifetime of an operation.
416 
417  /// Return all of the attributes on this operation.
418  ArrayRef<NamedAttribute> getAttrs() { return attrs.getValue(); }
419 
420  /// Return all of the attributes on this operation as a DictionaryAttr.
421  DictionaryAttr getAttrDictionary() { return attrs; }
422 
423  /// Set the attribute dictionary on this operation.
424  void setAttrs(DictionaryAttr newAttrs) {
425  assert(newAttrs && "expected valid attribute dictionary");
426  attrs = newAttrs;
427  }
429  setAttrs(DictionaryAttr::get(getContext(), newAttrs));
430  }
431 
432  /// Return the specified attribute if present, null otherwise.
433  Attribute getAttr(StringAttr name) { return attrs.get(name); }
434  Attribute getAttr(StringRef name) { return attrs.get(name); }
435 
436  template <typename AttrClass>
437  AttrClass getAttrOfType(StringAttr name) {
438  return getAttr(name).dyn_cast_or_null<AttrClass>();
439  }
440  template <typename AttrClass>
441  AttrClass getAttrOfType(StringRef name) {
442  return getAttr(name).dyn_cast_or_null<AttrClass>();
443  }
444 
445  /// Return true if the operation has an attribute with the provided name,
446  /// false otherwise.
447  bool hasAttr(StringAttr name) { return attrs.contains(name); }
448  bool hasAttr(StringRef name) { return attrs.contains(name); }
449  template <typename AttrClass, typename NameT>
450  bool hasAttrOfType(NameT &&name) {
451  return static_cast<bool>(
452  getAttrOfType<AttrClass>(std::forward<NameT>(name)));
453  }
454 
455  /// If the an attribute exists with the specified name, change it to the new
456  /// value. Otherwise, add a new attribute with the specified name/value.
457  void setAttr(StringAttr name, Attribute value) {
458  NamedAttrList attributes(attrs);
459  if (attributes.set(name, value) != value)
460  attrs = attributes.getDictionary(getContext());
461  }
462  void setAttr(StringRef name, Attribute value) {
463  setAttr(StringAttr::get(getContext(), name), value);
464  }
465 
466  /// Remove the attribute with the specified name if it exists. Return the
467  /// attribute that was erased, or nullptr if there was no attribute with such
468  /// name.
469  Attribute removeAttr(StringAttr name) {
470  NamedAttrList attributes(attrs);
471  Attribute removedAttr = attributes.erase(name);
472  if (removedAttr)
473  attrs = attributes.getDictionary(getContext());
474  return removedAttr;
475  }
476  Attribute removeAttr(StringRef name) {
477  return removeAttr(StringAttr::get(getContext(), name));
478  }
479 
480  /// A utility iterator that filters out non-dialect attributes.
482  : public llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
483  bool (*)(NamedAttribute)> {
484  static bool filter(NamedAttribute attr) {
485  // Dialect attributes are prefixed by the dialect name, like operations.
486  return attr.getName().strref().count('.');
487  }
488 
491  : llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
492  bool (*)(NamedAttribute)>(it, end, &filter) {}
493 
494  // Allow access to the constructor.
495  friend Operation;
496  };
498 
499  /// Return a range corresponding to the dialect attributes for this operation.
501  auto attrs = getAttrs();
502  return {dialect_attr_iterator(attrs.begin(), attrs.end()),
503  dialect_attr_iterator(attrs.end(), attrs.end())};
504  }
506  auto attrs = getAttrs();
507  return dialect_attr_iterator(attrs.begin(), attrs.end());
508  }
510  auto attrs = getAttrs();
511  return dialect_attr_iterator(attrs.end(), attrs.end());
512  }
513 
514  /// Set the dialect attributes for this operation, and preserve all dependent.
515  template <typename DialectAttrT>
516  void setDialectAttrs(DialectAttrT &&dialectAttrs) {
517  NamedAttrList attrs;
518  attrs.append(std::begin(dialectAttrs), std::end(dialectAttrs));
519  for (auto attr : getAttrs())
520  if (!attr.getName().strref().contains('.'))
521  attrs.push_back(attr);
523  }
524 
525  /// Sets default attributes on unset attributes.
528  name.populateDefaultAttrs(attrs);
530  }
531 
532  //===--------------------------------------------------------------------===//
533  // Blocks
534  //===--------------------------------------------------------------------===//
535 
536  /// Returns the number of regions held by this operation.
537  unsigned getNumRegions() { return numRegions; }
538 
539  /// Returns the regions held by this operation.
541  // Check the count first, as computing the trailing objects can be slow.
542  if (numRegions == 0)
543  return MutableArrayRef<Region>();
544 
545  auto *regions = getTrailingObjects<Region>();
546  return {regions, numRegions};
547  }
548 
549  /// Returns the region held by this operation at position 'index'.
550  Region &getRegion(unsigned index) {
551  assert(index < numRegions && "invalid region index");
552  return getRegions()[index];
553  }
554 
555  //===--------------------------------------------------------------------===//
556  // Successors
557  //===--------------------------------------------------------------------===//
558 
560  return {getTrailingObjects<BlockOperand>(), numSuccs};
561  }
562 
563  // Successor iteration.
564  using succ_iterator = SuccessorRange::iterator;
568 
569  bool hasSuccessors() { return numSuccs != 0; }
570  unsigned getNumSuccessors() { return numSuccs; }
571 
572  Block *getSuccessor(unsigned index) {
573  assert(index < getNumSuccessors());
574  return getBlockOperands()[index].get();
575  }
576  void setSuccessor(Block *block, unsigned index);
577 
578  //===--------------------------------------------------------------------===//
579  // Accessors for various properties of operations
580  //===--------------------------------------------------------------------===//
581 
582  /// Attempt to fold this operation with the specified constant operand values
583  /// - the elements in "operands" will correspond directly to the operands of
584  /// the operation, but may be null if non-constant. If folding is successful,
585  /// this fills in the `results` vector. If not, `results` is unspecified.
588 
589  /// Returns true if the operation was registered with a particular trait, e.g.
590  /// hasTrait<OperandsAreSignlessIntegerLike>().
591  template <template <typename T> class Trait>
592  bool hasTrait() {
593  return name.hasTrait<Trait>();
594  }
595 
596  /// Returns true if the operation *might* have the provided trait. This
597  /// means that either the operation is unregistered, or it was registered with
598  /// the provide trait.
599  template <template <typename T> class Trait>
600  bool mightHaveTrait() {
601  return name.mightHaveTrait<Trait>();
602  }
603 
604  //===--------------------------------------------------------------------===//
605  // Operation Walkers
606  //===--------------------------------------------------------------------===//
607 
608  /// Walk the operation by calling the callback for each nested operation
609  /// (including this one), block or region, depending on the callback provided.
610  /// The order in which regions, blocks and operations at the same nesting
611  /// level are visited (e.g., lexicographical or reverse lexicographical order)
612  /// is determined by 'Iterator'. The walk order for enclosing regions, blocks
613  /// and operations with respect to their nested ones is specified by 'Order'
614  /// (post-order by default). A callback on a block or operation is allowed to
615  /// erase that block or operation if either:
616  /// * the walk is in post-order, or
617  /// * the walk is in pre-order and the walk is skipped after the erasure.
618  ///
619  /// The callback method can take any of the following forms:
620  /// void(Operation*) : Walk all operations opaquely.
621  /// * op->walk([](Operation *nestedOp) { ...});
622  /// void(OpT) : Walk all operations of the given derived type.
623  /// * op->walk([](ReturnOp returnOp) { ...});
624  /// WalkResult(Operation*|OpT) : Walk operations, but allow for
625  /// interruption/skipping.
626  /// * op->walk([](... op) {
627  /// // Skip the walk of this op based on some invariant.
628  /// if (some_invariant)
629  /// return WalkResult::skip();
630  /// // Interrupt, i.e cancel, the walk based on some invariant.
631  /// if (another_invariant)
632  /// return WalkResult::interrupt();
633  /// return WalkResult::advance();
634  /// });
635  template <WalkOrder Order = WalkOrder::PostOrder,
636  typename Iterator = ForwardIterator, typename FnT,
637  typename RetT = detail::walkResultType<FnT>>
638  std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 1,
639  RetT>
640  walk(FnT &&callback) {
641  return detail::walk<Order, Iterator>(this, std::forward<FnT>(callback));
642  }
643 
644  /// Generic walker with a stage aware callback. Walk the operation by calling
645  /// the callback for each nested operation (including this one) N+1 times,
646  /// where N is the number of regions attached to that operation.
647  ///
648  /// The callback method can take any of the following forms:
649  /// void(Operation *, const WalkStage &) : Walk all operation opaquely
650  /// * op->walk([](Operation *nestedOp, const WalkStage &stage) { ...});
651  /// void(OpT, const WalkStage &) : Walk all operations of the given derived
652  /// type.
653  /// * op->walk([](ReturnOp returnOp, const WalkStage &stage) { ...});
654  /// WalkResult(Operation*|OpT, const WalkStage &stage) : Walk operations,
655  /// but allow for interruption/skipping.
656  /// * op->walk([](... op, const WalkStage &stage) {
657  /// // Skip the walk of this op based on some invariant.
658  /// if (some_invariant)
659  /// return WalkResult::skip();
660  /// // Interrupt, i.e cancel, the walk based on some invariant.
661  /// if (another_invariant)
662  /// return WalkResult::interrupt();
663  /// return WalkResult::advance();
664  /// });
665  template <typename FnT, typename RetT = detail::walkResultType<FnT>>
666  std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 2,
667  RetT>
668  walk(FnT &&callback) {
669  return detail::walk(this, std::forward<FnT>(callback));
670  }
671 
672  //===--------------------------------------------------------------------===//
673  // Uses
674  //===--------------------------------------------------------------------===//
675 
676  /// Drop all uses of results of this operation.
677  void dropAllUses() {
678  for (OpResult result : getOpResults())
679  result.dropAllUses();
680  }
681 
684 
687 
688  /// Returns a range of all uses, which is useful for iterating over all uses.
690 
691  /// Returns true if this operation has exactly one use.
692  bool hasOneUse() { return llvm::hasSingleElement(getUses()); }
693 
694  /// Returns true if this operation has no uses.
695  bool use_empty() { return getResults().use_empty(); }
696 
697  /// Returns true if the results of this operation are used outside of the
698  /// given block.
700  return llvm::any_of(getOpResults(), [block](OpResult result) {
701  return result.isUsedOutsideOfBlock(block);
702  });
703  }
704 
705  //===--------------------------------------------------------------------===//
706  // Users
707  //===--------------------------------------------------------------------===//
708 
711 
714 
715  /// Returns a range of all users.
716  user_range getUsers() { return {user_begin(), user_end()}; }
717 
718  //===--------------------------------------------------------------------===//
719  // Other
720  //===--------------------------------------------------------------------===//
721 
722  /// Emit an error with the op name prefixed, like "'dim' op " which is
723  /// convenient for verifiers.
724  InFlightDiagnostic emitOpError(const Twine &message = {});
725 
726  /// Emit an error about fatal conditions with this operation, reporting up to
727  /// any diagnostic handlers that may be listening.
728  InFlightDiagnostic emitError(const Twine &message = {});
729 
730  /// Emit a warning about this operation, reporting up to any diagnostic
731  /// handlers that may be listening.
732  InFlightDiagnostic emitWarning(const Twine &message = {});
733 
734  /// Emit a remark about this operation, reporting up to any diagnostic
735  /// handlers that may be listening.
736  InFlightDiagnostic emitRemark(const Twine &message = {});
737 
738 private:
739  //===--------------------------------------------------------------------===//
740  // Ordering
741  //===--------------------------------------------------------------------===//
742 
743  /// This value represents an invalid index ordering for an operation within a
744  /// block.
745  static constexpr unsigned kInvalidOrderIdx = -1;
746 
747  /// This value represents the stride to use when computing a new order for an
748  /// operation.
749  static constexpr unsigned kOrderStride = 5;
750 
751  /// Update the order index of this operation of this operation if necessary,
752  /// potentially recomputing the order of the parent block.
753  void updateOrderIfNecessary();
754 
755  /// Returns true if this operation has a valid order.
756  bool hasValidOrder() { return orderIndex != kInvalidOrderIdx; }
757 
758 private:
759  Operation(Location location, OperationName name, unsigned numResults,
760  unsigned numSuccessors, unsigned numRegions,
761  DictionaryAttr attributes, bool hasOperandStorage);
762 
763  // Operations are deleted through the destroy() member because they are
764  // allocated with malloc.
765  ~Operation();
766 
767  /// Returns the additional size necessary for allocating the given objects
768  /// before an Operation in-memory.
769  static size_t prefixAllocSize(unsigned numOutOfLineResults,
770  unsigned numInlineResults) {
771  return sizeof(detail::OutOfLineOpResult) * numOutOfLineResults +
772  sizeof(detail::InlineOpResult) * numInlineResults;
773  }
774  /// Returns the additional size allocated before this Operation in-memory.
775  size_t prefixAllocSize() {
776  unsigned numResults = getNumResults();
777  unsigned numOutOfLineResults = OpResult::getNumTrailing(numResults);
778  unsigned numInlineResults = OpResult::getNumInline(numResults);
779  return prefixAllocSize(numOutOfLineResults, numInlineResults);
780  }
781 
782  /// Returns the operand storage object.
783  detail::OperandStorage &getOperandStorage() {
784  assert(hasOperandStorage && "expected operation to have operand storage");
785  return *getTrailingObjects<detail::OperandStorage>();
786  }
787 
788  /// Returns a pointer to the use list for the given out-of-line result.
789  detail::OutOfLineOpResult *getOutOfLineOpResult(unsigned resultNumber) {
790  // Out-of-line results are stored in reverse order after (before in memory)
791  // the inline results.
792  return reinterpret_cast<detail::OutOfLineOpResult *>(getInlineOpResult(
794  ++resultNumber;
795  }
796 
797  /// Returns a pointer to the use list for the given inline result.
798  detail::InlineOpResult *getInlineOpResult(unsigned resultNumber) {
799  // Inline results are stored in reverse order before the operation in
800  // memory.
801  return reinterpret_cast<detail::InlineOpResult *>(this) - ++resultNumber;
802  }
803 
804  /// Returns a pointer to the use list for the given result, which may be
805  /// either inline or out-of-line.
806  detail::OpResultImpl *getOpResultImpl(unsigned resultNumber) {
807  unsigned maxInlineResults = detail::OpResultImpl::getMaxInlineResults();
808  if (resultNumber < maxInlineResults)
809  return getInlineOpResult(resultNumber);
810  return getOutOfLineOpResult(resultNumber - maxInlineResults);
811  }
812 
813  /// Provide a 'getParent' method for ilist_node_with_parent methods.
814  /// We mark it as a const function because ilist_node_with_parent specifically
815  /// requires a 'getParent() const' method. Once ilist_node removes this
816  /// constraint, we should drop the const to fit the rest of the MLIR const
817  /// model.
818  Block *getParent() const { return block; }
819 
820  /// Expose a few methods explicitly for the debugger to call for
821  /// visualization.
822 #ifndef NDEBUG
823  LLVM_DUMP_METHOD operand_range debug_getOperands() { return getOperands(); }
824  LLVM_DUMP_METHOD result_range debug_getResults() { return getResults(); }
825  LLVM_DUMP_METHOD SuccessorRange debug_getSuccessors() {
826  return getSuccessors();
827  }
828  LLVM_DUMP_METHOD MutableArrayRef<Region> debug_getRegions() {
829  return getRegions();
830  }
831 #endif
832 
833  /// The operation block that contains this operation.
834  Block *block = nullptr;
835 
836  /// This holds information about the source location the operation was defined
837  /// or derived from.
838  Location location;
839 
840  /// Relative order of this operation in its parent block. Used for
841  /// O(1) local dominance checks between operations.
842  mutable unsigned orderIndex = 0;
843 
844  const unsigned numResults;
845  const unsigned numSuccs;
846  const unsigned numRegions : 31;
847 
848  /// This bit signals whether this operation has an operand storage or not. The
849  /// operand storage may be elided for operations that are known to never have
850  /// operands.
851  bool hasOperandStorage : 1;
852 
853  /// This holds the name of the operation.
854  OperationName name;
855 
856  /// This holds general named attributes for the operation.
857  DictionaryAttr attrs;
858 
859  // allow ilist_traits access to 'block' field.
860  friend struct llvm::ilist_traits<Operation>;
861 
862  // allow block to access the 'orderIndex' field.
863  friend class Block;
864 
865  // allow value to access the 'ResultStorage' methods.
866  friend class Value;
867 
868  // allow ilist_node_with_parent to access the 'getParent' method.
869  friend class llvm::ilist_node_with_parent<Operation, Block>;
870 
871  // This stuff is used by the TrailingObjects template.
872  friend llvm::TrailingObjects<Operation, detail::OperandStorage, BlockOperand,
873  Region, OpOperand>;
874  size_t numTrailingObjects(OverloadToken<detail::OperandStorage>) const {
875  return hasOperandStorage ? 1 : 0;
876  }
877  size_t numTrailingObjects(OverloadToken<BlockOperand>) const {
878  return numSuccs;
879  }
880  size_t numTrailingObjects(OverloadToken<Region>) const { return numRegions; }
881 };
882 
883 inline raw_ostream &operator<<(raw_ostream &os, const Operation &op) {
884  const_cast<Operation &>(op).print(os, OpPrintingFlags().useLocalScope());
885  return os;
886 }
887 
888 } // namespace mlir
889 
890 namespace llvm {
891 /// Cast from an (const) Operation * to a derived operation type.
892 template <typename T>
893 struct CastInfo<T, ::mlir::Operation *>
894  : public ValueFromPointerCast<T, ::mlir::Operation,
895  CastInfo<T, ::mlir::Operation *>> {
896  static bool isPossible(::mlir::Operation *op) { return T::classof(op); }
897 };
898 template <typename T>
899 struct CastInfo<T, const ::mlir::Operation *>
900  : public ConstStrippingForwardingCast<T, const ::mlir::Operation *,
901  CastInfo<T, ::mlir::Operation *>> {};
902 
903 /// Cast from an (const) Operation & to a derived operation type.
904 template <typename T>
906  : public NullableValueCastFailed<T>,
907  public DefaultDoCastIfPossible<T, ::mlir::Operation &,
908  CastInfo<T, ::mlir::Operation>> {
909  // Provide isPossible here because here we have the const-stripping from
910  // ConstStrippingCast.
911  static bool isPossible(::mlir::Operation &val) { return T::classof(&val); }
912  static T doCast(::mlir::Operation &val) { return T(&val); }
913 };
914 template <typename T>
915 struct CastInfo<T, const ::mlir::Operation>
916  : public ConstStrippingForwardingCast<T, const ::mlir::Operation,
917  CastInfo<T, ::mlir::Operation>> {};
918 
919 /// Cast (const) Operation * to itself. This is helpful to avoid SFINAE in
920 /// templated implementations that should work on both base and derived
921 /// operation types.
922 template <>
924  : public NullableValueCastFailed<::mlir::Operation *>,
926  ::mlir::Operation *, ::mlir::Operation *,
927  CastInfo<::mlir::Operation *, ::mlir::Operation *>> {
928  static bool isPossible(::mlir::Operation *op) { return true; }
929  static ::mlir::Operation *doCast(::mlir::Operation *op) { return op; }
930 };
931 template <>
932 struct CastInfo<const ::mlir::Operation *, const ::mlir::Operation *>
934  const ::mlir::Operation *, const ::mlir::Operation *,
935  CastInfo<::mlir::Operation *, ::mlir::Operation *>> {};
936 } // namespace llvm
937 
938 #endif // MLIR_IR_OPERATION_H
static llvm::ManagedStatic< PassManagerOptions > options
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
This class provides management for the lifetime of the state used when printing the IR.
Definition: AsmState.h:525
Attributes are known-constant values of operations.
Definition: Attributes.h:25
U dyn_cast_or_null() const
Definition: Attributes.h:171
MLIRContext * getContext() const
Return the context this attribute belongs to.
Definition: Attributes.cpp:37
A block operand represents an operand that holds a reference to a Block, e.g.
Definition: BlockSupport.h:30
This class provides an abstraction over the different types of ranges over Blocks.
Definition: BlockSupport.h:106
Block represents an ordered list of Operations.
Definition: Block.h:30
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
Definition: Block.cpp:26
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
Definition: Block.cpp:30
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
This is a utility class for mapping one set of IR entities to another.
Definition: IRMapping.h:26
IRValueT get() const
Return the current value being used by this operand.
Definition: UseDefLists.h:137
void set(IRValueT newValue)
Set the current value being used by this operand.
Definition: UseDefLists.h:140
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:308
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:63
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
DictionaryAttr getDictionary(MLIRContext *context) const
Return a dictionary attribute for the underlying dictionary.
void push_back(NamedAttribute newAttribute)
Add an attribute with the specified name.
Attribute erase(StringAttr name)
Erase the attribute with the given name from the list.
Attribute set(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:189
StringAttr getName() const
Return the name of the attribute.
Definition: Attributes.cpp:49
This class represents an operand of an operation.
Definition: Value.h:255
Set of flags used to control the behavior of the various IR print methods (e.g.
OpPrintingFlags & useLocalScope()
Use local scope when printing the operation.
Definition: AsmPrinter.cpp:242
This is a value defined by a result of an operation.
Definition: Value.h:442
This class implements the operand iterators for the Operation class.
Definition: ValueRange.h:42
type_range getTypes() const
Definition: ValueRange.cpp:26
ValueTypeRange< OperandRange > type_range
Definition: ValueRange.h:48
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Definition: ValueRange.h:47
bool hasTrait() const
Returns true if the operation was registered with a particular trait, e.g.
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context,...
std::optional< RegisteredOperationName > getRegisteredInfo() const
If this operation is registered, returns the registered information, std::nullopt otherwise.
bool mightHaveTrait() const
Returns true if the operation might have the provided trait.
bool isRegistered() const
Return if this operation is registered.
void populateDefaultAttrs(NamedAttrList &attrs) const
This hook implements the method to populate defaults attributes that are unset.
Class encompassing various options related to cloning an operation.
Definition: Operation.h:127
bool shouldCloneRegions() const
Returns whether regions of the operation should be cloned as well.
Definition: Operation.h:150
CloneOptions()
Default constructs an option with all flags set to false.
Definition: Operation.cpp:528
static CloneOptions all()
Returns an instance with all flags set to true.
Definition: Operation.cpp:534
bool shouldCloneOperands() const
Returns whether operands should be cloned as well.
Definition: Operation.h:157
CloneOptions & cloneRegions(bool enable=true)
Configures whether cloning should traverse into any of the regions of the operation.
Definition: Operation.cpp:538
CloneOptions & cloneOperands(bool enable=true)
Configures whether operation' operands should be cloned.
Definition: Operation.cpp:543
A utility iterator that filters out non-dialect attributes.
Definition: Operation.h:483
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:75
AttrClass getAttrOfType(StringRef name)
Definition: Operation.h:441
void setLoc(Location loc)
Set the source location the operation was defined or derived from.
Definition: Operation.h:210
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:345
void replaceUsesOfWith(Value from, Value to)
Replace any uses of 'from' with 'to' within this operation.
Definition: Operation.cpp:193
ResultRange result_range
Support result iteration.
Definition: Operation.h:389
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Attempt to fold this operation with the specified constant operand values.
Definition: Operation.cpp:499
void setAttrs(ArrayRef< NamedAttribute > newAttrs)
Definition: Operation.h:428
bool use_empty()
Returns true if this operation has no uses.
Definition: Operation.h:695
Value getOperand(unsigned idx)
Definition: Operation.h:329
OpResult getOpResult(unsigned idx)
Definition: Operation.h:400
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Definition: Operation.h:592
Operation * cloneWithoutRegions()
Create a partial copy of this operation without traversing into attached regions.
Definition: Operation.cpp:556
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
Definition: Operation.h:204
void insertOperands(unsigned index, ValueRange operands)
Insert the given operands into the operand list at the given 'index'.
Definition: Operation.cpp:222
void dropAllUses()
Drop all uses of results of this operation.
Definition: Operation.h:677
AttrClass getAttrOfType(StringAttr name)
Definition: Operation.h:437
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
Definition: Operation.h:433
bool hasAttr(StringRef name)
Definition: Operation.h:448
OpOperand & getOpOperand(unsigned idx)
Definition: Operation.h:367
bool hasAttrOfType(NameT &&name)
Definition: Operation.h:450
void setOperand(unsigned idx, Value value)
Definition: Operation.h:330
Block * getSuccessor(unsigned index)
Definition: Operation.h:572
bool hasAttr(StringAttr name)
Return true if the operation has an attribute with the provided name, false otherwise.
Definition: Operation.h:447
unsigned getNumSuccessors()
Definition: Operation.h:570
bool isBeforeInBlock(Operation *other)
Given an operation 'other' that is within the same parent block, return whether the current operation...
Definition: Operation.cpp:274
result_iterator result_begin()
Definition: Operation.h:392
void eraseOperands(unsigned idx, unsigned length=1)
Erase the operands starting at position idx and ending at position 'idx'+'length'.
Definition: Operation.h:339
void dropAllReferences()
This drops all operand uses from this operation, which is an essential step in breaking cyclic depend...
Definition: Operation.cpp:472
bool isRegistered()
Returns true if this operation has a registered operation description, otherwise false.
Definition: Operation.h:113
InFlightDiagnostic emitWarning(const Twine &message={})
Emit a warning about this operation, reporting up to any diagnostic handlers that may be listening.
Definition: Operation.cpp:246
Operation * clone(IRMapping &mapper, CloneOptions options=CloneOptions::all())
Create a deep copy of this operation, remapping any operands that use values outside of the operation...
Definition: Operation.cpp:566
result_range::iterator result_iterator
Definition: Operation.h:390
void setAttrs(DictionaryAttr newAttrs)
Set the attribute dictionary on this operation.
Definition: Operation.h:424
operand_iterator operand_begin()
Definition: Operation.h:353
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
Definition: Operation.h:600
bool hasOneUse()
Returns true if this operation has exactly one use.
Definition: Operation.h:692
dialect_attr_iterator dialect_attr_begin()
Definition: Operation.h:505
Attribute getAttr(StringRef name)
Definition: Operation.h:434
user_iterator user_end()
Definition: Operation.h:713
Attribute removeAttr(StringRef name)
Definition: Operation.h:476
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition: Operation.h:386
use_iterator use_begin()
Definition: Operation.h:685
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
Definition: Operation.h:640
void print(raw_ostream &os, const OpPrintingFlags &flags=std::nullopt)
operand_type_iterator operand_type_end()
Definition: Operation.h:375
MLIRContext * getContext()
Return the context this operation is associated with.
Definition: Operation.h:200
unsigned getNumRegions()
Returns the number of regions held by this operation.
Definition: Operation.h:537
void setDialectAttrs(DialectAttrT &&dialectAttrs)
Set the dialect attributes for this operation, and preserve all dependent.
Definition: Operation.h:516
std::optional< RegisteredOperationName > getRegisteredInfo()
If this operation has a registered operation description, return it.
Definition: Operation.h:107
Location getLoc()
The source location the operation was defined or derived from.
Definition: Operation.h:207
void replaceUsesWithIf(ValuesT &&values, function_ref< bool(OpOperand &)> shouldReplace)
Replace uses of results of this operation with the provided values if the given callback returns true...
Definition: Operation.h:263
void eraseOperand(unsigned idx)
Erase the operand at position idx.
Definition: Operation.h:335
void dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
Definition: Operation.cpp:485
unsigned getNumOperands()
Definition: Operation.h:325
result_type_iterator result_type_end()
Definition: Operation.h:406
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Definition: Operation.h:218
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, NamedAttrList &&attributes, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
Definition: Operation.cpp:48
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
Definition: Operation.h:418
OperandRange operand_range
Definition: Operation.h:350
void populateDefaultAttrs()
Sets default attributes on unset attributes.
Definition: Operation.h:526
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:234
Block * getBlock()
Returns the operation block that contains this operation.
Definition: Operation.h:197
ValueUserIterator< use_iterator, OpOperand > user_iterator
Definition: Operation.h:709
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition: Operation.h:222
operand_iterator operand_end()
Definition: Operation.h:354
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
Definition: Operation.h:550
bool isUsedOutsideOfBlock(Block *block)
Returns true if the results of this operation are used outside of the given block.
Definition: Operation.h:699
result_type_iterator result_type_begin()
Definition: Operation.h:405
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
Definition: Operation.h:457
Operation * getParentWithTrait()
Returns the closest surrounding parent operation with trait Trait.
Definition: Operation.h:232
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
Definition: Operation.h:540
void destroy()
Destroys this operation and its subclass data.
Definition: Operation.cpp:174
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
Definition: Operation.h:421
OperationName getName()
The name of an operation is the key identifier for it.
Definition: Operation.h:103
void remove()
Remove the operation from its parent block, but don't delete it.
Definition: Operation.cpp:435
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
Definition: Operation.h:500
MutableArrayRef< BlockOperand > getBlockOperands()
Definition: Operation.h:559
bool hasSuccessors()
Definition: Operation.h:569
operand_type_range getOperandTypes()
Definition: Operation.h:376
result_iterator result_end()
Definition: Operation.h:393
MutableArrayRef< OpOperand > getOpOperands()
Definition: Operation.h:362
friend class Block
Definition: Operation.h:863
result_type_range getResultTypes()
Definition: Operation.h:407
operand_range getOperands()
Returns an iterator on the underlying Value's.
Definition: Operation.h:357
void setSuccessor(Block *block, unsigned index)
Definition: Operation.cpp:493
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:443
bool isAncestor(Operation *other)
Return true if this operation is an ancestor of the other operation.
Definition: Operation.h:247
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided 'values'.
Definition: Operation.h:256
void setOperands(ValueRange operands)
Replace the current operands of this operation with the ones provided in 'operands'.
Definition: Operation.cpp:203
user_range getUsers()
Returns a range of all users.
Definition: Operation.h:716
SuccessorRange getSuccessors()
Definition: Operation.h:567
result_range getOpResults()
Definition: Operation.h:399
Region * getParentRegion()
Returns the region to which the instruction belongs.
Definition: Operation.h:214
result_range getResults()
Definition: Operation.h:394
Attribute removeAttr(StringAttr name)
Remove the attribute with the specified name if it exists.
Definition: Operation.h:469
SuccessorRange::iterator succ_iterator
Definition: Operation.h:564
dialect_attr_iterator dialect_attr_end()
Definition: Operation.h:509
bool isProperAncestor(Operation *other)
Return true if this operation is a proper ancestor of the other operation.
Definition: Operation.cpp:185
use_range getUses()
Returns a range of all uses, which is useful for iterating over all uses.
Definition: Operation.h:689
void setAttr(StringRef name, Attribute value)
Definition: Operation.h:462
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening.
Definition: Operation.cpp:255
operand_range::iterator operand_iterator
Definition: Operation.h:351
user_iterator user_begin()
Definition: Operation.h:712
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:457
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
Definition: Operation.cpp:520
succ_iterator successor_end()
Definition: Operation.h:566
use_iterator use_end()
Definition: Operation.h:686
void erase()
Remove this operation from its parent block and delete it.
Definition: Operation.cpp:427
succ_iterator successor_begin()
Definition: Operation.h:565
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==2, RetT > walk(FnT &&callback)
Generic walker with a stage aware callback.
Definition: Operation.h:668
unsigned getNumResults()
Return the number of results held by this operation.
Definition: Operation.h:383
operand_type_iterator operand_type_begin()
Definition: Operation.h:374
This class provides an abstraction over the different types of ranges over Regions.
Definition: Region.h:334
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition: Region.h:26
This class implements a use iterator for a range of operation results.
Definition: ValueRange.h:334
This class implements the result iterators for the Operation class.
Definition: ValueRange.h:231
use_range getUses() const
Returns a range of all uses of results within this range, which is useful for iterating over all uses...
bool use_empty() const
Returns true if no results in this range have uses.
Definition: ValueRange.h:261
ValueTypeRange< ResultRange > type_range
Definition: ValueRange.h:242
use_iterator use_begin() const
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Definition: ValueRange.h:241
use_iterator use_end() const
std::enable_if_t<!std::is_convertible< ValuesT, Operation * >::value > replaceUsesWithIf(ValuesT &&values, function_ref< bool(OpOperand &)> shouldReplace)
Replace uses of results of this range with the provided 'values' if the given callback returns true.
Definition: ValueRange.h:287
type_range getTypes() const
Definition: ValueRange.cpp:35
std::enable_if_t<!std::is_convertible< ValuesT, Operation * >::value > replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this range with the provided 'values'.
Definition: ValueRange.h:270
iterator_range< use_iterator > use_range
Definition: ValueRange.h:252
UseIterator use_iterator
Definition: ValueRange.h:251
This class implements the successor iterators for Block.
Definition: BlockSupport.h:73
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:36
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:370
This class implements iteration on the types of a given range of values.
Definition: TypeRange.h:118
This class implements iteration on the types of a given range of values.
Definition: TypeRange.h:131
An iterator over the users of an IRObject.
Definition: UseDefLists.h:291
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:93
bool isUsedOutsideOfBlock(Block *block)
Returns true if the value is used outside of the given block.
Definition: Value.cpp:90
static unsigned getMaxInlineResults()
Returns the maximum number of results that can be stored inline.
Definition: Value.h:375
This class handles the management of operation operands.
MutableArrayRef< OpOperand > getOperands()
Get the operation operands held by the storage.
void eraseOperands(unsigned start, unsigned length)
Erase the operands held by the storage within the given range.
unsigned size()
Return the number of operands held in the storage.
Include the generated interface declarations.
Definition: CallGraph.h:229
void walk(Operation *op, function_ref< void(Region *)> callback, WalkOrder order)
Walk all of the regions, blocks, or operations nested under (and including) the given operation.
Definition: Visitors.h:137
decltype(walk(nullptr, std::declval< FnT >())) walkResultType
Utility to provide the return type of a templated walk method.
Definition: Visitors.h:466
This header declares functions that assit transformations in the MemRef dialect.
WalkOrder
Traversal order for region, block and operation walk utilities.
Definition: Visitors.h:63
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
static T doCast(::mlir::Operation &val)
Definition: Operation.h:912
static bool isPossible(::mlir::Operation &val)
Definition: Operation.h:911
static bool isPossible(::mlir::Operation *op)
Definition: Operation.h:896
::mlir::Operation * doCast(::mlir::Operation *op)
Definition: Operation.h:929
static bool isPossible(::mlir::Operation *op)
Definition: Operation.h:928
This iterator enumerates the elements in "forward" order.
Definition: Visitors.h:66
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
This represents an operation in an abstracted form, suitable for use with the builder APIs.