MLIR  19.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  void setDiscardableAttr(StringRef name, Attribute value) {
462  }
463 
464  /// Remove the discardable attribute with the specified name if it exists.
465  /// Return the attribute that was erased, or nullptr if there was no attribute
466  /// with such name.
467  Attribute removeDiscardableAttr(StringAttr name) {
468  NamedAttrList attributes(attrs);
469  Attribute removedAttr = attributes.erase(name);
470  if (removedAttr)
471  attrs = attributes.getDictionary(getContext());
472  return removedAttr;
473  }
476  }
477 
478  /// Return a range of all of discardable attributes on this operation. Note
479  /// that for unregistered operations that are not storing inherent attributes
480  /// as properties, all attributes are considered discardable.
482  std::optional<RegisteredOperationName> opName = getRegisteredInfo();
483  ArrayRef<StringAttr> attributeNames =
484  opName ? getRegisteredInfo()->getAttributeNames()
486  return llvm::make_filter_range(
487  attrs.getValue(),
488  [this, attributeNames](const NamedAttribute attribute) {
489  return getPropertiesStorage() ||
490  !llvm::is_contained(attributeNames, attribute.getName());
491  });
492  }
493 
494  /// Return all of the discardable attributes on this operation as a
495  /// DictionaryAttr.
496  DictionaryAttr getDiscardableAttrDictionary() {
497  if (getPropertiesStorage())
498  return attrs;
500  llvm::to_vector(getDiscardableAttrs()));
501  }
502 
503  /// Return all attributes that are not stored as properties.
504  DictionaryAttr getRawDictionaryAttrs() { return attrs; }
505 
506  /// Return all of the attributes on this operation.
508 
509  /// Return all of the attributes on this operation as a DictionaryAttr.
510  DictionaryAttr getAttrDictionary();
511 
512  /// Set the attributes from a dictionary on this operation.
513  /// These methods are expensive: if the dictionnary only contains discardable
514  /// attributes, `setDiscardableAttrs` is more efficient.
515  void setAttrs(DictionaryAttr newAttrs);
516  void setAttrs(ArrayRef<NamedAttribute> newAttrs);
517  /// Set the discardable attribute dictionary on this operation.
518  void setDiscardableAttrs(DictionaryAttr newAttrs) {
519  assert(newAttrs && "expected valid attribute dictionary");
520  attrs = newAttrs;
521  }
524  }
525 
526  /// Return the specified attribute if present, null otherwise.
527  /// These methods are expensive: if the dictionnary only contains discardable
528  /// attributes, `getDiscardableAttr` is more efficient.
529  Attribute getAttr(StringAttr name) {
530  if (getPropertiesStorageSize()) {
531  if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
532  return *inherentAttr;
533  }
534  return attrs.get(name);
535  }
536  Attribute getAttr(StringRef name) {
537  if (getPropertiesStorageSize()) {
538  if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
539  return *inherentAttr;
540  }
541  return attrs.get(name);
542  }
543 
544  template <typename AttrClass>
545  AttrClass getAttrOfType(StringAttr name) {
546  return llvm::dyn_cast_or_null<AttrClass>(getAttr(name));
547  }
548  template <typename AttrClass>
549  AttrClass getAttrOfType(StringRef name) {
550  return llvm::dyn_cast_or_null<AttrClass>(getAttr(name));
551  }
552 
553  /// Return true if the operation has an attribute with the provided name,
554  /// false otherwise.
555  bool hasAttr(StringAttr name) {
556  if (getPropertiesStorageSize()) {
557  if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
558  return (bool)*inherentAttr;
559  }
560  return attrs.contains(name);
561  }
562  bool hasAttr(StringRef name) {
563  if (getPropertiesStorageSize()) {
564  if (std::optional<Attribute> inherentAttr = getInherentAttr(name))
565  return (bool)*inherentAttr;
566  }
567  return attrs.contains(name);
568  }
569  template <typename AttrClass, typename NameT>
570  bool hasAttrOfType(NameT &&name) {
571  return static_cast<bool>(
572  getAttrOfType<AttrClass>(std::forward<NameT>(name)));
573  }
574 
575  /// If the an attribute exists with the specified name, change it to the new
576  /// value. Otherwise, add a new attribute with the specified name/value.
577  void setAttr(StringAttr name, Attribute value) {
578  if (getPropertiesStorageSize()) {
579  if (getInherentAttr(name)) {
580  setInherentAttr(name, value);
581  return;
582  }
583  }
584  NamedAttrList attributes(attrs);
585  if (attributes.set(name, value) != value)
586  attrs = attributes.getDictionary(getContext());
587  }
588  void setAttr(StringRef name, Attribute value) {
589  setAttr(StringAttr::get(getContext(), name), value);
590  }
591 
592  /// Remove the attribute with the specified name if it exists. Return the
593  /// attribute that was erased, or nullptr if there was no attribute with such
594  /// name.
595  Attribute removeAttr(StringAttr name) {
596  if (getPropertiesStorageSize()) {
597  if (std::optional<Attribute> inherentAttr = getInherentAttr(name)) {
598  setInherentAttr(name, {});
599  return *inherentAttr;
600  }
601  }
602  NamedAttrList attributes(attrs);
603  Attribute removedAttr = attributes.erase(name);
604  if (removedAttr)
605  attrs = attributes.getDictionary(getContext());
606  return removedAttr;
607  }
608  Attribute removeAttr(StringRef name) {
609  return removeAttr(StringAttr::get(getContext(), name));
610  }
611 
612  /// A utility iterator that filters out non-dialect attributes.
614  : public llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
615  bool (*)(NamedAttribute)> {
616  static bool filter(NamedAttribute attr) {
617  // Dialect attributes are prefixed by the dialect name, like operations.
618  return attr.getName().strref().count('.');
619  }
620 
623  : llvm::filter_iterator<ArrayRef<NamedAttribute>::iterator,
624  bool (*)(NamedAttribute)>(it, end, &filter) {}
625 
626  // Allow access to the constructor.
627  friend Operation;
628  };
630 
631  /// Return a range corresponding to the dialect attributes for this operation.
633  auto attrs = getAttrs();
634  return {dialect_attr_iterator(attrs.begin(), attrs.end()),
635  dialect_attr_iterator(attrs.end(), attrs.end())};
636  }
638  auto attrs = getAttrs();
639  return dialect_attr_iterator(attrs.begin(), attrs.end());
640  }
642  auto attrs = getAttrs();
643  return dialect_attr_iterator(attrs.end(), attrs.end());
644  }
645 
646  /// Set the dialect attributes for this operation, and preserve all inherent.
647  template <typename DialectAttrT>
648  void setDialectAttrs(DialectAttrT &&dialectAttrs) {
649  NamedAttrList attrs;
650  attrs.append(std::begin(dialectAttrs), std::end(dialectAttrs));
651  for (auto attr : getAttrs())
652  if (!attr.getName().strref().contains('.'))
653  attrs.push_back(attr);
655  }
656 
657  /// Sets default attributes on unset attributes.
660  name.populateDefaultAttrs(attrs);
662  }
663 
664  //===--------------------------------------------------------------------===//
665  // Blocks
666  //===--------------------------------------------------------------------===//
667 
668  /// Returns the number of regions held by this operation.
669  unsigned getNumRegions() { return numRegions; }
670 
671  /// Returns the regions held by this operation.
673  // Check the count first, as computing the trailing objects can be slow.
674  if (numRegions == 0)
675  return MutableArrayRef<Region>();
676 
677  auto *regions = getTrailingObjects<Region>();
678  return {regions, numRegions};
679  }
680 
681  /// Returns the region held by this operation at position 'index'.
682  Region &getRegion(unsigned index) {
683  assert(index < numRegions && "invalid region index");
684  return getRegions()[index];
685  }
686 
687  //===--------------------------------------------------------------------===//
688  // Successors
689  //===--------------------------------------------------------------------===//
690 
692  return {getTrailingObjects<BlockOperand>(), numSuccs};
693  }
694 
695  // Successor iteration.
696  using succ_iterator = SuccessorRange::iterator;
700 
701  bool hasSuccessors() { return numSuccs != 0; }
702  unsigned getNumSuccessors() { return numSuccs; }
703 
704  Block *getSuccessor(unsigned index) {
705  assert(index < getNumSuccessors());
706  return getBlockOperands()[index].get();
707  }
708  void setSuccessor(Block *block, unsigned index);
709 
710  //===--------------------------------------------------------------------===//
711  // Accessors for various properties of operations
712  //===--------------------------------------------------------------------===//
713 
714  /// Attempt to fold this operation with the specified constant operand values
715  /// - the elements in "operands" will correspond directly to the operands of
716  /// the operation, but may be null if non-constant.
717  ///
718  /// If folding was successful, this function returns "success".
719  /// * If this operation was modified in-place (but not folded away),
720  /// `results` is empty.
721  /// * Otherwise, `results` is filled with the folded results.
722  /// If folding was unsuccessful, this function returns "failure".
725 
726  /// Attempt to fold this operation.
727  ///
728  /// If folding was successful, this function returns "success".
729  /// * If this operation was modified in-place (but not folded away),
730  /// `results` is empty.
731  /// * Otherwise, `results` is filled with the folded results.
732  /// If folding was unsuccessful, this function returns "failure".
734 
735  /// Returns true if `InterfaceT` has been promised by the dialect or
736  /// implemented.
737  template <typename InterfaceT>
739  return name.hasPromiseOrImplementsInterface<InterfaceT>();
740  }
741 
742  /// Returns true if the operation was registered with a particular trait, e.g.
743  /// hasTrait<OperandsAreSignlessIntegerLike>().
744  template <template <typename T> class Trait>
745  bool hasTrait() {
746  return name.hasTrait<Trait>();
747  }
748 
749  /// Returns true if the operation *might* have the provided trait. This
750  /// means that either the operation is unregistered, or it was registered with
751  /// the provide trait.
752  template <template <typename T> class Trait>
753  bool mightHaveTrait() {
754  return name.mightHaveTrait<Trait>();
755  }
756 
757  //===--------------------------------------------------------------------===//
758  // Operation Walkers
759  //===--------------------------------------------------------------------===//
760 
761  /// Walk the operation by calling the callback for each nested operation
762  /// (including this one), block or region, depending on the callback provided.
763  /// The order in which regions, blocks and operations at the same nesting
764  /// level are visited (e.g., lexicographical or reverse lexicographical order)
765  /// is determined by 'Iterator'. The walk order for enclosing regions, blocks
766  /// and operations with respect to their nested ones is specified by 'Order'
767  /// (post-order by default). A callback on a block or operation is allowed to
768  /// erase that block or operation if either:
769  /// * the walk is in post-order, or
770  /// * the walk is in pre-order and the walk is skipped after the erasure.
771  ///
772  /// The callback method can take any of the following forms:
773  /// void(Operation*) : Walk all operations opaquely.
774  /// * op->walk([](Operation *nestedOp) { ...});
775  /// void(OpT) : Walk all operations of the given derived type.
776  /// * op->walk([](ReturnOp returnOp) { ...});
777  /// WalkResult(Operation*|OpT) : Walk operations, but allow for
778  /// interruption/skipping.
779  /// * op->walk([](... op) {
780  /// // Skip the walk of this op based on some invariant.
781  /// if (some_invariant)
782  /// return WalkResult::skip();
783  /// // Interrupt, i.e cancel, the walk based on some invariant.
784  /// if (another_invariant)
785  /// return WalkResult::interrupt();
786  /// return WalkResult::advance();
787  /// });
788  template <WalkOrder Order = WalkOrder::PostOrder,
789  typename Iterator = ForwardIterator, typename FnT,
790  typename RetT = detail::walkResultType<FnT>>
791  std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 1,
792  RetT>
793  walk(FnT &&callback) {
794  return detail::walk<Order, Iterator>(this, std::forward<FnT>(callback));
795  }
796 
797  /// Generic walker with a stage aware callback. Walk the operation by calling
798  /// the callback for each nested operation (including this one) N+1 times,
799  /// where N is the number of regions attached to that operation.
800  ///
801  /// The callback method can take any of the following forms:
802  /// void(Operation *, const WalkStage &) : Walk all operation opaquely
803  /// * op->walk([](Operation *nestedOp, const WalkStage &stage) { ...});
804  /// void(OpT, const WalkStage &) : Walk all operations of the given derived
805  /// type.
806  /// * op->walk([](ReturnOp returnOp, const WalkStage &stage) { ...});
807  /// WalkResult(Operation*|OpT, const WalkStage &stage) : Walk operations,
808  /// but allow for interruption/skipping.
809  /// * op->walk([](... op, const WalkStage &stage) {
810  /// // Skip the walk of this op based on some invariant.
811  /// if (some_invariant)
812  /// return WalkResult::skip();
813  /// // Interrupt, i.e cancel, the walk based on some invariant.
814  /// if (another_invariant)
815  /// return WalkResult::interrupt();
816  /// return WalkResult::advance();
817  /// });
818  template <typename FnT, typename RetT = detail::walkResultType<FnT>>
819  std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 2,
820  RetT>
821  walk(FnT &&callback) {
822  return detail::walk(this, std::forward<FnT>(callback));
823  }
824 
825  //===--------------------------------------------------------------------===//
826  // Uses
827  //===--------------------------------------------------------------------===//
828 
829  /// Drop all uses of results of this operation.
830  void dropAllUses() {
831  for (OpResult result : getOpResults())
832  result.dropAllUses();
833  }
834 
837 
840 
841  /// Returns a range of all uses, which is useful for iterating over all uses.
843 
844  /// Returns true if this operation has exactly one use.
845  bool hasOneUse() { return llvm::hasSingleElement(getUses()); }
846 
847  /// Returns true if this operation has no uses.
848  bool use_empty() { return getResults().use_empty(); }
849 
850  /// Returns true if the results of this operation are used outside of the
851  /// given block.
853  return llvm::any_of(getOpResults(), [block](OpResult result) {
854  return result.isUsedOutsideOfBlock(block);
855  });
856  }
857 
858  //===--------------------------------------------------------------------===//
859  // Users
860  //===--------------------------------------------------------------------===//
861 
864 
867 
868  /// Returns a range of all users.
869  user_range getUsers() { return {user_begin(), user_end()}; }
870 
871  //===--------------------------------------------------------------------===//
872  // Other
873  //===--------------------------------------------------------------------===//
874 
875  /// Emit an error with the op name prefixed, like "'dim' op " which is
876  /// convenient for verifiers.
877  InFlightDiagnostic emitOpError(const Twine &message = {});
878 
879  /// Emit an error about fatal conditions with this operation, reporting up to
880  /// any diagnostic handlers that may be listening.
881  InFlightDiagnostic emitError(const Twine &message = {});
882 
883  /// Emit a warning about this operation, reporting up to any diagnostic
884  /// handlers that may be listening.
885  InFlightDiagnostic emitWarning(const Twine &message = {});
886 
887  /// Emit a remark about this operation, reporting up to any diagnostic
888  /// handlers that may be listening.
889  InFlightDiagnostic emitRemark(const Twine &message = {});
890 
891  /// Returns the properties storage size.
893  return ((int)propertiesStorageSize) * 8;
894  }
895  /// Returns the properties storage.
897  if (propertiesStorageSize)
898  return {
899  reinterpret_cast<void *>(getTrailingObjects<detail::OpProperties>())};
900  return {nullptr};
901  }
903  if (propertiesStorageSize)
904  return {reinterpret_cast<void *>(const_cast<detail::OpProperties *>(
905  getTrailingObjects<detail::OpProperties>()))};
906  return {nullptr};
907  }
908 
909  /// Return the properties converted to an attribute.
910  /// This is expensive, and mostly useful when dealing with unregistered
911  /// operation. Returns an empty attribute if no properties are present.
913 
914  /// Set the properties from the provided attribute.
915  /// This is an expensive operation that can fail if the attribute is not
916  /// matching the expectations of the properties for this operation. This is
917  /// mostly useful for unregistered operations or used when parsing the
918  /// generic format. An optional diagnostic can be passed in for richer errors.
922 
923  /// Copy properties from an existing other properties object. The two objects
924  /// must be the same type.
926 
927  /// Compute a hash for the op properties (if any).
928  llvm::hash_code hashProperties();
929 
930 private:
931  //===--------------------------------------------------------------------===//
932  // Ordering
933  //===--------------------------------------------------------------------===//
934 
935  /// This value represents an invalid index ordering for an operation within a
936  /// block.
937  static constexpr unsigned kInvalidOrderIdx = -1;
938 
939  /// This value represents the stride to use when computing a new order for an
940  /// operation.
941  static constexpr unsigned kOrderStride = 5;
942 
943  /// Update the order index of this operation of this operation if necessary,
944  /// potentially recomputing the order of the parent block.
945  void updateOrderIfNecessary();
946 
947  /// Returns true if this operation has a valid order.
948  bool hasValidOrder() { return orderIndex != kInvalidOrderIdx; }
949 
950 private:
951  Operation(Location location, OperationName name, unsigned numResults,
952  unsigned numSuccessors, unsigned numRegions,
953  int propertiesStorageSize, DictionaryAttr attributes,
954  OpaqueProperties properties, bool hasOperandStorage);
955 
956  // Operations are deleted through the destroy() member because they are
957  // allocated with malloc.
958  ~Operation();
959 
960  /// Returns the additional size necessary for allocating the given objects
961  /// before an Operation in-memory.
962  static size_t prefixAllocSize(unsigned numOutOfLineResults,
963  unsigned numInlineResults) {
964  return sizeof(detail::OutOfLineOpResult) * numOutOfLineResults +
965  sizeof(detail::InlineOpResult) * numInlineResults;
966  }
967  /// Returns the additional size allocated before this Operation in-memory.
968  size_t prefixAllocSize() {
969  unsigned numResults = getNumResults();
970  unsigned numOutOfLineResults = OpResult::getNumTrailing(numResults);
971  unsigned numInlineResults = OpResult::getNumInline(numResults);
972  return prefixAllocSize(numOutOfLineResults, numInlineResults);
973  }
974 
975  /// Returns the operand storage object.
976  detail::OperandStorage &getOperandStorage() {
977  assert(hasOperandStorage && "expected operation to have operand storage");
978  return *getTrailingObjects<detail::OperandStorage>();
979  }
980 
981  /// Returns a pointer to the use list for the given out-of-line result.
982  detail::OutOfLineOpResult *getOutOfLineOpResult(unsigned resultNumber) {
983  // Out-of-line results are stored in reverse order after (before in memory)
984  // the inline results.
985  return reinterpret_cast<detail::OutOfLineOpResult *>(getInlineOpResult(
987  ++resultNumber;
988  }
989 
990  /// Returns a pointer to the use list for the given inline result.
991  detail::InlineOpResult *getInlineOpResult(unsigned resultNumber) {
992  // Inline results are stored in reverse order before the operation in
993  // memory.
994  return reinterpret_cast<detail::InlineOpResult *>(this) - ++resultNumber;
995  }
996 
997  /// Returns a pointer to the use list for the given result, which may be
998  /// either inline or out-of-line.
999  detail::OpResultImpl *getOpResultImpl(unsigned resultNumber) {
1000  assert(resultNumber < getNumResults() &&
1001  "Result number is out of range for operation");
1002  unsigned maxInlineResults = detail::OpResultImpl::getMaxInlineResults();
1003  if (resultNumber < maxInlineResults)
1004  return getInlineOpResult(resultNumber);
1005  return getOutOfLineOpResult(resultNumber - maxInlineResults);
1006  }
1007 
1008  /// Provide a 'getParent' method for ilist_node_with_parent methods.
1009  /// We mark it as a const function because ilist_node_with_parent specifically
1010  /// requires a 'getParent() const' method. Once ilist_node removes this
1011  /// constraint, we should drop the const to fit the rest of the MLIR const
1012  /// model.
1013  Block *getParent() const { return block; }
1014 
1015  /// Expose a few methods explicitly for the debugger to call for
1016  /// visualization.
1017 #ifndef NDEBUG
1018  LLVM_DUMP_METHOD operand_range debug_getOperands() { return getOperands(); }
1019  LLVM_DUMP_METHOD result_range debug_getResults() { return getResults(); }
1020  LLVM_DUMP_METHOD SuccessorRange debug_getSuccessors() {
1021  return getSuccessors();
1022  }
1023  LLVM_DUMP_METHOD MutableArrayRef<Region> debug_getRegions() {
1024  return getRegions();
1025  }
1026 #endif
1027 
1028  /// The operation block that contains this operation.
1029  Block *block = nullptr;
1030 
1031  /// This holds information about the source location the operation was defined
1032  /// or derived from.
1033  Location location;
1034 
1035  /// Relative order of this operation in its parent block. Used for
1036  /// O(1) local dominance checks between operations.
1037  mutable unsigned orderIndex = 0;
1038 
1039  const unsigned numResults;
1040  const unsigned numSuccs;
1041  const unsigned numRegions : 23;
1042 
1043  /// This bit signals whether this operation has an operand storage or not. The
1044  /// operand storage may be elided for operations that are known to never have
1045  /// operands.
1046  bool hasOperandStorage : 1;
1047 
1048  /// The size of the storage for properties (if any), divided by 8: since the
1049  /// Properties storage will always be rounded up to the next multiple of 8 we
1050  /// save some bits here.
1051  unsigned char propertiesStorageSize : 8;
1052  /// This is the maximum size we support to allocate properties inline with an
1053  /// operation: this must match the bitwidth above.
1054  static constexpr int64_t propertiesCapacity = 8 * 256;
1055 
1056  /// This holds the name of the operation.
1057  OperationName name;
1058 
1059  /// This holds general named attributes for the operation.
1060  DictionaryAttr attrs;
1061 
1062  // allow ilist_traits access to 'block' field.
1063  friend struct llvm::ilist_traits<Operation>;
1064 
1065  // allow block to access the 'orderIndex' field.
1066  friend class Block;
1067 
1068  // allow value to access the 'ResultStorage' methods.
1069  friend class Value;
1070 
1071  // allow ilist_node_with_parent to access the 'getParent' method.
1072  friend class llvm::ilist_node_with_parent<Operation, Block>;
1073 
1074  // This stuff is used by the TrailingObjects template.
1075  friend llvm::TrailingObjects<Operation, detail::OperandStorage,
1077  OpOperand>;
1078  size_t numTrailingObjects(OverloadToken<detail::OperandStorage>) const {
1079  return hasOperandStorage ? 1 : 0;
1080  }
1081  size_t numTrailingObjects(OverloadToken<BlockOperand>) const {
1082  return numSuccs;
1083  }
1084  size_t numTrailingObjects(OverloadToken<Region>) const { return numRegions; }
1085  size_t numTrailingObjects(OverloadToken<detail::OpProperties>) const {
1086  return getPropertiesStorageSize();
1087  }
1088 };
1089 
1090 inline raw_ostream &operator<<(raw_ostream &os, const Operation &op) {
1091  const_cast<Operation &>(op).print(os, OpPrintingFlags().useLocalScope());
1092  return os;
1093 }
1094 
1095 } // namespace mlir
1096 
1097 namespace llvm {
1098 /// Cast from an (const) Operation * to a derived operation type.
1099 template <typename T>
1101  : public ValueFromPointerCast<T, ::mlir::Operation,
1102  CastInfo<T, ::mlir::Operation *>> {
1103  static bool isPossible(::mlir::Operation *op) { return T::classof(op); }
1104 };
1105 template <typename T>
1106 struct CastInfo<T, const ::mlir::Operation *>
1107  : public ConstStrippingForwardingCast<T, const ::mlir::Operation *,
1108  CastInfo<T, ::mlir::Operation *>> {};
1109 
1110 /// Cast from an (const) Operation & to a derived operation type.
1111 template <typename T>
1113  : public NullableValueCastFailed<T>,
1114  public DefaultDoCastIfPossible<T, ::mlir::Operation &,
1115  CastInfo<T, ::mlir::Operation>> {
1116  // Provide isPossible here because here we have the const-stripping from
1117  // ConstStrippingCast.
1118  static bool isPossible(::mlir::Operation &val) { return T::classof(&val); }
1119  static T doCast(::mlir::Operation &val) { return T(&val); }
1120 };
1121 template <typename T>
1122 struct CastInfo<T, const ::mlir::Operation>
1123  : public ConstStrippingForwardingCast<T, const ::mlir::Operation,
1124  CastInfo<T, ::mlir::Operation>> {};
1125 
1126 /// Cast (const) Operation * to itself. This is helpful to avoid SFINAE in
1127 /// templated implementations that should work on both base and derived
1128 /// operation types.
1129 template <>
1131  : public NullableValueCastFailed<::mlir::Operation *>,
1132  public DefaultDoCastIfPossible<
1133  ::mlir::Operation *, ::mlir::Operation *,
1134  CastInfo<::mlir::Operation *, ::mlir::Operation *>> {
1135  static bool isPossible(::mlir::Operation *op) { return true; }
1136  static ::mlir::Operation *doCast(::mlir::Operation *op) { return op; }
1137 };
1138 template <>
1139 struct CastInfo<const ::mlir::Operation *, const ::mlir::Operation *>
1141  const ::mlir::Operation *, const ::mlir::Operation *,
1142  CastInfo<::mlir::Operation *, ::mlir::Operation *>> {};
1143 } // namespace llvm
1144 
1145 #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: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: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:202
StringAttr getName() const
Return the name of the attribute.
Definition: Attributes.cpp:49
This class represents an operand of an operation.
Definition: Value.h:263
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:272
This is a value defined by a result of an operation.
Definition: Value.h:453
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:615
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
AttrClass getAttrOfType(StringRef name)
Definition: Operation.h:549
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: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: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:405
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:848
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:745
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:830
AttrClass getAttrOfType(StringAttr name)
Definition: Operation.h:545
Attribute getAttr(StringAttr name)
Return the specified attribute if present, null otherwise.
Definition: Operation.h:529
bool hasAttr(StringRef name)
Definition: Operation.h:562
OpOperand & getOpOperand(unsigned idx)
Definition: Operation.h:383
bool hasAttrOfType(NameT &&name)
Definition: Operation.h:570
void setOperand(unsigned idx, Value value)
Definition: Operation.h:346
Block * getSuccessor(unsigned index)
Definition: Operation.h:704
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:555
OpaqueProperties getPropertiesStorage() const
Definition: Operation.h:902
unsigned getNumSuccessors()
Definition: Operation.h:702
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: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: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:406
operand_iterator operand_begin()
Definition: Operation.h:369
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
Definition: Operation.h:753
bool hasOneUse()
Returns true if this operation has exactly one use.
Definition: Operation.h:845
dialect_attr_iterator dialect_attr_begin()
Definition: Operation.h:637
Attribute getAttr(StringRef name)
Definition: Operation.h:536
user_iterator user_end()
Definition: Operation.h:866
void setDiscardableAttr(StringAttr name, Attribute value)
Set a discardable attribute by name.
Definition: Operation.h:455
Attribute removeAttr(StringRef name)
Definition: Operation.h:608
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition: Operation.h:402
use_iterator use_begin()
Definition: Operation.h:838
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:793
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:391
Attribute removeDiscardableAttr(StringRef name)
Definition: Operation.h:474
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:669
void setDialectAttrs(DialectAttrT &&dialectAttrs)
Set the dialect attributes for this operation, and preserve all inherent.
Definition: Operation.h:648
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:738
DictionaryAttr getRawDictionaryAttrs()
Return all attributes that are not stored as properties.
Definition: Operation.h:504
void dropAllDefinedValueUses()
Drop uses of all values defined by this operation or its nested regions.
Definition: Operation.cpp:597
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: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:507
OperandRange operand_range
Definition: Operation.h:366
void populateDefaultAttrs()
Sets default attributes on unset attributes.
Definition: Operation.h:658
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:862
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:682
bool isUsedOutsideOfBlock(Block *block)
Returns true if the results of this operation are used outside of the given block.
Definition: Operation.h:852
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:577
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:672
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:481
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:496
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:522
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
Definition: Operation.h:632
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:691
bool hasSuccessors()
Definition: Operation.h:701
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:1066
result_type_range getResultTypes()
Definition: Operation.h:423
Attribute removeDiscardableAttr(StringAttr name)
Remove the discardable attribute with the specified name if it exists.
Definition: Operation.h:467
void setDiscardableAttr(StringRef name, Attribute value)
Definition: Operation.h:460
operand_range getOperands()
Returns an iterator on the underlying Value's.
Definition: Operation.h:373
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:869
SuccessorRange getSuccessors()
Definition: Operation.h:699
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:892
Attribute removeAttr(StringAttr name)
Remove the attribute with the specified name if it exists.
Definition: Operation.h:595
SuccessorRange::iterator succ_iterator
Definition: Operation.h:696
dialect_attr_iterator dialect_attr_end()
Definition: Operation.h:641
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:842
void setAttr(StringRef name, Attribute value)
Definition: Operation.h:588
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:367
user_iterator user_begin()
Definition: Operation.h:865
void setDiscardableAttrs(DictionaryAttr newAttrs)
Set the discardable attribute dictionary on this operation.
Definition: Operation.h:518
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:698
OpaqueProperties getPropertiesStorage()
Returns the properties storage.
Definition: Operation.h:896
use_iterator use_end()
Definition: Operation.h:839
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:697
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:821
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: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:386
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
Include the generated interface declarations.
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:1119
static bool isPossible(::mlir::Operation &val)
Definition: Operation.h:1118
static bool isPossible(::mlir::Operation *op)
Definition: Operation.h:1103
::mlir::Operation * doCast(::mlir::Operation *op)
Definition: Operation.h:1136
static bool isPossible(::mlir::Operation *op)
Definition: Operation.h:1135
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.