19 #ifndef MLIR_IR_OPDEFINITION_H
20 #define MLIR_IR_OPDEFINITION_H
24 #include "llvm/Support/PointerLikeTypeTraits.h"
26 #include <type_traits>
55 std::optional<ParseResult>
impl;
66 Region ®ion, OpBuilder &builder, Location loc,
67 function_ref<Operation *(OpBuilder &, Location)> buildTerminatorOp);
69 Region ®ion, Builder &builder, Location loc,
70 function_ref<Operation *(OpBuilder &, Location)> buildTerminatorOp);
99 state->
print(os, flags);
102 state->
print(os, asmState);
123 InFlightDiagnostic
emitError(
const Twine &message = {});
127 InFlightDiagnostic
emitWarning(
const Twine &message = {});
131 InFlightDiagnostic
emitRemark(
const Twine &message = {});
145 typename Iterator = ForwardIterator,
typename FnT,
146 typename RetT = detail::walkResultType<FnT>>
147 std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 1,
150 return state->
walk<Order, Iterator>(std::forward<FnT>(callback));
174 template <
typename FnT,
typename RetT = detail::walkResultType<FnT>>
175 std::enable_if_t<llvm::function_traits<std::decay_t<FnT>>::num_args == 2,
178 return state->
walk(std::forward<FnT>(callback));
211 StringRef defaultDialect);
232 raw_ostream &
operator<<(raw_ostream &os, OpFoldResult ofr);
239 void dump()
const { llvm::errs() << *
this <<
"\n"; }
284 LogicalResult
verifyNResults(Operation *op,
unsigned numOperands);
300 StringRef valueGroupName,
301 size_t expectedCount);
311 template <
typename ConcreteType,
template <
typename>
class TraitType>
316 auto *concrete =
static_cast<ConcreteType *
>(
this);
317 return concrete->getOperation();
327 template <
typename ConcreteType,
template <
typename>
class TraitType>
369 template <
typename ConcreteType>
373 return cast<ConcreteType>(op).verifyInvariantsImpl();
379 template <
typename ConcreteType>
394 template <
typename ConcreteType>
411 template <
unsigned N>
414 static_assert(N > 1,
"use ZeroOperands/OneOperand for N < 2");
416 template <
typename ConcreteType>
431 template <
unsigned N>
434 template <
typename ConcreteType>
436 AtLeastNOperands<N>::Impl> {
446 template <
typename ConcreteType>
455 template <
typename ConcreteType>
466 template <
typename ConcreteType,
template <
typename>
class TraitType>
487 template <
typename ConcreteType>
494 template <
typename OpT>
496 return getRegion().template getOps<OpT>();
506 template <
unsigned N>
509 static_assert(N > 1,
"use ZeroRegions/OneRegion for N < 2");
511 template <
typename ConcreteType>
523 template <
unsigned N>
526 template <
typename ConcreteType>
528 AtLeastNRegions<N>::Impl> {
538 template <
typename ConcreteType>
547 template <
typename ConcreteType>
558 template <
typename ConcreteType,
template <
typename>
class TraitType>
573 template <
typename ValuesT>
603 template <
typename ConcreteType>
627 template <
typename ResultType>
632 template <
typename ConcreteType>
634 :
public TraitBase<ConcreteType, OneTypedResult<ResultType>::Impl> {
637 return cast<mlir::TypedValue<ResultType>>(
654 template <
unsigned N>
657 static_assert(N > 1,
"use ZeroResults/OneResult for N < 2");
659 template <
typename ConcreteType>
674 template <
unsigned N>
677 template <
typename ConcreteType>
679 AtLeastNResults<N>::Impl> {
689 template <
typename ConcreteType>
698 template <
typename ConcreteType>
702 template <
typename ConcreteType>
712 template <
typename ConcreteType>
723 template <
typename ConcreteType,
template <
typename>
class TraitType>
751 template <
typename ConcreteType>
766 template <
unsigned N>
769 static_assert(N > 1,
"use ZeroSuccessors/OneSuccessor for N < 2");
771 template <
typename ConcreteType>
773 NSuccessors<N>::Impl> {
783 template <
unsigned N>
786 template <
typename ConcreteType>
789 AtLeastNSuccessors<N>::Impl> {
799 template <
typename ConcreteType>
809 template <
typename ConcreteType>
821 if (!llvm::hasSingleElement(region))
823 << i <<
" to have 0 or 1 blocks";
825 if (!ConcreteType::template hasTrait<NoTerminator>()) {
828 return op->
emitOpError() <<
"expects a non-empty block";
836 assert(!region.
empty() &&
"unexpected empty region");
837 return ®ion.
front();
851 template <
typename OpT,
typename T =
void>
853 std::enable_if_t<OpT::template hasTrait<OneRegion>(), T>;
855 template <
typename OpT = ConcreteType>
859 template <
typename OpT = ConcreteType>
863 template <
typename OpT = ConcreteType>
869 template <
typename OpT = ConcreteType>
875 template <
typename OpT = ConcreteType>
879 template <
typename OpT = ConcreteType>
890 template <
typename TerminatorOpType>
892 template <
typename ConcreteType>
900 TerminatorOpType::build(builder, state);
917 if (isa<TerminatorOpType>(terminator))
920 return op->
emitOpError(
"expects regions to end with '" +
921 TerminatorOpType::getOperationName() +
925 <<
"in custom textual format, the absence of terminator implies "
927 << TerminatorOpType::getOperationName() <<
'\'';
954 template <
typename OpT,
typename T =
void>
956 std::enable_if_t<OpT::template hasTrait<OneRegion>(), T>;
959 template <
typename OpT = ConcreteType>
967 template <
typename OpT = ConcreteType>
971 template <
typename OpT = ConcreteType>
975 if (insertPt == body->end())
977 body->getOperations().insert(insertPt, op);
990 template <
class Op,
bool hasTerminator =
991 llvm::is_detected<has_implicit_terminator_t, Op>::value>
993 static constexpr
bool value = std::is_base_of<
995 typename Op::ImplicitTerminatorOpT>::template Impl<Op>,
1009 template <
typename ConcreteType>
1020 template <
typename ConcreteType>
1022 :
public TraitBase<ConcreteType, SameOperandsAndResultShape> {
1032 template <
typename ConcreteType>
1034 :
public TraitBase<ConcreteType, SameOperandsElementType> {
1044 template <
typename ConcreteType>
1046 :
public TraitBase<ConcreteType, SameOperandsAndResultElementType> {
1058 template <
typename ConcreteType>
1060 :
public TraitBase<ConcreteType, SameOperandsAndResultType> {
1069 template <
typename ConcreteType>
1079 template <
typename ConcreteType>
1081 :
public TraitBase<ConcreteType, ResultsAreFloatLike> {
1090 template <
typename ConcreteType>
1092 :
public TraitBase<ConcreteType, ResultsAreSignlessIntegerLike> {
1100 template <
typename ConcreteType>
1105 template <
typename ConcreteType>
1109 static_assert(ConcreteType::template hasTrait<OneResult>(),
1110 "expected operation to produce one result");
1111 static_assert(ConcreteType::template hasTrait<OneOperand>(),
1112 "expected operation to take one operand");
1113 static_assert(ConcreteType::template hasTrait<SameOperandsAndResultType>(),
1114 "expected operation to preserve type");
1128 template <
typename ConcreteType>
1132 static_assert(ConcreteType::template hasTrait<OneResult>(),
1133 "expected operation to produce one result");
1134 static_assert(ConcreteType::template hasTrait<OneOperand>() ||
1136 "expected operation to take one or two operands");
1137 static_assert(ConcreteType::template hasTrait<SameOperandsAndResultType>(),
1138 "expected operation to preserve type");
1151 template <
typename ConcreteType>
1153 :
public TraitBase<ConcreteType, OperandsAreFloatLike> {
1162 template <
typename ConcreteType>
1164 :
public TraitBase<ConcreteType, OperandsAreSignlessIntegerLike> {
1173 template <
typename ConcreteType>
1184 template <
typename ConcreteType>
1188 static_assert(ConcreteType::template hasTrait<OneResult>(),
1189 "expected operation to produce one result");
1190 static_assert(ConcreteType::template hasTrait<ZeroOperands>(),
1191 "expected operation to take zero operands");
1202 template <
typename ConcreteType>
1204 :
public TraitBase<ConcreteType, IsIsolatedFromAbove> {
1216 template <
typename ConcreteType>
1220 static_assert(!ConcreteType::template hasTrait<ZeroRegions>(),
1221 "expected operation to have one or more regions");
1231 template <
typename ConcreteType>
1233 :
public TraitBase<ConcreteType, AutomaticAllocationScope> {
1236 static_assert(!ConcreteType::template hasTrait<ZeroRegions>(),
1237 "expected operation to have one or more regions");
1244 template <
typename... ParentOpTypes>
1246 template <
typename ConcreteType>
1250 if (llvm::isa_and_nonnull<ParentOpTypes...>(op->
getParentOp()))
1254 <<
"expects parent op "
1255 << (
sizeof...(ParentOpTypes) != 1 ?
"to be one of '" :
"'")
1256 <<
llvm::ArrayRef({ParentOpTypes::getOperationName()...}) <<
"'";
1271 template <
typename ConcreteType>
1273 :
public TraitBase<ConcreteType, AttrSizedOperandSegments> {
1276 return "operand_segment_sizes";
1286 template <
typename ConcreteType>
1288 :
public TraitBase<ConcreteType, AttrSizedResultSegments> {
1300 template <
typename ConcrentType>
1312 template <
typename ConcrentType>
1314 :
public TraitBase<ConcrentType, MemRefsNormalizable> {};
1348 template <
typename ConcreteType>
1377 template <
typename ConcreteType>
1381 ConcreteType::template hasTrait<Elementwise>(),
1382 "`Scalarizable` trait is only applicable to `Elementwise` ops.");
1397 template <
typename ConcreteType>
1401 ConcreteType::template hasTrait<Elementwise>(),
1402 "`Vectorizable` trait is only applicable to `Elementwise` ops.");
1438 template <
typename ConcreteType>
1442 ConcreteType::template hasTrait<Elementwise>(),
1443 "`Tensorizable` trait is only applicable to `Elementwise` ops.");
1459 namespace op_definition_impl {
1465 template <
template <
typename T>
class... Traits>
1467 TypeID traitIDs[] = {TypeID::get<Traits>()...};
1468 for (
unsigned i = 0, e =
sizeof...(Traits); i != e; ++i)
1469 if (traitIDs[i] == traitID)
1479 template <
typename T,
typename... Args>
1482 template <
typename T>
1484 llvm::is_detected<has_single_result_fold_trait, T>;
1486 template <
typename T,
typename... Args>
1491 template <
typename T>
1494 template <
typename T>
1496 std::disjunction<detect_has_fold_trait<T>,
1501 template <
typename Trait>
1502 static std::enable_if_t<detect_has_single_result_fold_trait<Trait>::value,
1507 "expected trait on non single-result operation to implement the "
1508 "general `foldTrait` method");
1511 if (!results.empty())
1515 if (result.template dyn_cast<Value>() != op->
getResult(0))
1516 results.push_back(result);
1523 template <
typename Trait>
1524 static std::enable_if_t<detect_has_fold_trait<Trait>::value,
LogicalResult>
1531 template <
typename Trait>
1532 static inline std::enable_if_t<!detect_has_any_fold_trait<Trait>::value,
1540 template <
typename... Ts>
1550 template <
typename T,
typename... Args>
1552 template <
typename T>
1556 template <
typename T,
typename... Args>
1559 template <
typename T>
1561 llvm::is_detected<has_verify_region_trait, T>;
1564 template <
typename T>
1565 std::enable_if_t<detect_has_verify_trait<T>::value,
LogicalResult>
1569 template <
typename T>
1570 inline std::enable_if_t<!detect_has_verify_trait<T>::value,
LogicalResult>
1576 template <
typename... Ts>
1582 template <
typename T>
1583 std::enable_if_t<detect_has_verify_region_trait<T>::value,
LogicalResult>
1587 template <
typename T>
1588 inline std::enable_if_t<!detect_has_verify_region_trait<T>::value,
1596 template <
typename... Ts>
1609 template <
typename ConcreteType,
template <
typename T>
class... Traits>
1618 template <
template <
typename T>
class Trait>
1620 return llvm::is_one_of<Trait<ConcreteType>, Traits<ConcreteType>...>::value;
1636 return TypeID::get<ConcreteType>() == info->getTypeID();
1639 llvm::report_fatal_error(
1640 "classof on '" + ConcreteType::getOperationName() +
1641 "' failed due to the operation not being registered");
1647 template <
typename T>
1648 static std::enable_if_t<std::is_base_of<OpState, T>::value,
bool>
1667 return static_cast<const void *
>((
Operation *)*
this);
1671 reinterpret_cast<Operation *
>(
const_cast<void *
>(pointer)));
1676 template <
typename... Models>
1678 std::optional<RegisteredOperationName> info =
1682 llvm::report_fatal_error(
1683 "Attempting to attach an interface to an unregistered operation " +
1684 ConcreteType::getOperationName() +
".");
1685 (checkInterfaceTarget<Models>(), ...);
1686 info->attachInterface<Models...>();
1691 template <
typename T,
typename... Args>
1692 using has_single_result_fold_t =
1694 template <
typename T>
1695 constexpr
static bool has_single_result_fold_v =
1696 llvm::is_detected<has_single_result_fold_t, T>::value;
1698 template <
typename T,
typename... Args>
1699 using has_fold_t = decltype(std::declval<T>().fold(
1702 template <
typename T>
1703 constexpr
static bool has_fold_v = llvm::is_detected<has_fold_t, T>::value;
1706 template <
typename T,
typename... Args>
1707 using has_fold_adaptor_single_result_fold_t =
1708 decltype(std::declval<T>().fold(std::declval<typename T::FoldAdaptor>()));
1710 constexpr
static bool has_fold_adaptor_single_result_v =
1711 llvm::is_detected<has_fold_adaptor_single_result_fold_t, T>::value;
1713 template <
typename T,
typename... Args>
1714 using has_fold_adaptor_fold_t = decltype(std::declval<T>().fold(
1715 std::declval<typename T::FoldAdaptor>(),
1718 constexpr
static bool has_fold_adaptor_v =
1719 llvm::is_detected<has_fold_adaptor_fold_t, T>::value;
1722 template <
typename T,
typename... Args>
1724 decltype(std::declval<T>().
print(std::declval<OpAsmPrinter &>()));
1725 template <
typename T>
1726 using detect_has_print = llvm::is_detected<has_print, T>;
1729 template <
typename T>
1730 using has_concrete_entity_t =
typename T::ConcreteEntity;
1736 template <
typename T,
1737 bool = llvm::is_detected<has_concrete_entity_t, T>::value>
1738 struct InterfaceTargetOrOpT {
1739 using type =
typename T::ConcreteEntity;
1741 template <
typename T>
1742 struct InterfaceTargetOrOpT<T, false> {
1743 using type = ConcreteType;
1749 template <
typename T>
1750 static void checkInterfaceTarget() {
1751 static_assert(std::is_same<
typename InterfaceTargetOrOpT<T>::type,
1752 ConcreteType>::value,
1753 "attaching an interface to the wrong op kind");
1758 static detail::InterfaceMap getInterfaceMap() {
1759 return detail::InterfaceMap::template get<Traits<ConcreteType>...>();
1767 if constexpr (llvm::is_one_of<OpTrait::OneResult<ConcreteType>,
1768 Traits<ConcreteType>...>::value &&
1769 (has_single_result_fold_v<ConcreteType> ||
1770 has_fold_adaptor_single_result_v<ConcreteType>))
1771 return [](Operation *op, ArrayRef<Attribute> operands,
1772 SmallVectorImpl<OpFoldResult> &results) {
1773 return foldSingleResultHook<ConcreteType>(op, operands, results);
1776 if constexpr (has_fold_v<ConcreteType> || has_fold_adaptor_v<ConcreteType>)
1777 return [](Operation *op, ArrayRef<Attribute> operands,
1778 SmallVectorImpl<OpFoldResult> &results) {
1779 return foldHook<ConcreteType>(op, operands, results);
1782 return [](Operation *op, ArrayRef<Attribute> operands,
1783 SmallVectorImpl<OpFoldResult> &results) {
1785 return op_definition_impl::foldTraits<Traits<ConcreteType>...>(
1786 op, operands, results);
1791 template <
typename ConcreteOpT>
1792 static LogicalResult
1793 foldSingleResultHook(Operation *op, ArrayRef<Attribute> operands,
1794 SmallVectorImpl<OpFoldResult> &results) {
1795 OpFoldResult result;
1796 if constexpr (has_fold_adaptor_single_result_v<ConcreteOpT>)
1797 result = cast<ConcreteOpT>(op).fold(
typename ConcreteOpT::FoldAdaptor(
1798 operands, op->getAttrDictionary(), op->getRegions()));
1800 result = cast<ConcreteOpT>(op).fold(operands);
1804 if (!result || result.template dyn_cast<Value>() == op->getResult(0)) {
1806 op, operands, results)))
1808 return success(
static_cast<bool>(result));
1810 results.push_back(result);
1814 template <
typename ConcreteOpT>
1815 static LogicalResult foldHook(Operation *op, ArrayRef<Attribute> operands,
1816 SmallVectorImpl<OpFoldResult> &results) {
1818 if constexpr (has_fold_adaptor_v<ConcreteOpT>) {
1819 result = cast<ConcreteOpT>(op).fold(
1820 typename ConcreteOpT::FoldAdaptor(operands, op->getAttrDictionary(),
1824 result = cast<ConcreteOpT>(op).fold(operands, results);
1829 if (
failed(result) || results.empty()) {
1831 op, operands, results)))
1844 if constexpr (detect_has_print<ConcreteType>::value)
1845 return [](Operation *op, OpAsmPrinter &p, StringRef defaultDialect) {
1847 return cast<ConcreteType>(op).print(p);
1849 return [](Operation *op, OpAsmPrinter &printer, StringRef defaultDialect) {
1856 return ConcreteType::populateDefaultAttrs;
1859 static LogicalResult verifyInvariants(Operation *op) {
1860 static_assert(hasNoDataMembers(),
1861 "Op class shouldn't define new data members");
1867 return static_cast<LogicalResult (*)(Operation *)
>(&verifyInvariants);
1870 static LogicalResult verifyRegionInvariants(Operation *op) {
1871 static_assert(hasNoDataMembers(),
1872 "Op class shouldn't define new data members");
1879 return static_cast<LogicalResult (*)(Operation *)
>(&verifyRegionInvariants);
1882 static constexpr
bool hasNoDataMembers() {
1885 class EmptyOp :
public Op<EmptyOp, Traits...> {};
1886 return sizeof(ConcreteType) ==
sizeof(EmptyOp);
1890 friend RegisteredOperationName;
1895 template <
typename ConcreteType,
typename Traits>
1898 Op<ConcreteType>, OpTrait::TraitBase> {
1913 if (std::optional<RegisteredOperationName> rInfo =
1915 if (
auto *opIface = rInfo->getInterface<ConcreteType>())
1925 return dialect->getRegisteredInterfaceForOp<ConcreteType>(name);
1952 template <
typename T>
1954 std::enable_if_t<std::is_base_of<mlir::OpState, T>::value &&
1955 !mlir::detail::IsInterface<T>::value>> {
1958 return T::getFromOpaquePointer(pointer);
1962 return T::getFromOpaquePointer(pointer);
1967 static bool isEqual(T lhs, T rhs) {
return lhs == rhs; }
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
This class provides management for the lifetime of the state used when printing the IR.
Attributes are known-constant values of operations.
Block represents an ordered list of Operations.
OpListType::iterator iterator
OpListType & getOperations()
This class is a general helper class for creating context-global objects like types,...
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
virtual void * getRegisteredInterfaceForOp(TypeID interfaceID, OperationName opName)
Lookup an op interface for the given ID if one is registered, otherwise nullptr.
This class represents a diagnostic that is inflight and set to be reported.
Diagnostic & attachNote(std::optional< Location > noteLoc=std::nullopt)
Attaches a note to this diagnostic.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This class helps build Operations.
This class represents a single result from folding an operation.
This class represents the base of an operation interface.
friend InterfaceBase
Allow access to getInterfaceFor.
static InterfaceBase::Concept * getInterfaceFor(Operation *op)
Returns the impl interface instance for the given operation.
Set of flags used to control the behavior of the various IR print methods (e.g.
This is the concrete base class that holds the operation pointer and has non-generic methods that onl...
void dump()
Dump this operation.
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==2, RetT > walk(FnT &&callback)
Generic walker with a stage aware callback.
MLIRContext * getContext()
Return the context this operation belongs to.
void erase()
Remove this operation from its parent block and delete it.
bool use_empty()
Return true if there are no users of any results of this operation.
LogicalResult verify()
If the concrete type didn't implement a custom verifier hook, just fall back to this one which accept...
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
void print(raw_ostream &os, AsmState &asmState)
static void printOpName(Operation *op, OpAsmPrinter &p, StringRef defaultDialect)
Print an operation name, eliding the dialect prefix if necessary.
LogicalResult verifyRegions()
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
InFlightDiagnostic emitWarning(const Twine &message={})
Emit a warning about this operation, reporting up to any diagnostic handlers that may be listening.
Operation * getOperation()
Return the operation that this refers to.
static void getCanonicalizationPatterns(RewritePatternSet &results, MLIRContext *context)
This hook returns any canonicalization pattern rewrites that the operation supports,...
static ParseResult parse(OpAsmParser &parser, OperationState &result)
Parse the custom form of an operation.
InFlightDiagnostic emitRemark(const Twine &message={})
Emit a remark about this operation, reporting up to any diagnostic handlers that may be listening.
OpState(Operation *state)
Mutability management is handled by the OpWrapper/OpConstWrapper classes, so we can cast it away here...
Location getLoc()
The source location the operation was defined or derived from.
static void populateDefaultAttrs(const OperationName &, NamedAttrList &)
This hook populates any unset default attrs.
void print(raw_ostream &os, OpPrintingFlags flags=std::nullopt)
Print the operation to the given stream.
Operation * operator->() const
Shortcut of -> to access a member of Operation.
A trait of region holding operations that defines a new scope for polyhedral optimization purposes.
static LogicalResult verifyTrait(Operation *op)
static LogicalResult verifyTrait(Operation *op)
This class provides the API for ops that are known to have a at least a specified number of operands.
static LogicalResult verifyTrait(Operation *op)
This class provides APIs for ops that are known to have at least a specified number of regions.
static LogicalResult verifyTrait(Operation *op)
This class provides the API for ops that are known to have at least a specified number of results.
static LogicalResult verifyTrait(Operation *op)
This class provides APIs for ops that are known to have at least a specified number of successors.
A trait for operations that have an attribute specifying operand segments.
static StringRef getOperandSegmentSizeAttr()
static LogicalResult verifyTrait(Operation *op)
Similar to AttrSizedOperandSegments but used for results.
static StringRef getResultSegmentSizeAttr()
static LogicalResult verifyTrait(Operation *op)
A trait of region holding operations that define a new scope for automatic allocations,...
static LogicalResult verifyTrait(Operation *op)
This class provides the API for a sub-set of ops that are known to be constant-like.
static LogicalResult verifyTrait(Operation *op)
static LogicalResult verifyTrait(Operation *op)
This class adds property that the operation is commutative.
This class adds property that the operation is idempotent.
static OpFoldResult foldTrait(Operation *op, ArrayRef< Attribute > operands)
static LogicalResult verifyTrait(Operation *op)
This class adds property that the operation is an involution.
static LogicalResult verifyTrait(Operation *op)
static OpFoldResult foldTrait(Operation *op, ArrayRef< Attribute > operands)
This class provides the API for ops that are known to be isolated from above.
static LogicalResult verifyRegionTrait(Operation *op)
This class provides the API for ops that are known to be terminators.
static LogicalResult verifyTrait(Operation *op)
static LogicalResult verifyTrait(Operation *op)
This class provides the API for ops that are known to have a specified number of operands.
static LogicalResult verifyTrait(Operation *op)
This class provides the API for ops that are known to have a specified number of regions.
static LogicalResult verifyTrait(Operation *op)
This class provides the API for ops that are known to have a specified number of results.
static LogicalResult verifyTrait(Operation *op)
This class provides the API for ops that are known to have a specified number of successors.
This class indicates that the regions associated with this op don't have terminators.
This class provides the API for ops that are known to have exactly one SSA operand.
void setOperand(Value value)
static LogicalResult verifyTrait(Operation *op)
This class provides APIs for ops that are known to have a single region.
static LogicalResult verifyTrait(Operation *op)
auto getOps()
Returns a range of operations within the region of this operation.
This class provides return value APIs for ops that are known to have a single result.
static LogicalResult verifyTrait(Operation *op)
void replaceAllUsesWith(Operation *op)
Replace all uses of 'this' value with the result of 'op'.
void replaceAllUsesWith(Value newValue)
Replace all uses of 'this' value with the new value, updating anything in the IR that uses 'this' to ...
This class provides APIs for ops that are known to have a single successor.
void setSuccessor(Block *succ)
static LogicalResult verifyTrait(Operation *op)
This class provides return value APIs for ops that are known to have a single result.
mlir::TypedValue< ResultType > getResult()
This trait is used for return value APIs for ops that are known to have a specific type other than Ty...
verifyInvariantsImpl verifies the invariants like the types, attrs, .etc.
static LogicalResult verifyTrait(Operation *op)
This class verifies that all operands of the specified op have a float type, a vector thereof,...
static LogicalResult verifyTrait(Operation *op)
This class verifies that all operands of the specified op have a signless integer or index type,...
static LogicalResult verifyTrait(Operation *op)
This class verifies that any results of the specified op have a boolean type, a vector thereof,...
static LogicalResult verifyTrait(Operation *op)
This class verifies that any results of the specified op have a floating point type,...
static LogicalResult verifyTrait(Operation *op)
This class verifies that any results of the specified op have a signless integer or index type,...
static LogicalResult verifyTrait(Operation *op)
This class provides verification for ops that are known to have the same operand and result element t...
static LogicalResult verifyTrait(Operation *op)
This class provides verification for ops that are known to have the same operand and result shape: bo...
static LogicalResult verifyTrait(Operation *op)
This class provides verification for ops that are known to have the same operand and result type.
static LogicalResult verifyTrait(Operation *op)
This class provides verification for ops that are known to have the same operand element type (or the...
static LogicalResult verifyTrait(Operation *op)
This class provides verification for ops that are known to have the same operand shape: all 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)
static void ensureTerminator(Region ®ion, OpBuilder &builder, Location loc)
enable_if_single_region< OpT > insert(Operation *insertPt, Operation *op)
Insert the operation at the given insertion point.
static void ensureTerminator(Region ®ion, Builder &builder, Location loc)
Ensure that the given region has the terminator required by this trait.
enable_if_single_region< OpT > push_back(Operation *op)
Insert the operation into the back of the body, before the terminator.
static LogicalResult verifyRegionTrait(Operation *op)
TerminatorOpType ImplicitTerminatorOpT
The type of the operation used as the implicit terminator type.
enable_if_single_region< OpT > insert(Block::iterator insertPt, Operation *op)
Block * getBody(unsigned idx=0)
Helper class for implementing traits.
Operation * getOperation()
Return the ultimate Operation being worked on.
This class provides the API for ops which have an unknown number of SSA operands.
This class provides the API for ops which have an unknown number of regions.
This class provides the API for ops which have an unknown number of results.
This class provides the API for ops which have an unknown number of successors.
This class provides the API for ops that are known to have no SSA operand.
static LogicalResult verifyTrait(Operation *op)
This class provides verification for ops that are known to have zero regions.
static LogicalResult verifyTrait(Operation *op)
This class provides return value APIs for ops that are known to have zero results.
static LogicalResult verifyTrait(Operation *op)
This class provides verification for ops that are known to have zero successors.
static LogicalResult verifyTrait(Operation *op)
This provides public APIs that all operations should have.
static bool classof(Operation *op)
Return true if this "op class" can match against the specified operation.
static ConcreteOpType getFromOpaquePointer(const void *pointer)
LogicalResult verify()
If the concrete type didn't implement a custom verifier hook, just fall back to this one which accept...
Op(Operation *state)
This is a public constructor to enable access via the llvm::cast family of methods.
ConcreteType ConcreteOpType
Expose the type we are instantiated on to template machinery that may want to introspect traits on th...
LogicalResult verifyRegions()
ConcreteType clone()
Create a deep copy of this operation.
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.
Operation * getOperation()
Inherit getOperation from OpState.
static constexpr bool hasTrait()
Return if this operation contains the provided trait.
const void * getAsOpaquePointer() const
Methods for supporting PointerLikeTypeTraits.
Op()
This is a public constructor. Any op can be initialized to null.
static void attachInterface(MLIRContext &context)
Attach the given models as implementations of the corresponding interfaces for the concrete operation...
ConcreteType cloneWithoutRegions()
Create a partial copy of this operation without traversing into attached regions.
This class implements the operand iterators for the Operation class.
llvm::unique_function< LogicalResult(Operation *) const > VerifyInvariantsFn
StringRef getStringRef() const
Return the name of this operation. This always succeeds.
llvm::unique_function< bool(TypeID) const > HasTraitFn
Dialect * getDialect() const
Return the dialect this operation is registered to if the dialect is loaded in the context,...
llvm::unique_function< LogicalResult(Operation *) const > VerifyRegionInvariantsFn
std::optional< RegisteredOperationName > getRegisteredInfo() const
If this operation is registered, returns the registered information, std::nullopt otherwise.
llvm::unique_function< void(Operation *, OpAsmPrinter &, StringRef) const > PrintAssemblyFn
llvm::unique_function< LogicalResult(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &) const > FoldHookFn
llvm::unique_function< void(const OperationName &, NamedAttrList &) const > PopulateDefaultAttrsFn
Operation is the basic unit of execution within MLIR.
ResultRange result_range
Support result iteration.
bool use_empty()
Returns true if this operation has no uses.
Value getOperand(unsigned idx)
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
operand_range::type_range operand_type_range
void setOperand(unsigned idx, Value value)
Block * getSuccessor(unsigned index)
unsigned getNumSuccessors()
result_iterator result_begin()
result_range::iterator result_iterator
operand_iterator operand_begin()
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
void print(raw_ostream &os, const OpPrintingFlags &flags=std::nullopt)
operand_range::type_iterator operand_type_iterator
operand_type_iterator operand_type_end()
result_range::type_range result_type_range
MLIRContext * getContext()
Return the context this operation is associated with.
unsigned getNumRegions()
Returns the number of regions held by this operation.
std::optional< RegisteredOperationName > getRegisteredInfo()
If this operation has a registered operation description, return it.
Location getLoc()
The source location the operation was defined or derived from.
unsigned getNumOperands()
result_type_iterator result_type_end()
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, NamedAttrList &&attributes, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
OperandRange operand_range
result_range::type_iterator result_type_iterator
Support result type iteration.
operand_iterator operand_end()
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
result_type_iterator result_type_begin()
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
OperationName getName()
The name of an operation is the key identifier for it.
operand_type_range getOperandTypes()
result_iterator result_end()
result_type_range getResultTypes()
operand_range getOperands()
Returns an iterator on the underlying Value's.
void setSuccessor(Block *block, unsigned index)
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided 'values'.
SuccessorRange getSuccessors()
result_range getResults()
SuccessorRange::iterator succ_iterator
operand_range::iterator operand_iterator
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
void erase()
Remove this operation from its parent block and delete it.
unsigned getNumResults()
Return the number of results held by this operation.
operand_type_iterator operand_type_begin()
This class implements Optional functionality for ParseResult.
OptionalParseResult()=default
ParseResult value() const
Access the internal ParseResult value.
OptionalParseResult(ParseResult result)
OptionalParseResult(std::nullopt_t)
OptionalParseResult(const InFlightDiagnostic &)
OptionalParseResult(LogicalResult result)
bool has_value() const
Returns true if we contain a valid ParseResult value.
ParseResult operator*() const
This class represents success/failure for parsing-like operations that find it important to chain tog...
This class provides an abstraction over the different types of ranges over Regions.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
iterator_range< OpIterator > getOps()
This is a "type erased" representation of a registered operation.
static std::optional< RegisteredOperationName > lookup(StringRef name, MLIRContext *ctx)
Lookup the registered operation information for the given operation.
This class implements the result iterators for the Operation class.
This class implements the successor iterators for Block.
This class provides an efficient unique identifier for a specific C++ type.
This class provides an abstraction over the various different ranges of value types.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class implements iteration on the types of a given range of values.
This class implements iteration on the types of a given range of values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Type getType() const
Return the type of this value.
void replaceAllUsesWith(Value newValue) const
Replace all uses of 'this' value with the new value, updating anything in the IR that uses 'this' to ...
This class represents an abstract interface.
Interface< ConcreteType, Operation *, Traits, Op< ConcreteType >, OpTrait::TraitBase > InterfaceBase
typename Traits::Concept Concept
Include the generated interface declarations.
OpFoldResult foldIdempotent(Operation *op)
LogicalResult verifyResultsAreFloatLike(Operation *op)
LogicalResult verifyAtLeastNResults(Operation *op, unsigned numOperands)
LogicalResult verifyIsIdempotent(Operation *op)
LogicalResult verifyOperandsAreSignlessIntegerLike(Operation *op)
LogicalResult verifyNOperands(Operation *op, unsigned numOperands)
LogicalResult verifyNoRegionArguments(Operation *op)
LogicalResult verifyResultsAreSignlessIntegerLike(Operation *op)
LogicalResult verifyIsInvolution(Operation *op)
LogicalResult verifyOperandsAreFloatLike(Operation *op)
LogicalResult verifyZeroRegions(Operation *op)
LogicalResult verifyNSuccessors(Operation *op, unsigned numSuccessors)
LogicalResult verifyOperandSizeAttr(Operation *op, StringRef sizeAttrName)
LogicalResult verifyAtLeastNRegions(Operation *op, unsigned numRegions)
LogicalResult verifyValueSizeAttr(Operation *op, StringRef attrName, StringRef valueGroupName, size_t expectedCount)
LogicalResult verifyZeroResults(Operation *op)
LogicalResult verifySameOperandsAndResultType(Operation *op)
LogicalResult verifySameOperandsShape(Operation *op)
LogicalResult verifyAtLeastNSuccessors(Operation *op, unsigned numSuccessors)
LogicalResult verifyIsTerminator(Operation *op)
LogicalResult verifyAtLeastNOperands(Operation *op, unsigned numOperands)
LogicalResult verifyZeroOperands(Operation *op)
LogicalResult verifyElementwise(Operation *op)
LogicalResult verifyOneRegion(Operation *op)
LogicalResult verifyOneOperand(Operation *op)
LogicalResult verifyIsIsolatedFromAbove(Operation *op)
Check for any values used by operations regions attached to the specified "IsIsolatedFromAbove" opera...
LogicalResult verifyZeroSuccessors(Operation *op)
LogicalResult verifySameOperandsElementType(Operation *op)
LogicalResult verifyOneSuccessor(Operation *op)
LogicalResult verifySameOperandsAndResultElementType(Operation *op)
OpFoldResult foldInvolution(Operation *op)
LogicalResult verifyResultsAreBoolLike(Operation *op)
LogicalResult verifyNResults(Operation *op, unsigned numOperands)
LogicalResult verifyResultSizeAttr(Operation *op, StringRef sizeAttrName)
LogicalResult verifyNRegions(Operation *op, unsigned numRegions)
LogicalResult verifyOneResult(Operation *op)
LogicalResult verifySameTypeOperands(Operation *op)
LogicalResult verifySameOperandsAndResultShape(Operation *op)
bool hasElementwiseMappableTraits(Operation *op)
Together, Elementwise, Scalarizable, Vectorizable, and Tensorizable provide an easy way for scalar op...
typename T::ImplicitTerminatorOpT has_implicit_terminator_t
Check is an op defines the ImplicitTerminatorOpT member.
LogicalResult foldCastInterfaceOp(Operation *op, ArrayRef< Attribute > attrOperands, SmallVectorImpl< OpFoldResult > &foldResults)
Attempt to fold the given cast operation.
LogicalResult verifyCastInterfaceOp(Operation *op, function_ref< bool(TypeRange, TypeRange)> areCastCompatible)
Attempt to verify the given cast operation.
void ensureRegionTerminator(Region ®ion, OpBuilder &builder, Location loc, function_ref< Operation *(OpBuilder &, Location)> buildTerminatorOp)
Insert an operation, generated by buildTerminatorOp, at the end of the region's only block if it does...
void ensureRegionTerminator(Region ®ion, Builder &builder, Location loc, function_ref< Operation *(OpBuilder &, Location)> buildTerminatorOp)
Create a simple OpBuilder and forward to the OpBuilder version of this function.
NestedPattern Op(FilterFunctionType filter=defaultFilterFunction)
llvm::is_detected< has_fold_trait, T > detect_has_fold_trait
std::enable_if_t< detect_has_verify_trait< T >::value, LogicalResult > verifyTrait(Operation *op)
Verify the given trait if it provides a verifier.
llvm::is_detected< has_verify_trait, T > detect_has_verify_trait
llvm::is_detected< has_verify_region_trait, T > detect_has_verify_region_trait
LogicalResult verifyTraits(Operation *op)
Given a set of traits, return the result of verifying the given operation.
std::enable_if_t<!detect_has_verify_trait< T >::value, LogicalResult > verifyTrait(Operation *)
decltype(T::verifyTrait(std::declval< Operation * >())) has_verify_trait
Trait to check if T provides a verifyTrait method.
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 'foldTrait' method.
static bool hasTrait(TypeID traitID)
Returns true if this given Trait ID matches the IDs of any of the provided trait types Traits.
llvm::is_detected< has_single_result_fold_trait, T > detect_has_single_result_fold_trait
std::enable_if_t< detect_has_verify_region_trait< T >::value, LogicalResult > verifyRegionTrait(Operation *op)
Verify the given trait if it provides a region verifier.
static std::enable_if_t<!detect_has_any_fold_trait< Trait >::value, LogicalResult > foldTrait(Operation *, ArrayRef< Attribute >, SmallVectorImpl< OpFoldResult > &)
std::disjunction< 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.
decltype(T::verifyRegionTrait(std::declval< Operation * >())) has_verify_region_trait
Trait to check if T provides a verifyTrait method.
static LogicalResult foldTraits(Operation *op, ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Given a tuple type containing a set of traits, return the result of folding the given operation.
static std::enable_if_t< detect_has_single_result_fold_trait< Trait >::value, LogicalResult > foldTrait(Operation *op, ArrayRef< Attribute > operands, SmallVectorImpl< OpFoldResult > &results)
Returns the result of folding a trait that implements a foldTrait function that is specialized for op...
decltype(T::foldTrait(std::declval< Operation * >(), std::declval< ArrayRef< Attribute > >())) has_single_result_fold_trait
Trait to check if T provides a 'foldTrait' method for single result operations.
LogicalResult verifyRegionTraits(Operation *op)
Given a set of traits, return the result of verifying the regions of the given operation.
std::enable_if_t<!detect_has_verify_region_trait< T >::value, LogicalResult > verifyRegionTrait(Operation *)
llvm::hash_code hash_value(const MPInt &x)
Redeclarations of friend declaration above to make it discoverable by lookups.
This header declares functions that assit transformations in the MemRef dialect.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
llvm::function_ref< Fn > function_ref
std::conditional_t< std::is_same_v< Ty, mlir::Type >, mlir::Value, detail::TypedValue< Ty > > TypedValue
If Ty is mlir::Type this will select Value instead of having a wrapper around it.
bool operator==(StringAttr lhs, std::nullptr_t)
Define comparisons for StringAttr against nullptr and itself to avoid the StringRef overloads from be...
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
WalkOrder
Traversal order for region, block and operation walk utilities.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
bool operator!=(StringAttr lhs, std::nullptr_t)
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
static bool isEqual(T lhs, T rhs)
static T getTombstoneKey()
static unsigned getHashValue(T val)
This class represents an efficient way to signal success or failure.
static LogicalResult failure(bool isFailure=true)
If isFailure is true a failure result is generated, otherwise a 'success' result is generated.
This trait tags element-wise ops on vectors or tensors.
static LogicalResult verifyTrait(Operation *op)
This class provides a verifier for ops that are expecting their parent to be one of the given parent ...
This trait provides a verifier for ops that are expecting their regions to not have any arguments.
static LogicalResult verifyTrait(Operation *op)
This trait tags Elementwise operatons that can be systematically scalarized.
static LogicalResult verifyTrait(Operation *op)
This class provides APIs and verifiers for ops with regions having a single block that must terminate...
This class provides APIs and verifiers for ops with regions having a single block.
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.
enable_if_single_region< OpT > insert(Operation *insertPt, Operation *op)
Insert the operation at the given insertion point.
Region & getBodyRegion(unsigned idx=0)
enable_if_single_region< OpT > push_back(Operation *op)
Insert the operation into the back of the body.
enable_if_single_region< OpT, Block::iterator > begin()
enable_if_single_region< OpT, Operation & > front()
static LogicalResult verifyTrait(Operation *op)
enable_if_single_region< OpT > insert(Block::iterator insertPt, Operation *op)
Block * getBody(unsigned idx=0)
enable_if_single_region< OpT, Block::iterator > end()
This trait tags Elementwise operatons that can be systematically tensorized.
static LogicalResult verifyTrait(Operation *op)
This trait tags Elementwise operatons that can be systematically vectorized.
static LogicalResult verifyTrait(Operation *op)
Utility trait base that provides accessors for derived traits that have multiple operands.
Value getOperand(unsigned i)
Return the operand at index 'i'.
operand_type_range getOperandTypes()
operand_type_iterator operand_type_begin()
Operand type access.
unsigned getNumOperands()
Return the number of operands.
operand_iterator operand_begin()
Operand iterator access.
operand_type_iterator operand_type_end()
void setOperand(unsigned i, Value value)
Set the operand at index 'i' to 'value'.
Operation::operand_iterator operand_iterator
operand_iterator operand_end()
operand_range getOperands()
Utility trait base that provides accessors for derived traits that have multiple regions.
unsigned getNumRegions()
Return the number of regions.
Region & getRegion(unsigned i)
Return the region at index.
region_iterator region_begin()
Region iterator access.
region_range getRegions()
region_iterator region_end()
Utility trait base that provides accessors for derived traits that have multiple results.
result_type_iterator result_type_end()
result_type_range getResultTypes()
result_type_iterator result_type_begin()
Result type access.
result_iterator result_end()
Value getResult(unsigned i)
Return the result at index 'i'.
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided 'values'.
Operation::result_iterator result_iterator
result_iterator result_begin()
Result iterator access.
unsigned getNumResults()
Return the number of results.
result_range getResults()
Type getType(unsigned i)
Return the type of the i-th result.
Utility trait base that provides accessors for derived traits that have multiple successors.
void setSuccessor(Block *block, unsigned i)
Set the successor at index.
succ_iterator succ_begin()
Successor iterator access.
unsigned getNumSuccessors()
Return the number of successors.
Operation::succ_iterator succ_iterator
Block * getSuccessor(unsigned i)
Return the successor at index.
succ_range getSuccessors()
Support to check if an operation has the SingleBlockImplicitTerminator trait.
static constexpr bool value
This represents an operation in an abstracted form, suitable for use with the builder APIs.