13 #ifndef CIRCT_DIALECT_FIRRTL_FIRRTLINTRINSICS_H
14 #define CIRCT_DIALECT_FIRRTL_FIRRTLINTRINSICS_H
18 #include "mlir/IR/Diagnostics.h"
19 #include "mlir/Transforms/DialectConversion.h"
27 GenericIntrinsicOp
op;
31 InFlightDiagnostic
emitError() {
return op.emitError(
op.getIntrinsic()); }
41 if (n >=
op.getNumOperands())
42 return emitError() <<
" missing input " << n;
43 if (!std::invoke(std::forward<C>(call),
op.getOperand(n).getType()))
44 return emitError() <<
" input " << n <<
" " << msg;
50 return checkInputType(n,
"not of correct type", std::forward<C>(call));
60 auto baseType = dyn_cast<FIRRTLBaseType>(ty);
61 return baseType && baseType.isResetType();
67 return checkInputType(n,
"not size " + Twine(size), [size](
auto ty) {
68 auto t = dyn_cast<T>(ty);
69 return t && t.getWidth() == size;
77 ParseResult
hasNParam(
unsigned n,
unsigned c = 0);
79 ParseResult
namedParam(StringRef paramName,
bool optional =
false);
81 ParseResult
namedIntParam(StringRef paramName,
bool optional =
false);
84 for (
auto param :
op.getParameters().getAsRange<ParamDeclAttr>())
85 if (param.getName().getValue().equals(name))
96 return cast<T>(p.getValue());
104 if (
op.getNumResults() == 0)
109 if (
op.getNumResults() != 0)
110 return emitError() <<
" should not have outputs";
114 template <
typename T>
118 if (!isa<T>(
op.getResult().getType()))
119 return emitError() <<
" output not of correct type";
123 template <
typename T>
125 if (failed(typedOutput<T>()))
127 if (cast<T>(
op.getResult().getType()).getWidth() != size)
128 return emitError() <<
" output not size " << size;
137 return dyn_cast_or_null<mlir::TypedValue<BundleType>>(
op.getResult());
142 template <
typename C>
147 return emitError() <<
" missing output bundle";
148 auto ty = b.getType();
149 if (n >= ty.getNumElements())
150 return emitError() <<
" missing output element " << n;
151 auto elementName = ty.getElementName(n);
152 if (elementName != name)
153 return emitError() <<
" output element " << n <<
" is named "
154 << elementName <<
" not " << name;
155 if (!std::invoke(std::forward<C>(call),
156 ty.getElementTypePreservingConst(n)))
157 return emitError() <<
" output element " << n <<
" " << msg;
161 template <
typename C>
164 std::forward<C>(call));
171 template <
typename T>
176 template <
typename T>
180 auto t = dyn_cast<T>(ty);
181 return t && t.getWidth() == size;
201 PatternRewriter &rewriter) = 0;
204 template <
typename OpTy>
210 PatternRewriter &rewriter)
final {
212 rewriter.replaceOpWithNewOp<OpTy>(gi.op, gi.op.getResultTypes(),
213 adaptor.getOperands());
221 llvm::DenseMap<StringAttr, std::unique_ptr<IntrinsicConverter>>;
234 template <
typename T,
typename... Args>
236 (addConverter<T>(args), ...);
240 LogicalResult
lower(FModuleOp mod,
bool allowUnknownIntrinsics =
false);
243 template <
typename T>
244 typename std::enable_if_t<std::is_base_of_v<IntrinsicConverter, T>>
248 "duplicate conversion for intrinsic");
249 conversions.try_emplace(nameAttr, std::make_unique<T>());
263 :
public mlir::DialectInterfaceCollection<
264 IntrinsicLoweringDialectInterface> {
assert(baseType &&"element must be base type")
Base class for Intrinsic Converters.
virtual ~IntrinsicConverter()=default
virtual void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor, PatternRewriter &rewriter)=0
Transform the intrinsic to its implementation.
virtual bool check(GenericIntrinsic gi)=0
Checks whether the intrinsic is well-formed.
Lowering helper which collects all intrinsic converters.
IntrinsicLowerings(MLIRContext *context)
llvm::DenseMap< StringAttr, std::unique_ptr< IntrinsicConverter > > ConversionMapTy
std::enable_if_t< std::is_base_of_v< IntrinsicConverter, T > > addConverter(StringRef name)
LogicalResult lower(FModuleOp mod, bool allowUnknownIntrinsics=false)
Lowers all intrinsics in a module.
void add(Args... args)
Registers a converter to one or more intrinsic names.
MLIRContext * context
Reference to the MLIR context.
ConversionMapTy conversions
Mapping from intrinsic names to converters.
void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor, PatternRewriter &rewriter) final
Transform the intrinsic to its implementation.
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
void populateIntrinsicLowerings(IntrinsicLowerings &lowerings) const override
Helper class for checking and extracting information from the generic instrinsic op.
ParseResult sizedInput(unsigned n, int32_t size)
mlir::TypedValue< BundleType > getOutputBundle()
T getParamValue(StringRef name)
Get parameter value by name, if present, as requested type.
ParseResult typedOutput()
ParseResult hasResetInput(unsigned n)
ParseResult checkInputType(unsigned n, const Twine &msg, C &&call)
GenericIntrinsic(GenericIntrinsicOp op)
ParseResult typedInput(unsigned n)
ParseResult hasNOutputElements(unsigned n)
InFlightDiagnostic emitError()
ParseResult checkOutputElement(unsigned n, StringRef name, C &&call)
ParseResult namedIntParam(StringRef paramName, bool optional=false)
ParamDeclAttr getParamByName(StringRef name)
ParseResult checkOutputElement(unsigned n, StringRef name, const Twine &msg, C &&call)
ParseResult namedParam(StringRef paramName, bool optional=false)
ParseResult sizedOutput(int32_t size)
ParseResult sizedOutputElement(unsigned n, StringRef name, int32_t size)
ParseResult hasNParam(unsigned n, unsigned c=0)
ParseResult hasOutputElement(unsigned n, StringRef name)
ParseResult hasNInputs(unsigned n)
ParseResult typedOutputElement(unsigned n, StringRef name)
ParseResult hasNoOutput()
ParseResult checkInputType(unsigned n, C &&call)
A dialect interface to provide lowering conversions.
IntrinsicLoweringDialectInterface(Dialect *dialect)
virtual void populateIntrinsicLowerings(IntrinsicLowerings &lowerings) const =0
void populateIntrinsicLowerings(IntrinsicLowerings &lowerings) const