Files
gps/tools/local/circt/include/mlir/Interfaces/LoopLikeInterface.h.inc
T
2026-07-12 11:01:51 +03:00

984 lines
59 KiB
C++

/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|* *|
|* Interface Declarations *|
|* *|
|* Automatically generated file, do not edit! *|
|* *|
\*===----------------------------------------------------------------------===*/
namespace mlir {
/// Contains helper functions to query properties and perform transformations
/// of a loop. Operations that implement this interface will be considered by
/// loop-invariant code motion.
///
/// Loop-carried variables can be exposed through this interface. There are
/// 3 components to a loop-carried variable.
/// - The "region iter_arg" is the block argument of the entry block that
/// represents the loop-carried variable in each iteration.
/// - The "init value" is an operand of the loop op that serves as the initial
/// region iter_arg value for the first iteration (if any).
/// - The "yielded" value is the value that is forwarded from one iteration to
/// serve as the region iter_arg of the next iteration.
///
/// If one of the respective interface methods is implemented, so must the other
/// two. The interface verifier ensures that the number of region iter_args,
/// init values and yielded values match. Note: the types are not required to
/// strictly match; if the op also implements `RegionBranchOpInterface`, type
/// compatibility is deferred to that interface's `areTypesCompatible` hook.
///
/// Optionally, "loop results" can be exposed through this interface. These are
/// the values that are returned from the loop op when there are no more
/// iterations. The number and types of the loop results must match with the
/// region iter_args. Note: Loop results are optional because some loops
/// (e.g., `scf.while`) may produce results that do match 1-to-1 with the
/// region iter_args.
class LoopLikeOpInterface;
} // namespace mlir
namespace mlir {
/// Contains helper functions to query properties and perform transformations
/// of a loop. Operations that implement this interface will be considered by
/// loop-invariant code motion.
///
/// Loop-carried variables can be exposed through this interface. There are
/// 3 components to a loop-carried variable.
/// - The "region iter_arg" is the block argument of the entry block that
/// represents the loop-carried variable in each iteration.
/// - The "init value" is an operand of the loop op that serves as the initial
/// region iter_arg value for the first iteration (if any).
/// - The "yielded" value is the value that is forwarded from one iteration to
/// serve as the region iter_arg of the next iteration.
///
/// If one of the respective interface methods is implemented, so must the other
/// two. The interface verifier ensures that the number of region iter_args,
/// init values and yielded values match. Note: the types are not required to
/// strictly match; if the op also implements `RegionBranchOpInterface`, type
/// compatibility is deferred to that interface's `areTypesCompatible` hook.
///
/// Optionally, "loop results" can be exposed through this interface. These are
/// the values that are returned from the loop op when there are no more
/// iterations. The number and types of the loop results must match with the
/// region iter_args. Note: Loop results are optional because some loops
/// (e.g., `scf.while`) may produce results that do match 1-to-1 with the
/// region iter_args.
namespace detail {
struct LoopLikeOpInterfaceInterfaceTraits {
struct Concept {
/// The methods defined by the interface.
bool (*isDefinedOutsideOfLoop)(const Concept *impl, ::mlir::Operation *, ::mlir::Value );
::llvm::SmallVector<::mlir::Region *> (*getLoopRegions)(const Concept *impl, ::mlir::Operation *);
void (*moveOutOfLoop)(const Concept *impl, ::mlir::Operation *, ::mlir::Operation *);
::llvm::LogicalResult (*promoteIfSingleIteration)(const Concept *impl, ::mlir::Operation *, ::mlir::RewriterBase &);
::std::optional<::llvm::SmallVector<::mlir::Value>> (*getLoopInductionVars)(const Concept *impl, ::mlir::Operation *);
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> (*getLoopLowerBounds)(const Concept *impl, ::mlir::Operation *);
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> (*getLoopSteps)(const Concept *impl, ::mlir::Operation *);
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> (*getLoopUpperBounds)(const Concept *impl, ::mlir::Operation *);
::llvm::MutableArrayRef<::mlir::OpOperand> (*getInitsMutable)(const Concept *impl, ::mlir::Operation *);
::mlir::Block::BlockArgListType (*getRegionIterArgs)(const Concept *impl, ::mlir::Operation *);
::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> (*getYieldedValuesMutable)(const Concept *impl, ::mlir::Operation *);
::std::optional<::mlir::ResultRange> (*getLoopResults)(const Concept *impl, ::mlir::Operation *);
::mlir::FailureOr<::mlir::LoopLikeOpInterface> (*replaceWithAdditionalYields)(const Concept *impl, ::mlir::Operation *, ::mlir::RewriterBase &, ::mlir::ValueRange, bool, const ::mlir::NewYieldValuesFn &);
::std::optional<::llvm::APInt> (*getStaticTripCount)(const Concept *impl, ::mlir::Operation *);
bool (*isValidInductionVarType)(const Concept *impl, ::mlir::Operation *, ::mlir::Type);
::mlir::LogicalResult (*setLoopLowerBounds)(const Concept *impl, ::mlir::Operation *, ::llvm::ArrayRef<::mlir::OpFoldResult>);
::mlir::LogicalResult (*setLoopUpperBounds)(const Concept *impl, ::mlir::Operation *, ::llvm::ArrayRef<::mlir::OpFoldResult>);
::mlir::LogicalResult (*setLoopSteps)(const Concept *impl, ::mlir::Operation *, ::llvm::ArrayRef<::mlir::OpFoldResult>);
};
template<typename ConcreteOp>
class Model : public Concept {
public:
using Interface = ::mlir::LoopLikeOpInterface;
Model() : Concept{isDefinedOutsideOfLoop, getLoopRegions, moveOutOfLoop, promoteIfSingleIteration, getLoopInductionVars, getLoopLowerBounds, getLoopSteps, getLoopUpperBounds, getInitsMutable, getRegionIterArgs, getYieldedValuesMutable, getLoopResults, replaceWithAdditionalYields, getStaticTripCount, isValidInductionVarType, setLoopLowerBounds, setLoopUpperBounds, setLoopSteps} {}
static inline bool isDefinedOutsideOfLoop(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Value value);
static inline ::llvm::SmallVector<::mlir::Region *> getLoopRegions(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline void moveOutOfLoop(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * op);
static inline ::llvm::LogicalResult promoteIfSingleIteration(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase & rewriter);
static inline ::std::optional<::llvm::SmallVector<::mlir::Value>> getLoopInductionVars(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopLowerBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopSteps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopUpperBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::llvm::MutableArrayRef<::mlir::OpOperand> getInitsMutable(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::mlir::Block::BlockArgListType getRegionIterArgs(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> getYieldedValuesMutable(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::mlir::ResultRange> getLoopResults(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::mlir::FailureOr<::mlir::LoopLikeOpInterface> replaceWithAdditionalYields(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase & rewriter, ::mlir::ValueRange newInitOperands, bool replaceInitOperandUsesInLoop, const ::mlir::NewYieldValuesFn & newYieldValuesFn);
static inline ::std::optional<::llvm::APInt> getStaticTripCount(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline bool isValidInductionVarType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Type type);
static inline ::mlir::LogicalResult setLoopLowerBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds);
static inline ::mlir::LogicalResult setLoopUpperBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds);
static inline ::mlir::LogicalResult setLoopSteps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> steps);
};
template<typename ConcreteOp>
class FallbackModel : public Concept {
public:
using Interface = ::mlir::LoopLikeOpInterface;
FallbackModel() : Concept{isDefinedOutsideOfLoop, getLoopRegions, moveOutOfLoop, promoteIfSingleIteration, getLoopInductionVars, getLoopLowerBounds, getLoopSteps, getLoopUpperBounds, getInitsMutable, getRegionIterArgs, getYieldedValuesMutable, getLoopResults, replaceWithAdditionalYields, getStaticTripCount, isValidInductionVarType, setLoopLowerBounds, setLoopUpperBounds, setLoopSteps} {}
static inline bool isDefinedOutsideOfLoop(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Value value);
static inline ::llvm::SmallVector<::mlir::Region *> getLoopRegions(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline void moveOutOfLoop(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * op);
static inline ::llvm::LogicalResult promoteIfSingleIteration(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase & rewriter);
static inline ::std::optional<::llvm::SmallVector<::mlir::Value>> getLoopInductionVars(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopLowerBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopSteps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopUpperBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::llvm::MutableArrayRef<::mlir::OpOperand> getInitsMutable(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::mlir::Block::BlockArgListType getRegionIterArgs(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> getYieldedValuesMutable(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::std::optional<::mlir::ResultRange> getLoopResults(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline ::mlir::FailureOr<::mlir::LoopLikeOpInterface> replaceWithAdditionalYields(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase & rewriter, ::mlir::ValueRange newInitOperands, bool replaceInitOperandUsesInLoop, const ::mlir::NewYieldValuesFn & newYieldValuesFn);
static inline ::std::optional<::llvm::APInt> getStaticTripCount(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
static inline bool isValidInductionVarType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Type type);
static inline ::mlir::LogicalResult setLoopLowerBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds);
static inline ::mlir::LogicalResult setLoopUpperBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds);
static inline ::mlir::LogicalResult setLoopSteps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> steps);
};
template<typename ConcreteModel, typename ConcreteOp>
class ExternalModel : public FallbackModel<ConcreteModel> {
public:
using ConcreteEntity = ConcreteOp;
bool isDefinedOutsideOfLoop(::mlir::Operation *tablegen_opaque_val, ::mlir::Value value) const;
void moveOutOfLoop(::mlir::Operation *tablegen_opaque_val, ::mlir::Operation *op) const;
::llvm::LogicalResult promoteIfSingleIteration(::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase &rewriter) const;
::std::optional<::llvm::SmallVector<::mlir::Value>> getLoopInductionVars(::mlir::Operation *tablegen_opaque_val) const;
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopLowerBounds(::mlir::Operation *tablegen_opaque_val) const;
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopSteps(::mlir::Operation *tablegen_opaque_val) const;
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopUpperBounds(::mlir::Operation *tablegen_opaque_val) const;
::llvm::MutableArrayRef<::mlir::OpOperand> getInitsMutable(::mlir::Operation *tablegen_opaque_val) const;
::mlir::Block::BlockArgListType getRegionIterArgs(::mlir::Operation *tablegen_opaque_val) const;
::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> getYieldedValuesMutable(::mlir::Operation *tablegen_opaque_val) const;
::std::optional<::mlir::ResultRange> getLoopResults(::mlir::Operation *tablegen_opaque_val) const;
::mlir::FailureOr<::mlir::LoopLikeOpInterface> replaceWithAdditionalYields(::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase &rewriter, ::mlir::ValueRange newInitOperands, bool replaceInitOperandUsesInLoop, const ::mlir::NewYieldValuesFn &newYieldValuesFn) const;
::std::optional<::llvm::APInt> getStaticTripCount(::mlir::Operation *tablegen_opaque_val) const;
bool isValidInductionVarType(::mlir::Operation *tablegen_opaque_val, ::mlir::Type type) const;
::mlir::LogicalResult setLoopLowerBounds(::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds) const;
::mlir::LogicalResult setLoopUpperBounds(::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds) const;
::mlir::LogicalResult setLoopSteps(::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> steps) const;
};
};
template <typename ConcreteOp>
struct LoopLikeOpInterfaceTrait;
} // namespace detail
class LoopLikeOpInterface : public ::mlir::OpInterface<LoopLikeOpInterface, detail::LoopLikeOpInterfaceInterfaceTraits> {
public:
using ::mlir::OpInterface<LoopLikeOpInterface, detail::LoopLikeOpInterfaceInterfaceTraits>::OpInterface;
template <typename ConcreteOp>
struct Trait : public detail::LoopLikeOpInterfaceTrait<ConcreteOp> {};
/// Returns true if the given value is defined outside of the loop.
/// A sensible implementation could be to check whether the value's defining
/// operation lies outside of the loops body region. If the loop uses
/// explicit capture of dependencies, an implementation could check whether
/// the value corresponds to a captured dependency.
bool isDefinedOutsideOfLoop(::mlir::Value value);
/// Returns the regions that make up the body of the loop and should be
/// inspected for loop-invariant operations.
::llvm::SmallVector<::mlir::Region *> getLoopRegions();
/// Moves the given loop-invariant operation out of the loop.
void moveOutOfLoop(::mlir::Operation * op);
/// Promotes the loop body to its containing block if the loop is known to
/// have a single iteration. Returns "success" if the promotion was
/// successful.
::llvm::LogicalResult promoteIfSingleIteration(::mlir::RewriterBase & rewriter);
/// Return all induction variables, if they exist. If the op has no notion of
/// induction variable, then return std::nullopt. If it does have
/// a notion but an instance doesn't have induction variables, then
/// return empty vector.
::std::optional<::llvm::SmallVector<::mlir::Value>> getLoopInductionVars();
/// Return all lower bounds, if they exist. If the op has no notion of
/// lower bounds, then return std::nullopt. If it does have
/// a notion but an instance doesn't have lower bounds, then
/// return empty vector.
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopLowerBounds();
/// Return all steps, if they exist. If the op has no notion of
/// steps, then return std::nullopt. If it does have
/// a notion but an instance doesn't have steps, then
/// return empty vector.
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopSteps();
/// Return all upper bounds, if they exist. If the op has no notion of
/// lower bounds, then return std::nullopt. If it does have
/// a notion but an instance doesn't have lower bounds, then
/// return empty vector.
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopUpperBounds();
/// Return the mutable "init" operands that are used as initialization
/// values for the region "iter_args" of this loop.
::llvm::MutableArrayRef<::mlir::OpOperand> getInitsMutable();
/// Return the region "iter_args" (block arguments) that correspond to the
/// "init" operands. If the op has multiple regions, return the
/// corresponding block arguments of the entry region.
::mlir::Block::BlockArgListType getRegionIterArgs();
/// Return the mutable operand range of values that are yielded to the next
/// iteration by the loop terminator.
///
/// For loop operations that dont yield a value, this should return
/// std::nullopt.
::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> getYieldedValuesMutable();
/// Return the range of results that are return from this loop and
/// correspond to the "init" operands.
///
/// Note: This interface method is optional. If loop results are not
/// exposed via this interface, "std::nullopt" should be returned.
/// Otherwise, the number and types of results must match with the
/// region iter_args, inits and yielded values that are exposed via this
/// interface. If loop results are exposed but this loop op has no
/// loop-carried variables, an empty result range (and not "std::nullopt")
/// should be returned.
::std::optional<::mlir::ResultRange> getLoopResults();
/// Append the specified additional "init" operands: replace this loop with
/// a new loop that has the additional init operands. The loop body of
/// this loop is moved over to the new loop.
///
/// `newInitOperands` specifies the additional "init" operands.
/// `newYieldValuesFn` is a function that returns the yielded values (which
/// can be computed based on the additional region iter_args). If
/// `replaceInitOperandUsesInLoop` is set, all uses of the additional init
/// operands inside of this loop are replaced with the corresponding, newly
/// added region iter_args.
///
/// Note: Loops that do not support init/iter_args should return "failure".
::mlir::FailureOr<::mlir::LoopLikeOpInterface> replaceWithAdditionalYields(::mlir::RewriterBase & rewriter, ::mlir::ValueRange newInitOperands, bool replaceInitOperandUsesInLoop, const ::mlir::NewYieldValuesFn & newYieldValuesFn);
/// Compute the static trip count if possible.
::std::optional<::llvm::APInt> getStaticTripCount();
/// Check if the given type is supported as a loop induction variable.
/// By default, only IndexType is supported.
bool isValidInductionVarType(::mlir::Type type);
/// Update the loop lower bounds. Returns failure if the loop doesn't
/// support updating bounds or if the number of bounds doesn't match.
::mlir::LogicalResult setLoopLowerBounds(::llvm::ArrayRef<::mlir::OpFoldResult> bounds);
/// Update the loop upper bounds. Returns failure if the loop doesn't
/// support updating bounds or if the number of bounds doesn't match.
::mlir::LogicalResult setLoopUpperBounds(::llvm::ArrayRef<::mlir::OpFoldResult> bounds);
/// Update the loop steps. Returns failure if the loop doesn't support
/// updating steps or if the number of steps doesn't match.
::mlir::LogicalResult setLoopSteps(::llvm::ArrayRef<::mlir::OpFoldResult> steps);
/// Returns if a block is inside a loop (within the current function). This
/// can either be because the block is nested inside a LoopLikeInterface, or
/// because the control flow graph is cyclic
static bool blockIsInLoop(::mlir::Block *block);
/// If there is a single induction variable return it, otherwise return
/// std::nullopt.
::std::optional<::mlir::Value> getSingleInductionVar() {
auto inductionVars = (*this).getLoopInductionVars();
if (inductionVars.has_value() && (*inductionVars).size() == 1)
return (*inductionVars)[0];
return ::std::nullopt;
}
/// Return the single lower bound value or attribute if it exists, otherwise
/// return std::nullopt.
::std::optional<::mlir::OpFoldResult> getSingleLowerBound() {
auto lowerBounds = (*this).getLoopLowerBounds();
if (lowerBounds.has_value() && (*lowerBounds).size() == 1)
return (*lowerBounds)[0];
return ::std::nullopt;
}
/// Return the single step value or attribute if it exists, otherwise
/// return std::nullopt.
::std::optional<::mlir::OpFoldResult> getSingleStep() {
auto steps = (*this).getLoopSteps();
if (steps.has_value() && (*steps).size() == 1)
return (*steps)[0];
return ::std::nullopt;
}
/// Return the single upper bound value or attribute if it exists, otherwise
/// return std::nullopt.
::std::optional<::mlir::OpFoldResult> getSingleUpperBound() {
auto upperBounds = (*this).getLoopUpperBounds();
if (upperBounds.has_value() && (*upperBounds).size() == 1)
return (*upperBounds)[0];
return ::std::nullopt;
}
/// Append the specified additional "init" operands: replace this loop with
/// a new loop that has the additional init operands. The loop body of this
/// loop is moved over to the new loop.
///
/// The newly added region iter_args are yielded from the loop.
::mlir::FailureOr<::mlir::LoopLikeOpInterface>
replaceWithAdditionalIterOperands(::mlir::RewriterBase &rewriter,
::mlir::ValueRange newInitOperands,
bool replaceInitOperandUsesInLoop) {
return (*this).replaceWithAdditionalYields(
rewriter, newInitOperands, replaceInitOperandUsesInLoop,
[](::mlir::OpBuilder &b, ::mlir::Location loc,
::mlir::ArrayRef<::mlir::BlockArgument> newBBArgs) {
return ::mlir::SmallVector<::mlir::Value>(newBBArgs);
});
}
/// Return the values that are yielded to the next iteration. If
/// the loop doesnt yield any values return `{}`.
::mlir::ValueRange getYieldedValues() {
auto mutableValues = (*this).getYieldedValuesMutable();
if (!mutableValues || mutableValues->empty())
return {};
::mlir::Operation *yieldOp = mutableValues->begin()->getOwner();
unsigned firstOperandIndex = mutableValues->begin()->getOperandNumber();
return ::mlir::OperandRange(
yieldOp->operand_begin() + firstOperandIndex,
yieldOp->operand_begin() + firstOperandIndex + mutableValues->size());
}
/// Return the "init" operands that are used as initialization values for
/// the region "iter_args" of this loop.
::mlir::OperandRange getInits() {
auto initsMutable = (*this).getInitsMutable();
if (initsMutable.empty())
return ::mlir::OperandRange((*this)->operand_end(), (*this)->operand_end());
unsigned firstOperandIndex = initsMutable.begin()->getOperandNumber();
return ::mlir::OperandRange(
(*this)->operand_begin() + firstOperandIndex,
(*this)->operand_begin() + firstOperandIndex + initsMutable.size());
}
/// Return the region iter_arg that corresponds to the given init operand.
/// Return an "empty" block argument if the given operand is not an init
/// operand of this loop op.
::mlir::BlockArgument getTiedLoopRegionIterArg(
::mlir::OpOperand *opOperand) {
auto initsMutable = (*this).getInitsMutable();
auto it = ::llvm::find(initsMutable, *opOperand);
if (it == initsMutable.end())
return {};
return (*this).getRegionIterArgs()[
::std::distance(initsMutable.begin(), it)];
}
/// Return the region iter_arg that corresponds to the given loop result.
/// Return an "empty" block argument if the given OpResult is not a loop
/// result or if this op does not expose any loop results.
::mlir::BlockArgument getTiedLoopRegionIterArg(::mlir::OpResult opResult) {
auto loopResults = (*this).getLoopResults();
if (!loopResults)
return {};
auto it = ::llvm::find(*loopResults, opResult);
if (it == loopResults->end())
return {};
return (*this).getRegionIterArgs()[
::std::distance(loopResults->begin(), it)];
}
/// Return the init operand that corresponds to the given region iter_arg.
/// Return "nullptr" if the given block argument is not a region iter_arg
/// of this loop op.
::mlir::OpOperand *getTiedLoopInit(::mlir::BlockArgument bbArg) {
auto iterArgs = (*this).getRegionIterArgs();
auto it = ::llvm::find(iterArgs, bbArg);
if (it == iterArgs.end())
return {};
return &(*this).getInitsMutable()[::std::distance(iterArgs.begin(), it)];
}
/// Return the init operand that corresponds to the given loop result.
/// Return "nullptr" if the given OpResult is not a loop result or if this
/// op does not expose any loop results.
::mlir::OpOperand *getTiedLoopInit(::mlir::OpResult opResult) {
auto loopResults = (*this).getLoopResults();
if (!loopResults)
return nullptr;
auto it = ::llvm::find(*loopResults, opResult);
if (it == loopResults->end())
return nullptr;
return &(*this).getInitsMutable()[::std::distance(
loopResults->begin(), it)];
}
/// Return the yielded value that corresponds to the given region iter_arg.
/// Return "nullptr" if the given block argument is not a region iter_arg
/// of this loop op or if there is no yield corresponding to this `bbArg`.
::mlir::OpOperand *getTiedLoopYieldedValue(::mlir::BlockArgument bbArg) {
auto iterArgs = (*this).getRegionIterArgs();
auto it = ::llvm::find(iterArgs, bbArg);
if (it == iterArgs.end())
return {};
::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> yieldValues =
(*this).getYieldedValuesMutable();
if (!yieldValues)
return {};
return &yieldValues.value()[::std::distance(iterArgs.begin(), it)];
}
/// Return the loop result that corresponds to the given init operand.
/// Return an "empty" OpResult if the given operand is not an init operand
/// of this loop op or if this op does not expose any loop results.
::mlir::OpResult getTiedLoopResult(::mlir::OpOperand *opOperand) {
auto loopResults = (*this).getLoopResults();
if (!loopResults)
return {};
auto initsMutable = (*this).getInitsMutable();
auto it = ::llvm::find(initsMutable, *opOperand);
if (it == initsMutable.end())
return {};
return (*loopResults)[::std::distance(initsMutable.begin(), it)];
}
/// Return the loop result that corresponds to the given region iter_arg.
/// Return an "empty" OpResult if the given block argument is not a region
/// iter_arg of this loop op or if this op does not expose any loop results.
::mlir::OpResult getTiedLoopResult(::mlir::BlockArgument bbArg) {
auto loopResults = (*this).getLoopResults();
if (!loopResults)
return {};
auto iterArgs = (*this).getRegionIterArgs();
auto it = ::llvm::find(iterArgs, bbArg);
if (it == iterArgs.end())
return {};
return (*loopResults)[::std::distance(iterArgs.begin(), it)];
}
};
} // namespace mlir
namespace mlir::detail {
template <typename ConcreteOp>
struct LoopLikeOpInterfaceTrait : public ::mlir::OpInterface<LoopLikeOpInterface, detail::LoopLikeOpInterfaceInterfaceTraits>::Trait<ConcreteOp> {
/// Returns true if the given value is defined outside of the loop.
/// A sensible implementation could be to check whether the value's defining
/// operation lies outside of the loops body region. If the loop uses
/// explicit capture of dependencies, an implementation could check whether
/// the value corresponds to a captured dependency.
bool isDefinedOutsideOfLoop(::mlir::Value value) {
return !(*static_cast<ConcreteOp *>(this))->isAncestor(value.getParentRegion()->getParentOp());
}
/// Moves the given loop-invariant operation out of the loop.
void moveOutOfLoop(::mlir::Operation * op) {
op->moveBefore((*static_cast<ConcreteOp *>(this)));
}
/// Promotes the loop body to its containing block if the loop is known to
/// have a single iteration. Returns "success" if the promotion was
/// successful.
::llvm::LogicalResult promoteIfSingleIteration(::mlir::RewriterBase & rewriter) {
return ::mlir::failure();
}
/// Return all induction variables, if they exist. If the op has no notion of
/// induction variable, then return std::nullopt. If it does have
/// a notion but an instance doesn't have induction variables, then
/// return empty vector.
::std::optional<::llvm::SmallVector<::mlir::Value>> getLoopInductionVars() {
return ::std::nullopt;
}
/// Return all lower bounds, if they exist. If the op has no notion of
/// lower bounds, then return std::nullopt. If it does have
/// a notion but an instance doesn't have lower bounds, then
/// return empty vector.
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopLowerBounds() {
return ::std::nullopt;
}
/// Return all steps, if they exist. If the op has no notion of
/// steps, then return std::nullopt. If it does have
/// a notion but an instance doesn't have steps, then
/// return empty vector.
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopSteps() {
return ::std::nullopt;
}
/// Return all upper bounds, if they exist. If the op has no notion of
/// lower bounds, then return std::nullopt. If it does have
/// a notion but an instance doesn't have lower bounds, then
/// return empty vector.
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> getLoopUpperBounds() {
return ::std::nullopt;
}
/// Return the mutable "init" operands that are used as initialization
/// values for the region "iter_args" of this loop.
::llvm::MutableArrayRef<::mlir::OpOperand> getInitsMutable() {
return {};
}
/// Return the region "iter_args" (block arguments) that correspond to the
/// "init" operands. If the op has multiple regions, return the
/// corresponding block arguments of the entry region.
::mlir::Block::BlockArgListType getRegionIterArgs() {
return ::mlir::Block::BlockArgListType();
}
/// Return the mutable operand range of values that are yielded to the next
/// iteration by the loop terminator.
///
/// For loop operations that dont yield a value, this should return
/// std::nullopt.
::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> getYieldedValuesMutable() {
return ::std::nullopt;
}
/// Return the range of results that are return from this loop and
/// correspond to the "init" operands.
///
/// Note: This interface method is optional. If loop results are not
/// exposed via this interface, "std::nullopt" should be returned.
/// Otherwise, the number and types of results must match with the
/// region iter_args, inits and yielded values that are exposed via this
/// interface. If loop results are exposed but this loop op has no
/// loop-carried variables, an empty result range (and not "std::nullopt")
/// should be returned.
::std::optional<::mlir::ResultRange> getLoopResults() {
return ::std::nullopt;
}
/// Append the specified additional "init" operands: replace this loop with
/// a new loop that has the additional init operands. The loop body of
/// this loop is moved over to the new loop.
///
/// `newInitOperands` specifies the additional "init" operands.
/// `newYieldValuesFn` is a function that returns the yielded values (which
/// can be computed based on the additional region iter_args). If
/// `replaceInitOperandUsesInLoop` is set, all uses of the additional init
/// operands inside of this loop are replaced with the corresponding, newly
/// added region iter_args.
///
/// Note: Loops that do not support init/iter_args should return "failure".
::mlir::FailureOr<::mlir::LoopLikeOpInterface> replaceWithAdditionalYields(::mlir::RewriterBase & rewriter, ::mlir::ValueRange newInitOperands, bool replaceInitOperandUsesInLoop, const ::mlir::NewYieldValuesFn & newYieldValuesFn) {
return ::mlir::failure();
}
/// Compute the static trip count if possible.
::std::optional<::llvm::APInt> getStaticTripCount() {
return ::std::nullopt;
}
/// Check if the given type is supported as a loop induction variable.
/// By default, only IndexType is supported.
bool isValidInductionVarType(::mlir::Type type) {
return type.isIndex();
}
/// Update the loop lower bounds. Returns failure if the loop doesn't
/// support updating bounds or if the number of bounds doesn't match.
::mlir::LogicalResult setLoopLowerBounds(::llvm::ArrayRef<::mlir::OpFoldResult> bounds) {
return ::mlir::failure();
}
/// Update the loop upper bounds. Returns failure if the loop doesn't
/// support updating bounds or if the number of bounds doesn't match.
::mlir::LogicalResult setLoopUpperBounds(::llvm::ArrayRef<::mlir::OpFoldResult> bounds) {
return ::mlir::failure();
}
/// Update the loop steps. Returns failure if the loop doesn't support
/// updating steps or if the number of steps doesn't match.
::mlir::LogicalResult setLoopSteps(::llvm::ArrayRef<::mlir::OpFoldResult> steps) {
return ::mlir::failure();
}
static ::llvm::LogicalResult verifyRegionTrait(::mlir::Operation *op) {
return ::mlir::detail::verifyLoopLikeOpInterface(op);
}
/// If there is a single induction variable return it, otherwise return
/// std::nullopt.
::std::optional<::mlir::Value> getSingleInductionVar() {
auto inductionVars = (*static_cast<ConcreteOp *>(this)).getLoopInductionVars();
if (inductionVars.has_value() && (*inductionVars).size() == 1)
return (*inductionVars)[0];
return ::std::nullopt;
}
/// Return the single lower bound value or attribute if it exists, otherwise
/// return std::nullopt.
::std::optional<::mlir::OpFoldResult> getSingleLowerBound() {
auto lowerBounds = (*static_cast<ConcreteOp *>(this)).getLoopLowerBounds();
if (lowerBounds.has_value() && (*lowerBounds).size() == 1)
return (*lowerBounds)[0];
return ::std::nullopt;
}
/// Return the single step value or attribute if it exists, otherwise
/// return std::nullopt.
::std::optional<::mlir::OpFoldResult> getSingleStep() {
auto steps = (*static_cast<ConcreteOp *>(this)).getLoopSteps();
if (steps.has_value() && (*steps).size() == 1)
return (*steps)[0];
return ::std::nullopt;
}
/// Return the single upper bound value or attribute if it exists, otherwise
/// return std::nullopt.
::std::optional<::mlir::OpFoldResult> getSingleUpperBound() {
auto upperBounds = (*static_cast<ConcreteOp *>(this)).getLoopUpperBounds();
if (upperBounds.has_value() && (*upperBounds).size() == 1)
return (*upperBounds)[0];
return ::std::nullopt;
}
/// Append the specified additional "init" operands: replace this loop with
/// a new loop that has the additional init operands. The loop body of this
/// loop is moved over to the new loop.
///
/// The newly added region iter_args are yielded from the loop.
::mlir::FailureOr<::mlir::LoopLikeOpInterface>
replaceWithAdditionalIterOperands(::mlir::RewriterBase &rewriter,
::mlir::ValueRange newInitOperands,
bool replaceInitOperandUsesInLoop) {
return (*static_cast<ConcreteOp *>(this)).replaceWithAdditionalYields(
rewriter, newInitOperands, replaceInitOperandUsesInLoop,
[](::mlir::OpBuilder &b, ::mlir::Location loc,
::mlir::ArrayRef<::mlir::BlockArgument> newBBArgs) {
return ::mlir::SmallVector<::mlir::Value>(newBBArgs);
});
}
/// Return the values that are yielded to the next iteration. If
/// the loop doesnt yield any values return `{}`.
::mlir::ValueRange getYieldedValues() {
auto mutableValues = (*static_cast<ConcreteOp *>(this)).getYieldedValuesMutable();
if (!mutableValues || mutableValues->empty())
return {};
::mlir::Operation *yieldOp = mutableValues->begin()->getOwner();
unsigned firstOperandIndex = mutableValues->begin()->getOperandNumber();
return ::mlir::OperandRange(
yieldOp->operand_begin() + firstOperandIndex,
yieldOp->operand_begin() + firstOperandIndex + mutableValues->size());
}
/// Return the "init" operands that are used as initialization values for
/// the region "iter_args" of this loop.
::mlir::OperandRange getInits() {
auto initsMutable = (*static_cast<ConcreteOp *>(this)).getInitsMutable();
if (initsMutable.empty())
return ::mlir::OperandRange((*static_cast<ConcreteOp *>(this))->operand_end(), (*static_cast<ConcreteOp *>(this))->operand_end());
unsigned firstOperandIndex = initsMutable.begin()->getOperandNumber();
return ::mlir::OperandRange(
(*static_cast<ConcreteOp *>(this))->operand_begin() + firstOperandIndex,
(*static_cast<ConcreteOp *>(this))->operand_begin() + firstOperandIndex + initsMutable.size());
}
/// Return the region iter_arg that corresponds to the given init operand.
/// Return an "empty" block argument if the given operand is not an init
/// operand of this loop op.
::mlir::BlockArgument getTiedLoopRegionIterArg(
::mlir::OpOperand *opOperand) {
auto initsMutable = (*static_cast<ConcreteOp *>(this)).getInitsMutable();
auto it = ::llvm::find(initsMutable, *opOperand);
if (it == initsMutable.end())
return {};
return (*static_cast<ConcreteOp *>(this)).getRegionIterArgs()[
::std::distance(initsMutable.begin(), it)];
}
/// Return the region iter_arg that corresponds to the given loop result.
/// Return an "empty" block argument if the given OpResult is not a loop
/// result or if this op does not expose any loop results.
::mlir::BlockArgument getTiedLoopRegionIterArg(::mlir::OpResult opResult) {
auto loopResults = (*static_cast<ConcreteOp *>(this)).getLoopResults();
if (!loopResults)
return {};
auto it = ::llvm::find(*loopResults, opResult);
if (it == loopResults->end())
return {};
return (*static_cast<ConcreteOp *>(this)).getRegionIterArgs()[
::std::distance(loopResults->begin(), it)];
}
/// Return the init operand that corresponds to the given region iter_arg.
/// Return "nullptr" if the given block argument is not a region iter_arg
/// of this loop op.
::mlir::OpOperand *getTiedLoopInit(::mlir::BlockArgument bbArg) {
auto iterArgs = (*static_cast<ConcreteOp *>(this)).getRegionIterArgs();
auto it = ::llvm::find(iterArgs, bbArg);
if (it == iterArgs.end())
return {};
return &(*static_cast<ConcreteOp *>(this)).getInitsMutable()[::std::distance(iterArgs.begin(), it)];
}
/// Return the init operand that corresponds to the given loop result.
/// Return "nullptr" if the given OpResult is not a loop result or if this
/// op does not expose any loop results.
::mlir::OpOperand *getTiedLoopInit(::mlir::OpResult opResult) {
auto loopResults = (*static_cast<ConcreteOp *>(this)).getLoopResults();
if (!loopResults)
return nullptr;
auto it = ::llvm::find(*loopResults, opResult);
if (it == loopResults->end())
return nullptr;
return &(*static_cast<ConcreteOp *>(this)).getInitsMutable()[::std::distance(
loopResults->begin(), it)];
}
/// Return the yielded value that corresponds to the given region iter_arg.
/// Return "nullptr" if the given block argument is not a region iter_arg
/// of this loop op or if there is no yield corresponding to this `bbArg`.
::mlir::OpOperand *getTiedLoopYieldedValue(::mlir::BlockArgument bbArg) {
auto iterArgs = (*static_cast<ConcreteOp *>(this)).getRegionIterArgs();
auto it = ::llvm::find(iterArgs, bbArg);
if (it == iterArgs.end())
return {};
::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> yieldValues =
(*static_cast<ConcreteOp *>(this)).getYieldedValuesMutable();
if (!yieldValues)
return {};
return &yieldValues.value()[::std::distance(iterArgs.begin(), it)];
}
/// Return the loop result that corresponds to the given init operand.
/// Return an "empty" OpResult if the given operand is not an init operand
/// of this loop op or if this op does not expose any loop results.
::mlir::OpResult getTiedLoopResult(::mlir::OpOperand *opOperand) {
auto loopResults = (*static_cast<ConcreteOp *>(this)).getLoopResults();
if (!loopResults)
return {};
auto initsMutable = (*static_cast<ConcreteOp *>(this)).getInitsMutable();
auto it = ::llvm::find(initsMutable, *opOperand);
if (it == initsMutable.end())
return {};
return (*loopResults)[::std::distance(initsMutable.begin(), it)];
}
/// Return the loop result that corresponds to the given region iter_arg.
/// Return an "empty" OpResult if the given block argument is not a region
/// iter_arg of this loop op or if this op does not expose any loop results.
::mlir::OpResult getTiedLoopResult(::mlir::BlockArgument bbArg) {
auto loopResults = (*static_cast<ConcreteOp *>(this)).getLoopResults();
if (!loopResults)
return {};
auto iterArgs = (*static_cast<ConcreteOp *>(this)).getRegionIterArgs();
auto it = ::llvm::find(iterArgs, bbArg);
if (it == iterArgs.end())
return {};
return (*loopResults)[::std::distance(iterArgs.begin(), it)];
}
};
} // namespace mlir::detail
namespace mlir {
template<typename ConcreteOp>
bool detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::isDefinedOutsideOfLoop(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Value value) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).isDefinedOutsideOfLoop(value);
}
template<typename ConcreteOp>
::llvm::SmallVector<::mlir::Region *> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getLoopRegions(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getLoopRegions();
}
template<typename ConcreteOp>
void detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::moveOutOfLoop(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * op) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).moveOutOfLoop(op);
}
template<typename ConcreteOp>
::llvm::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::promoteIfSingleIteration(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase & rewriter) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).promoteIfSingleIteration(rewriter);
}
template<typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::Value>> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getLoopInductionVars(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getLoopInductionVars();
}
template<typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getLoopLowerBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getLoopLowerBounds();
}
template<typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getLoopSteps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getLoopSteps();
}
template<typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getLoopUpperBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getLoopUpperBounds();
}
template<typename ConcreteOp>
::llvm::MutableArrayRef<::mlir::OpOperand> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getInitsMutable(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getInitsMutable();
}
template<typename ConcreteOp>
::mlir::Block::BlockArgListType detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getRegionIterArgs(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getRegionIterArgs();
}
template<typename ConcreteOp>
::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getYieldedValuesMutable(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getYieldedValuesMutable();
}
template<typename ConcreteOp>
::std::optional<::mlir::ResultRange> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getLoopResults(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getLoopResults();
}
template<typename ConcreteOp>
::mlir::FailureOr<::mlir::LoopLikeOpInterface> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::replaceWithAdditionalYields(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase & rewriter, ::mlir::ValueRange newInitOperands, bool replaceInitOperandUsesInLoop, const ::mlir::NewYieldValuesFn & newYieldValuesFn) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).replaceWithAdditionalYields(rewriter, newInitOperands, replaceInitOperandUsesInLoop, newYieldValuesFn);
}
template<typename ConcreteOp>
::std::optional<::llvm::APInt> detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::getStaticTripCount(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getStaticTripCount();
}
template<typename ConcreteOp>
bool detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::isValidInductionVarType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Type type) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).isValidInductionVarType(type);
}
template<typename ConcreteOp>
::mlir::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::setLoopLowerBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).setLoopLowerBounds(bounds);
}
template<typename ConcreteOp>
::mlir::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::setLoopUpperBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).setLoopUpperBounds(bounds);
}
template<typename ConcreteOp>
::mlir::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::Model<ConcreteOp>::setLoopSteps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> steps) {
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).setLoopSteps(steps);
}
template<typename ConcreteOp>
bool detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::isDefinedOutsideOfLoop(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Value value) {
return static_cast<const ConcreteOp *>(impl)->isDefinedOutsideOfLoop(tablegen_opaque_val, value);
}
template<typename ConcreteOp>
::llvm::SmallVector<::mlir::Region *> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getLoopRegions(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getLoopRegions(tablegen_opaque_val);
}
template<typename ConcreteOp>
void detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::moveOutOfLoop(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * op) {
return static_cast<const ConcreteOp *>(impl)->moveOutOfLoop(tablegen_opaque_val, op);
}
template<typename ConcreteOp>
::llvm::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::promoteIfSingleIteration(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase & rewriter) {
return static_cast<const ConcreteOp *>(impl)->promoteIfSingleIteration(tablegen_opaque_val, rewriter);
}
template<typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::Value>> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getLoopInductionVars(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getLoopInductionVars(tablegen_opaque_val);
}
template<typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getLoopLowerBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getLoopLowerBounds(tablegen_opaque_val);
}
template<typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getLoopSteps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getLoopSteps(tablegen_opaque_val);
}
template<typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getLoopUpperBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getLoopUpperBounds(tablegen_opaque_val);
}
template<typename ConcreteOp>
::llvm::MutableArrayRef<::mlir::OpOperand> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getInitsMutable(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getInitsMutable(tablegen_opaque_val);
}
template<typename ConcreteOp>
::mlir::Block::BlockArgListType detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getRegionIterArgs(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getRegionIterArgs(tablegen_opaque_val);
}
template<typename ConcreteOp>
::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getYieldedValuesMutable(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getYieldedValuesMutable(tablegen_opaque_val);
}
template<typename ConcreteOp>
::std::optional<::mlir::ResultRange> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getLoopResults(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getLoopResults(tablegen_opaque_val);
}
template<typename ConcreteOp>
::mlir::FailureOr<::mlir::LoopLikeOpInterface> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::replaceWithAdditionalYields(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase & rewriter, ::mlir::ValueRange newInitOperands, bool replaceInitOperandUsesInLoop, const ::mlir::NewYieldValuesFn & newYieldValuesFn) {
return static_cast<const ConcreteOp *>(impl)->replaceWithAdditionalYields(tablegen_opaque_val, rewriter, newInitOperands, replaceInitOperandUsesInLoop, newYieldValuesFn);
}
template<typename ConcreteOp>
::std::optional<::llvm::APInt> detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getStaticTripCount(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
return static_cast<const ConcreteOp *>(impl)->getStaticTripCount(tablegen_opaque_val);
}
template<typename ConcreteOp>
bool detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::isValidInductionVarType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Type type) {
return static_cast<const ConcreteOp *>(impl)->isValidInductionVarType(tablegen_opaque_val, type);
}
template<typename ConcreteOp>
::mlir::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::setLoopLowerBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds) {
return static_cast<const ConcreteOp *>(impl)->setLoopLowerBounds(tablegen_opaque_val, bounds);
}
template<typename ConcreteOp>
::mlir::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::setLoopUpperBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds) {
return static_cast<const ConcreteOp *>(impl)->setLoopUpperBounds(tablegen_opaque_val, bounds);
}
template<typename ConcreteOp>
::mlir::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::setLoopSteps(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> steps) {
return static_cast<const ConcreteOp *>(impl)->setLoopSteps(tablegen_opaque_val, steps);
}
template<typename ConcreteModel, typename ConcreteOp>
bool detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::isDefinedOutsideOfLoop(::mlir::Operation *tablegen_opaque_val, ::mlir::Value value) const {
return !(llvm::cast<ConcreteOp>(tablegen_opaque_val))->isAncestor(value.getParentRegion()->getParentOp());
}
template<typename ConcreteModel, typename ConcreteOp>
void detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::moveOutOfLoop(::mlir::Operation *tablegen_opaque_val, ::mlir::Operation *op) const {
op->moveBefore((llvm::cast<ConcreteOp>(tablegen_opaque_val)));
}
template<typename ConcreteModel, typename ConcreteOp>
::llvm::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::promoteIfSingleIteration(::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase &rewriter) const {
return ::mlir::failure();
}
template<typename ConcreteModel, typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::Value>> detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getLoopInductionVars(::mlir::Operation *tablegen_opaque_val) const {
return ::std::nullopt;
}
template<typename ConcreteModel, typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getLoopLowerBounds(::mlir::Operation *tablegen_opaque_val) const {
return ::std::nullopt;
}
template<typename ConcreteModel, typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getLoopSteps(::mlir::Operation *tablegen_opaque_val) const {
return ::std::nullopt;
}
template<typename ConcreteModel, typename ConcreteOp>
::std::optional<::llvm::SmallVector<::mlir::OpFoldResult>> detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getLoopUpperBounds(::mlir::Operation *tablegen_opaque_val) const {
return ::std::nullopt;
}
template<typename ConcreteModel, typename ConcreteOp>
::llvm::MutableArrayRef<::mlir::OpOperand> detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getInitsMutable(::mlir::Operation *tablegen_opaque_val) const {
return {};
}
template<typename ConcreteModel, typename ConcreteOp>
::mlir::Block::BlockArgListType detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getRegionIterArgs(::mlir::Operation *tablegen_opaque_val) const {
return ::mlir::Block::BlockArgListType();
}
template<typename ConcreteModel, typename ConcreteOp>
::std::optional<::llvm::MutableArrayRef<::mlir::OpOperand>> detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getYieldedValuesMutable(::mlir::Operation *tablegen_opaque_val) const {
return ::std::nullopt;
}
template<typename ConcreteModel, typename ConcreteOp>
::std::optional<::mlir::ResultRange> detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getLoopResults(::mlir::Operation *tablegen_opaque_val) const {
return ::std::nullopt;
}
template<typename ConcreteModel, typename ConcreteOp>
::mlir::FailureOr<::mlir::LoopLikeOpInterface> detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::replaceWithAdditionalYields(::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase &rewriter, ::mlir::ValueRange newInitOperands, bool replaceInitOperandUsesInLoop, const ::mlir::NewYieldValuesFn &newYieldValuesFn) const {
return ::mlir::failure();
}
template<typename ConcreteModel, typename ConcreteOp>
::std::optional<::llvm::APInt> detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getStaticTripCount(::mlir::Operation *tablegen_opaque_val) const {
return ::std::nullopt;
}
template<typename ConcreteModel, typename ConcreteOp>
bool detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::isValidInductionVarType(::mlir::Operation *tablegen_opaque_val, ::mlir::Type type) const {
return type.isIndex();
}
template<typename ConcreteModel, typename ConcreteOp>
::mlir::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::setLoopLowerBounds(::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds) const {
return ::mlir::failure();
}
template<typename ConcreteModel, typename ConcreteOp>
::mlir::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::setLoopUpperBounds(::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> bounds) const {
return ::mlir::failure();
}
template<typename ConcreteModel, typename ConcreteOp>
::mlir::LogicalResult detail::LoopLikeOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::setLoopSteps(::mlir::Operation *tablegen_opaque_val, ::llvm::ArrayRef<::mlir::OpFoldResult> steps) const {
return ::mlir::failure();
}
} // namespace mlir