MLIR  15.0.0git
OpDefinition.h
Go to the documentation of this file.
1 //===- OpDefinition.h - Classes for defining concrete Op types --*- 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 implements helper classes for implementing the "Op" types. This
10 // includes the Op type, which is the base class for Op class definitions,
11 // as well as number of traits in the OpTrait namespace that provide a
12 // declarative way to specify properties of Ops.
13 //
14 // The purpose of these types are to allow light-weight implementation of
15 // concrete ops (like DimOp) with very little boilerplate.
16 //
17 //===----------------------------------------------------------------------===//
18 
19 #ifndef MLIR_IR_OPDEFINITION_H
20 #define MLIR_IR_OPDEFINITION_H
21 
22 #include "mlir/IR/Dialect.h"
23 #include "mlir/IR/Operation.h"
24 #include "llvm/Support/PointerLikeTypeTraits.h"
25 
26 #include <type_traits>
27 
28 namespace mlir {
29 class Builder;
30 class OpBuilder;
31 
32 /// This class implements `Optional` functionality for ParseResult. We don't
33 /// directly use Optional here, because it provides an implicit conversion
34 /// to 'bool' which we want to avoid. This class is used to implement tri-state
35 /// 'parseOptional' functions that may have a failure mode when parsing that
36 /// shouldn't be attributed to "not present".
38 public:
39  OptionalParseResult() = default;
40  OptionalParseResult(LogicalResult result) : impl(result) {}
41  OptionalParseResult(ParseResult result) : impl(result) {}
44  OptionalParseResult(llvm::NoneType) : impl(llvm::None) {}
45 
46  /// Returns true if we contain a valid ParseResult value.
47  bool hasValue() const { return impl.hasValue(); }
48 
49  /// Access the internal ParseResult value.
50  ParseResult getValue() const { return impl.getValue(); }
51  ParseResult operator*() const { return getValue(); }
52 
53 private:
55 };
56 
57 // These functions are out-of-line utilities, which avoids them being template
58 // instantiated/duplicated.
59 namespace impl {
60 /// Insert an operation, generated by `buildTerminatorOp`, at the end of the
61 /// region's only block if it does not have a terminator already. If the region
62 /// is empty, insert a new block first. `buildTerminatorOp` should return the
63 /// terminator operation to insert.
65  Region &region, OpBuilder &builder, Location loc,
66  function_ref<Operation *(OpBuilder &, Location)> buildTerminatorOp);
68  Region &region, Builder &builder, Location loc,
69  function_ref<Operation *(OpBuilder &, Location)> buildTerminatorOp);
70 
71 } // namespace impl
72 
73 /// This is the concrete base class that holds the operation pointer and has
74 /// non-generic methods that only depend on State (to avoid having them
75 /// instantiated on template types that don't affect them.
76 ///
77 /// This also has the fallback implementations of customization hooks for when
78 /// they aren't customized.
79 class OpState {
80 public:
81  /// Ops are pointer-like, so we allow conversion to bool.
82  explicit operator bool() { return getOperation() != nullptr; }
83 
84  /// This implicitly converts to Operation*.
85  operator Operation *() const { return state; }
86 
87  /// Shortcut of `->` to access a member of Operation.
88  Operation *operator->() const { return state; }
89 
90  /// Return the operation that this refers to.
91  Operation *getOperation() { return state; }
92 
93  /// Return the context this operation belongs to.
94  MLIRContext *getContext() { return getOperation()->getContext(); }
95 
96  /// Print the operation to the given stream.
97  void print(raw_ostream &os, OpPrintingFlags flags = llvm::None) {
98  state->print(os, flags);
99  }
100  void print(raw_ostream &os, AsmState &asmState) {
101  state->print(os, asmState);
102  }
103 
104  /// Dump this operation.
105  void dump() { state->dump(); }
106 
107  /// The source location the operation was defined or derived from.
108  Location getLoc() { return state->getLoc(); }
109 
110  /// Return true if there are no users of any results of this operation.
111  bool use_empty() { return state->use_empty(); }
112 
113  /// Remove this operation from its parent block and delete it.
114  void erase() { state->erase(); }
115 
116  /// Emit an error with the op name prefixed, like "'dim' op " which is
117  /// convenient for verifiers.
118  InFlightDiagnostic emitOpError(const Twine &message = {});
119 
120  /// Emit an error about fatal conditions with this operation, reporting up to
121  /// any diagnostic handlers that may be listening.
122  InFlightDiagnostic emitError(const Twine &message = {});
123 
124  /// Emit a warning about this operation, reporting up to any diagnostic
125  /// handlers that may be listening.
126  InFlightDiagnostic emitWarning(const Twine &message = {});
127 
128  /// Emit a remark about this operation, reporting up to any diagnostic
129  /// handlers that may be listening.
130  InFlightDiagnostic emitRemark(const Twine &message = {});
131 
132  /// Walk the operation by calling the callback for each nested operation
133  /// (including this one), block or region, depending on the callback provided.
134  /// Regions, blocks and operations at the same nesting level are visited in
135  /// lexicographical order. The walk order for enclosing regions, blocks and
136  /// operations with respect to their nested ones is specified by 'Order'
137  /// (post-order by default). A callback on a block or operation is allowed to
138  /// erase that block or operation if either:
139  /// * the walk is in post-order, or
140  /// * the walk is in pre-order and the walk is skipped after the erasure.
141  /// See Operation::walk for more details.
142  template <WalkOrder Order = WalkOrder::PostOrder, typename FnT,
143  typename RetT = detail::walkResultType<FnT>>
144  typename std::enable_if<
145  llvm::function_traits<std::decay_t<FnT>>::num_args == 1, RetT>::type
146  walk(FnT &&callback) {
147  return state->walk<Order>(std::forward<FnT>(callback));
148  }
149 
150  /// Generic walker with a stage aware callback. Walk the operation by calling
151  /// the callback for each nested operation (including this one) N+1 times,
152  /// where N is the number of regions attached to that operation.
153  ///
154  /// The callback method can take any of the following forms:
155  /// void(Operation *, const WalkStage &) : Walk all operation opaquely
156  /// * op.walk([](Operation *nestedOp, const WalkStage &stage) { ...});
157  /// void(OpT, const WalkStage &) : Walk all operations of the given derived
158  /// type.
159  /// * op.walk([](ReturnOp returnOp, const WalkStage &stage) { ...});
160  /// WalkResult(Operation*|OpT, const WalkStage &stage) : Walk operations,
161  /// but allow for interruption/skipping.
162  /// * op.walk([](... op, const WalkStage &stage) {
163  /// // Skip the walk of this op based on some invariant.
164  /// if (some_invariant)
165  /// return WalkResult::skip();
166  /// // Interrupt, i.e cancel, the walk based on some invariant.
167  /// if (another_invariant)
168  /// return WalkResult::interrupt();
169  /// return WalkResult::advance();
170  /// });
171  template <typename FnT, typename RetT = detail::walkResultType<FnT>>
172  typename std::enable_if<
173  llvm::function_traits<std::decay_t<FnT>>::num_args == 2, RetT>::type
174  walk(FnT &&callback) {
175  return state->walk(std::forward<FnT>(callback));
176  }
177 
178  // These are default implementations of customization hooks.
179 public:
180  /// This hook returns any canonicalization pattern rewrites that the operation
181  /// supports, for use by the canonicalization pass.
183  MLIRContext *context) {}
184 
185 protected:
186  /// If the concrete type didn't implement a custom verifier hook, just fall
187  /// back to this one which accepts everything.
188  LogicalResult verify() { return success(); }
190 
191  /// Parse the custom form of an operation. Unless overridden, this method will
192  /// first try to get an operation parser from the op's dialect. Otherwise the
193  /// custom assembly form of an op is always rejected. Op implementations
194  /// should implement this to return failure. On success, they should fill in
195  /// result with the fields to use.
196  static ParseResult parse(OpAsmParser &parser, OperationState &result);
197 
198  /// Print the operation. Unless overridden, this method will first try to get
199  /// an operation printer from the dialect. Otherwise, it prints the operation
200  /// in generic form.
201  static void print(Operation *op, OpAsmPrinter &p, StringRef defaultDialect);
202 
203  /// Print an operation name, eliding the dialect prefix if necessary.
204  static void printOpName(Operation *op, OpAsmPrinter &p,
205  StringRef defaultDialect);
206 
207  /// Mutability management is handled by the OpWrapper/OpConstWrapper classes,
208  /// so we can cast it away here.
209  explicit OpState(Operation *state) : state(state) {}
210 
211 private:
212  Operation *state;
213 
214  /// Allow access to internal hook implementation methods.
216 };
217 
218 // Allow comparing operators.
219 inline bool operator==(OpState lhs, OpState rhs) {
220  return lhs.getOperation() == rhs.getOperation();
221 }
222 inline bool operator!=(OpState lhs, OpState rhs) {
223  return lhs.getOperation() != rhs.getOperation();
224 }
225 
226 raw_ostream &operator<<(raw_ostream &os, OpFoldResult ofr);
227 
228 /// This class represents a single result from folding an operation.
229 class OpFoldResult : public PointerUnion<Attribute, Value> {
231 
232 public:
233  void dump() { llvm::errs() << *this << "\n"; }
234 };
235 
236 /// Allow printing to a stream.
237 inline raw_ostream &operator<<(raw_ostream &os, OpFoldResult ofr) {
238  if (Value value = ofr.dyn_cast<Value>())
239  value.print(os);
240  else
241  ofr.dyn_cast<Attribute>().print(os);
242  return os;
243 }
244 
245 /// Allow printing to a stream.
246 inline raw_ostream &operator<<(raw_ostream &os, OpState op) {
247  op.print(os, OpPrintingFlags().useLocalScope());
248  return os;
249 }
250 
251 //===----------------------------------------------------------------------===//
252 // Operation Trait Types
253 //===----------------------------------------------------------------------===//
254 
255 namespace OpTrait {
256 
257 // These functions are out-of-line implementations of the methods in the
258 // corresponding trait classes. This avoids them being template
259 // instantiated/duplicated.
260 namespace impl {
265 LogicalResult verifyNOperands(Operation *op, unsigned numOperands);
268 LogicalResult verifyAtLeastNOperands(Operation *op, unsigned numOperands);
274 LogicalResult verifyNRegions(Operation *op, unsigned numRegions);
275 LogicalResult verifyAtLeastNRegions(Operation *op, unsigned numRegions);
278 LogicalResult verifyNResults(Operation *op, unsigned numOperands);
279 LogicalResult verifyAtLeastNResults(Operation *op, unsigned numOperands);
291 LogicalResult verifyNSuccessors(Operation *op, unsigned numSuccessors);
292 LogicalResult verifyAtLeastNSuccessors(Operation *op, unsigned numSuccessors);
293 LogicalResult verifyValueSizeAttr(Operation *op, StringRef attrName,
294  StringRef valueGroupName,
295  size_t expectedCount);
296 LogicalResult verifyOperandSizeAttr(Operation *op, StringRef sizeAttrName);
297 LogicalResult verifyResultSizeAttr(Operation *op, StringRef sizeAttrName);
301 } // namespace impl
302 
303 /// Helper class for implementing traits. Clients are not expected to interact
304 /// with this directly, so its members are all protected.
305 template <typename ConcreteType, template <typename> class TraitType>
306 class TraitBase {
307 protected:
308  /// Return the ultimate Operation being worked on.
310  auto *concrete = static_cast<ConcreteType *>(this);
311  return concrete->getOperation();
312  }
313 };
314 
315 //===----------------------------------------------------------------------===//
316 // Operand Traits
317 
318 namespace detail {
319 /// Utility trait base that provides accessors for derived traits that have
320 /// multiple operands.
321 template <typename ConcreteType, template <typename> class TraitType>
322 struct MultiOperandTraitBase : public TraitBase<ConcreteType, TraitType> {
327 
328  /// Return the number of operands.
329  unsigned getNumOperands() { return this->getOperation()->getNumOperands(); }
330 
331  /// Return the operand at index 'i'.
332  Value getOperand(unsigned i) { return this->getOperation()->getOperand(i); }
333 
334  /// Set the operand at index 'i' to 'value'.
335  void setOperand(unsigned i, Value value) {
336  this->getOperation()->setOperand(i, value);
337  }
338 
339  /// Operand iterator access.
341  return this->getOperation()->operand_begin();
342  }
343  operand_iterator operand_end() { return this->getOperation()->operand_end(); }
344  operand_range getOperands() { return this->getOperation()->getOperands(); }
345 
346  /// Operand type access.
348  return this->getOperation()->operand_type_begin();
349  }
351  return this->getOperation()->operand_type_end();
352  }
354  return this->getOperation()->getOperandTypes();
355  }
356 };
357 } // namespace detail
358 
359 /// `verifyInvariantsImpl` verifies the invariants like the types, attrs, .etc.
360 /// It should be run after core traits and before any other user defined traits.
361 /// In order to run it in the correct order, wrap it with OpInvariants trait so
362 /// that tblgen will be able to put it in the right order.
363 template <typename ConcreteType>
364 class OpInvariants : public TraitBase<ConcreteType, OpInvariants> {
365 public:
367  return cast<ConcreteType>(op).verifyInvariantsImpl();
368  }
369 };
370 
371 /// This class provides the API for ops that are known to have no
372 /// SSA operand.
373 template <typename ConcreteType>
374 class ZeroOperands : public TraitBase<ConcreteType, ZeroOperands> {
375 public:
377  return impl::verifyZeroOperands(op);
378  }
379 
380 private:
381  // Disable these.
382  void getOperand() {}
383  void setOperand() {}
384 };
385 
386 /// This class provides the API for ops that are known to have exactly one
387 /// SSA operand.
388 template <typename ConcreteType>
389 class OneOperand : public TraitBase<ConcreteType, OneOperand> {
390 public:
391  Value getOperand() { return this->getOperation()->getOperand(0); }
392 
393  void setOperand(Value value) { this->getOperation()->setOperand(0, value); }
394 
396  return impl::verifyOneOperand(op);
397  }
398 };
399 
400 /// This class provides the API for ops that are known to have a specified
401 /// number of operands. This is used as a trait like this:
402 ///
403 /// class FooOp : public Op<FooOp, OpTrait::NOperands<2>::Impl> {
404 ///
405 template <unsigned N>
406 class NOperands {
407 public:
408  static_assert(N > 1, "use ZeroOperands/OneOperand for N < 2");
409 
410  template <typename ConcreteType>
411  class Impl
412  : public detail::MultiOperandTraitBase<ConcreteType, NOperands<N>::Impl> {
413  public:
415  return impl::verifyNOperands(op, N);
416  }
417  };
418 };
419 
420 /// This class provides the API for ops that are known to have a at least a
421 /// specified number of operands. This is used as a trait like this:
422 ///
423 /// class FooOp : public Op<FooOp, OpTrait::AtLeastNOperands<2>::Impl> {
424 ///
425 template <unsigned N>
427 public:
428  template <typename ConcreteType>
429  class Impl : public detail::MultiOperandTraitBase<ConcreteType,
430  AtLeastNOperands<N>::Impl> {
431  public:
433  return impl::verifyAtLeastNOperands(op, N);
434  }
435  };
436 };
437 
438 /// This class provides the API for ops which have an unknown number of
439 /// SSA operands.
440 template <typename ConcreteType>
442  : public detail::MultiOperandTraitBase<ConcreteType, VariadicOperands> {};
443 
444 //===----------------------------------------------------------------------===//
445 // Region Traits
446 
447 /// This class provides verification for ops that are known to have zero
448 /// regions.
449 template <typename ConcreteType>
450 class ZeroRegions : public TraitBase<ConcreteType, ZeroRegions> {
451 public:
453  return impl::verifyZeroRegions(op);
454  }
455 };
456 
457 namespace detail {
458 /// Utility trait base that provides accessors for derived traits that have
459 /// multiple regions.
460 template <typename ConcreteType, template <typename> class TraitType>
461 struct MultiRegionTraitBase : public TraitBase<ConcreteType, TraitType> {
464 
465  /// Return the number of regions.
466  unsigned getNumRegions() { return this->getOperation()->getNumRegions(); }
467 
468  /// Return the region at `index`.
469  Region &getRegion(unsigned i) { return this->getOperation()->getRegion(i); }
470 
471  /// Region iterator access.
473  return this->getOperation()->region_begin();
474  }
475  region_iterator region_end() { return this->getOperation()->region_end(); }
476  region_range getRegions() { return this->getOperation()->getRegions(); }
477 };
478 } // namespace detail
479 
480 /// This class provides APIs for ops that are known to have a single region.
481 template <typename ConcreteType>
482 class OneRegion : public TraitBase<ConcreteType, OneRegion> {
483 public:
484  Region &getRegion() { return this->getOperation()->getRegion(0); }
485 
486  /// Returns a range of operations within the region of this operation.
487  auto getOps() { return getRegion().getOps(); }
488  template <typename OpT>
489  auto getOps() {
490  return getRegion().template getOps<OpT>();
491  }
492 
494  return impl::verifyOneRegion(op);
495  }
496 };
497 
498 /// This class provides the API for ops that are known to have a specified
499 /// number of regions.
500 template <unsigned N>
501 class NRegions {
502 public:
503  static_assert(N > 1, "use ZeroRegions/OneRegion for N < 2");
504 
505  template <typename ConcreteType>
506  class Impl
507  : public detail::MultiRegionTraitBase<ConcreteType, NRegions<N>::Impl> {
508  public:
510  return impl::verifyNRegions(op, N);
511  }
512  };
513 };
514 
515 /// This class provides APIs for ops that are known to have at least a specified
516 /// number of regions.
517 template <unsigned N>
519 public:
520  template <typename ConcreteType>
521  class Impl : public detail::MultiRegionTraitBase<ConcreteType,
522  AtLeastNRegions<N>::Impl> {
523  public:
525  return impl::verifyAtLeastNRegions(op, N);
526  }
527  };
528 };
529 
530 /// This class provides the API for ops which have an unknown number of
531 /// regions.
532 template <typename ConcreteType>
534  : public detail::MultiRegionTraitBase<ConcreteType, VariadicRegions> {};
535 
536 //===----------------------------------------------------------------------===//
537 // Result Traits
538 
539 /// This class provides return value APIs for ops that are known to have
540 /// zero results.
541 template <typename ConcreteType>
542 class ZeroResults : public TraitBase<ConcreteType, ZeroResults> {
543 public:
545  return impl::verifyZeroResults(op);
546  }
547 };
548 
549 namespace detail {
550 /// Utility trait base that provides accessors for derived traits that have
551 /// multiple results.
552 template <typename ConcreteType, template <typename> class TraitType>
553 struct MultiResultTraitBase : public TraitBase<ConcreteType, TraitType> {
558 
559  /// Return the number of results.
560  unsigned getNumResults() { return this->getOperation()->getNumResults(); }
561 
562  /// Return the result at index 'i'.
563  Value getResult(unsigned i) { return this->getOperation()->getResult(i); }
564 
565  /// Replace all uses of results of this operation with the provided 'values'.
566  /// 'values' may correspond to an existing operation, or a range of 'Value'.
567  template <typename ValuesT>
568  void replaceAllUsesWith(ValuesT &&values) {
569  this->getOperation()->replaceAllUsesWith(std::forward<ValuesT>(values));
570  }
571 
572  /// Return the type of the `i`-th result.
573  Type getType(unsigned i) { return getResult(i).getType(); }
574 
575  /// Result iterator access.
577  return this->getOperation()->result_begin();
578  }
579  result_iterator result_end() { return this->getOperation()->result_end(); }
580  result_range getResults() { return this->getOperation()->getResults(); }
581 
582  /// Result type access.
584  return this->getOperation()->result_type_begin();
585  }
587  return this->getOperation()->result_type_end();
588  }
590  return this->getOperation()->getResultTypes();
591  }
592 };
593 } // namespace detail
594 
595 /// This class provides return value APIs for ops that are known to have a
596 /// single result. ResultType is the concrete type returned by getType().
597 template <typename ConcreteType>
598 class OneResult : public TraitBase<ConcreteType, OneResult> {
599 public:
600  Value getResult() { return this->getOperation()->getResult(0); }
601 
602  /// If the operation returns a single value, then the Op can be implicitly
603  /// converted to an Value. This yields the value of the only result.
604  operator Value() { return getResult(); }
605 
606  /// Replace all uses of 'this' value with the new value, updating anything
607  /// in the IR that uses 'this' to use the other value instead. When this
608  /// returns there are zero uses of 'this'.
609  void replaceAllUsesWith(Value newValue) {
610  getResult().replaceAllUsesWith(newValue);
611  }
612 
613  /// Replace all uses of 'this' value with the result of 'op'.
615  this->getOperation()->replaceAllUsesWith(op);
616  }
617 
619  return impl::verifyOneResult(op);
620  }
621 };
622 
623 /// This trait is used for return value APIs for ops that are known to have a
624 /// specific type other than `Type`. This allows the "getType()" member to be
625 /// more specific for an op. This should be used in conjunction with OneResult,
626 /// and occur in the trait list before OneResult.
627 template <typename ResultType>
629 public:
630  /// This class provides return value APIs for ops that are known to have a
631  /// single result. ResultType is the concrete type returned by getType().
632  template <typename ConcreteType>
633  class Impl
634  : public TraitBase<ConcreteType, OneTypedResult<ResultType>::Impl> {
635  public:
636  ResultType getType() {
637  auto resultTy = this->getOperation()->getResult(0).getType();
638  return resultTy.template cast<ResultType>();
639  }
640  };
641 };
642 
643 /// This class provides the API for ops that are known to have a specified
644 /// number of results. This is used as a trait like this:
645 ///
646 /// class FooOp : public Op<FooOp, OpTrait::NResults<2>::Impl> {
647 ///
648 template <unsigned N>
649 class NResults {
650 public:
651  static_assert(N > 1, "use ZeroResults/OneResult for N < 2");
652 
653  template <typename ConcreteType>
654  class Impl
655  : public detail::MultiResultTraitBase<ConcreteType, NResults<N>::Impl> {
656  public:
658  return impl::verifyNResults(op, N);
659  }
660  };
661 };
662 
663 /// This class provides the API for ops that are known to have at least a
664 /// specified number of results. This is used as a trait like this:
665 ///
666 /// class FooOp : public Op<FooOp, OpTrait::AtLeastNResults<2>::Impl> {
667 ///
668 template <unsigned N>
670 public:
671  template <typename ConcreteType>
672  class Impl : public detail::MultiResultTraitBase<ConcreteType,
673  AtLeastNResults<N>::Impl> {
674  public:
676  return impl::verifyAtLeastNResults(op, N);
677  }
678  };
679 };
680 
681 /// This class provides the API for ops which have an unknown number of
682 /// results.
683 template <typename ConcreteType>
685  : public detail::MultiResultTraitBase<ConcreteType, VariadicResults> {};
686 
687 //===----------------------------------------------------------------------===//
688 // Terminator Traits
689 
690 /// This class indicates that the regions associated with this op don't have
691 /// terminators.
692 template <typename ConcreteType>
693 class NoTerminator : public TraitBase<ConcreteType, NoTerminator> {};
694 
695 /// This class provides the API for ops that are known to be terminators.
696 template <typename ConcreteType>
697 class IsTerminator : public TraitBase<ConcreteType, IsTerminator> {
698 public:
700  return impl::verifyIsTerminator(op);
701  }
702 };
703 
704 /// This class provides verification for ops that are known to have zero
705 /// successors.
706 template <typename ConcreteType>
707 class ZeroSuccessors : public TraitBase<ConcreteType, ZeroSuccessors> {
708 public:
710  return impl::verifyZeroSuccessors(op);
711  }
712 };
713 
714 namespace detail {
715 /// Utility trait base that provides accessors for derived traits that have
716 /// multiple successors.
717 template <typename ConcreteType, template <typename> class TraitType>
718 struct MultiSuccessorTraitBase : public TraitBase<ConcreteType, TraitType> {
721 
722  /// Return the number of successors.
723  unsigned getNumSuccessors() {
724  return this->getOperation()->getNumSuccessors();
725  }
726 
727  /// Return the successor at `index`.
728  Block *getSuccessor(unsigned i) {
729  return this->getOperation()->getSuccessor(i);
730  }
731 
732  /// Set the successor at `index`.
733  void setSuccessor(Block *block, unsigned i) {
734  return this->getOperation()->setSuccessor(block, i);
735  }
736 
737  /// Successor iterator access.
738  succ_iterator succ_begin() { return this->getOperation()->succ_begin(); }
739  succ_iterator succ_end() { return this->getOperation()->succ_end(); }
740  succ_range getSuccessors() { return this->getOperation()->getSuccessors(); }
741 };
742 } // namespace detail
743 
744 /// This class provides APIs for ops that are known to have a single successor.
745 template <typename ConcreteType>
746 class OneSuccessor : public TraitBase<ConcreteType, OneSuccessor> {
747 public:
748  Block *getSuccessor() { return this->getOperation()->getSuccessor(0); }
749  void setSuccessor(Block *succ) {
750  this->getOperation()->setSuccessor(succ, 0);
751  }
752 
754  return impl::verifyOneSuccessor(op);
755  }
756 };
757 
758 /// This class provides the API for ops that are known to have a specified
759 /// number of successors.
760 template <unsigned N>
761 class NSuccessors {
762 public:
763  static_assert(N > 1, "use ZeroSuccessors/OneSuccessor for N < 2");
764 
765  template <typename ConcreteType>
766  class Impl : public detail::MultiSuccessorTraitBase<ConcreteType,
767  NSuccessors<N>::Impl> {
768  public:
770  return impl::verifyNSuccessors(op, N);
771  }
772  };
773 };
774 
775 /// This class provides APIs for ops that are known to have at least a specified
776 /// number of successors.
777 template <unsigned N>
779 public:
780  template <typename ConcreteType>
781  class Impl
782  : public detail::MultiSuccessorTraitBase<ConcreteType,
783  AtLeastNSuccessors<N>::Impl> {
784  public:
786  return impl::verifyAtLeastNSuccessors(op, N);
787  }
788  };
789 };
790 
791 /// This class provides the API for ops which have an unknown number of
792 /// successors.
793 template <typename ConcreteType>
795  : public detail::MultiSuccessorTraitBase<ConcreteType, VariadicSuccessors> {
796 };
797 
798 //===----------------------------------------------------------------------===//
799 // SingleBlock
800 
801 /// This class provides APIs and verifiers for ops with regions having a single
802 /// block.
803 template <typename ConcreteType>
804 struct SingleBlock : public TraitBase<ConcreteType, SingleBlock> {
805 public:
807  for (unsigned i = 0, e = op->getNumRegions(); i < e; ++i) {
808  Region &region = op->getRegion(i);
809 
810  // Empty regions are fine.
811  if (region.empty())
812  continue;
813 
814  // Non-empty regions must contain a single basic block.
815  if (!llvm::hasSingleElement(region))
816  return op->emitOpError("expects region #")
817  << i << " to have 0 or 1 blocks";
818 
819  if (!ConcreteType::template hasTrait<NoTerminator>()) {
820  Block &block = region.front();
821  if (block.empty())
822  return op->emitOpError() << "expects a non-empty block";
823  }
824  }
825  return success();
826  }
827 
828  Block *getBody(unsigned idx = 0) {
829  Region &region = this->getOperation()->getRegion(idx);
830  assert(!region.empty() && "unexpected empty region");
831  return &region.front();
832  }
833  Region &getBodyRegion(unsigned idx = 0) {
834  return this->getOperation()->getRegion(idx);
835  }
836 
837  //===------------------------------------------------------------------===//
838  // Single Region Utilities
839  //===------------------------------------------------------------------===//
840 
841  /// The following are a set of methods only enabled when the parent
842  /// operation has a single region. Each of these methods take an additional
843  /// template parameter that represents the concrete operation so that we
844  /// can use SFINAE to disable the methods for non-single region operations.
845  template <typename OpT, typename T = void>
847  typename std::enable_if_t<OpT::template hasTrait<OneRegion>(), T>;
848 
849  template <typename OpT = ConcreteType>
851  return getBody()->begin();
852  }
853  template <typename OpT = ConcreteType>
855  return getBody()->end();
856  }
857  template <typename OpT = ConcreteType>
859  return *begin();
860  }
861 
862  /// Insert the operation into the back of the body.
863  template <typename OpT = ConcreteType>
865  insert(Block::iterator(getBody()->end()), op);
866  }
867 
868  /// Insert the operation at the given insertion point.
869  template <typename OpT = ConcreteType>
871  insert(Block::iterator(insertPt), op);
872  }
873  template <typename OpT = ConcreteType>
875  getBody()->getOperations().insert(insertPt, op);
876  }
877 };
878 
879 //===----------------------------------------------------------------------===//
880 // SingleBlockImplicitTerminator
881 
882 /// This class provides APIs and verifiers for ops with regions having a single
883 /// block that must terminate with `TerminatorOpType`.
884 template <typename TerminatorOpType>
886  template <typename ConcreteType>
887  class Impl : public SingleBlock<ConcreteType> {
888  private:
890  /// Builds a terminator operation without relying on OpBuilder APIs to avoid
891  /// cyclic header inclusion.
892  static Operation *buildTerminator(OpBuilder &builder, Location loc) {
893  OperationState state(loc, TerminatorOpType::getOperationName());
894  TerminatorOpType::build(builder, state);
895  return Operation::create(state);
896  }
897 
898  public:
899  /// The type of the operation used as the implicit terminator type.
900  using ImplicitTerminatorOpT = TerminatorOpType;
901 
903  if (failed(Base::verifyTrait(op)))
904  return failure();
905  for (unsigned i = 0, e = op->getNumRegions(); i < e; ++i) {
906  Region &region = op->getRegion(i);
907  // Empty regions are fine.
908  if (region.empty())
909  continue;
910  Operation &terminator = region.front().back();
911  if (isa<TerminatorOpType>(terminator))
912  continue;
913 
914  return op->emitOpError("expects regions to end with '" +
915  TerminatorOpType::getOperationName() +
916  "', found '" +
917  terminator.getName().getStringRef() + "'")
918  .attachNote()
919  << "in custom textual format, the absence of terminator implies "
920  "'"
921  << TerminatorOpType::getOperationName() << '\'';
922  }
923 
924  return success();
925  }
926 
927  /// Ensure that the given region has the terminator required by this trait.
928  /// If OpBuilder is provided, use it to build the terminator and notify the
929  /// OpBuilder listeners accordingly. If only a Builder is provided, locally
930  /// construct an OpBuilder with no listeners; this should only be used if no
931  /// OpBuilder is available at the call site, e.g., in the parser.
932  static void ensureTerminator(Region &region, Builder &builder,
933  Location loc) {
934  ::mlir::impl::ensureRegionTerminator(region, builder, loc,
935  buildTerminator);
936  }
937  static void ensureTerminator(Region &region, OpBuilder &builder,
938  Location loc) {
939  ::mlir::impl::ensureRegionTerminator(region, builder, loc,
940  buildTerminator);
941  }
942 
943  //===------------------------------------------------------------------===//
944  // Single Region Utilities
945  //===------------------------------------------------------------------===//
946  using Base::getBody;
947 
948  template <typename OpT, typename T = void>
950  typename std::enable_if_t<OpT::template hasTrait<OneRegion>(), T>;
951 
952  /// Insert the operation into the back of the body, before the terminator.
953  template <typename OpT = ConcreteType>
955  insert(Block::iterator(getBody()->getTerminator()), op);
956  }
957 
958  /// Insert the operation at the given insertion point. Note: The operation
959  /// is never inserted after the terminator, even if the insertion point is
960  /// end().
961  template <typename OpT = ConcreteType>
963  insert(Block::iterator(insertPt), op);
964  }
965  template <typename OpT = ConcreteType>
967  Operation *op) {
968  auto *body = getBody();
969  if (insertPt == body->end())
970  insertPt = Block::iterator(body->getTerminator());
971  body->getOperations().insert(insertPt, op);
972  }
973  };
974 };
975 
976 /// Check is an op defines the `ImplicitTerminatorOpT` member. This is intended
977 /// to be used with `llvm::is_detected`.
978 template <class T>
979 using has_implicit_terminator_t = typename T::ImplicitTerminatorOpT;
980 
981 /// Support to check if an operation has the SingleBlockImplicitTerminator
982 /// trait. We can't just use `hasTrait` because this class is templated on a
983 /// specific terminator op.
984 template <class Op, bool hasTerminator =
987  static constexpr bool value = std::is_base_of<
989  typename Op::ImplicitTerminatorOpT>::template Impl<Op>,
990  Op>::value;
991 };
992 template <class Op>
994  static constexpr bool value = false;
995 };
996 
997 //===----------------------------------------------------------------------===//
998 // Misc Traits
999 
1000 /// This class provides verification for ops that are known to have the same
1001 /// operand shape: all operands are scalars, vectors/tensors of the same
1002 /// shape.
1003 template <typename ConcreteType>
1004 class SameOperandsShape : public TraitBase<ConcreteType, SameOperandsShape> {
1005 public:
1007  return impl::verifySameOperandsShape(op);
1008  }
1009 };
1010 
1011 /// This class provides verification for ops that are known to have the same
1012 /// operand and result shape: both are scalars, vectors/tensors of the same
1013 /// shape.
1014 template <typename ConcreteType>
1016  : public TraitBase<ConcreteType, SameOperandsAndResultShape> {
1017 public:
1020  }
1021 };
1022 
1023 /// This class provides verification for ops that are known to have the same
1024 /// operand element type (or the type itself if it is scalar).
1025 ///
1026 template <typename ConcreteType>
1028  : public TraitBase<ConcreteType, SameOperandsElementType> {
1029 public:
1032  }
1033 };
1034 
1035 /// This class provides verification for ops that are known to have the same
1036 /// operand and result element type (or the type itself if it is scalar).
1037 ///
1038 template <typename ConcreteType>
1040  : public TraitBase<ConcreteType, SameOperandsAndResultElementType> {
1041 public:
1044  }
1045 };
1046 
1047 /// This class provides verification for ops that are known to have the same
1048 /// operand and result type.
1049 ///
1050 /// Note: this trait subsumes the SameOperandsAndResultShape and
1051 /// SameOperandsAndResultElementType traits.
1052 template <typename ConcreteType>
1054  : public TraitBase<ConcreteType, SameOperandsAndResultType> {
1055 public:
1058  }
1059 };
1060 
1061 /// This class verifies that any results of the specified op have a boolean
1062 /// type, a vector thereof, or a tensor thereof.
1063 template <typename ConcreteType>
1064 class ResultsAreBoolLike : public TraitBase<ConcreteType, ResultsAreBoolLike> {
1065 public:
1067  return impl::verifyResultsAreBoolLike(op);
1068  }
1069 };
1070 
1071 /// This class verifies that any results of the specified op have a floating
1072 /// point type, a vector thereof, or a tensor thereof.
1073 template <typename ConcreteType>
1075  : public TraitBase<ConcreteType, ResultsAreFloatLike> {
1076 public:
1079  }
1080 };
1081 
1082 /// This class verifies that any results of the specified op have a signless
1083 /// integer or index type, a vector thereof, or a tensor thereof.
1084 template <typename ConcreteType>
1086  : public TraitBase<ConcreteType, ResultsAreSignlessIntegerLike> {
1087 public:
1090  }
1091 };
1092 
1093 /// This class adds property that the operation is commutative.
1094 template <typename ConcreteType>
1095 class IsCommutative : public TraitBase<ConcreteType, IsCommutative> {};
1096 
1097 /// This class adds property that the operation is an involution.
1098 /// This means a unary to unary operation "f" that satisfies f(f(x)) = x
1099 template <typename ConcreteType>
1100 class IsInvolution : public TraitBase<ConcreteType, IsInvolution> {
1101 public:
1103  static_assert(ConcreteType::template hasTrait<OneResult>(),
1104  "expected operation to produce one result");
1105  static_assert(ConcreteType::template hasTrait<OneOperand>(),
1106  "expected operation to take one operand");
1107  static_assert(ConcreteType::template hasTrait<SameOperandsAndResultType>(),
1108  "expected operation to preserve type");
1109  // Involution requires the operation to be side effect free as well
1110  // but currently this check is under a FIXME and is not actually done.
1111  return impl::verifyIsInvolution(op);
1112  }
1113 
1115  return impl::foldInvolution(op);
1116  }
1117 };
1118 
1119 /// This class adds property that the operation is idempotent.
1120 /// This means a unary to unary operation "f" that satisfies f(f(x)) = f(x),
1121 /// or a binary operation "g" that satisfies g(x, x) = x.
1122 template <typename ConcreteType>
1123 class IsIdempotent : public TraitBase<ConcreteType, IsIdempotent> {
1124 public:
1126  static_assert(ConcreteType::template hasTrait<OneResult>(),
1127  "expected operation to produce one result");
1128  static_assert(ConcreteType::template hasTrait<OneOperand>() ||
1129  ConcreteType::template hasTrait<NOperands<2>::Impl>(),
1130  "expected operation to take one or two operands");
1131  static_assert(ConcreteType::template hasTrait<SameOperandsAndResultType>(),
1132  "expected operation to preserve type");
1133  // Idempotent requires the operation to be side effect free as well
1134  // but currently this check is under a FIXME and is not actually done.
1135  return impl::verifyIsIdempotent(op);
1136  }
1137 
1139  return impl::foldIdempotent(op);
1140  }
1141 };
1142 
1143 /// This class verifies that all operands of the specified op have a float type,
1144 /// a vector thereof, or a tensor thereof.
1145 template <typename ConcreteType>
1147  : public TraitBase<ConcreteType, OperandsAreFloatLike> {
1148 public:
1151  }
1152 };
1153 
1154 /// This class verifies that all operands of the specified op have a signless
1155 /// integer or index type, a vector thereof, or a tensor thereof.
1156 template <typename ConcreteType>
1158  : public TraitBase<ConcreteType, OperandsAreSignlessIntegerLike> {
1159 public:
1162  }
1163 };
1164 
1165 /// This class verifies that all operands of the specified op have the same
1166 /// type.
1167 template <typename ConcreteType>
1168 class SameTypeOperands : public TraitBase<ConcreteType, SameTypeOperands> {
1169 public:
1171  return impl::verifySameTypeOperands(op);
1172  }
1173 };
1174 
1175 /// This class provides the API for a sub-set of ops that are known to be
1176 /// constant-like. These are non-side effecting operations with one result and
1177 /// zero operands that can always be folded to a specific attribute value.
1178 template <typename ConcreteType>
1179 class ConstantLike : public TraitBase<ConcreteType, ConstantLike> {
1180 public:
1182  static_assert(ConcreteType::template hasTrait<OneResult>(),
1183  "expected operation to produce one result");
1184  static_assert(ConcreteType::template hasTrait<ZeroOperands>(),
1185  "expected operation to take zero operands");
1186  // TODO: We should verify that the operation can always be folded, but this
1187  // requires that the attributes of the op already be verified. We should add
1188  // support for verifying traits "after" the operation to enable this use
1189  // case.
1190  return success();
1191  }
1192 };
1193 
1194 /// This class provides the API for ops that are known to be isolated from
1195 /// above.
1196 template <typename ConcreteType>
1198  : public TraitBase<ConcreteType, IsIsolatedFromAbove> {
1199 public:
1202  }
1203 };
1204 
1205 /// A trait of region holding operations that defines a new scope for polyhedral
1206 /// optimization purposes. Any SSA values of 'index' type that either dominate
1207 /// such an operation or are used at the top-level of such an operation
1208 /// automatically become valid symbols for the polyhedral scope defined by that
1209 /// operation. For more details, see `Traits.md#AffineScope`.
1210 template <typename ConcreteType>
1211 class AffineScope : public TraitBase<ConcreteType, AffineScope> {
1212 public:
1214  static_assert(!ConcreteType::template hasTrait<ZeroRegions>(),
1215  "expected operation to have one or more regions");
1216  return success();
1217  }
1218 };
1219 
1220 /// A trait of region holding operations that define a new scope for automatic
1221 /// allocations, i.e., allocations that are freed when control is transferred
1222 /// back from the operation's region. Any operations performing such allocations
1223 /// (for eg. memref.alloca) will have their allocations automatically freed at
1224 /// their closest enclosing operation with this trait.
1225 template <typename ConcreteType>
1227  : public TraitBase<ConcreteType, AutomaticAllocationScope> {
1228 public:
1230  static_assert(!ConcreteType::template hasTrait<ZeroRegions>(),
1231  "expected operation to have one or more regions");
1232  return success();
1233  }
1234 };
1235 
1236 /// This class provides a verifier for ops that are expecting their parent
1237 /// to be one of the given parent ops
1238 template <typename... ParentOpTypes>
1239 struct HasParent {
1240  template <typename ConcreteType>
1241  class Impl : public TraitBase<ConcreteType, Impl> {
1242  public:
1244  if (llvm::isa_and_nonnull<ParentOpTypes...>(op->getParentOp()))
1245  return success();
1246 
1247  return op->emitOpError()
1248  << "expects parent op "
1249  << (sizeof...(ParentOpTypes) != 1 ? "to be one of '" : "'")
1250  << llvm::makeArrayRef({ParentOpTypes::getOperationName()...})
1251  << "'";
1252  }
1253  };
1254 };
1255 
1256 /// A trait for operations that have an attribute specifying operand segments.
1257 ///
1258 /// Certain operations can have multiple variadic operands and their size
1259 /// relationship is not always known statically. For such cases, we need
1260 /// a per-op-instance specification to divide the operands into logical groups
1261 /// or segments. This can be modeled by attributes. The attribute will be named
1262 /// as `operand_segment_sizes`.
1263 ///
1264 /// This trait verifies the attribute for specifying operand segments has
1265 /// the correct type (1D vector) and values (non-negative), etc.
1266 template <typename ConcreteType>
1268  : public TraitBase<ConcreteType, AttrSizedOperandSegments> {
1269 public:
1270  static StringRef getOperandSegmentSizeAttr() {
1271  return "operand_segment_sizes";
1272  }
1273 
1276  op, getOperandSegmentSizeAttr());
1277  }
1278 };
1279 
1280 /// Similar to AttrSizedOperandSegments but used for results.
1281 template <typename ConcreteType>
1283  : public TraitBase<ConcreteType, AttrSizedResultSegments> {
1284 public:
1285  static StringRef getResultSegmentSizeAttr() { return "result_segment_sizes"; }
1286 
1289  op, getResultSegmentSizeAttr());
1290  }
1291 };
1292 
1293 /// This trait provides a verifier for ops that are expecting their regions to
1294 /// not have any arguments
1295 template <typename ConcrentType>
1296 struct NoRegionArguments : public TraitBase<ConcrentType, NoRegionArguments> {
1299  }
1300 };
1301 
1302 // This trait is used to flag operations that consume or produce
1303 // values of `MemRef` type where those references can be 'normalized'.
1304 // TODO: Right now, the operands of an operation are either all normalizable,
1305 // or not. In the future, we may want to allow some of the operands to be
1306 // normalizable.
1307 template <typename ConcrentType>
1309  : public TraitBase<ConcrentType, MemRefsNormalizable> {};
1310 
1311 /// This trait tags element-wise ops on vectors or tensors.
1312 ///
1313 /// NOTE: Not all ops that are "elementwise" in some abstract sense satisfy this
1314 /// trait. In particular, broadcasting behavior is not allowed.
1315 ///
1316 /// An `Elementwise` op must satisfy the following properties:
1317 ///
1318 /// 1. If any result is a vector/tensor then at least one operand must also be a
1319 /// vector/tensor.
1320 /// 2. If any operand is a vector/tensor then there must be at least one result
1321 /// and all results must be vectors/tensors.
1322 /// 3. All operand and result vector/tensor types must be of the same shape. The
1323 /// shape may be dynamic in which case the op's behaviour is undefined for
1324 /// non-matching shapes.
1325 /// 4. The operation must be elementwise on its vector/tensor operands and
1326 /// results. When applied to single-element vectors/tensors, the result must
1327 /// be the same per elememnt.
1328 ///
1329 /// TODO: Avoid hardcoding vector/tensor, and generalize this trait to a new
1330 /// interface `ElementwiseTypeInterface` that describes the container types for
1331 /// which the operation is elementwise.
1332 ///
1333 /// Rationale:
1334 /// - 1. and 2. guarantee a well-defined iteration space and exclude the cases
1335 /// of 0 non-scalar operands or 0 non-scalar results, which complicate a
1336 /// generic definition of the iteration space.
1337 /// - 3. guarantees that folding can be done across scalars/vectors/tensors with
1338 /// the same pattern, as otherwise lots of special handling for type
1339 /// mismatches would be needed.
1340 /// - 4. guarantees that no error handling is needed. Higher-level dialects
1341 /// should reify any needed guards or error handling code before lowering to
1342 /// an `Elementwise` op.
1343 template <typename ConcreteType>
1344 struct Elementwise : public TraitBase<ConcreteType, Elementwise> {
1347  }
1348 };
1349 
1350 /// This trait tags `Elementwise` operatons that can be systematically
1351 /// scalarized. All vector/tensor operands and results are then replaced by
1352 /// scalars of the respective element type. Semantically, this is the operation
1353 /// on a single element of the vector/tensor.
1354 ///
1355 /// Rationale:
1356 /// Allow to define the vector/tensor semantics of elementwise operations based
1357 /// on the same op's behavior on scalars. This provides a constructive procedure
1358 /// for IR transformations to, e.g., create scalar loop bodies from tensor ops.
1359 ///
1360 /// Example:
1361 /// ```
1362 /// %tensor_select = "arith.select"(%pred_tensor, %true_val, %false_val)
1363 /// : (tensor<?xi1>, tensor<?xf32>, tensor<?xf32>)
1364 /// -> tensor<?xf32>
1365 /// ```
1366 /// can be scalarized to
1367 ///
1368 /// ```
1369 /// %scalar_select = "arith.select"(%pred, %true_val_scalar, %false_val_scalar)
1370 /// : (i1, f32, f32) -> f32
1371 /// ```
1372 template <typename ConcreteType>
1373 struct Scalarizable : public TraitBase<ConcreteType, Scalarizable> {
1375  static_assert(
1376  ConcreteType::template hasTrait<Elementwise>(),
1377  "`Scalarizable` trait is only applicable to `Elementwise` ops.");
1378  return success();
1379  }
1380 };
1381 
1382 /// This trait tags `Elementwise` operatons that can be systematically
1383 /// vectorized. All scalar operands and results are then replaced by vectors
1384 /// with the respective element type. Semantically, this is the operation on
1385 /// multiple elements simultaneously. See also `Tensorizable`.
1386 ///
1387 /// Rationale:
1388 /// Provide the reverse to `Scalarizable` which, when chained together, allows
1389 /// reasoning about the relationship between the tensor and vector case.
1390 /// Additionally, it permits reasoning about promoting scalars to vectors via
1391 /// broadcasting in cases like `%select_scalar_pred` below.
1392 template <typename ConcreteType>
1393 struct Vectorizable : public TraitBase<ConcreteType, Vectorizable> {
1395  static_assert(
1396  ConcreteType::template hasTrait<Elementwise>(),
1397  "`Vectorizable` trait is only applicable to `Elementwise` ops.");
1398  return success();
1399  }
1400 };
1401 
1402 /// This trait tags `Elementwise` operatons that can be systematically
1403 /// tensorized. All scalar operands and results are then replaced by tensors
1404 /// with the respective element type. Semantically, this is the operation on
1405 /// multiple elements simultaneously. See also `Vectorizable`.
1406 ///
1407 /// Rationale:
1408 /// Provide the reverse to `Scalarizable` which, when chained together, allows
1409 /// reasoning about the relationship between the tensor and vector case.
1410 /// Additionally, it permits reasoning about promoting scalars to tensors via
1411 /// broadcasting in cases like `%select_scalar_pred` below.
1412 ///
1413 /// Examples:
1414 /// ```
1415 /// %scalar = "arith.addf"(%a, %b) : (f32, f32) -> f32
1416 /// ```
1417 /// can be tensorized to
1418 /// ```
1419 /// %tensor = "arith.addf"(%a, %b) : (tensor<?xf32>, tensor<?xf32>)
1420 /// -> tensor<?xf32>
1421 /// ```
1422 ///
1423 /// ```
1424 /// %scalar_pred = "arith.select"(%pred, %true_val, %false_val)
1425 /// : (i1, tensor<?xf32>, tensor<?xf32>) -> tensor<?xf32>
1426 /// ```
1427 /// can be tensorized to
1428 /// ```
1429 /// %tensor_pred = "arith.select"(%pred, %true_val, %false_val)
1430 /// : (tensor<?xi1>, tensor<?xf32>, tensor<?xf32>)
1431 /// -> tensor<?xf32>
1432 /// ```
1433 template <typename ConcreteType>
1434 struct Tensorizable : public TraitBase<ConcreteType, Tensorizable> {
1436  static_assert(
1437  ConcreteType::template hasTrait<Elementwise>(),
1438  "`Tensorizable` trait is only applicable to `Elementwise` ops.");
1439  return success();
1440  }
1441 };
1442 
1443 /// Together, `Elementwise`, `Scalarizable`, `Vectorizable`, and `Tensorizable`
1444 /// provide an easy way for scalar operations to conveniently generalize their
1445 /// behavior to vectors/tensors, and systematize conversion between these forms.
1447 
1448 } // namespace OpTrait
1449 
1450 //===----------------------------------------------------------------------===//
1451 // Internal Trait Utilities
1452 //===----------------------------------------------------------------------===//
1453 
1454 namespace op_definition_impl {
1455 //===----------------------------------------------------------------------===//
1456 // Trait Existence
1457 
1458 /// Returns true if this given Trait ID matches the IDs of any of the provided
1459 /// trait types `Traits`.
1460 template <template <typename T> class... Traits>
1461 static bool hasTrait(TypeID traitID) {
1462  TypeID traitIDs[] = {TypeID::get<Traits>()...};
1463  for (unsigned i = 0, e = sizeof...(Traits); i != e; ++i)
1464  if (traitIDs[i] == traitID)
1465  return true;
1466  return false;
1467 }
1468 
1469 //===----------------------------------------------------------------------===//
1470 // Trait Folding
1471 
1472 /// Trait to check if T provides a 'foldTrait' method for single result
1473 /// operations.
1474 template <typename T, typename... Args>
1476  std::declval<Operation *>(), std::declval<ArrayRef<Attribute>>()));
1477 template <typename T>
1479  llvm::is_detected<has_single_result_fold_trait, T>;
1480 /// Trait to check if T provides a general 'foldTrait' method.
1481 template <typename T, typename... Args>
1482 using has_fold_trait =
1483  decltype(T::foldTrait(std::declval<Operation *>(),
1484  std::declval<ArrayRef<Attribute>>(),
1485  std::declval<SmallVectorImpl<OpFoldResult> &>()));
1486 template <typename T>
1487 using detect_has_fold_trait = llvm::is_detected<has_fold_trait, T>;
1488 /// Trait to check if T provides any `foldTrait` method.
1489 /// NOTE: This should use std::disjunction when C++17 is available.
1490 template <typename T>
1495 
1496 /// Returns the result of folding a trait that implements a `foldTrait` function
1497 /// that is specialized for operations that have a single result.
1498 template <typename Trait>
1500  LogicalResult>
1502  SmallVectorImpl<OpFoldResult> &results) {
1503  assert(op->hasTrait<OpTrait::OneResult>() &&
1504  "expected trait on non single-result operation to implement the "
1505  "general `foldTrait` method");
1506  // If a previous trait has already been folded and replaced this operation, we
1507  // fail to fold this trait.
1508  if (!results.empty())
1509  return failure();
1510 
1511  if (OpFoldResult result = Trait::foldTrait(op, operands)) {
1512  if (result.template dyn_cast<Value>() != op->getResult(0))
1513  results.push_back(result);
1514  return success();
1515  }
1516  return failure();
1517 }
1518 /// Returns the result of folding a trait that implements a generalized
1519 /// `foldTrait` function that is supports any operation type.
1520 template <typename Trait>
1523  SmallVectorImpl<OpFoldResult> &results) {
1524  // If a previous trait has already been folded and replaced this operation, we
1525  // fail to fold this trait.
1526  return results.empty() ? Trait::foldTrait(op, operands, results) : failure();
1527 }
1528 template <typename Trait>
1530  LogicalResult>
1532  return failure();
1533 }
1534 
1535 /// Given a tuple type containing a set of traits, return the result of folding
1536 /// the given operation.
1537 template <typename... Ts>
1539  SmallVectorImpl<OpFoldResult> &results) {
1540  bool anyFolded = false;
1541  (void)std::initializer_list<int>{
1542  (anyFolded |= succeeded(foldTrait<Ts>(op, operands, results)), 0)...};
1543  return success(anyFolded);
1544 }
1545 
1546 //===----------------------------------------------------------------------===//
1547 // Trait Verification
1548 
1549 /// Trait to check if T provides a `verifyTrait` method.
1550 template <typename T, typename... Args>
1551 using has_verify_trait = decltype(T::verifyTrait(std::declval<Operation *>()));
1552 template <typename T>
1553 using detect_has_verify_trait = llvm::is_detected<has_verify_trait, T>;
1554 
1555 /// Trait to check if T provides a `verifyTrait` method.
1556 template <typename T, typename... Args>
1558  decltype(T::verifyRegionTrait(std::declval<Operation *>()));
1559 template <typename T>
1561  llvm::is_detected<has_verify_region_trait, T>;
1562 
1563 /// Verify the given trait if it provides a verifier.
1564 template <typename T>
1567  return T::verifyTrait(op);
1568 }
1569 template <typename T>
1572  return success();
1573 }
1574 
1575 /// Given a set of traits, return the result of verifying the given operation.
1576 template <typename... Ts>
1578  LogicalResult result = success();
1579  (void)std::initializer_list<int>{
1580  (result = succeeded(result) ? verifyTrait<Ts>(op) : failure(), 0)...};
1581  return result;
1582 }
1583 
1584 /// Verify the given trait if it provides a region verifier.
1585 template <typename T>
1588  return T::verifyRegionTrait(op);
1589 }
1590 template <typename T>
1592  LogicalResult>
1594  return success();
1595 }
1596 
1597 /// Given a set of traits, return the result of verifying the regions of the
1598 /// given operation.
1599 template <typename... Ts>
1601  (void)op;
1602  LogicalResult result = success();
1603  (void)std::initializer_list<int>{
1604  (result = succeeded(result) ? verifyRegionTrait<Ts>(op) : failure(),
1605  0)...};
1606  return result;
1607 }
1608 } // namespace op_definition_impl
1609 
1610 //===----------------------------------------------------------------------===//
1611 // Operation Definition classes
1612 //===----------------------------------------------------------------------===//
1613 
1614 /// This provides public APIs that all operations should have. The template
1615 /// argument 'ConcreteType' should be the concrete type by CRTP and the others
1616 /// are base classes by the policy pattern.
1617 template <typename ConcreteType, template <typename T> class... Traits>
1618 class Op : public OpState, public Traits<ConcreteType>... {
1619 public:
1620  /// Inherit getOperation from `OpState`.
1621  using OpState::getOperation;
1622  using OpState::verify;
1623  using OpState::verifyRegions;
1624 
1625  /// Return if this operation contains the provided trait.
1626  template <template <typename T> class Trait>
1627  static constexpr bool hasTrait() {
1628  return llvm::is_one_of<Trait<ConcreteType>, Traits<ConcreteType>...>::value;
1629  }
1630 
1631  /// Create a deep copy of this operation.
1632  ConcreteType clone() { return cast<ConcreteType>(getOperation()->clone()); }
1633 
1634  /// Create a partial copy of this operation without traversing into attached
1635  /// regions. The new operation will have the same number of regions as the
1636  /// original one, but they will be left empty.
1637  ConcreteType cloneWithoutRegions() {
1638  return cast<ConcreteType>(getOperation()->cloneWithoutRegions());
1639  }
1640 
1641  /// Return true if this "op class" can match against the specified operation.
1642  static bool classof(Operation *op) {
1643  if (auto info = op->getRegisteredInfo())
1644  return TypeID::get<ConcreteType>() == info->getTypeID();
1645 #ifndef NDEBUG
1646  if (op->getName().getStringRef() == ConcreteType::getOperationName())
1647  llvm::report_fatal_error(
1648  "classof on '" + ConcreteType::getOperationName() +
1649  "' failed due to the operation not being registered");
1650 #endif
1651  return false;
1652  }
1653  /// Provide `classof` support for other OpBase derived classes, such as
1654  /// Interfaces.
1655  template <typename T>
1657  classof(const T *op) {
1658  return classof(const_cast<T *>(op)->getOperation());
1659  }
1660 
1661  /// Expose the type we are instantiated on to template machinery that may want
1662  /// to introspect traits on this operation.
1663  using ConcreteOpType = ConcreteType;
1664 
1665  /// This is a public constructor. Any op can be initialized to null.
1666  explicit Op() : OpState(nullptr) {}
1667  Op(std::nullptr_t) : OpState(nullptr) {}
1668 
1669  /// This is a public constructor to enable access via the llvm::cast family of
1670  /// methods. This should not be used directly.
1671  explicit Op(Operation *state) : OpState(state) {}
1672 
1673  /// Methods for supporting PointerLikeTypeTraits.
1674  const void *getAsOpaquePointer() const {
1675  return static_cast<const void *>((Operation *)*this);
1676  }
1677  static ConcreteOpType getFromOpaquePointer(const void *pointer) {
1678  return ConcreteOpType(
1679  reinterpret_cast<Operation *>(const_cast<void *>(pointer)));
1680  }
1681 
1682  /// Attach the given models as implementations of the corresponding
1683  /// interfaces for the concrete operation.
1684  template <typename... Models>
1685  static void attachInterface(MLIRContext &context) {
1687  ConcreteType::getOperationName(), &context);
1688  if (!info)
1689  llvm::report_fatal_error(
1690  "Attempting to attach an interface to an unregistered operation " +
1691  ConcreteType::getOperationName() + ".");
1692  (void)std::initializer_list<int>{(checkInterfaceTarget<Models>(), 0)...};
1693  info->attachInterface<Models...>();
1694  }
1695 
1696 private:
1697  /// Trait to check if T provides a 'fold' method for a single result op.
1698  template <typename T, typename... Args>
1699  using has_single_result_fold =
1700  decltype(std::declval<T>().fold(std::declval<ArrayRef<Attribute>>()));
1701  template <typename T>
1702  using detect_has_single_result_fold =
1703  llvm::is_detected<has_single_result_fold, T>;
1704  /// Trait to check if T provides a general 'fold' method.
1705  template <typename T, typename... Args>
1706  using has_fold = decltype(std::declval<T>().fold(
1707  std::declval<ArrayRef<Attribute>>(),
1708  std::declval<SmallVectorImpl<OpFoldResult> &>()));
1709  template <typename T>
1710  using detect_has_fold = llvm::is_detected<has_fold, T>;
1711  /// Trait to check if T provides a 'print' method.
1712  template <typename T, typename... Args>
1713  using has_print =
1714  decltype(std::declval<T>().print(std::declval<OpAsmPrinter &>()));
1715  template <typename T>
1716  using detect_has_print = llvm::is_detected<has_print, T>;
1717 
1718  /// Trait to check if T provides a 'ConcreteEntity' type alias.
1719  template <typename T>
1720  using has_concrete_entity_t = typename T::ConcreteEntity;
1721 
1722  /// A struct-wrapped type alias to T::ConcreteEntity if provided and to
1723  /// ConcreteType otherwise. This is akin to std::conditional but doesn't fail
1724  /// on the missing typedef. Useful for checking if the interface is targeting
1725  /// the right class.
1726  template <typename T,
1728  struct InterfaceTargetOrOpT {
1729  using type = typename T::ConcreteEntity;
1730  };
1731  template <typename T> struct InterfaceTargetOrOpT<T, false> {
1732  using type = ConcreteType;
1733  };
1734 
1735  /// A hook for static assertion that the external interface model T is
1736  /// targeting the concrete type of this op. The model can also be a fallback
1737  /// model that works for every op.
1738  template <typename T> static void checkInterfaceTarget() {
1739  static_assert(std::is_same<typename InterfaceTargetOrOpT<T>::type,
1740  ConcreteType>::value,
1741  "attaching an interface to the wrong op kind");
1742  }
1743 
1744  /// Returns an interface map containing the interfaces registered to this
1745  /// operation.
1746  static detail::InterfaceMap getInterfaceMap() {
1747  return detail::InterfaceMap::template get<Traits<ConcreteType>...>();
1748  }
1749 
1750  /// Return the internal implementations of each of the OperationName
1751  /// hooks.
1752  /// Implementation of `FoldHookFn` OperationName hook.
1753  static OperationName::FoldHookFn getFoldHookFn() {
1754  return getFoldHookFnImpl<ConcreteType>();
1755  }
1756  /// The internal implementation of `getFoldHookFn` above that is invoked if
1757  /// the operation is single result and defines a `fold` method.
1758  template <typename ConcreteOpT>
1759  static std::enable_if_t<llvm::is_one_of<OpTrait::OneResult<ConcreteOpT>,
1760  Traits<ConcreteOpT>...>::value &&
1761  detect_has_single_result_fold<ConcreteOpT>::value,
1763  getFoldHookFnImpl() {
1764  return [](Operation *op, ArrayRef<Attribute> operands,
1765  SmallVectorImpl<OpFoldResult> &results) {
1766  return foldSingleResultHook<ConcreteOpT>(op, operands, results);
1767  };
1768  }
1769  /// The internal implementation of `getFoldHookFn` above that is invoked if
1770  /// the operation is not single result and defines a `fold` method.
1771  template <typename ConcreteOpT>
1772  static std::enable_if_t<!llvm::is_one_of<OpTrait::OneResult<ConcreteOpT>,
1773  Traits<ConcreteOpT>...>::value &&
1774  detect_has_fold<ConcreteOpT>::value,
1776  getFoldHookFnImpl() {
1777  return [](Operation *op, ArrayRef<Attribute> operands,
1778  SmallVectorImpl<OpFoldResult> &results) {
1779  return foldHook<ConcreteOpT>(op, operands, results);
1780  };
1781  }
1782  /// The internal implementation of `getFoldHookFn` above that is invoked if
1783  /// the operation does not define a `fold` method.
1784  template <typename ConcreteOpT>
1786  !detect_has_fold<ConcreteOpT>::value,
1788  getFoldHookFnImpl() {
1789  return [](Operation *op, ArrayRef<Attribute> operands,
1790  SmallVectorImpl<OpFoldResult> &results) {
1791  // In this case, we only need to fold the traits of the operation.
1792  return op_definition_impl::foldTraits<Traits<ConcreteType>...>(
1793  op, operands, results);
1794  };
1795  }
1796  /// Return the result of folding a single result operation that defines a
1797  /// `fold` method.
1798  template <typename ConcreteOpT>
1799  static LogicalResult
1800  foldSingleResultHook(Operation *op, ArrayRef<Attribute> operands,
1801  SmallVectorImpl<OpFoldResult> &results) {
1802  OpFoldResult result = cast<ConcreteOpT>(op).fold(operands);
1803 
1804  // If the fold failed or was in-place, try to fold the traits of the
1805  // operation.
1806  if (!result || result.template dyn_cast<Value>() == op->getResult(0)) {
1807  if (succeeded(op_definition_impl::foldTraits<Traits<ConcreteType>...>(
1808  op, operands, results)))
1809  return success();
1810  return success(static_cast<bool>(result));
1811  }
1812  results.push_back(result);
1813  return success();
1814  }
1815  /// Return the result of folding an operation that defines a `fold` method.
1816  template <typename ConcreteOpT>
1817  static LogicalResult foldHook(Operation *op, ArrayRef<Attribute> operands,
1818  SmallVectorImpl<OpFoldResult> &results) {
1819  LogicalResult result = cast<ConcreteOpT>(op).fold(operands, results);
1820 
1821  // If the fold failed or was in-place, try to fold the traits of the
1822  // operation.
1823  if (failed(result) || results.empty()) {
1824  if (succeeded(op_definition_impl::foldTraits<Traits<ConcreteType>...>(
1825  op, operands, results)))
1826  return success();
1827  }
1828  return result;
1829  }
1830 
1831  /// Implementation of `GetCanonicalizationPatternsFn` OperationName hook.
1833  getGetCanonicalizationPatternsFn() {
1834  return &ConcreteType::getCanonicalizationPatterns;
1835  }
1836  /// Implementation of `GetHasTraitFn`
1837  static OperationName::HasTraitFn getHasTraitFn() {
1838  return
1839  [](TypeID id) { return op_definition_impl::hasTrait<Traits...>(id); };
1840  }
1841  /// Implementation of `ParseAssemblyFn` OperationName hook.
1842  static OperationName::ParseAssemblyFn getParseAssemblyFn() {
1843  return &ConcreteType::parse;
1844  }
1845  /// Implementation of `PrintAssemblyFn` OperationName hook.
1846  static OperationName::PrintAssemblyFn getPrintAssemblyFn() {
1847  return getPrintAssemblyFnImpl<ConcreteType>();
1848  }
1849  /// The internal implementation of `getPrintAssemblyFn` that is invoked when
1850  /// the concrete operation does not define a `print` method.
1851  template <typename ConcreteOpT>
1854  getPrintAssemblyFnImpl() {
1855  return [](Operation *op, OpAsmPrinter &printer, StringRef defaultDialect) {
1856  return OpState::print(op, printer, defaultDialect);
1857  };
1858  }
1859  /// The internal implementation of `getPrintAssemblyFn` that is invoked when
1860  /// the concrete operation defines a `print` method.
1861  template <typename ConcreteOpT>
1864  getPrintAssemblyFnImpl() {
1865  return &printAssembly;
1866  }
1867  static void printAssembly(Operation *op, OpAsmPrinter &p,
1868  StringRef defaultDialect) {
1869  OpState::printOpName(op, p, defaultDialect);
1870  return cast<ConcreteType>(op).print(p);
1871  }
1872  /// Implementation of `VerifyInvariantsFn` OperationName hook.
1873  static LogicalResult verifyInvariants(Operation *op) {
1874  static_assert(hasNoDataMembers(),
1875  "Op class shouldn't define new data members");
1876  return failure(
1877  failed(op_definition_impl::verifyTraits<Traits<ConcreteType>...>(op)) ||
1878  failed(cast<ConcreteType>(op).verify()));
1879  }
1880  static OperationName::VerifyInvariantsFn getVerifyInvariantsFn() {
1881  return static_cast<LogicalResult (*)(Operation *)>(&verifyInvariants);
1882  }
1883  /// Implementation of `VerifyRegionInvariantsFn` OperationName hook.
1884  static LogicalResult verifyRegionInvariants(Operation *op) {
1885  static_assert(hasNoDataMembers(),
1886  "Op class shouldn't define new data members");
1887  return failure(
1888  failed(op_definition_impl::verifyRegionTraits<Traits<ConcreteType>...>(
1889  op)) ||
1890  failed(cast<ConcreteType>(op).verifyRegions()));
1891  }
1892  static OperationName::VerifyRegionInvariantsFn getVerifyRegionInvariantsFn() {
1893  return static_cast<LogicalResult (*)(Operation *)>(&verifyRegionInvariants);
1894  }
1895 
1896  static constexpr bool hasNoDataMembers() {
1897  // Checking that the derived class does not define any member by comparing
1898  // its size to an ad-hoc EmptyOp.
1899  class EmptyOp : public Op<EmptyOp, Traits...> {};
1900  return sizeof(ConcreteType) == sizeof(EmptyOp);
1901  }
1902 
1903  /// Allow access to internal implementation methods.
1904  friend RegisteredOperationName;
1905 };
1906 
1907 /// This class represents the base of an operation interface. See the definition
1908 /// of `detail::Interface` for requirements on the `Traits` type.
1909 template <typename ConcreteType, typename Traits>
1911  : public detail::Interface<ConcreteType, Operation *, Traits,
1912  Op<ConcreteType>, OpTrait::TraitBase> {
1913 public:
1915  using InterfaceBase = detail::Interface<ConcreteType, Operation *, Traits,
1917 
1918  /// Inherit the base class constructor.
1920 
1921 protected:
1922  /// Returns the impl interface instance for the given operation.
1923  static typename InterfaceBase::Concept *getInterfaceFor(Operation *op) {
1924  OperationName name = op->getName();
1925 
1926  // Access the raw interface from the operation info.
1928  if (auto *opIface = rInfo->getInterface<ConcreteType>())
1929  return opIface;
1930  // Fallback to the dialect to provide it with a chance to implement this
1931  // interface for this operation.
1932  return rInfo->getDialect().getRegisteredInterfaceForOp<ConcreteType>(
1933  op->getName());
1934  }
1935  // Fallback to the dialect to provide it with a chance to implement this
1936  // interface for this operation.
1937  if (Dialect *dialect = name.getDialect())
1938  return dialect->getRegisteredInterfaceForOp<ConcreteType>(name);
1939  return nullptr;
1940  }
1941 
1942  /// Allow access to `getInterfaceFor`.
1944 };
1945 
1946 //===----------------------------------------------------------------------===//
1947 // CastOpInterface utilities
1948 //===----------------------------------------------------------------------===//
1949 
1950 // These functions are out-of-line implementations of the methods in
1951 // CastOpInterface, which avoids them being template instantiated/duplicated.
1952 namespace impl {
1953 /// Attempt to fold the given cast operation.
1955  ArrayRef<Attribute> attrOperands,
1956  SmallVectorImpl<OpFoldResult> &foldResults);
1957 /// Attempt to verify the given cast operation.
1959  Operation *op, function_ref<bool(TypeRange, TypeRange)> areCastCompatible);
1960 } // namespace impl
1961 } // namespace mlir
1962 
1963 namespace llvm {
1964 
1965 template <typename T>
1967  T, std::enable_if_t<std::is_base_of<mlir::OpState, T>::value>> {
1968  static inline T getEmptyKey() {
1969  auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
1970  return T::getFromOpaquePointer(pointer);
1971  }
1972  static inline T getTombstoneKey() {
1974  return T::getFromOpaquePointer(pointer);
1975  }
1976  static unsigned getHashValue(T val) {
1977  return hash_value(val.getAsOpaquePointer());
1978  }
1979  static bool isEqual(T lhs, T rhs) { return lhs == rhs; }
1980 };
1981 
1982 } // namespace llvm
1983 
1984 #endif
operand_range::iterator operand_iterator
Definition: Operation.h:296
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, ArrayRef< NamedAttribute > attributes, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
Definition: Operation.cpp:27
static LogicalResult verifyTrait(Operation *op)
static LogicalResult verifyTrait(Operation *op)
Block * getSuccessor(unsigned i)
Definition: Block.cpp:240
OptionalParseResult(const InFlightDiagnostic &)
Definition: OpDefinition.h:42
This class contains a list of basic blocks and a link to the parent operation it is attached to...
Definition: Region.h:26
LogicalResult verifyRegionTraits(Operation *op)
Given a set of traits, return the result of verifying the regions of the given operation.
Similar to AttrSizedOperandSegments but used for results.
static LogicalResult verifyTrait(Operation *op)
result_range::type_range result_type_range
Definition: Operation.h:349
LogicalResult verifyNSuccessors(Operation *op, unsigned numSuccessors)
Definition: Operation.cpp:950
This class provides APIs for ops that are known to have at least a specified number of successors...
Definition: OpDefinition.h:778
void setSuccessor(Block *block, unsigned i)
Set the successor at index.
Definition: OpDefinition.h:733
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:221
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
LogicalResult verifyZeroOperands(Operation *op)
Definition: Operation.cpp:689
This class adds property that the operation is commutative.
Operation & back()
Definition: Block.h:143
LogicalResult verifyElementwise(Operation *op)
Definition: Operation.cpp:1054
Value getResult(unsigned i)
Return the result at index &#39;i&#39;.
Definition: OpDefinition.h:563
LogicalResult verifyResultsAreFloatLike(Operation *op)
Definition: Operation.cpp:980
static LogicalResult verifyTrait(Operation *op)
static LogicalResult verifyTrait(Operation *op)
This is the concrete base class that holds the operation pointer and has non-generic methods that onl...
Definition: OpDefinition.h:79
unsigned getNumRegions()
Returns the number of regions held by this operation.
Definition: Operation.h:475
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:311
Operation * operator->() const
Shortcut of -> to access a member of Operation.
Definition: OpDefinition.h:88
std::enable_if< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT >::type walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one)...
Definition: OpDefinition.h:146
LogicalResult foldCastInterfaceOp(Operation *op, ArrayRef< Attribute > attrOperands, SmallVectorImpl< OpFoldResult > &foldResults)
Attempt to fold the given cast operation.
Definition: Operation.cpp:1150
LogicalResult verifyResultSizeAttr(Operation *op, StringRef sizeAttrName)
Definition: Operation.cpp:1034
This class provides APIs for ops that are known to have at least a specified number of regions...
Definition: OpDefinition.h:518
Block represents an ordered list of Operations.
Definition: Block.h:29
Block & front()
Definition: Region.h:65
LogicalResult verifyIsInvolution(Operation *op)
Definition: Operation.cpp:739
static LogicalResult verifyTrait(Operation *op)
This class provides APIs and verifiers for ops with regions having a single block.
Definition: OpDefinition.h:804
LogicalResult verifySameOperandsAndResultShape(Operation *op)
Definition: Operation.cpp:842
A trait of region holding operations that define a new scope for automatic allocations, i.e., allocations that are freed when control is transferred back from the operation&#39;s region.
LogicalResult verifyIsIsolatedFromAbove(Operation *op)
Check for any values used by operations regions attached to the specified "IsIsolatedFromAbove" opera...
Definition: Operation.cpp:1097
This class verifies that any results of the specified op have a floating point type, a vector thereof, or a tensor thereof.
OpFoldResult foldIdempotent(Operation *op)
Definition: Operation.cpp:665
typename std::enable_if_t< OpT::template hasTrait< OneRegion >(), T > enable_if_single_region
The following are a set of methods only enabled when the parent operation has a single region...
Definition: OpDefinition.h:847
This class represents a single result from folding an operation.
Definition: OpDefinition.h:229
enable_if_single_region< OpT, Block::iterator > end()
Definition: OpDefinition.h:854
A trait for operations that have an attribute specifying operand segments.
bool hasElementwiseMappableTraits(Operation *op)
Together, Elementwise, Scalarizable, Vectorizable, and Tensorizable provide an easy way for scalar op...
Definition: Operation.cpp:1139
This class provides verification for ops that are known to have the same operand element type (or the...
LogicalResult verifyNOperands(Operation *op, unsigned numOperands)
Definition: Operation.cpp:701
A trait of region holding operations that defines a new scope for polyhedral optimization purposes...
void print(raw_ostream &os, OpPrintingFlags flags=llvm::None)
Print the operation to the given stream.
Definition: OpDefinition.h:97
static LogicalResult verifyTrait(Operation *op)
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
Definition: LogicalResult.h:72
static LogicalResult verifyTrait(Operation *op)
This class provides return value APIs for ops that are known to have a single result.
Definition: OpDefinition.h:598
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:785
void setOperand(Value value)
Definition: OpDefinition.h:393
static std::enable_if_t< std::is_base_of< OpState, T >::value, bool > classof(const T *op)
Provide classof support for other OpBase derived classes, such as Interfaces.
LogicalResult verifySameOperandsElementType(Operation *op)
Definition: Operation.cpp:857
static LogicalResult verifyTrait(Operation *op)
static void ensureTerminator(Region &region, OpBuilder &builder, Location loc)
Definition: OpDefinition.h:937
static LogicalResult verifyTrait(Operation *op)
This class provides the API for ops which have an unknown number of successors.
Definition: OpDefinition.h:794
MLIRContext * getContext()
Return the context this operation belongs to.
Definition: OpDefinition.h:94
static void attachInterface(MLIRContext &context)
Attach the given models as implementations of the corresponding interfaces for the concrete operation...
OpFoldResult foldInvolution(Operation *op)
Definition: Operation.cpp:679
std::enable_if_t<!detect_has_verify_trait< T >::value, LogicalResult > verifyTrait(Operation *)
bool operator!=(StringAttr lhs, std::nullptr_t)
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:509
LogicalResult verify()
If the concrete type didn&#39;t implement a custom verifier hook, just fall back to this one which accept...
Definition: OpDefinition.h:188
static LogicalResult verifyTrait(Operation *op)
LogicalResult verifyCastInterfaceOp(Operation *op, function_ref< bool(TypeRange, TypeRange)> areCastCompatible)
Attempt to verify the given cast operation.
Definition: Operation.cpp:1167
static LogicalResult verifyTrait(Operation *op)
unsigned getNumSuccessors()
Return the number of successors.
Definition: OpDefinition.h:723
This class implements the result iterators for the Operation class.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value...
Definition: LogicalResult.h:68
Utility trait base that provides accessors for derived traits that have multiple regions.
Definition: OpDefinition.h:461
This class provides the API for ops that are known to be terminators.
Definition: OpDefinition.h:697
void print(raw_ostream &os, AsmState &asmState)
Definition: OpDefinition.h:100
decltype(T::verifyRegionTrait(std::declval< Operation * >())) has_verify_region_trait
Trait to check if T provides a verifyTrait method.
This class represents an abstract interface.
Operation * getOperation()
Return the operation that this refers to.
Definition: OpDefinition.h:91
enable_if_single_region< OpT, Operation & > front()
Definition: OpDefinition.h:858
static bool classof(Operation *op)
Return true if this "op class" can match against the specified operation.
This class provides return value APIs for ops that are known to have a single result.
Definition: OpDefinition.h:633
The OpAsmParser has methods for interacting with the asm parser: parsing things from it...
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:452
enable_if_single_region< OpT > insert(Block::iterator insertPt, Operation *op)
Definition: OpDefinition.h:966
LogicalResult verifyAtLeastNSuccessors(Operation *op, unsigned numSuccessors)
Definition: Operation.cpp:959
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
LogicalResult verifySameOperandsAndResultElementType(Operation *op)
Definition: Operation.cpp:871
LogicalResult verifyOperandsAreFloatLike(Operation *op)
Definition: Operation.cpp:757
LogicalResult verifyResultsAreBoolLike(Operation *op)
Definition: Operation.cpp:969
Op(Operation *state)
This is a public constructor to enable access via the llvm::cast family of methods.
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:657
llvm::unique_function< ParseResult(OpAsmParser &, OperationState &) const > ParseAssemblyFn
enable_if_single_region< OpT > push_back(Operation *op)
Insert the operation into the back of the body, before the terminator.
Definition: OpDefinition.h:954
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
static constexpr const bool value
LogicalResult verifySameOperandsAndResultType(Operation *op)
Definition: Operation.cpp:895
This class provides the API for ops which have an unknown number of results.
Definition: OpDefinition.h:684
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:366
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
LogicalResult verifyOneOperand(Operation *op)
Definition: Operation.cpp:695
result_range::type_iterator result_type_iterator
Support result type iteration.
Definition: Operation.h:348
operand_iterator operand_begin()
Operand iterator access.
Definition: OpDefinition.h:340
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:544
LogicalResult verifyAtLeastNResults(Operation *op, unsigned numOperands)
Definition: Operation.cpp:824
OpState(Operation *state)
Mutability management is handled by the OpWrapper/OpConstWrapper classes, so we can cast it away here...
Definition: OpDefinition.h:209
LogicalResult verifySameTypeOperands(Operation *op)
Definition: Operation.cpp:766
LogicalResult verifyNRegions(Operation *op, unsigned numRegions)
Definition: Operation.cpp:791
This class provides APIs for ops that are known to have a single region.
Definition: OpDefinition.h:482
decltype(walk(nullptr, std::declval< FnT >())) walkResultType
Utility to provide the return type of a templated walk method.
Definition: Visitors.h:319
static OpFoldResult foldTrait(Operation *op, ArrayRef< Attribute > operands)
llvm::is_detected< has_single_result_fold_trait, T > detect_has_single_result_fold_trait
enable_if_single_region< OpT > push_back(Operation *op)
Insert the operation into the back of the body.
Definition: OpDefinition.h:864
std::enable_if_t<!detect_has_verify_region_trait< T >::value, LogicalResult > verifyRegionTrait(Operation *)
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided &#39;values&#39;.
Definition: OpDefinition.h:568
static LogicalResult verifyTrait(Operation *op)
StringRef getStringRef() const
Return the name of this operation. This always succeeds.
bool use_empty()
Return true if there are no users of any results of this operation.
Definition: OpDefinition.h:111
void dump()
Dump this operation.
Definition: OpDefinition.h:105
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
This class implements iteration on the types of a given range of values.
Definition: TypeRange.h:126
static LogicalResult verifyTrait(Operation *op)
This class adds property that the operation is idempotent.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
LogicalResult verifyOneResult(Operation *op)
Definition: Operation.cpp:811
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
void setSuccessor(Block *succ)
Definition: OpDefinition.h:749
This trait tags Elementwise operatons that can be systematically tensorized.
OpListType::iterator iterator
Definition: Block.h:131
bool empty()
Definition: Region.h:60
This class provides an efficient mapping between a given Interface type, and a particular implementat...
unsigned getNumResults()
Return the number of results.
Definition: OpDefinition.h:560
llvm::unique_function< LogicalResult(Operation *) const > VerifyInvariantsFn
enable_if_single_region< OpT > insert(Operation *insertPt, Operation *op)
Insert the operation at the given insertion point.
Definition: OpDefinition.h:870
Region & getBodyRegion(unsigned idx=0)
Definition: OpDefinition.h:833
static LogicalResult verifyRegionTrait(Operation *op)
Definition: OpDefinition.h:902
This class verifies that any results of the specified op have a boolean type, a vector thereof...
SuccessorRange::iterator succ_iterator
Definition: Operation.h:498
llvm::unique_function< void(Operation *, OpAsmPrinter &, StringRef) const > PrintAssemblyFn
This class provides verification for ops that are known to have the same operand and result type...
LogicalResult verifyRegions()
Definition: OpDefinition.h:189
LogicalResult verifyAtLeastNRegions(Operation *op, unsigned numRegions)
Definition: Operation.cpp:798
virtual void * getRegisteredInterfaceForOp(TypeID interfaceID, OperationName opName)
Lookup an op interface for the given ID if one is registered, otherwise nullptr.
Definition: Dialect.h:171
void replaceAllUsesWith(Value newValue)
Replace all uses of &#39;this&#39; value with the new value, updating anything in the IR that uses &#39;this&#39; to ...
Definition: OpDefinition.h:609
static LogicalResult verifyTrait(Operation *op)
Support to check if an operation has the SingleBlockImplicitTerminator trait.
Definition: OpDefinition.h:986
LogicalResult verifyZeroResults(Operation *op)
Definition: Operation.cpp:805
Attributes are known-constant values of operations.
Definition: Attributes.h:24
void setOperand(unsigned i, Value value)
Set the operand at index &#39;i&#39; to &#39;value&#39;.
Definition: OpDefinition.h:335
static LogicalResult verifyTrait(Operation *op)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
Definition: Operation.h:526
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Definition: Operation.h:172
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:699
static LogicalResult verifyTrait(Operation *op)
LogicalResult verifyValueSizeAttr(Operation *op, StringRef attrName, StringRef valueGroupName, size_t expectedCount)
Definition: Operation.cpp:996
llvm::is_detected< has_fold_trait, T > detect_has_fold_trait
OptionalParseResult(ParseResult result)
Definition: OpDefinition.h:41
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:618
ParseResult operator*() const
Definition: OpDefinition.h:51
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
This class provides the API for ops which have an unknown number of SSA operands. ...
Definition: OpDefinition.h:441
OpResult getResult(unsigned idx)
Get the &#39;idx&#39;th result of this operation.
Definition: Operation.h:331
This class provides the API for ops that are known to have a specified number of successors.
Definition: OpDefinition.h:761
decltype(T::foldTrait(std::declval< Operation * >(), std::declval< ArrayRef< Attribute > >())) has_single_result_fold_trait
Trait to check if T provides a &#39;foldTrait&#39; method for single result operations.
verifyInvariantsImpl verifies the invariants like the types, attrs, .etc.
Definition: OpDefinition.h:364
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:38
This class provides verification for ops that are known to have zero successors.
Definition: OpDefinition.h:707
This class provides the API for ops that are known to have a specified number of operands.
Definition: OpDefinition.h:406
This class provides APIs and verifiers for ops with regions having a single block that must terminate...
Definition: OpDefinition.h:885
static LogicalResult verifyTrait(Operation *op)
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This class provides a verifier for ops that are expecting their parent to be one of the given parent ...
Optional< RegisteredOperationName > getRegisteredInfo() const
If this operation is registered, returns the registered information, None otherwise.
void erase()
Remove this operation from its parent block and delete it.
Definition: OpDefinition.h:114
void ensureRegionTerminator(Region &region, Builder &builder, Location loc, function_ref< Operation *(OpBuilder &, Location)> buildTerminatorOp)
Create a simple OpBuilder and forward to the OpBuilder version of this function.
Definition: Operation.cpp:1215
This represents an operation in an abstracted form, suitable for use with the builder APIs...
This class provides verification for ops that are known to have zero regions.
Definition: OpDefinition.h:450
ConcreteType clone()
Create a deep copy of this operation.
static LogicalResult verifyTrait(Operation *op)
LogicalResult verifyOneSuccessor(Operation *op)
Definition: Operation.cpp:943
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:769
static LogicalResult foldTraits(Operation *op, ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Given a tuple type containing a set of traits, return the result of folding the given operation...
friend InterfaceBase
Allow access to getInterfaceFor.
std::enable_if< llvm::function_traits< std::decay_t< FnT > >::num_args==2, RetT >::type walk(FnT &&callback)
Generic walker with a stage aware callback.
Definition: OpDefinition.h:174
auto getOps()
Returns a range of operations within the region of this operation.
Definition: OpDefinition.h:487
static Optional< RegisteredOperationName > lookup(StringRef name, MLIRContext *ctx)
Lookup the registered operation information for the given operation.
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:376
This class represents the base of an operation interface.
This trait tags element-wise ops on vectors or tensors.
Op()
This is a public constructor. Any op can be initialized to null.
llvm::unique_function< void(RewritePatternSet &, MLIRContext *) const > GetCanonicalizationPatternsFn
bool empty()
Definition: Block.h:139
This class implements the successor iterators for Block.
Definition: BlockSupport.h:72
static LogicalResult verifyRegionTrait(Operation *op)
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:432
This trait provides a verifier for ops that are expecting their regions to not have any arguments...
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:806
enable_if_single_region< OpT > insert(Operation *insertPt, Operation *op)
Insert the operation at the given insertion point.
Definition: OpDefinition.h:962
static InterfaceBase::Concept * getInterfaceFor(Operation *op)
Returns the impl interface instance for the given operation.
void replaceAllUsesWith(Operation *op)
Replace all uses of &#39;this&#39; value with the result of &#39;op&#39;.
Definition: OpDefinition.h:614
unsigned getNumRegions()
Return the number of regions.
Definition: OpDefinition.h:466
This class provides verification for ops that are known to have the same operand and result element t...
llvm::is_detected< has_verify_trait, T > detect_has_verify_trait
LogicalResult verifySameOperandsShape(Operation *op)
Definition: Operation.cpp:832
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:753
result_type_iterator result_type_begin()
Result type access.
Definition: OpDefinition.h:583
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
This class verifies that all operands of the specified op have a signless integer or index type...
enable_if_single_region< OpT, Block::iterator > begin()
Definition: OpDefinition.h:850
ParseResult getValue() const
Access the internal ParseResult value.
Definition: OpDefinition.h:50
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:37
static void ensureTerminator(Region &region, Builder &builder, Location loc)
Ensure that the given region has the terminator required by this trait.
Definition: OpDefinition.h:932
This class verifies that any results of the specified op have a signless integer or index type...
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:240
This class implements iteration on the types of a given range of values.
Definition: Block.h:26
LogicalResult verifyAtLeastNOperands(Operation *op, unsigned numOperands)
Definition: Operation.cpp:710
This class indicates that the regions associated with this op don&#39;t have terminators.
Definition: OpDefinition.h:693
LogicalResult verifyResultsAreSignlessIntegerLike(Operation *op)
Definition: Operation.cpp:989
succ_iterator succ_begin()
Successor iterator access.
Definition: OpDefinition.h:738
ConcreteType cloneWithoutRegions()
Create a partial copy of this operation without traversing into attached regions. ...
Block * getBody(unsigned idx=0)
Definition: OpDefinition.h:828
Helper class for implementing traits.
Definition: OpDefinition.h:306
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:675
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
Set of flags used to control the behavior of the various IR print methods (e.g.
llvm::unique_function< LogicalResult(Operation *) const > VerifyRegionInvariantsFn
This class provides the API for ops which have an unknown number of regions.
Definition: OpDefinition.h:533
enable_if_single_region< OpT > insert(Block::iterator insertPt, Operation *op)
Definition: OpDefinition.h:874
Utility trait base that provides accessors for derived traits that have multiple successors.
Definition: OpDefinition.h:718
This class is a general helper class for creating context-global objects like types, attributes, and affine expressions.
Definition: Builders.h:49
This class provides the API for ops that are known to have a specified number of regions.
Definition: OpDefinition.h:501
std::conditional_t< bool(detect_has_fold_trait< T >::value), detect_has_fold_trait< T >, detect_has_single_result_fold_trait< T > > detect_has_any_fold_trait
Trait to check if T provides any foldTrait method.
Location getLoc()
The source location the operation was defined or derived from.
Definition: OpDefinition.h:108
This class provides verification for ops that are known to have the same operand and result shape: bo...
static void getCanonicalizationPatterns(RewritePatternSet &results, MLIRContext *context)
This hook returns any canonicalization pattern rewrites that the operation supports, for use by the canonicalization pass.
Definition: OpDefinition.h:182
This class provides the API for ops that are known to be isolated from above.
OperandRange operand_range
Definition: Operation.h:295
OptionalParseResult(llvm::NoneType)
Definition: OpDefinition.h:44
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:395
LogicalResult verifyTraits(Operation *op)
Given a set of traits, return the result of verifying the given operation.
static constexpr bool hasTrait()
Return if this operation contains the provided trait.
static bool hasTrait(TypeID traitID)
Returns true if this given Trait ID matches the IDs of any of the provided trait types Traits...
Region & getRegion(unsigned i)
Return the region at index.
Definition: OpDefinition.h:469
This class provides the API for ops that are known to have a at least a specified number of operands...
Definition: OpDefinition.h:426
This trait tags Elementwise operatons that can be systematically scalarized.
TerminatorOpType ImplicitTerminatorOpT
The type of the operation used as the implicit terminator type.
Definition: OpDefinition.h:900
static std::enable_if_t<!detect_has_any_fold_trait< Trait >::value, LogicalResult > foldTrait(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &)
NestedPattern Op(FilterFunctionType filter=defaultFilterFunction)
This class provides verification for ops that are known to have the same operand shape: all operands ...
Op(std::nullptr_t)
Utility trait base that provides accessors for derived traits that have multiple operands.
Definition: OpDefinition.h:322
static LogicalResult verifyTrait(Operation *op)
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
This class provides the API for ops that are known to have no SSA operand.
Definition: OpDefinition.h:374
LogicalResult verifyNoRegionArguments(Operation *op)
Definition: Operation.cpp:1039
static ConcreteOpType getFromOpaquePointer(const void *pointer)
This class provides an abstraction over the different types of ranges over Regions.
Definition: Region.h:328
AffineDmaStartOp starts a non-blocking DMA operation that transfers data from a source memref to a de...
Definition: AffineOps.h:89
operand_type_iterator operand_type_begin()
Operand type access.
Definition: OpDefinition.h:347
LogicalResult verifyOperandsAreSignlessIntegerLike(Operation *op)
Definition: Operation.cpp:748
This class provides the API for ops that are known to have exactly one SSA operand.
Definition: OpDefinition.h:389
This class implements the operand iterators for the Operation class.
This provides public APIs that all operations should have.
static LogicalResult verifyTrait(Operation *op)
result_range::iterator result_iterator
Definition: Operation.h:335
static LogicalResult verifyTrait(Operation *op)
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context...
LogicalResult verifyIsIdempotent(Operation *op)
Definition: Operation.cpp:731
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs, on this operation and any nested operations.
Definition: Verifier.cpp:372
llvm::unique_function< LogicalResult(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) const > FoldHookFn
This class provides the API for ops that are known to have a specified number of results.
Definition: OpDefinition.h:649
This trait is used for return value APIs for ops that are known to have a specific type other than Ty...
Definition: OpDefinition.h:628
bool hasValue() const
Returns true if we contain a valid ParseResult value.
Definition: OpDefinition.h:47
LogicalResult verifyZeroRegions(Operation *op)
Definition: Operation.cpp:779
ResultRange result_range
Support result iteration.
Definition: Operation.h:334
operand_range::type_range operand_type_range
Definition: Operation.h:318
InFlightDiagnostic emitRemark(Location loc)
Utility method to emit a remark message using this location.
static OpFoldResult foldTrait(Operation *op, ArrayRef< Attribute > operands)
static LogicalResult verifyTrait(Operation *op)
This class verifies that all operands of the specified op have the same type.
LogicalResult verifyZeroSuccessors(Operation *op)
Definition: Operation.cpp:935
This is a "type erased" representation of a registered operation.
LogicalResult verifyNResults(Operation *op, unsigned numOperands)
Definition: Operation.cpp:817
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:414
decltype(T::foldTrait(std::declval< Operation * >(), std::declval< ArrayRef< Attribute > >(), std::declval< SmallVectorImpl< OpFoldResult > & >())) has_fold_trait
Trait to check if T provides a general &#39;foldTrait&#39; method.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "&#39;dim&#39; op " which is convenient for verifiers...
Definition: Operation.cpp:518
Optional< RegisteredOperationName > getRegisteredInfo()
If this operation has a registered operation description, return it.
Definition: Operation.h:61
This class provides APIs for ops that are known to have a single successor.
Definition: OpDefinition.h:746
This trait tags Elementwise operatons that can be systematically vectorized.
decltype(T::verifyTrait(std::declval< Operation * >())) has_verify_trait
Trait to check if T provides a verifyTrait method.
Utility trait base that provides accessors for derived traits that have multiple results.
Definition: OpDefinition.h:553
OperationName getName()
The name of an operation is the key identifier for it.
Definition: Operation.h:57
This class adds property that the operation is an involution.
static LogicalResult verifyTrait(Operation *op)
WalkOrder
Traversal order for region, block and operation walk utilities.
Definition: Visitors.h:62
This class represents success/failure for parsing-like operations that find it important to chain tog...
OptionalParseResult(LogicalResult result)
Definition: OpDefinition.h:40
llvm::is_detected< has_verify_region_trait, T > detect_has_verify_region_trait
unsigned getNumOperands()
Return the number of operands.
Definition: OpDefinition.h:329
This class provides the API for a sub-set of ops that are known to be constant-like.
This class helps build Operations.
Definition: Builders.h:184
llvm::unique_function< bool(TypeID) const > HasTraitFn
Type getType(unsigned i)
Return the type of the i-th result.
Definition: OpDefinition.h:573
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:524
region_iterator region_begin()
Region iterator access.
Definition: OpDefinition.h:472
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:493
Value getOperand(unsigned i)
Return the operand at index &#39;i&#39;.
Definition: OpDefinition.h:332
LogicalResult verifyOperandSizeAttr(Operation *op, StringRef sizeAttrName)
Definition: Operation.cpp:1029
Region & getRegion(unsigned index)
Returns the region held by this operation at position &#39;index&#39;.
Definition: Operation.h:484
This class verifies that all operands of the specified op have a float type, a vector thereof...
LogicalResult verifyIsTerminator(Operation *op)
Definition: Operation.cpp:917
LogicalResult verifyOneRegion(Operation *op)
Definition: Operation.cpp:785
Operation * getOperation()
Return the ultimate Operation being worked on.
Definition: OpDefinition.h:309
bool operator==(StringAttr lhs, std::nullptr_t)
Define comparisons for StringAttr against nullptr and itself to avoid the StringRef overloads from be...
typename T::ImplicitTerminatorOpT has_implicit_terminator_t
Check is an op defines the ImplicitTerminatorOpT member.
Definition: OpDefinition.h:979
This class provides management for the lifetime of the state used when printing the IR...
Definition: AsmState.h:345
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:709
result_iterator result_begin()
Result iterator access.
Definition: OpDefinition.h:576
Block * getSuccessor(unsigned i)
Return the successor at index.
Definition: OpDefinition.h:728
static void printOpName(Operation *op, OpAsmPrinter &p, StringRef defaultDialect)
Print an operation name, eliding the dialect prefix if necessary.
Definition: Operation.cpp:629
const void * getAsOpaquePointer() const
Methods for supporting PointerLikeTypeTraits.
This class provides the API for ops that are known to have at least a specified number of results...
Definition: OpDefinition.h:669
This class provides return value APIs for ops that are known to have zero results.
Definition: OpDefinition.h:542
operand_range::type_iterator operand_type_iterator
Definition: Operation.h:317