My Project
OpDefinition.h
Go to the documentation of this file.
1 //===- OpDefinition.h - Classes for defining concrete Op types --*- C++ -*-===//
2 //
3 // Part of the MLIR 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/Operation.h"
23 #include <type_traits>
24 
25 namespace mlir {
26 class Builder;
27 
28 namespace OpTrait {
29 template <typename ConcreteType> class OneResult;
30 }
31 
36 class ParseResult : public LogicalResult {
37 public:
39 
40  // Allow diagnostics emitted during parsing to be converted to failure.
43 
45  explicit operator bool() const { return failed(*this); }
46 };
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 
62  bool hasValue() const { return impl.hasValue(); }
63 
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 {
79 void ensureRegionTerminator(Region &region, Location loc,
80  function_ref<Operation *()> buildTerminatorOp);
82 template <typename OpTy>
83 void ensureRegionTerminator(Region &region, Builder &builder, Location loc) {
84  ensureRegionTerminator(region, loc, [&] {
85  OperationState state(loc, OpTy::getOperationName());
86  OpTy::build(&builder, state);
87  return Operation::create(state);
88  });
89 }
90 } // namespace impl
91 
98 class OpState {
99 public:
101  operator bool() { return getOperation() != nullptr; }
102 
104  operator Operation *() const { return state; }
105 
107  Operation *getOperation() { return state; }
108 
111  Operation *getParentOp() { return getOperation()->getParentOp(); }
112 
114  template <typename OpTy> OpTy getParentOfType() {
115  return getOperation()->getParentOfType<OpTy>();
116  }
117 
119  MLIRContext *getContext() { return getOperation()->getContext(); }
120 
122  void print(raw_ostream &os, OpPrintingFlags flags = llvm::None) {
123  state->print(os, flags);
124  }
125 
127  void dump() { state->dump(); }
128 
130  Location getLoc() { return state->getLoc(); }
131  void setLoc(Location loc) { state->setLoc(loc); }
132 
134  ArrayRef<NamedAttribute> getAttrs() { return state->getAttrs(); }
135 
139 
141  dialect_attr_range getDialectAttrs() { return state->getDialectAttrs(); }
143  return state->dialect_attr_begin();
144  }
145  dialect_attr_iterator dialect_attr_end() { return state->dialect_attr_end(); }
146 
148  Attribute getAttr(StringRef name) { return state->getAttr(name); }
149 
151  template <typename AttrClass> AttrClass getAttrOfType(StringRef name) {
152  return getAttr(name).dyn_cast_or_null<AttrClass>();
153  }
154 
157  void setAttr(Identifier name, Attribute value) {
158  state->setAttr(name, value);
159  }
160  void setAttr(StringRef name, Attribute value) {
161  setAttr(Identifier::get(name, getContext()), value);
162  }
163 
166  state->setAttrs(attributes);
167  }
168  void setAttrs(NamedAttributeList newAttrs) { state->setAttrs(newAttrs); }
169 
171  template <typename DialectAttrs> void setDialectAttrs(DialectAttrs &&attrs) {
172  state->setDialectAttrs(std::move(attrs));
173  }
174 
178  return state->removeAttr(name);
179  }
181  return state->removeAttr(Identifier::get(name, getContext()));
182  }
183 
185  bool use_empty() { return state->use_empty(); }
186 
188  void erase() { state->erase(); }
189 
192  InFlightDiagnostic emitOpError(const Twine &message = {});
193 
196  InFlightDiagnostic emitError(const Twine &message = {});
197 
200  InFlightDiagnostic emitWarning(const Twine &message = {});
201 
204  InFlightDiagnostic emitRemark(const Twine &message = {});
205 
209  template <typename FnT, typename RetT = detail::walkResultType<FnT>>
210  RetT walk(FnT &&callback) {
211  return state->walk(std::forward<FnT>(callback));
212  }
213 
214  // These are default implementations of customization hooks.
215 public:
219  MLIRContext *context) {}
220 
221 protected:
224  LogicalResult verify() { return success(); }
225 
229  static ParseResult parse(OpAsmParser &parser, OperationState &result);
230 
231  // The fallback for the printer is to print it the generic assembly form.
232  void print(OpAsmPrinter &p);
233 
236  explicit OpState(Operation *state) : state(state) {}
237 
238 private:
239  Operation *state;
240 };
241 
242 // Allow comparing operators.
243 inline bool operator==(OpState lhs, OpState rhs) {
244  return lhs.getOperation() == rhs.getOperation();
245 }
246 inline bool operator!=(OpState lhs, OpState rhs) {
247  return lhs.getOperation() != rhs.getOperation();
248 }
249 
251 class OpFoldResult : public PointerUnion<Attribute, Value> {
253 };
254 
259 template <typename ConcreteType, bool isSingleResult, typename = void>
260 class FoldingHook {
261 public:
266  return cast<ConcreteType>(op).fold(operands, results);
267  }
268 
293  return failure();
294  }
295 };
296 
300 template <typename ConcreteType, bool isSingleResult>
301 class FoldingHook<ConcreteType, isSingleResult,
302  typename std::enable_if<isSingleResult>::type> {
303 public:
306  operator Value() {
307  return static_cast<ConcreteType *>(this)->getOperation()->getResult(0);
308  }
309 
314  auto result = cast<ConcreteType>(op).fold(operands);
315  if (!result)
316  return failure();
317 
318  // Check if the operation was folded in place. In this case, the operation
319  // returns itself.
320  if (result.template dyn_cast<Value>() != op->getResult(0))
321  results.push_back(result);
322  return success();
323  }
324 
346  OpFoldResult fold(ArrayRef<Attribute> operands) { return {}; }
347 };
348 
349 //===----------------------------------------------------------------------===//
350 // Operation Trait Types
351 //===----------------------------------------------------------------------===//
352 
353 namespace OpTrait {
354 
355 // These functions are out-of-line implementations of the methods in the
356 // corresponding trait classes. This avoids them being template
357 // instantiated/duplicated.
358 namespace impl {
361 LogicalResult verifyNOperands(Operation *op, unsigned numOperands);
362 LogicalResult verifyAtLeastNOperands(Operation *op, unsigned numOperands);
368 LogicalResult verifyNResults(Operation *op, unsigned numOperands);
369 LogicalResult verifyAtLeastNResults(Operation *op, unsigned numOperands);
379 LogicalResult verifyOperandSizeAttr(Operation *op, StringRef sizeAttrName);
380 LogicalResult verifyResultSizeAttr(Operation *op, StringRef sizeAttrName);
381 } // namespace impl
382 
385 template <typename ConcreteType, template <typename> class TraitType>
386 class TraitBase {
387 protected:
390  // We have to cast up to the trait type, then to the concrete type, then to
391  // the BaseState class in explicit hops because the concrete type will
392  // multiply derive from the (content free) TraitBase class, and we need to
393  // be able to disambiguate the path for the C++ compiler.
394  auto *trait = static_cast<TraitType<ConcreteType> *>(this);
395  auto *concrete = static_cast<ConcreteType *>(trait);
396  auto *base = static_cast<OpState *>(concrete);
397  return base->getOperation();
398  }
399 
402  static LogicalResult verifyTrait(Operation *op) { return success(); }
404  return 0;
405  }
406 };
407 
408 namespace detail {
411 template <typename ConcreteType, template <typename> class TraitType>
412 struct MultiOperandTraitBase : public TraitBase<ConcreteType, TraitType> {
417 
419  unsigned getNumOperands() { return this->getOperation()->getNumOperands(); }
420 
422  Value getOperand(unsigned i) { return this->getOperation()->getOperand(i); }
423 
425  void setOperand(unsigned i, Value value) {
426  this->getOperation()->setOperand(i, value);
427  }
428 
431  return this->getOperation()->operand_begin();
432  }
433  operand_iterator operand_end() { return this->getOperation()->operand_end(); }
434  operand_range getOperands() { return this->getOperation()->getOperands(); }
435 
438  return this->getOperation()->operand_type_begin();
439  }
441  return this->getOperation()->operand_type_end();
442  }
444  return this->getOperation()->getOperandTypes();
445  }
446 };
447 } // end namespace detail
448 
451 template <typename ConcreteType>
452 class ZeroOperands : public TraitBase<ConcreteType, ZeroOperands> {
453 public:
455  return impl::verifyZeroOperands(op);
456  }
457 
458 private:
459  // Disable these.
460  void getOperand() {}
461  void setOperand() {}
462 };
463 
466 template <typename ConcreteType>
467 class OneOperand : public TraitBase<ConcreteType, OneOperand> {
468 public:
469  Value getOperand() { return this->getOperation()->getOperand(0); }
470 
471  void setOperand(Value value) { this->getOperation()->setOperand(0, value); }
472 
474  return impl::verifyOneOperand(op);
475  }
476 };
477 
483 template <unsigned N> class NOperands {
484 public:
485  static_assert(N > 1, "use ZeroOperands/OneOperand for N < 2");
486 
487  template <typename ConcreteType>
488  class Impl
489  : public detail::MultiOperandTraitBase<ConcreteType, NOperands<N>::Impl> {
490  public:
492  return impl::verifyNOperands(op, N);
493  }
494  };
495 };
496 
502 template <unsigned N> class AtLeastNOperands {
503 public:
504  template <typename ConcreteType>
505  class Impl : public detail::MultiOperandTraitBase<ConcreteType,
506  AtLeastNOperands<N>::Impl> {
507  public:
509  return impl::verifyAtLeastNOperands(op, N);
510  }
511  };
512 };
513 
516 template <typename ConcreteType>
518  : public detail::MultiOperandTraitBase<ConcreteType, VariadicOperands> {};
519 
522 template <typename ConcreteType>
523 class ZeroResult : public TraitBase<ConcreteType, ZeroResult> {
524 public:
526  return impl::verifyZeroResult(op);
527  }
528 };
529 
530 namespace detail {
533 template <typename ConcreteType, template <typename> class TraitType>
534 struct MultiResultTraitBase : public TraitBase<ConcreteType, TraitType> {
539 
541  unsigned getNumResults() { return this->getOperation()->getNumResults(); }
542 
544  Value getResult(unsigned i) { return this->getOperation()->getResult(i); }
545 
548  template <typename ValuesT> void replaceAllUsesWith(ValuesT &&values) {
549  this->getOperation()->replaceAllUsesWith(std::forward<ValuesT>(values));
550  }
551 
553  Type getType(unsigned i) { return getResult(i)->getType(); }
554 
557  return this->getOperation()->result_begin();
558  }
559  result_iterator result_end() { return this->getOperation()->result_end(); }
560  result_range getResults() { return this->getOperation()->getResults(); }
561 
564  return this->getOperation()->result_type_begin();
565  }
567  return this->getOperation()->result_type_end();
568  }
570  return this->getOperation()->getResultTypes();
571  }
572 };
573 } // end namespace detail
574 
577 template <typename ConcreteType>
578 class OneResult : public TraitBase<ConcreteType, OneResult> {
579 public:
580  Value getResult() { return this->getOperation()->getResult(0); }
581  Type getType() { return getResult()->getType(); }
582 
586  void replaceAllUsesWith(Value newValue) {
587  getResult()->replaceAllUsesWith(newValue);
588  }
589 
592  this->getOperation()->replaceAllUsesWith(op);
593  }
594 
596  return impl::verifyOneResult(op);
597  }
598 };
599 
605 template <unsigned N> class NResults {
606 public:
607  static_assert(N > 1, "use ZeroResult/OneResult for N < 2");
608 
609  template <typename ConcreteType>
610  class Impl
611  : public detail::MultiResultTraitBase<ConcreteType, NResults<N>::Impl> {
612  public:
614  return impl::verifyNResults(op, N);
615  }
616  };
617 };
618 
624 template <unsigned N> class AtLeastNResults {
625 public:
626  template <typename ConcreteType>
627  class Impl : public detail::MultiResultTraitBase<ConcreteType,
628  AtLeastNResults<N>::Impl> {
629  public:
631  return impl::verifyAtLeastNResults(op, N);
632  }
633  };
634 };
635 
638 template <typename ConcreteType>
640  : public detail::MultiResultTraitBase<ConcreteType, VariadicResults> {};
641 
645 template <typename ConcreteType>
646 class SameOperandsShape : public TraitBase<ConcreteType, SameOperandsShape> {
647 public:
650  }
651 };
652 
656 template <typename ConcreteType>
658  : public TraitBase<ConcreteType, SameOperandsAndResultShape> {
659 public:
662  }
663 };
664 
668 template <typename ConcreteType>
670  : public TraitBase<ConcreteType, SameOperandsElementType> {
671 public:
674  }
675 };
676 
680 template <typename ConcreteType>
682  : public TraitBase<ConcreteType, SameOperandsAndResultElementType> {
683 public:
686  }
687 };
688 
694 template <typename ConcreteType>
696  : public TraitBase<ConcreteType, SameOperandsAndResultType> {
697 public:
700  }
701 };
702 
705 template <typename ConcreteType>
706 class ResultsAreBoolLike : public TraitBase<ConcreteType, ResultsAreBoolLike> {
707 public:
710  }
711 };
712 
715 template <typename ConcreteType>
717  : public TraitBase<ConcreteType, ResultsAreFloatLike> {
718 public:
721  }
722 };
723 
726 template <typename ConcreteType>
728  : public TraitBase<ConcreteType, ResultsAreIntegerLike> {
729 public:
732  }
733 };
734 
736 template <typename ConcreteType>
737 class IsCommutative : public TraitBase<ConcreteType, IsCommutative> {
738 public:
740  return static_cast<AbstractOperation::OperationProperties>(
742  }
743 };
744 
746 template <typename ConcreteType>
747 class HasNoSideEffect : public TraitBase<ConcreteType, HasNoSideEffect> {
748 public:
750  return static_cast<AbstractOperation::OperationProperties>(
752  }
753 };
754 
757 template <typename ConcreteType>
759  : public TraitBase<ConcreteType, OperandsAreFloatLike> {
760 public:
763  }
764 };
765 
768 template <typename ConcreteType>
770  : public TraitBase<ConcreteType, OperandsAreIntegerLike> {
771 public:
774  }
775 };
776 
779 template <typename ConcreteType>
780 class SameTypeOperands : public TraitBase<ConcreteType, SameTypeOperands> {
781 public:
783  return impl::verifySameTypeOperands(op);
784  }
785 };
786 
788 template <typename ConcreteType>
789 class IsTerminator : public TraitBase<ConcreteType, IsTerminator> {
790 public:
792  return static_cast<AbstractOperation::OperationProperties>(
794  }
796  return impl::verifyIsTerminator(op);
797  }
798 
799  unsigned getNumSuccessors() {
800  return this->getOperation()->getNumSuccessors();
801  }
802  unsigned getNumSuccessorOperands(unsigned index) {
803  return this->getOperation()->getNumSuccessorOperands(index);
804  }
805 
806  Block *getSuccessor(unsigned index) {
807  return this->getOperation()->getSuccessor(index);
808  }
809 
810  void setSuccessor(Block *block, unsigned index) {
811  return this->getOperation()->setSuccessor(block, index);
812  }
813 
814  void addSuccessorOperand(unsigned index, Value value) {
815  return this->getOperation()->addSuccessorOperand(index, value);
816  }
817  void addSuccessorOperands(unsigned index, ArrayRef<Value> values) {
818  return this->getOperation()->addSuccessorOperand(index, values);
819  }
820 };
821 
824 template <typename ConcreteType>
826  : public TraitBase<ConcreteType, IsIsolatedFromAbove> {
827 public:
829  return static_cast<AbstractOperation::OperationProperties>(
831  }
833  for (auto &region : op->getRegions())
834  if (!region.isIsolatedFromAbove(op->getLoc()))
835  return failure();
836  return success();
837  }
838 };
839 
842 template <typename TerminatorOpType> struct SingleBlockImplicitTerminator {
843  template <typename ConcreteType>
844  class Impl : public TraitBase<ConcreteType, Impl> {
845  public:
847  for (unsigned i = 0, e = op->getNumRegions(); i < e; ++i) {
848  Region &region = op->getRegion(i);
849 
850  // Empty regions are fine.
851  if (region.empty())
852  continue;
853 
854  // Non-empty regions must contain a single basic block.
855  if (std::next(region.begin()) != region.end())
856  return op->emitOpError("expects region #")
857  << i << " to have 0 or 1 blocks";
858 
859  Block &block = region.front();
860  if (block.empty())
861  return op->emitOpError() << "expects a non-empty block";
862  Operation &terminator = block.back();
863  if (isa<TerminatorOpType>(terminator))
864  continue;
865 
866  return op->emitOpError("expects regions to end with '" +
867  TerminatorOpType::getOperationName() +
868  "', found '" +
869  terminator.getName().getStringRef() + "'")
870  .attachNote()
871  << "in custom textual format, the absence of terminator implies "
872  "'"
873  << TerminatorOpType::getOperationName() << '\'';
874  }
875 
876  return success();
877  }
878 
880  static void ensureTerminator(Region &region, Builder &builder,
881  Location loc) {
882  ::mlir::impl::template ensureRegionTerminator<TerminatorOpType>(
883  region, builder, loc);
884  }
885  };
886 };
887 
889 template <typename ParentOpType> struct HasParent {
890  template <typename ConcreteType>
891  class Impl : public TraitBase<ConcreteType, Impl> {
892  public:
894  if (isa<ParentOpType>(op->getParentOp()))
895  return success();
896  return op->emitOpError() << "expects parent op '"
897  << ParentOpType::getOperationName() << "'";
898  }
899  };
900 };
901 
912 template <typename ConcreteType>
914  : public TraitBase<ConcreteType, AttrSizedOperandSegments> {
915 public:
916  static StringRef getOperandSegmentSizeAttr() {
917  return "operand_segment_sizes";
918  }
919 
922  op, getOperandSegmentSizeAttr());
923  }
924 };
925 
927 template <typename ConcreteType>
929  : public TraitBase<ConcreteType, AttrSizedResultSegments> {
930 public:
931  static StringRef getResultSegmentSizeAttr() { return "result_segment_sizes"; }
932 
935  op, getResultSegmentSizeAttr());
936  }
937 };
938 
939 } // end namespace OpTrait
940 
941 //===----------------------------------------------------------------------===//
942 // Operation Definition classes
943 //===----------------------------------------------------------------------===//
944 
948 template <typename ConcreteType, template <typename T> class... Traits>
949 class Op : public OpState,
950  public Traits<ConcreteType>...,
951  public FoldingHook<ConcreteType,
952  llvm::is_one_of<OpTrait::OneResult<ConcreteType>,
953  Traits<ConcreteType>...>::value> {
954 public:
956  template <template <typename T> class Trait>
957  static constexpr bool hasTrait() {
958  return llvm::is_one_of<Trait<ConcreteType>, Traits<ConcreteType>...>::value;
959  }
960 
963 
965  ConcreteType clone() { return cast<ConcreteType>(getOperation()->clone()); }
966 
970  ConcreteType cloneWithoutRegions() {
971  return cast<ConcreteType>(getOperation()->cloneWithoutRegions());
972  }
973 
975  Dialect *getDialect() { return getOperation()->getDialect(); }
976 
978  Region *getParentRegion() { return getOperation()->getParentRegion(); }
979 
981  static bool classof(Operation *op) {
982  if (auto *abstractOp = op->getAbstractOperation())
983  return &classof == abstractOp->classof;
984  return op->getName().getStringRef() == ConcreteType::getOperationName();
985  }
986 
992  OperationState &result) {
993  return ConcreteType::parse(parser, result);
994  }
995 
998  static void printAssembly(Operation *op, OpAsmPrinter &p) {
999  auto opPointer = dyn_cast<ConcreteType>(op);
1000  assert(opPointer &&
1001  "op's name does not match name of concrete type instantiated with");
1002  opPointer.print(p);
1003  }
1004 
1013  return failure(
1014  failed(BaseVerifier<Traits<ConcreteType>...>::verifyTrait(op)) ||
1015  failed(cast<ConcreteType>(op).verify()));
1016  }
1017 
1018  // Returns the properties of an operation by combining the properties of the
1019  // traits of the op.
1021  return BaseProperties<Traits<ConcreteType>...>::getTraitProperties();
1022  }
1023 
1026  using ConcreteOpType = ConcreteType;
1027 
1029  explicit Op() : OpState(nullptr) {}
1030  Op(std::nullptr_t) : OpState(nullptr) {}
1031 
1034  explicit Op(Operation *state) : OpState(state) {}
1035 
1037  const void *getAsOpaquePointer() const {
1038  return static_cast<const void *>((Operation *)*this);
1039  }
1040  static ConcreteOpType getFromOpaquePointer(const void *pointer) {
1041  return ConcreteOpType(
1042  reinterpret_cast<Operation *>(const_cast<void *>(pointer)));
1043  }
1044 
1045 private:
1046  template <typename... Types> struct BaseVerifier;
1047 
1048  template <typename First, typename... Rest>
1049  struct BaseVerifier<First, Rest...> {
1050  static LogicalResult verifyTrait(Operation *op) {
1051  return failure(failed(First::verifyTrait(op)) ||
1052  failed(BaseVerifier<Rest...>::verifyTrait(op)));
1053  }
1054  };
1055 
1056  template <typename...> struct BaseVerifier {
1057  static LogicalResult verifyTrait(Operation *op) { return success(); }
1058  };
1059 
1060  template <typename... Types> struct BaseProperties;
1061 
1062  template <typename First, typename... Rest>
1063  struct BaseProperties<First, Rest...> {
1064  static AbstractOperation::OperationProperties getTraitProperties() {
1065  return First::getTraitProperties() |
1066  BaseProperties<Rest...>::getTraitProperties();
1067  }
1068  };
1069 
1070  template <typename...> struct BaseProperties {
1071  static AbstractOperation::OperationProperties getTraitProperties() {
1072  return 0;
1073  }
1074  };
1075 
1077  static bool hasTrait(ClassID *traitID) {
1078  return llvm::is_contained(llvm::makeArrayRef({ClassID::getID<Traits>()...}),
1079  traitID);
1080  }
1081 
1084  static void *getRawInterface(ClassID *id) {
1085  return InterfaceLookup::template lookup<Traits<ConcreteType>...>(id);
1086  }
1087 
1088  struct InterfaceLookup {
1090  template <typename T, typename... Args>
1091  using has_get_interface_id = decltype(T::getInterfaceID());
1092 
1095  template <typename T>
1096  static typename std::enable_if<is_detected<has_get_interface_id, T>::value,
1097  void *>::type
1098  lookup(ClassID *interfaceID) {
1099  return (T::getInterfaceID() == interfaceID) ? &T::instance() : nullptr;
1100  }
1101 
1103  template <typename T>
1104  static typename std::enable_if<!is_detected<has_get_interface_id, T>::value,
1105  void *>::type
1106  lookup(ClassID *) {
1107  return nullptr;
1108  }
1109 
1110  template <typename T, typename T2, typename... Ts>
1111  static void *lookup(ClassID *interfaceID) {
1112  auto *concept = lookup<T>(interfaceID);
1113  return concept ? concept : lookup<T2, Ts...>(interfaceID);
1114  }
1115  };
1116 
1118  friend AbstractOperation;
1119 };
1120 
1140 template <typename ConcreteType, typename Traits>
1141 class OpInterface : public Op<ConcreteType> {
1142 public:
1143  using Concept = typename Traits::Concept;
1144  template <typename T> using Model = typename Traits::template Model<T>;
1145 
1146  OpInterface(Operation *op = nullptr)
1147  : Op<ConcreteType>(op), impl(op ? getInterfaceFor(op) : nullptr) {
1148  assert((!op || impl) &&
1149  "instantiating an interface with an unregistered operation");
1150  }
1151 
1154  static bool classof(Operation *op) { return getInterfaceFor(op); }
1155 
1157  static ClassID *getInterfaceID() { return ClassID::getID<ConcreteType>(); }
1158 
1161  template <typename ConcreteOp>
1162  struct Trait : public OpTrait::TraitBase<ConcreteOp, Trait> {
1164  static ClassID *getInterfaceID() { return ClassID::getID<ConcreteType>(); }
1165 
1175  static Concept &instance() {
1176  static Model<ConcreteOp> singleton;
1177  return singleton;
1178  }
1179  };
1180 
1181 protected:
1183  Concept *getImpl() { return impl; }
1184 
1185 private:
1187  static Concept *getInterfaceFor(Operation *op) {
1188  // Access the raw interface from the abstract operation.
1189  auto *abstractOp = op->getAbstractOperation();
1190  return abstractOp ? abstractOp->getInterface<ConcreteType>() : nullptr;
1191  }
1192 
1194  Concept *impl;
1195 };
1196 
1197 // These functions are out-of-line implementations of the methods in UnaryOp and
1198 // BinaryOp, which avoids them being template instantiated/duplicated.
1199 namespace impl {
1201  OperationState &result);
1202 
1203 void buildBinaryOp(Builder *builder, OperationState &result, Value lhs,
1204  Value rhs);
1206  OperationState &result);
1207 
1208 // Prints the given binary `op` in custom assembly form if both the two operands
1209 // and the result have the same time. Otherwise, prints the generic assembly
1210 // form.
1212 } // namespace impl
1213 
1214 // These functions are out-of-line implementations of the methods in CastOp,
1215 // which avoids them being template instantiated/duplicated.
1216 namespace impl {
1217 void buildCastOp(Builder *builder, OperationState &result, Value source,
1218  Type destType);
1220 void printCastOp(Operation *op, OpAsmPrinter &p);
1222 } // namespace impl
1223 } // end namespace mlir
1224 
1225 #endif
ParseResult(LogicalResult result=success())
Definition: OpDefinition.h:38
operand_range::iterator operand_iterator
Definition: Operation.h:214
Definition: InferTypeOpInterface.cpp:20
Attribute getAttr(StringRef name)
Return an attribute with the specified name.
Definition: OpDefinition.h:148
void setAttr(StringRef name, Attribute value)
Definition: OpDefinition.h:160
Block * getSuccessor(unsigned i)
Definition: Block.cpp:215
OptionalParseResult(const InFlightDiagnostic &)
Definition: OpDefinition.h:57
Definition: Region.h:23
static LogicalResult foldHook(Operation *op, ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Definition: OpDefinition.h:264
Similar to AttrSizedOperandSegments but used for results.
Definition: OpDefinition.h:928
static ParseResult parseAssembly(OpAsmParser &parser, OperationState &result)
Definition: OpDefinition.h:991
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:708
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:402
Definition: STLExtras.h:95
Definition: PassRegistry.cpp:413
Definition: Operation.h:27
void buildBinaryOp(Builder *builder, OperationState &result, Value lhs, Value rhs)
Definition: Operation.cpp:1057
static AbstractOperation::OperationProperties getTraitProperties()
Definition: OpDefinition.h:403
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
Definition: Operation.h:363
LogicalResult verifyZeroOperands(Operation *op)
Definition: Operation.cpp:747
This class adds property that the operation is commutative.
Definition: OpDefinition.h:737
Operation & back()
Definition: Block.h:119
Value getResult(unsigned i)
Return the result at index &#39;i&#39;.
Definition: OpDefinition.h:544
LogicalResult verifyResultsAreFloatLike(Operation *op)
Definition: Operation.cpp:994
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:698
Definition: OpDefinition.h:98
Definition: OpDefinition.h:260
unsigned getNumRegions()
Returns the number of regions held by this operation.
Definition: Operation.h:360
Definition: Diagnostics.h:320
operand_type_range getOperandTypes()
Definition: OpDefinition.h:443
operand_iterator operand_end()
Definition: OpDefinition.h:433
Definition: OpDefinition.h:1162
LogicalResult verifyResultSizeAttr(Operation *op, StringRef sizeAttrName)
Definition: Operation.cpp:1045
NamedAttributeList::RemoveResult removeAttr(StringRef name)
Definition: OpDefinition.h:180
Block represents an ordered list of Operations.
Definition: Block.h:21
Block & front()
Definition: Region.h:54
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:920
LogicalResult verifySameOperandsAndResultShape(Operation *op)
Definition: Operation.cpp:858
Definition: OpDefinition.h:716
This class represents a single result from folding an operation.
Definition: OpDefinition.h:251
Definition: OpDefinition.h:913
Definition: LLVM.h:49
Definition: OpDefinition.h:669
LogicalResult verify(Operation *op)
Definition: Verifier.cpp:264
LogicalResult verifyNOperands(Operation *op, unsigned numOperands)
Definition: Operation.cpp:759
void print(raw_ostream &os, OpPrintingFlags flags=llvm::None)
Print the operation to the given stream.
Definition: OpDefinition.h:122
static ClassID * getInterfaceID()
Define an accessor for the ID of this interface.
Definition: OpDefinition.h:1157
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:684
bool failed(LogicalResult result)
Definition: LogicalResult.h:45
Definition: OpDefinition.h:29
void setOperand(Value value)
Definition: OpDefinition.h:471
bool operator!=(IntInfty lhs, IntInfty rhs)
Definition: SDBM.h:94
LogicalResult verifySameOperandsElementType(Operation *op)
Definition: Operation.cpp:877
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:660
static Identifier get(StringRef str, MLIRContext *context)
Return an identifier for the specified string.
Definition: MLIRContext.cpp:426
void setSuccessor(Block *block, unsigned index)
Definition: OpDefinition.h:810
Operation * getParentOp()
Definition: OpDefinition.h:111
Definition: Identifier.h:26
ParseResult parseCastOp(OpAsmParser &parser, OperationState &result)
Definition: Operation.cpp:1104
MLIRContext * getContext()
Return the context this operation belongs to.
Definition: OpDefinition.h:119
LogicalResult verify()
Definition: OpDefinition.h:224
LogicalResult verifyZeroResult(Operation *op)
Definition: Operation.cpp:819
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:933
This class implements the result iterators for the Operation class.
Definition: OperationSupport.h:588
This class provides the API for ops that are known to be terminators.
Definition: OpDefinition.h:789
Operation * getOperation()
Return the operation that this refers to.
Definition: OpDefinition.h:107
static bool classof(Operation *op)
Return true if this "op class" can match against the specified operation.
Definition: OpDefinition.h:981
Definition: OpImplementation.h:214
Definition: LLVM.h:40
Definition: OpDefinition.h:769
LogicalResult verifySameOperandsAndResultElementType(Operation *op)
Definition: Operation.cpp:891
LogicalResult verifyOperandsAreFloatLike(Operation *op)
Definition: Operation.cpp:797
LogicalResult verifyResultsAreBoolLike(Operation *op)
Definition: Operation.cpp:983
Definition: AffineOps.h:392
Op(Operation *state)
Definition: OpDefinition.h:1034
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:613
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
Definition: Diagnostics.cpp:307
Operation * getOperation()
Return the operation that this refers to.
Definition: OpDefinition.h:962
Definition: LLVM.h:34
LogicalResult verifySameOperandsAndResultType(Operation *op)
Definition: Operation.cpp:915
static AbstractOperation::OperationProperties getTraitProperties()
Definition: OpDefinition.h:739
Definition: OpDefinition.h:639
Definition: Location.h:52
LogicalResult verifyOneOperand(Operation *op)
Definition: Operation.cpp:753
result_range::type_iterator result_type_iterator
Support result type iteration.
Definition: Operation.h:260
operand_iterator operand_begin()
Operand iterator access.
Definition: OpDefinition.h:430
LogicalResult verifyAtLeastNResults(Operation *op, unsigned numOperands)
Definition: Operation.cpp:838
LogicalResult verifyOperandsAreIntegerLike(Operation *op)
Definition: Operation.cpp:788
OpState(Operation *state)
Definition: OpDefinition.h:236
LogicalResult verifySameTypeOperands(Operation *op)
Definition: Operation.cpp:806
Concept * getImpl()
Get the raw concept in the correct derived concept type.
Definition: OpDefinition.h:1183
Region * getParentRegion()
Definition: Region.cpp:36
typename Traits::Concept Concept
Definition: OpDefinition.h:1143
void replaceAllUsesWith(ValuesT &&values)
Definition: OpDefinition.h:548
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:782
Type getType()
Definition: OpDefinition.h:581
bool use_empty()
Return true if there are no users of any results of this operation.
Definition: OpDefinition.h:185
void dump()
Dump this operation.
Definition: OpDefinition.h:127
LogicalResult success(bool isSuccess=true)
Definition: LogicalResult.h:25
This class implements iteration on the types of a given range of values.
Definition: OperationSupport.h:540
Definition: Diagnostics.h:173
Definition: OpDefinition.h:488
Region * getParentRegion()
Return the parent Region of this operation.
Definition: OpDefinition.h:978
Definition: LogicalResult.h:18
LogicalResult verifyOneResult(Operation *op)
Definition: Operation.cpp:825
LogicalResult failure(bool isFailure=true)
Definition: LogicalResult.h:32
AttrClass getAttrOfType(StringRef name)
If the operation has an attribute of the specified type, return it.
Definition: OpDefinition.h:151
void setAttr(Identifier name, Attribute value)
Definition: OpDefinition.h:157
Definition: LLVM.h:37
Definition: OpDefinition.h:505
bool empty()
Definition: Region.h:49
unsigned getNumResults()
Return the number of results.
Definition: OpDefinition.h:541
Definition: OpDefinition.h:627
iterator begin()
Definition: Region.h:44
ParseResult(const Diagnostic &)
Definition: OpDefinition.h:42
ParseResult(const InFlightDiagnostic &)
Definition: OpDefinition.h:41
Definition: OpDefinition.h:706
Definition: OpDefinition.h:695
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:846
dialect_attr_iterator dialect_attr_end()
Definition: OpDefinition.h:145
unsigned getNumSuccessors()
Definition: OpDefinition.h:799
void replaceAllUsesWith(Value newValue)
Definition: OpDefinition.h:586
Definition: Attributes.h:53
void setOperand(unsigned i, Value value)
Set the operand at index &#39;i&#39; to &#39;value&#39;.
Definition: OpDefinition.h:425
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:648
result_type_range getResultTypes()
Definition: OpDefinition.h:569
static Concept & instance()
Definition: OpDefinition.h:1175
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:795
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:672
Definition: OpDefinition.h:727
OptionalParseResult(ParseResult result)
Definition: OpDefinition.h:56
ParseResult parseOneResultOneOperandTypeOp(OpAsmParser &parser, OperationState &result)
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:595
ParseResult operator*() const
Definition: OpDefinition.h:66
Definition: Dialect.h:39
void printOneResultOp(Operation *op, OpAsmPrinter &p)
Definition: Operation.cpp:1075
Definition: OpDefinition.h:517
OpResult getResult(unsigned idx)
Get the &#39;idx&#39;th result of this operation.
Definition: Operation.h:246
T::Concept * getInterface() const
Definition: OperationSupport.h:142
Definition: OpDefinition.h:483
iterator_range< result_type_iterator > result_type_range
Definition: Operation.h:261
void ensureRegionTerminator(Region &region, Builder &builder, Location loc)
Templated version that fills the generates the provided operation type.
Definition: OpDefinition.h:83
OpFoldResult fold(ArrayRef< Attribute > operands)
Definition: OpDefinition.h:346
Definition: OperationSupport.h:83
Definition: OpDefinition.h:842
Definition: OpImplementation.h:32
This class provides a verifier for ops that are expecting a specific parent.
Definition: OpDefinition.h:889
void erase()
Remove this operation from its parent block and delete it.
Definition: OpDefinition.h:188
Location getLoc()
The source location the operation was defined or derived from.
Definition: Operation.h:107
operand_range getOperands()
Definition: OpDefinition.h:434
NamedAttributeList::RemoveResult removeAttr(Identifier name)
Definition: OpDefinition.h:177
operand_type_iterator operand_type_end()
Definition: OpDefinition.h:440
Definition: OperationSupport.h:261
ConcreteType clone()
Create a deep copy of this operation.
Definition: OpDefinition.h:965
Definition: Attributes.h:1374
static AbstractOperation::OperationProperties getTraitProperties()
Definition: OpDefinition.h:791
StringRef getStringRef() const
Return the name of this operation. This always succeeds.
Definition: Operation.cpp:52
LogicalResult verifyResultsAreIntegerLike(Operation *op)
Definition: Operation.cpp:1002
void setDialectAttrs(DialectAttrs &&attrs)
Set the dialect attributes for this operation, and preserve all dependent.
Definition: OpDefinition.h:171
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:454
void setLoc(Location loc)
Definition: OpDefinition.h:131
Definition: OpDefinition.h:1141
Op()
This is a public constructor. Any op can be initialized to null.
Definition: OpDefinition.h:1029
Block * getSuccessor(unsigned index)
Definition: OpDefinition.h:806
bool empty()
Definition: Block.h:115
Value getResult()
Definition: OpDefinition.h:580
bool operator==(IntInfty lhs, IntInfty rhs)
Definition: SDBM.h:90
Definition: Types.h:84
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:508
static StringRef getOperandSegmentSizeAttr()
Definition: OpDefinition.h:916
uint32_t OperationProperties
Definition: OperationSupport.h:85
Value foldCastOp(Operation *op)
Definition: Operation.cpp:1122
void replaceAllUsesWith(Operation *op)
Replace all uses of &#39;this&#39; value with the result of &#39;op&#39;.
Definition: OpDefinition.h:591
static ClassID * getInterfaceID()
Define an accessor for the ID of this interface.
Definition: OpDefinition.h:1164
LogicalResult verifySameOperandsShape(Operation *op)
Definition: Operation.cpp:846
static AbstractOperation::OperationProperties getTraitProperties()
Definition: OpDefinition.h:828
result_type_iterator result_type_begin()
Result type access.
Definition: OpDefinition.h:563
Definition: Value.h:38
ParseResult getValue() const
Access the internal ParseResult value.
Definition: OpDefinition.h:65
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:880
static Operation * create(Location location, OperationName name, ArrayRef< Type > resultTypes, ArrayRef< Value > operands, ArrayRef< NamedAttribute > attributes, ArrayRef< Block *> successors, unsigned numRegions, bool resizableOperandList)
Create a new Operation with the specific fields.
Definition: Operation.cpp:71
result_type_iterator result_type_end()
Definition: OpDefinition.h:566
LogicalResult verifyAtLeastNOperands(Operation *op, unsigned numOperands)
Definition: Operation.cpp:768
ConcreteType cloneWithoutRegions()
Definition: OpDefinition.h:970
Value getOperand()
Definition: OpDefinition.h:469
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type &#39;OpTy&#39;.
Definition: OpDefinition.h:114
Definition: OpDefinition.h:386
Definition: OpDefinition.h:610
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:630
dialect_attr_iterator dialect_attr_begin()
Definition: OpDefinition.h:142
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
Definition: Diagnostics.cpp:301
Definition: OperationSupport.h:474
result_range getResults()
Definition: OpDefinition.h:560
Definition: PatternMatch.h:418
Definition: Builders.h:47
Location getLoc()
The source location the operation was defined or derived from.
Definition: OpDefinition.h:130
Definition: LLVM.h:50
ParseResult parseOneResultSameOperandTypeOp(OpAsmParser &parser, OperationState &result)
Definition: Operation.cpp:1064
Definition: OpDefinition.h:657
A utility iterator that filters out non-dialect attributes.
Definition: Operation.h:311
iterator end()
Definition: Region.h:45
Definition: OpDefinition.h:825
OperandRange operand_range
Definition: Operation.h:213
OptionalParseResult(llvm::NoneType)
Definition: OpDefinition.h:59
OpInterface(Operation *op=nullptr)
Definition: OpDefinition.h:1146
result_iterator result_end()
Definition: OpDefinition.h:559
void setAttrs(ArrayRef< NamedAttribute > attributes)
Set the attributes held by this operation.
Definition: OpDefinition.h:165
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:473
static constexpr bool hasTrait()
Return if this operation contains the provided trait.
Definition: OpDefinition.h:957
static void getCanonicalizationPatterns(OwningRewritePatternList &results, MLIRContext *context)
Definition: OpDefinition.h:218
Definition: OpDefinition.h:502
void addSuccessorOperands(unsigned index, ArrayRef< Value > values)
Definition: OpDefinition.h:817
void buildCastOp(Builder *builder, OperationState &result, Value source, Type destType)
Definition: Operation.cpp:1098
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:893
Definition: OpDefinition.h:646
Op(std::nullptr_t)
Definition: OpDefinition.h:1030
Definition: OpDefinition.h:412
static AbstractOperation::OperationProperties getOperationProperties()
Definition: OpDefinition.h:1020
Definition: MLIRContext.h:34
static AbstractOperation::OperationProperties getTraitProperties()
Definition: OpDefinition.h:749
Operation::operand_iterator operand_iterator
Definition: OpDefinition.h:413
Definition: OpDefinition.h:452
void print(OpAsmPrinter &p, AffineIfOp op)
Definition: AffineOps.cpp:1671
Operation * getParentOp()
Definition: Operation.cpp:265
typename Traits::template Model< T > Model
Definition: OpDefinition.h:1144
iterator_range< dialect_attr_iterator > dialect_attr_range
Definition: Operation.h:327
static ConcreteOpType getFromOpaquePointer(const void *pointer)
Definition: OpDefinition.h:1040
static bool classof(Operation *op)
Definition: OpDefinition.h:1154
operand_type_iterator operand_type_begin()
Operand type access.
Definition: OpDefinition.h:437
void setAttrs(NamedAttributeList newAttrs)
Definition: OpDefinition.h:168
static LogicalResult foldHook(Operation *op, ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Definition: OpDefinition.h:312
Dialect * getDialect()
Return the dialect that this refers to.
Definition: OpDefinition.h:975
Operation::result_iterator result_iterator
Definition: OpDefinition.h:535
RetT walk(FnT &&callback)
Definition: OpDefinition.h:210
Definition: OpDefinition.h:467
This class implements the operand iterators for the Operation class.
Definition: OperationSupport.h:559
Definition: OpDefinition.h:949
void printCastOp(Operation *op, OpAsmPrinter &p)
Definition: Operation.cpp:1115
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:719
result_range::iterator result_iterator
Definition: Operation.h:250
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:730
Definition: StandardTypes.h:63
RemoveResult
Definition: Attributes.h:1405
This class adds property that the operation has no side effects.
Definition: OpDefinition.h:747
dialect_attr_range getDialectAttrs()
Return a range corresponding to the dialect attributes for this operation.
Definition: OpDefinition.h:141
unsigned getNumSuccessorOperands(unsigned index)
Definition: OpDefinition.h:802
Definition: OpDefinition.h:605
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:249
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:525
InFlightDiagnostic emitRemark(Location loc)
Utility method to emit a remark message using this location.
Definition: Diagnostics.cpp:315
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:761
Definition: OpDefinition.h:780
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:832
LogicalResult verifyNResults(Operation *op, unsigned numOperands)
Definition: Operation.cpp:831
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:491
InFlightDiagnostic emitOpError(const Twine &message={})
Definition: Operation.cpp:625
Definition: OpDefinition.h:534
LogicalResult fold(ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Definition: OpDefinition.h:291
OperationName getName()
The name of an operation is the key identifier for it.
Definition: Operation.h:61
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
Definition: OpDefinition.h:134
static void printAssembly(Operation *op, OpAsmPrinter &p)
Definition: OpDefinition.h:998
static StringRef getResultSegmentSizeAttr()
Definition: OpDefinition.h:931
Definition: OpDefinition.h:36
void addSuccessorOperand(unsigned index, Value value)
Definition: OpDefinition.h:814
OptionalParseResult(LogicalResult result)
Definition: OpDefinition.h:55
static LogicalResult verifyInvariants(Operation *op)
Definition: OpDefinition.h:1012
unsigned getNumOperands()
Return the number of operands.
Definition: OpDefinition.h:419
Definition: OpDefinition.h:523
static LogicalResult verifyTrait(Operation *op)
Definition: OpDefinition.h:772
Type getType(unsigned i)
Return the type of the i-th result.
Definition: OpDefinition.h:553
Definition: OpDefinition.h:891
Value getOperand(unsigned i)
Return the operand at index &#39;i&#39;.
Definition: OpDefinition.h:422
LogicalResult verifyOperandSizeAttr(Operation *op, StringRef sizeAttrName)
Definition: Operation.cpp:1040
Region & getRegion(unsigned index)
Returns the region held by this operation at position &#39;index&#39;.
Definition: Operation.h:369
Definition: OpDefinition.h:758
LogicalResult verifyIsTerminator(Operation *op)
Definition: Operation.cpp:971
Operation * getOperation()
Return the ultimate Operation being worked on.
Definition: OpDefinition.h:389
iterator_range< operand_type_iterator > operand_type_range
Definition: Operation.h:233
result_iterator result_begin()
Result iterator access.
Definition: OpDefinition.h:556
Definition: LLVM.h:41
const AbstractOperation * getAbstractOperation()
Definition: Operation.h:65
const void * getAsOpaquePointer() const
Methods for supporting PointerLikeTypeTraits.
Definition: OpDefinition.h:1037
Definition: OpDefinition.h:624
operand_range::type_iterator operand_type_iterator
Definition: Operation.h:232