MLIR  18.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  //===--------------------------------------------------------------------===//
326  // Operands
327  //===--------------------------------------------------------------------===//
328 
329  /// Replace the current operands of this operation with the ones provided in
330  /// 'operands'.
331  void setOperands(ValueRange operands);
332 
333  /// Replace the operands beginning at 'start' and ending at 'start' + 'length'
334  /// with the ones provided in 'operands'. 'operands' may be smaller or larger
335  /// than the range pointed to by 'start'+'length'.
336  void setOperands(unsigned start, unsigned length, ValueRange operands);
337 
338  /// Insert the given operands into the operand list at the given 'index'.
339  void insertOperands(unsigned index, ValueRange operands);
340 
341  unsigned getNumOperands() {
342  return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().size() : 0;
343  }
344 
345  Value getOperand(unsigned idx) { return getOpOperand(idx).get(); }
346  void setOperand(unsigned idx, Value value) {
347  return getOpOperand(idx).set(value);
348  }
349 
350  /// Erase the operand at position `idx`.
351  void eraseOperand(unsigned idx) { eraseOperands(idx); }
352 
353  /// Erase the operands starting at position `idx` and ending at position
354  /// 'idx'+'length'.
355  void eraseOperands(unsigned idx, unsigned length = 1) {
356  getOperandStorage().eraseOperands(idx, length);
357  }
358 
359  /// Erases the operands that have their corresponding bit set in
360  /// `eraseIndices` and removes them from the operand list.
361  void eraseOperands(const BitVector &eraseIndices) {
362  getOperandStorage().eraseOperands(eraseIndices);
363  }
364 
365  // Support operand iteration.
367  using operand_iterator = operand_range::iterator;
368 
371 
372  /// Returns an iterator on the underlying Value's.
375  return OperandRange(operands.data(), operands.size());
376  }
377 
379  return LLVM_LIKELY(hasOperandStorage) ? getOperandStorage().getOperands()
381  }
382 
383  OpOperand &getOpOperand(unsigned idx) {
384  return getOperandStorage().getOperands()[idx];
385  }
386 
387  // Support operand type iteration.
393 
394  //===--------------------------------------------------------------------===//
395  // Results
396  //===--------------------------------------------------------------------===//
397 
398  /// Return the number of results held by this operation.
399  unsigned getNumResults() { return numResults; }
400 
401  /// Get the 'idx'th result of this operation.
402  OpResult getResult(unsigned idx) { return OpResult(getOpResultImpl(idx)); }
403 
404  /// Support result iteration.
406  using result_iterator = result_range::iterator;
407 
408  result_iterator result_begin() { return getResults().begin(); }
409  result_iterator result_end() { return getResults().end(); }
411  return numResults == 0 ? result_range(nullptr, 0)
412  : result_range(getInlineOpResult(0), numResults);
413  }
414 
416  OpResult getOpResult(unsigned idx) { return getResult(idx); }
417 
418  /// Support result type iteration.
424 
425  //===--------------------------------------------------------------------===//
426  // Attributes
427  //===--------------------------------------------------------------------===//
428 
429  // Operations may optionally carry a list of attributes that associate
430  // constants to names. Attributes may be dynamically added and removed over
431  // the lifetime of an operation.
432 
433  /// Access an inherent attribute by name: returns an empty optional if there
434  /// is no inherent attribute with this name.
435  ///
436  /// This method is available as a transient facility in the migration process
437  /// to use Properties instead.
438  std::optional<Attribute> getInherentAttr(StringRef name);
439 
440  /// Set an inherent attribute by name.
441  ///
442  /// This method is available as a transient facility in the migration process
443  /// to use Properties instead.
444  void setInherentAttr(StringAttr name, Attribute value);
445 
446  /// Access a discardable attribute by name, returns an null Attribute if the
447  /// discardable attribute does not exist.
448  Attribute getDiscardableAttr(StringRef name) { return attrs.get(name); }
449 
450  /// Access a discardable attribute by name, returns an null Attribute if the
451  /// discardable attribute does not exist.
452  Attribute getDiscardableAttr(StringAttr name) { return attrs.get(name); }
453 
454  /// Set a discardable attribute by name.
455  void setDiscardableAttr(StringAttr name, Attribute value) {
456  NamedAttrList attributes(attrs);
457  if (attributes.set(name, value) != value)
458  attrs = attributes.getDictionary(getContext());
459  }
460 
461  /// Return all of the discardable attributes on this operation.
462  ArrayRef<NamedAttribute> getDiscardableAttrs() { return attrs.getValue(); }
463 
464  /// Return all of the discardable attributes on this operation as a
465  /// DictionaryAttr.
466  DictionaryAttr getDiscardableAttrDictionary() { return attrs; }
467 
468  /// Return all of the attributes on this operation.
470  if (!getPropertiesStorage())
471  return getDiscardableAttrs();
472  return getAttrDictionary().getValue();
473  }
474 
475  /// Return all of the attributes on this operation as a DictionaryAttr.
476  DictionaryAttr getAttrDictionary();
477 
478  /// Set the attributes from a dictionary on this operation.
479  /// These methods are expensive: if the dictionnary only contains discardable
480  /// attributes, `setDiscardableAttrs` is more efficient.
481  void setAttrs(DictionaryAttr newAttrs);
482  void setAttrs(ArrayRef<NamedAttribute> newAttrs);
483  /// Set the discardable attribute dictionary on this operation.
484  void setDiscardableAttrs(DictionaryAttr newAttrs) {
485  assert(newAttrs && "expected valid attribute dictionary");
486  attrs = newAttrs;
487  }
490  }
491 
492  /// Return the specified attribute if present, null otherwise.
493  /// These methods are expensive: if the dictionnary only contains discardable
494  /// attributes, `getDiscardableAttr` is more efficient.
495  Attribute getAttr(StringAttr name) {
496  if (getPropertiesStorageSize()) {
497  if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
498  return *inherentAttr;
499  }
500  return attrs.get(name);
501  }
502  Attribute getAttr(StringRef name) {
503  if (getPropertiesStorageSize()) {
504  if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
505  return *inherentAttr;
506  }
507  return attrs.get(name);
508  }
509 
510  template <typename AttrClass>
511  AttrClass getAttrOfType(StringAttr name) {
512  return llvm::dyn_cast_or_null<AttrClass>(getAttr(name));
513  }
514  template <typename AttrClass>
515  AttrClass getAttrOfType(StringRef name) {
516  return llvm::dyn_cast_or_null<AttrClass>(getAttr(name));
517  }
518 
519  /// Return true if the operation has an attribute with the provided name,
520  /// false otherwise.
521  bool hasAttr(StringAttr name) {
522  if (getPropertiesStorageSize()) {
523  if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
524  return (bool)*inherentAttr;
525  }
526  return attrs.contains(name);
527  }
528  bool hasAttr(StringRef name) {
529  if (getPropertiesStorageSize()) {
530  if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
531  return (bool)*inherentAttr;
532  }
533  return attrs.contains(name);
534  }
535  template <typename AttrClass, typename NameT>
536  bool hasAttrOfType(NameT &&name) {
537  return static_cast<bool>(
538  getAttrOfType<AttrClass>(std::forward<NameT>(name)));
539  }
540 
541  /// If the an attribute exists with the specified name, change it to the new
542  /// value. Otherwise, add a new attribute with the specified name/value.
543  void setAttr(StringAttr name, Attribute value) {
544  if (getPropertiesStorageSize()) {
545  if (getInherentAttr(name)) {
546  setInherentAttr(name, value);
547  return;
548  }
549  }
550  NamedAttrList attributes(attrs);
551  if (attributes.set(name, value) != value)
552  attrs = attributes.getDictionary(getContext());
553  }
554  void setAttr(StringRef name, Attribute value) {
555  setAttr(StringAttr::get(getContext(), name), value);
556  }
557 
558  /// Remove the attribute with the specified name if it exists. Return the
559  /// attribute that was erased, or nullptr if there was no attribute with such
560  /// name.
561  Attribute removeAttr(StringAttr name) {
562  if (getPropertiesStorageSize()) {
563  if (std::optional<Attribute> inherentAttr = getInherentAttr(name)) {
564  setInherentAttr(name, {});
565  return *inherentAttr;
566  }
567  }
568  NamedAttrList attributes(attrs);
569  Attribute removedAttr = attributes.erase(name);
570  if (removedAttr)
571  attrs = attributes.getDictionary(getContext());
572  return removedAttr;
573  }
574  Attribute removeAttr(StringRef name) {
575  return removeAttr(StringAttr::get(getContext(), name));
576  }
577 
578  /// A utility iterator that filters out non-dialect attributes.
580  : public llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
581  bool (*)(NamedAttribute)> {
582  static bool filter(NamedAttribute attr) {
583  // Dialect attributes are prefixed by the dialect name, like operations.
584  return attr.getName().strref().count('.');
585  }
586 
589  : llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
590  bool (*)(NamedAttribute)>(it, end, &filter) {}
591 
592  // Allow access to the constructor.
593  friend Operation;
594  };
596 
597  /// Return a range corresponding to the dialect attributes for this operation.
599  auto attrs = getAttrs();
600  return {dialect_attr_iterator(attrs.begin(), attrs.end()),
601  dialect_attr_iterator(attrs.end(), attrs.end())};
602  }
604  auto attrs = getAttrs();
605  return dialect_attr_iterator(attrs.begin(), attrs.end());
606  }
608  auto attrs = getAttrs();
609  return dialect_attr_iterator(attrs.end(), attrs.end());
610  }
611 
612  /// Set the dialect attributes for this operation, and preserve all inherent.
613  template <typename DialectAttrT>
614  void setDialectAttrs(DialectAttrT &&dialectAttrs) {
615  NamedAttrList attrs;
616  attrs.append(std::begin(dialectAttrs), std::end(dialectAttrs));
617  for (auto attr : getAttrs())
618  if (!attr.getName().strref().contains('.'))
619  attrs.push_back(attr);
621  }
622 
623  /// Sets default attributes on unset attributes.
626  name.populateDefaultAttrs(attrs);
628  }
629 
630  //===--------------------------------------------------------------------===//
631  // Blocks
632  //===--------------------------------------------------------------------===//
633 
634  /// Returns the number of regions held by this operation.
635  unsigned getNumRegions() { return numRegions; }
636 
637  /// Returns the regions held by this operation.
639  // Check the count first, as computing the trailing objects can be slow.
640  if (numRegions == 0)
641  return MutableArrayRef<Region>();
642 
643  auto *regions = getTrailingObjects<Region>();
644  return {regions, numRegions};
645  }
646 
647  /// Returns the region held by this operation at position 'index'.
648  Region &getRegion(unsigned index) {
649  assert(index < numRegions && "invalid region index");
650  return getRegions()[index];
651  }
652 
653  //===--------------------------------------------------------------------===//
654  // Successors
655  //===--------------------------------------------------------------------===//
656 
658  return {getTrailingObjects<BlockOperand>(), numSuccs};
659  }
660 
661  // Successor iteration.
662  using succ_iterator = SuccessorRange::iterator;
666 
667  bool hasSuccessors() { return numSuccs != 0; }
668  unsigned getNumSuccessors() { return numSuccs; }
669 
670  Block *getSuccessor(unsigned index) {
671  assert(index < getNumSuccessors());
672  return getBlockOperands()[index].get();
673  }
674  void setSuccessor(Block *block, unsigned index);
675 
676  //===--------------------------------------------------------------------===//
677  // Accessors for various properties of operations
678  //===--------------------------------------------------------------------===//
679 
680  /// Attempt to fold this operation with the specified constant operand values
681  /// - the elements in "operands" will correspond directly to the operands of
682  /// the operation, but may be null if non-constant.
683  ///
684  /// If folding was successful, this function returns "success".
685  /// * If this operation was modified in-place (but not folded away),
686  /// `results` is empty.
687  /// * Otherwise, `results` is filled with the folded results.
688  /// If folding was unsuccessful, this function returns "failure".
691 
692  /// Attempt to fold this operation.
693  ///
694  /// If folding was successful, this function returns "success".
695  /// * If this operation was modified in-place (but not folded away),
696  /// `results` is empty.
697  /// * Otherwise, `results` is filled with the folded results.
698  /// If folding was unsuccessful, this function returns "failure".
700 
701  /// Returns true if `InterfaceT` has been promised by the dialect or
702  /// implemented.
703  template <typename InterfaceT>
705  return name.hasPromiseOrImplementsInterface<InterfaceT>();
706  }
707 
708  /// Returns true if the operation was registered with a particular trait, e.g.
709  /// hasTrait<OperandsAreSignlessIntegerLike>().
710  template <template <typename T> class Trait>
711  bool hasTrait() {
712  return name.hasTrait<Trait>();
713  }
714 
715  /// Returns true if the operation *might* have the provided trait. This
716  /// means that either the operation is unregistered, or it was registered with
717  /// the provide trait.
718  template <template <typename T> class Trait>
719  bool mightHaveTrait() {
720  return name.mightHaveTrait<Trait>();
721  }
722 
723  //===--------------------------------------------------------------------===//
724  // Operation Walkers
725  //===--------------------------------------------------------------------===//
726 
727  /// Walk the operation by calling the callback for each nested operation
728  /// (including this one), block or region, depending on the callback provided.
729  /// The order in which regions, blocks and operations at the same nesting
730  /// level are visited (e.g., lexicographical or reverse lexicographical order)
731  /// is determined by 'Iterator'. The walk order for enclosing regions, blocks
732  /// and operations with respect to their nested ones is specified by 'Order'
733  /// (post-order by default). A callback on a block or operation is allowed to
734  /// erase that block or operation if either:
735  /// * the walk is in post-order, or
736  /// * the walk is in pre-order and the walk is skipped after the erasure.
737  ///
738  /// The callback method can take any of the following forms:
739  /// void(Operation*) : Walk all operations opaquely.
740  /// * op->walk([](Operation *nestedOp) { ...});
741  /// void(OpT) : Walk all operations of the given derived type.
742  /// * op->walk([](ReturnOp returnOp) { ...});
743  /// WalkResult(Operation*|OpT) : Walk operations, but allow for
744  /// interruption/skipping.
745  /// * op->walk([](... op) {
746  /// // Skip the walk of this op based on some invariant.
747  /// if (some_invariant)
748  /// return WalkResult::skip();
749  /// // Interrupt, i.e cancel, the walk based on some invariant.
750  /// if (another_invariant)
751  /// return WalkResult::interrupt();
752  /// return WalkResult::advance();
753  /// });
754  template <WalkOrder Order = WalkOrder::PostOrder,
755  typename Iterator = ForwardIterator, typename FnT,
756  typename RetT = detail::walkResultType<FnT>>
757  std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 1,
758  RetT>
759  walk(FnT &&callback) {
760  return detail::walk<Order, Iterator>(this, std::forward<FnT>(callback));
761  }
762 
763  /// Generic walker with a stage aware callback. Walk the operation by calling
764  /// the callback for each nested operation (including this one) N+1 times,
765  /// where N is the number of regions attached to that operation.
766  ///
767  /// The callback method can take any of the following forms:
768  /// void(Operation *, const WalkStage &) : Walk all operation opaquely
769  /// * op->walk([](Operation *nestedOp, const WalkStage &stage) { ...});
770  /// void(OpT, const WalkStage &) : Walk all operations of the given derived
771  /// type.
772  /// * op->walk([](ReturnOp returnOp, const WalkStage &stage) { ...});
773  /// WalkResult(Operation*|OpT, const WalkStage &stage) : Walk operations,
774  /// but allow for interruption/skipping.
775  /// * op->walk([](... op, const WalkStage &stage) {
776  /// // Skip the walk of this op based on some invariant.
777  /// if (some_invariant)
778  /// return WalkResult::skip();
779  /// // Interrupt, i.e cancel, the walk based on some invariant.
780  /// if (another_invariant)
781  /// return WalkResult::interrupt();
782  /// return WalkResult::advance();
783  /// });
784  template <typename FnT, typename RetT = detail::walkResultType<FnT>>
785  std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 2,
786  RetT>
787  walk(FnT &&callback) {
788  return detail::walk(this, std::forward<FnT>(callback));
789  }
790 
791  //===--------------------------------------------------------------------===//
792  // Uses
793  //===--------------------------------------------------------------------===//
794 
795  /// Drop all uses of results of this operation.
796  void dropAllUses() {
797  for (OpResult result : getOpResults())
798  result.dropAllUses();
799  }
800 
803 
806 
807  /// Returns a range of all uses, which is useful for iterating over all uses.
809 
810  /// Returns true if this operation has exactly one use.
811  bool hasOneUse() { return llvm::hasSingleElement(getUses()); }
812 
813  /// Returns true if this operation has no uses.
814  bool use_empty() { return getResults().use_empty(); }
815 
816  /// Returns true if the results of this operation are used outside of the
817  /// given block.
819  return llvm::any_of(getOpResults(), [block](OpResult result) {
820  return result.isUsedOutsideOfBlock(block);
821  });
822  }
823 
824  //===--------------------------------------------------------------------===//
825  // Users
826  //===--------------------------------------------------------------------===//
827 
830 
833 
834  /// Returns a range of all users.
835  user_range getUsers() { return {user_begin(), user_end()}; }
836 
837  //===--------------------------------------------------------------------===//
838  // Other
839  //===--------------------------------------------------------------------===//
840 
841  /// Emit an error with the op name prefixed, like "'dim' op " which is
842  /// convenient for verifiers.
843  InFlightDiagnostic emitOpError(const Twine &message = {});
844 
845  /// Emit an error about fatal conditions with this operation, reporting up to
846  /// any diagnostic handlers that may be listening.
847  InFlightDiagnostic emitError(const Twine &message = {});
848 
849  /// Emit a warning about this operation, reporting up to any diagnostic
850  /// handlers that may be listening.
851  InFlightDiagnostic emitWarning(const Twine &message = {});
852 
853  /// Emit a remark about this operation, reporting up to any diagnostic
854  /// handlers that may be listening.
855  InFlightDiagnostic emitRemark(const Twine &message = {});
856 
857  /// Returns the properties storage size.
859  return ((int)propertiesStorageSize) * 8;
860  }
861  /// Returns the properties storage.
863  if (propertiesStorageSize)
864  return {
865  reinterpret_cast<void *>(getTrailingObjects<detail::OpProperties>())};
866  return {nullptr};
867  }
869  if (propertiesStorageSize)
870  return {reinterpret_cast<void *>(const_cast<detail::OpProperties *>(
871  getTrailingObjects<detail::OpProperties>()))};
872  return {nullptr};
873  }
874 
875  /// Return the properties converted to an attribute.
876  /// This is expensive, and mostly useful when dealing with unregistered
877  /// operation. Returns an empty attribute if no properties are present.
879 
880  /// Set the properties from the provided attribute.
881  /// This is an expensive operation that can fail if the attribute is not
882  /// matching the expectations of the properties for this operation. This is
883  /// mostly useful for unregistered operations or used when parsing the
884  /// generic format. An optional diagnostic can be passed in for richer errors.
887  function_ref<InFlightDiagnostic &()> getDiag);
888 
889  /// Copy properties from an existing other properties object. The two objects
890  /// must be the same type.
892 
893  /// Compute a hash for the op properties (if any).
894  llvm::hash_code hashProperties();
895 
896 private:
897  //===--------------------------------------------------------------------===//
898  // Ordering
899  //===--------------------------------------------------------------------===//
900 
901  /// This value represents an invalid index ordering for an operation within a
902  /// block.
903  static constexpr unsigned kInvalidOrderIdx = -1;
904 
905  /// This value represents the stride to use when computing a new order for an
906  /// operation.
907  static constexpr unsigned kOrderStride = 5;
908 
909  /// Update the order index of this operation of this operation if necessary,
910  /// potentially recomputing the order of the parent block.
911  void updateOrderIfNecessary();
912 
913  /// Returns true if this operation has a valid order.
914  bool hasValidOrder() { return orderIndex != kInvalidOrderIdx; }
915 
916 private:
917  Operation(Location location, OperationName name, unsigned numResults,
918  unsigned numSuccessors, unsigned numRegions,
919  int propertiesStorageSize, DictionaryAttr attributes,
920  OpaqueProperties properties, bool hasOperandStorage);
921 
922  // Operations are deleted through the destroy() member because they are
923  // allocated with malloc.
924  ~Operation();
925 
926  /// Returns the additional size necessary for allocating the given objects
927  /// before an Operation in-memory.
928  static size_t prefixAllocSize(unsigned numOutOfLineResults,
929  unsigned numInlineResults) {
930  return sizeof(detail::OutOfLineOpResult) * numOutOfLineResults +
931  sizeof(detail::InlineOpResult) * numInlineResults;
932  }
933  /// Returns the additional size allocated before this Operation in-memory.
934  size_t prefixAllocSize() {
935  unsigned numResults = getNumResults();
936  unsigned numOutOfLineResults = OpResult::getNumTrailing(numResults);
937  unsigned numInlineResults = OpResult::getNumInline(numResults);
938  return prefixAllocSize(numOutOfLineResults, numInlineResults);
939  }
940 
941  /// Returns the operand storage object.
942  detail::OperandStorage &getOperandStorage() {
943  assert(hasOperandStorage && "expected operation to have operand storage");
944  return *getTrailingObjects<detail::OperandStorage>();
945  }
946 
947  /// Returns a pointer to the use list for the given out-of-line result.
948  detail::OutOfLineOpResult *getOutOfLineOpResult(unsigned resultNumber) {
949  // Out-of-line results are stored in reverse order after (before in memory)
950  // the inline results.
951  return reinterpret_cast<detail::OutOfLineOpResult *>(getInlineOpResult(
953  ++resultNumber;
954  }
955 
956  /// Returns a pointer to the use list for the given inline result.
957  detail::InlineOpResult *getInlineOpResult(unsigned resultNumber) {
958  // Inline results are stored in reverse order before the operation in
959  // memory.
960  return reinterpret_cast<detail::InlineOpResult *>(this) - ++resultNumber;
961  }
962 
963  /// Returns a pointer to the use list for the given result, which may be
964  /// either inline or out-of-line.
965  detail::OpResultImpl *getOpResultImpl(unsigned resultNumber) {
966  assert(resultNumber < getNumResults() &&
967  "Result number is out of range for operation");
968  unsigned maxInlineResults = detail::OpResultImpl::getMaxInlineResults();
969  if (resultNumber < maxInlineResults)
970  return getInlineOpResult(resultNumber);
971  return getOutOfLineOpResult(resultNumber - maxInlineResults);
972  }
973 
974  /// Provide a 'getParent' method for ilist_node_with_parent methods.
975  /// We mark it as a const function because ilist_node_with_parent specifically
976  /// requires a 'getParent() const' method. Once ilist_node removes this
977  /// constraint, we should drop the const to fit the rest of the MLIR const
978  /// model.
979  Block *getParent() const { return block; }
980 
981  /// Expose a few methods explicitly for the debugger to call for
982  /// visualization.
983 #ifndef NDEBUG
984  LLVM_DUMP_METHOD operand_range debug_getOperands() { return getOperands(); }
985  LLVM_DUMP_METHOD result_range debug_getResults() { return getResults(); }
986  LLVM_DUMP_METHOD SuccessorRange debug_getSuccessors() {
987  return getSuccessors();
988  }
989  LLVM_DUMP_METHOD MutableArrayRef<Region> debug_getRegions() {
990  return getRegions();
991  }
992 #endif
993 
994  /// The operation block that contains this operation.
995  Block *block = nullptr;
996 
997  /// This holds information about the source location the operation was defined
998  /// or derived from.
999  Location location;
1000 
1001  /// Relative order of this operation in its parent block. Used for
1002  /// O(1) local dominance checks between operations.
1003  mutable unsigned orderIndex = 0;
1004 
1005  const unsigned numResults;
1006  const unsigned numSuccs;
1007  const unsigned numRegions : 23;
1008 
1009  /// This bit signals whether this operation has an operand storage or not. The
1010  /// operand storage may be elided for operations that are known to never have
1011  /// operands.
1012  bool hasOperandStorage : 1;
1013 
1014  /// The size of the storage for properties (if any), divided by 8: since the
1015  /// Properties storage will always be rounded up to the next multiple of 8 we
1016  /// save some bits here.
1017  unsigned char propertiesStorageSize : 8;
1018  /// This is the maximum size we support to allocate properties inline with an
1019  /// operation: this must match the bitwidth above.
1020  static constexpr int64_t propertiesCapacity = 8 * 256;
1021 
1022  /// This holds the name of the operation.
1023  OperationName name;
1024 
1025  /// This holds general named attributes for the operation.
1026  DictionaryAttr attrs;
1027 
1028  // allow ilist_traits access to 'block' field.
1029  friend struct llvm::ilist_traits<Operation>;
1030 
1031  // allow block to access the 'orderIndex' field.
1032  friend class Block;
1033 
1034  // allow value to access the 'ResultStorage' methods.
1035  friend class Value;
1036 
1037  // allow ilist_node_with_parent to access the 'getParent' method.
1038  friend class llvm::ilist_node_with_parent<Operation, Block>;
1039 
1040  // This stuff is used by the TrailingObjects template.
1041  friend llvm::TrailingObjects<Operation, detail::OperandStorage,
1043  OpOperand>;
1044  size_t numTrailingObjects(OverloadToken<detail::OperandStorage>) const {
1045  return hasOperandStorage ? 1 : 0;
1046  }
1047  size_t numTrailingObjects(OverloadToken<BlockOperand>) const {
1048  return numSuccs;
1049  }
1050  size_t numTrailingObjects(OverloadToken<Region>) const { return numRegions; }
1051  size_t numTrailingObjects(OverloadToken<detail::OpProperties>) const {
1052  return getPropertiesStorageSize();
1053  }
1054 };
1055 
1056 inline raw_ostream &operator<<(raw_ostream &os, const Operation &op) {
1057  const_cast<Operation &>(op).print(os, OpPrintingFlags().useLocalScope());
1058  return os;
1059 }
1060 
1061 } // namespace mlir
1062 
1063 namespace llvm {
1064 /// Cast from an (const) Operation * to a derived operation type.
1065 template <typename T>
1067  : public ValueFromPointerCast<T, ::mlir::Operation,
1068  CastInfo<T, ::mlir::Operation *>> {
1069  static bool isPossible(::mlir::Operation *op) { return T::classof(op); }
1070 };
1071 template <typename T>
1072 struct CastInfo<T, const ::mlir::Operation *>
1073  : public ConstStrippingForwardingCast<T, const ::mlir::Operation *,
1074  CastInfo<T, ::mlir::Operation *>> {};
1075 
1076 /// Cast from an (const) Operation & to a derived operation type.
1077 template <typename T>
1079  : public NullableValueCastFailed<T>,
1080  public DefaultDoCastIfPossible<T, ::mlir::Operation &,
1081  CastInfo<T, ::mlir::Operation>> {
1082  // Provide isPossible here because here we have the const-stripping from
1083  // ConstStrippingCast.
1084  static bool isPossible(::mlir::Operation &val) { return T::classof(&val); }
1085  static T doCast(::mlir::Operation &val) { return T(&val); }
1086 };
1087 template <typename T>
1088 struct CastInfo<T, const ::mlir::Operation>
1089  : public ConstStrippingForwardingCast<T, const ::mlir::Operation,
1090  CastInfo<T, ::mlir::Operation>> {};
1091 
1092 /// Cast (const) Operation * to itself. This is helpful to avoid SFINAE in
1093 /// templated implementations that should work on both base and derived
1094 /// operation types.
1095 template <>
1097  : public NullableValueCastFailed<::mlir::Operation *>,
1098  public DefaultDoCastIfPossible<
1099  ::mlir::Operation *, ::mlir::Operation *,
1100  CastInfo<::mlir::Operation *, ::mlir::Operation *>> {
1101  static bool isPossible(::mlir::Operation *op) { return true; }
1102  static ::mlir::Operation *doCast(::mlir::Operation *op) { return op; }
1103 };
1104 template <>
1105 struct CastInfo<const ::mlir::Operation *, const ::mlir::Operation *>
1107  const ::mlir::Operation *, const ::mlir::Operation *,
1108  CastInfo<::mlir::Operation *, ::mlir::Operation *>> {};
1109 } // namespace llvm
1110 
1111 #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:533
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: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:150
void set(IRValueT newValue)
Set the current value being used by this operand.
Definition: UseDefLists.h:153
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:198
StringAttr getName() const
Return the name of the attribute.
Definition: Attributes.cpp:49
This class represents an operand of an operation.
Definition: Value.h:261
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:250
This is a value defined by a result of an operation.
Definition: Value.h:448
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:648
static CloneOptions all()
Returns an instance with all flags set to true.
Definition: Operation.cpp:654
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:658
CloneOptions & cloneOperands(bool enable=true)
Configures whether operation' operands should be cloned.
Definition: Operation.cpp:663
A utility iterator that filters out non-dialect attributes.
Definition: Operation.h:581
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
AttrClass getAttrOfType(StringRef name)
Definition: Operation.h:515
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:344
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:361
Attribute getDiscardableAttr(StringRef name)
Access a discardable attribute by name, returns an null Attribute if the discardable attribute does n...
Definition: Operation.h:448
void replaceUsesOfWith(Value from, Value to)
Replace any uses of 'from' with 'to' within this operation.
Definition: Operation.cpp:226
ArrayRef< NamedAttribute > getDiscardableAttrs()
Return all of the discardable attributes on this operation.
Definition: Operation.h:462
DictionaryAttr getAttrDictionary()
Return all of the attributes on this operation as a DictionaryAttr.
Definition: Operation.cpp:295
ResultRange result_range
Support result iteration.
Definition: Operation.h:405
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Attempt to fold this operation with the specified constant operand values.
Definition: Operation.cpp:610
bool use_empty()
Returns true if this operation has no uses.
Definition: Operation.h:814
Value getOperand(unsigned idx)
Definition: Operation.h:345
OpResult getOpResult(unsigned idx)
Definition: Operation.h:416
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Definition: Operation.h:711
Operation * cloneWithoutRegions()
Create a partial copy of this operation without traversing into attached regions.
Definition: Operation.cpp:676
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:255
void dropAllUses()
Drop all uses of results of this operation.
Definition: Operation.h:796
AttrClass getAttrOfType(StringAttr name)
Definition: Operation.h:511
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
Definition: Operation.h:495
bool hasAttr(StringRef name)
Definition: Operation.h:528
OpOperand & getOpOperand(unsigned idx)
Definition: Operation.h:383
bool hasAttrOfType(NameT &&name)
Definition: Operation.h:536
void setOperand(unsigned idx, Value value)
Definition: Operation.h:346
Block * getSuccessor(unsigned index)
Definition: Operation.h:670
void setAttrs(DictionaryAttr newAttrs)
Set the attributes from a dictionary on this operation.
Definition: Operation.cpp:304
bool hasAttr(StringAttr name)
Return true if the operation has an attribute with the provided name, false otherwise.
Definition: Operation.h:521
OpaqueProperties getPropertiesStorage() const
Definition: Operation.h:868
unsigned getNumSuccessors()
Definition: Operation.h:668
bool isBeforeInBlock(Operation *other)
Given an operation 'other' that is within the same parent block, return whether the current operation...
Definition: Operation.cpp:385
result_iterator result_begin()
Definition: Operation.h:408
void eraseOperands(unsigned idx, unsigned length=1)
Erase the operands starting at position idx and ending at position 'idx'+'length'.
Definition: Operation.h:355
void dropAllReferences()
This drops all operand uses from this operation, which is an essential step in breaking cyclic depend...
Definition: Operation.cpp:583
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:279
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:686
result_range::iterator result_iterator
Definition: Operation.h:406
operand_iterator operand_begin()
Definition: Operation.h:369
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
Definition: Operation.h:719
bool hasOneUse()
Returns true if this operation has exactly one use.
Definition: Operation.h:811
dialect_attr_iterator dialect_attr_begin()
Definition: Operation.h:603
Attribute getAttr(StringRef name)
Definition: Operation.h:502
user_iterator user_end()
Definition: Operation.h:832
void setDiscardableAttr(StringAttr name, Attribute value)
Set a discardable attribute by name.
Definition: Operation.h:455
Attribute removeAttr(StringRef name)
Definition: Operation.h:574
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition: Operation.h:402
use_iterator use_begin()
Definition: Operation.h:804
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:759
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:340
void print(raw_ostream &os, const OpPrintingFlags &flags=std::nullopt)
operand_type_iterator operand_type_end()
Definition: Operation.h:391
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:635
void setDialectAttrs(DialectAttrT &&dialectAttrs)
Set the dialect attributes for this operation, and preserve all inherent.
Definition: Operation.h:614
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:351
bool hasPromiseOrImplementsInterface() const
Returns true if InterfaceT has been promised by the dialect or implemented.
Definition: Operation.h:704
void dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
Definition: Operation.cpp:596
unsigned getNumOperands()
Definition: Operation.h:341
result_type_iterator result_type_end()
Definition: Operation.h:422
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:66
Attribute getPropertiesAsAttribute()
Return the properties converted to an attribute.
Definition: Operation.cpp:348
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:469
OperandRange operand_range
Definition: Operation.h:366
void populateDefaultAttrs()
Sets default attributes on unset attributes.
Definition: Operation.h:624
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:267
Block * getBlock()
Returns the operation block that contains this operation.
Definition: Operation.h:213
ValueUserIterator< use_iterator, OpOperand > user_iterator
Definition: Operation.h:828
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition: Operation.h:238
operand_iterator operand_end()
Definition: Operation.h:370
Attribute getDiscardableAttr(StringAttr name)
Access a discardable attribute by name, returns an null Attribute if the discardable attribute does n...
Definition: Operation.h:452
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
Definition: Operation.h:648
bool isUsedOutsideOfBlock(Block *block)
Returns true if the results of this operation are used outside of the given block.
Definition: Operation.h:818
result_type_iterator result_type_begin()
Definition: Operation.h:421
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
Definition: Operation.h:543
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:638
void destroy()
Destroys this operation and its subclass data.
Definition: Operation.cpp:207
LogicalResult setPropertiesFromAttribute(Attribute attr, function_ref< InFlightDiagnostic &()> getDiag)
Set the properties from the provided attribute.
Definition: Operation.cpp:354
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:466
void remove()
Remove the operation from its parent block, but don't delete it.
Definition: Operation.cpp:546
void setDiscardableAttrs(ArrayRef< NamedAttribute > newAttrs)
Definition: Operation.h:488
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
Definition: Operation.h:598
MutableArrayRef< BlockOperand > getBlockOperands()
Definition: Operation.h:657
bool hasSuccessors()
Definition: Operation.h:667
operand_type_range getOperandTypes()
Definition: Operation.h:392
result_iterator result_end()
Definition: Operation.h:409
MutableArrayRef< OpOperand > getOpOperands()
Definition: Operation.h:378
friend class Block
Definition: Operation.h:1032
result_type_range getResultTypes()
Definition: Operation.h:423
operand_range getOperands()
Returns an iterator on the underlying Value's.
Definition: Operation.h:373
void setSuccessor(Block *block, unsigned index)
Definition: Operation.cpp:604
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:554
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:236
user_range getUsers()
Returns a range of all users.
Definition: Operation.h:835
SuccessorRange getSuccessors()
Definition: Operation.h:665
result_range getOpResults()
Definition: Operation.h:415
Region * getParentRegion()
Returns the region to which the instruction belongs.
Definition: Operation.h:230
result_range getResults()
Definition: Operation.h:410
int getPropertiesStorageSize() const
Returns the properties storage size.
Definition: Operation.h:858
Attribute removeAttr(StringAttr name)
Remove the attribute with the specified name if it exists.
Definition: Operation.h:561
SuccessorRange::iterator succ_iterator
Definition: Operation.h:662
dialect_attr_iterator dialect_attr_end()
Definition: Operation.h:607
bool isProperAncestor(Operation *other)
Return true if this operation is a proper ancestor of the other operation.
Definition: Operation.cpp:218
use_range getUses()
Returns a range of all uses, which is useful for iterating over all uses.
Definition: Operation.h:808
void setAttr(StringRef name, Attribute value)
Definition: Operation.h:554
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening.
Definition: Operation.cpp:288
operand_range::iterator operand_iterator
Definition: Operation.h:367
user_iterator user_begin()
Definition: Operation.h:831
void setDiscardableAttrs(DictionaryAttr newAttrs)
Set the discardable attribute dictionary on this operation.
Definition: Operation.h:484
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:568
llvm::hash_code hashProperties()
Compute a hash for the op properties (if any).
Definition: Operation.cpp:369
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
Definition: Operation.cpp:640
succ_iterator successor_end()
Definition: Operation.h:664
OpaqueProperties getPropertiesStorage()
Returns the properties storage.
Definition: Operation.h:862
use_iterator use_end()
Definition: Operation.h:805
void erase()
Remove this operation from its parent block and delete it.
Definition: Operation.cpp:538
void copyProperties(OpaqueProperties rhs)
Copy properties from an existing other properties object.
Definition: Operation.cpp:365
succ_iterator successor_begin()
Definition: Operation.h:663
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:787
unsigned getNumResults()
Return the number of results held by this operation.
Definition: Operation.h:399
operand_type_iterator operand_type_begin()
Definition: Operation.h:390
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:336
This class implements the result iterators for the Operation class.
Definition: ValueRange.h:233
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:263
ValueTypeRange< ResultRange > type_range
Definition: ValueRange.h:244
use_iterator use_begin() const
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Definition: ValueRange.h:243
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:289
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:272
iterator_range< use_iterator > use_range
Definition: ValueRange.h:254
UseIterator use_iterator
Definition: ValueRange.h:253
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:372
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:334
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:381
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
OpProperties
This is a "tag" used for mapping the properties storage in llvm::TrailingObjects.
Definition: Operation.h:28
This header declares functions that assist transformations in the MemRef dialect.
WalkOrder
Traversal order for region, block and operation walk utilities.
Definition: Visitors.h:63
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:1085
static bool isPossible(::mlir::Operation &val)
Definition: Operation.h:1084
static bool isPossible(::mlir::Operation *op)
Definition: Operation.h:1069
::mlir::Operation * doCast(::mlir::Operation *op)
Definition: Operation.h:1102
static bool isPossible(::mlir::Operation *op)
Definition: Operation.h:1101
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.