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