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