15#include "mlir/Transforms/DialectConversion.h"
16#include "llvm/Support/JSON.h"
31 auto numOps =
op.getNumOperands();
33 if (numOps < n || numOps > m) {
34 auto err =
emitError() <<
" has " << numOps <<
" inputs instead of ";
38 err <<
" between " << n <<
" and " << m;
50 return emitError() <<
" missing output bundle";
51 if (b.getType().getNumElements() != n)
52 return emitError() <<
" has " << b.getType().getNumElements()
53 <<
" output elements instead of " << n;
59 if (
op.getParameters())
60 num =
op.getParameters().size();
61 if (num < n || num > n + c) {
62 auto d =
emitError() <<
" has " << num <<
" parameters instead of ";
66 d <<
" between " << n <<
" and " << (n + c);
73 for (
auto a :
op.getParameters()) {
74 auto param = cast<ParamDeclAttr>(a);
75 if (param.getName().getValue() == paramName) {
76 if (isa<StringAttr>(param.getValue()))
79 return emitError() <<
" has parameter '" << param.getName()
80 <<
"' which should be a string but is not";
85 return emitError() <<
" is missing parameter " << paramName;
90 for (
auto a :
op.getParameters()) {
91 auto param = cast<ParamDeclAttr>(a);
92 if (param.getName().getValue() == paramName) {
93 if (isa<IntegerAttr>(param.getValue()))
96 return emitError() <<
" has parameter '" << param.getName()
97 <<
"' which should be an integer but is not";
102 return emitError() <<
" is missing parameter " << paramName;
111class IntrinsicOpConversion final
117 const ConversionMapTy &conversions,
118 size_t &numConversions,
119 bool allowUnknownIntrinsics =
false)
121 numConversions(numConversions),
122 allowUnknownIntrinsics(allowUnknownIntrinsics) {}
125 matchAndRewrite(GenericIntrinsicOp op, OpAdaptor adaptor,
126 ConversionPatternRewriter &rewriter)
const override {
128 auto it = conversions.find(op.getIntrinsicAttr());
129 if (it == conversions.end()) {
130 if (!allowUnknownIntrinsics)
131 return op.emitError(
"unknown intrinsic ") << op.getIntrinsicAttr();
135 auto &conv = *it->second;
136 auto result = conv.checkAndConvert(
GenericIntrinsic(op), adaptor, rewriter);
137 if (succeeded(result))
143 const ConversionMapTy &conversions;
144 size_t &numConversions;
145 const bool allowUnknownIntrinsics;
154 bool allowUnknownIntrinsics) {
158 target.markUnknownOpDynamicallyLegal([](Operation *op) {
return true; });
159 if (allowUnknownIntrinsics)
160 target.addDynamicallyLegalOp<GenericIntrinsicOp>(
161 [
this](GenericIntrinsicOp op) {
162 return !
conversions.contains(op.getIntrinsicAttr());
165 target.addIllegalOp<GenericIntrinsicOp>();
170 typeConverter.addConversion([](Type type) {
return type; });
171 auto firrtlBaseTypeMaterialization =
172 [](OpBuilder &builder,
FIRRTLBaseType resultType, ValueRange inputs,
173 Location loc) -> Value {
174 if (inputs.size() != 1)
184 auto w = WireOp::create(builder, loc, resultType).getResult();
189 typeConverter.addSourceMaterialization(firrtlBaseTypeMaterialization);
191 typeConverter.addTargetMaterialization(firrtlBaseTypeMaterialization);
196 count, allowUnknownIntrinsics);
198 if (failed(mlir::applyPartialConversion(mod, target, std::move(
patterns))))
222 using IntrinsicOpConverter::IntrinsicOpConverter;
231 using IntrinsicOpConverter::IntrinsicOpConverter;
240 using IntrinsicConverter::IntrinsicConverter;
242 bool check(GenericIntrinsic gi)
override {
247 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
248 PatternRewriter &rewriter)
override {
249 rewriter.replaceOpWithNewOp<PlusArgsTestIntrinsicOp>(
256 using IntrinsicConverter::IntrinsicConverter;
258 bool check(GenericIntrinsic gi)
override {
265 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
266 PatternRewriter &rewriter)
override {
268 auto newop = PlusArgsValueIntrinsicOp::create(
269 rewriter, gi.
op.getLoc(), bty.getElementTypePreservingConst(0),
270 bty.getElementTypePreservingConst(1),
272 rewriter.replaceOpWithNewOp<BundleCreateOp>(
273 gi.
op, bty, ValueRange({newop.getFound(), newop.getResult()}));
277class CirctClockGateConverter
280 using IntrinsicOpConverter::IntrinsicOpConverter;
282 bool check(GenericIntrinsic gi)
override {
283 if (gi.
op.getNumOperands() == 3) {
288 if (gi.
op.getNumOperands() == 2) {
292 gi.
emitError() <<
" has " << gi.
op.getNumOperands()
293 <<
" ports instead of 3 or 4";
298class CirctClockInverterConverter
301 using IntrinsicOpConverter::IntrinsicOpConverter;
303 bool check(GenericIntrinsic gi)
override {
311 using IntrinsicConverter::IntrinsicConverter;
313 bool check(GenericIntrinsic gi)
override {
319 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
320 PatternRewriter &rewriter)
override {
322 gi.
getParamValue<IntegerAttr>(
"POW_2").getValue().getZExtValue();
324 auto pow2Attr = rewriter.getI64IntegerAttr(pow2);
326 rewriter.replaceOpWithNewOp<ClockDividerIntrinsicOp>(
327 gi.
op, adaptor.getOperands()[0], pow2Attr);
331template <
typename OpTy>
334 using IntrinsicOpConverter<OpTy>::IntrinsicOpConverter;
336 bool check(GenericIntrinsic gi)
override {
343template <
typename OpTy>
346 using IntrinsicOpConverter<OpTy>::IntrinsicOpConverter;
348 bool check(GenericIntrinsic gi)
override {
357 using IntrinsicConverter::IntrinsicConverter;
359 bool check(GenericIntrinsic gi)
override {
365 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
366 PatternRewriter &rewriter)
override {
367 auto operands = adaptor.getOperands();
368 rewriter.replaceOpWithNewOp<LTLAcceptOnIntrinsicOp>(
369 gi.
op, gi.
op.getResultTypes(), operands[0], operands[1],
370 Sync ? rewriter.getUnitAttr() : UnitAttr());
376 using IntrinsicConverter::IntrinsicConverter;
378 bool check(GenericIntrinsic gi)
override {
384 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
385 PatternRewriter &rewriter)
override {
386 auto getI64Attr = [&](IntegerAttr val) {
388 return IntegerAttr();
389 return rewriter.getI64IntegerAttr(val.getValue().getZExtValue());
391 auto delay = getI64Attr(gi.
getParamValue<IntegerAttr>(
"delay"));
392 auto length = getI64Attr(gi.
getParamValue<IntegerAttr>(
"length"));
393 rewriter.replaceOpWithNewOp<LTLDelayIntrinsicOp>(
394 gi.
op, gi.
op.getResultTypes(), adaptor.getOperands()[0], delay, length);
400 using IntrinsicConverter::IntrinsicConverter;
402 bool check(GenericIntrinsic gi)
override {
412 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
413 PatternRewriter &rewriter)
override {
414 auto delay = rewriter.getI64IntegerAttr(
415 gi.
getParamValue<IntegerAttr>(
"delay").getValue().getZExtValue());
416 auto operands = adaptor.getOperands();
417 Value clock = operands[1];
418 rewriter.replaceOpWithNewOp<LTLPastIntrinsicOp>(
419 gi.
op, gi.
op.getResultTypes(), operands[0], delay, clock);
425 using IntrinsicConverter::IntrinsicConverter;
427 bool check(GenericIntrinsic gi)
override {
433 auto params = gi.
op.getParameters();
434 if (!params || params.empty())
437 auto param = cast<ParamDeclAttr>(*params.begin());
438 if (param.getName().getValue() !=
"edge") {
439 gi.
emitError() <<
" has unexpected parameter '" << param.getName()
440 <<
"', expected 'edge'";
443 if (!isa<StringAttr>(param.getValue())) {
444 gi.
emitError() <<
" has parameter '" << param.getName()
445 <<
"' which should be a string but is not";
451 LogicalResult checkAndConvert(GenericIntrinsic gi,
452 GenericIntrinsicOpAdaptor adaptor,
453 PatternRewriter &rewriter)
override {
457 auto edge = EventControl::AtPosEdge;
459 auto parsedEdge = symbolizeEventControl(edgeAttr.getValue());
462 <<
" has invalid edge parameter '" << edgeAttr.getValue()
463 <<
"', expected one of [posedge, negedge, edge]";
467 auto operands = adaptor.getOperands();
468 rewriter.replaceOpWithNewOp<LTLClockIntrinsicOp>(
469 gi.
op, gi.
op.getResultTypes(), operands[0],
470 EventControlAttr::get(rewriter.getContext(), edge), operands[1]);
477 using IntrinsicConverter::IntrinsicConverter;
479 bool check(GenericIntrinsic gi)
override {
485 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
486 PatternRewriter &rewriter)
override {
487 auto getI64Attr = [&](IntegerAttr val) {
489 return IntegerAttr();
490 return rewriter.getI64IntegerAttr(val.getValue().getZExtValue());
492 auto base = getI64Attr(gi.
getParamValue<IntegerAttr>(
"base"));
493 auto more = getI64Attr(gi.
getParamValue<IntegerAttr>(
"more"));
494 rewriter.replaceOpWithNewOp<LTLRepeatIntrinsicOp>(
495 gi.
op, gi.
op.getResultTypes(), adaptor.getOperands()[0], base, more);
501 using IntrinsicConverter::IntrinsicConverter;
503 bool check(GenericIntrinsic gi)
override {
509 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
510 PatternRewriter &rewriter)
override {
511 auto getI64Attr = [&](IntegerAttr val) {
513 return IntegerAttr();
514 return rewriter.getI64IntegerAttr(val.getValue().getZExtValue());
516 auto base = getI64Attr(gi.
getParamValue<IntegerAttr>(
"base"));
517 auto more = getI64Attr(gi.
getParamValue<IntegerAttr>(
"more"));
518 rewriter.replaceOpWithNewOp<LTLGoToRepeatIntrinsicOp>(
519 gi.
op, gi.
op.getResultTypes(), adaptor.getOperands()[0], base, more);
525 using IntrinsicConverter::IntrinsicConverter;
527 bool check(GenericIntrinsic gi)
override {
533 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
534 PatternRewriter &rewriter)
override {
535 auto getI64Attr = [&](IntegerAttr val) {
537 return IntegerAttr();
538 return rewriter.getI64IntegerAttr(val.getValue().getZExtValue());
540 auto base = getI64Attr(gi.
getParamValue<IntegerAttr>(
"base"));
541 auto more = getI64Attr(gi.
getParamValue<IntegerAttr>(
"more"));
542 rewriter.replaceOpWithNewOp<LTLNonConsecutiveRepeatIntrinsicOp>(
543 gi.
op, gi.
op.getResultTypes(), adaptor.getOperands()[0], base, more);
550 using IntrinsicConverter::IntrinsicConverter;
552 bool check(GenericIntrinsic gi)
override {
558 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
559 PatternRewriter &rewriter)
override {
561 auto operands = adaptor.getOperands();
566 enable = operands[1];
568 rewriter.replaceOpWithNewOp<Op>(gi.
op, operands[0], enable, label);
573 using IntrinsicConverter::IntrinsicConverter;
575 bool check(GenericIntrinsic gi)
override {
580 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
581 PatternRewriter &rewriter)
override {
582 auto operands = adaptor.getOperands();
583 rewriter.replaceOpWithNewOp<Mux2CellIntrinsicOp>(gi.
op, operands[0],
584 operands[1], operands[2]);
589 using IntrinsicConverter::IntrinsicConverter;
591 bool check(GenericIntrinsic gi)
override {
596 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
597 PatternRewriter &rewriter)
override {
598 auto operands = adaptor.getOperands();
599 rewriter.replaceOpWithNewOp<Mux4CellIntrinsicOp>(
600 gi.
op, operands[0], operands[1], operands[2], operands[3], operands[4]);
604class CirctHasBeenResetConverter
607 using IntrinsicOpConverter::IntrinsicOpConverter;
609 bool check(GenericIntrinsic gi)
override {
618 using IntrinsicOpConverter::IntrinsicOpConverter;
620 bool check(GenericIntrinsic gi)
override {
626template <
class OpTy,
bool ifElseFatal = false>
629 using IntrinsicConverter::IntrinsicConverter;
631 LogicalResult checkAndConvert(GenericIntrinsic gi,
632 GenericIntrinsicOpAdaptor adaptor,
633 PatternRewriter &rewriter)
override {
647 auto clock = adaptor.getOperands()[0];
648 auto predicate = adaptor.getOperands()[1];
649 auto enable = adaptor.getOperands()[2];
651 auto substitutions = adaptor.getOperands().drop_front(3);
652 auto name = label ? label.strref() :
"";
657 SmallVector<Value> allOperands;
659 SmallVector<Value> substitutionVec(substitutions.begin(),
660 substitutions.end());
662 substitutionVec, message, allOperands)))
666 message = rewriter.getStringAttr(
"");
667 allOperands.append(substitutions.begin(), substitutions.end());
670 auto op = rewriter.template replaceOpWithNewOp<OpTy>(
671 gi.
op, clock, predicate, enable, message, allOperands, name,
674 SmallVector<StringRef> guardStrings;
675 guards.strref().split(guardStrings,
';', -1,
677 rewriter.startOpModification(op);
678 op->setAttr(
"guards", rewriter.getStrArrayAttr(guardStrings));
679 rewriter.finalizeOpModification(op);
682 if constexpr (ifElseFatal) {
683 rewriter.startOpModification(op);
684 op->setAttr(
"format", rewriter.getStringAttr(
"ifElseFatal"));
685 rewriter.finalizeOpModification(op);
694 using IntrinsicConverter::IntrinsicConverter;
696 bool check(GenericIntrinsic gi)
override {
704 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
705 PatternRewriter &rewriter)
override {
709 auto clock = adaptor.getOperands()[0];
710 auto predicate = adaptor.getOperands()[1];
711 auto enable = adaptor.getOperands()[2];
713 auto name = label ? label.strref() :
"";
715 auto message = rewriter.getStringAttr(
"");
716 auto op = rewriter.replaceOpWithNewOp<CoverOp>(
717 gi.
op, clock, predicate, enable, message, ValueRange{}, name,
720 SmallVector<StringRef> guardStrings;
721 guards.strref().split(guardStrings,
';', -1,
723 rewriter.startOpModification(op);
724 op->setAttr(
"guards", rewriter.getStrArrayAttr(guardStrings));
725 rewriter.finalizeOpModification(op);
732 using IntrinsicConverter::IntrinsicConverter;
734 bool check(GenericIntrinsic gi)
override {
742 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
743 PatternRewriter &rewriter)
override {
748 auto predicate = adaptor.getOperands()[0];
749 auto enable = adaptor.getOperands()[1];
751 auto substitutions = adaptor.getOperands().drop_front(2);
752 auto name = label ? label.strref() :
"";
754 auto message = format ? format : rewriter.getStringAttr(
"");
755 auto op = rewriter.template replaceOpWithNewOp<UnclockedAssumeIntrinsicOp>(
756 gi.
op, predicate, enable, message, substitutions, name);
758 SmallVector<StringRef> guardStrings;
759 guards.strref().split(guardStrings,
';', -1,
761 rewriter.startOpModification(op);
762 op->setAttr(
"guards", rewriter.getStrArrayAttr(guardStrings));
763 rewriter.finalizeOpModification(op);
769 static bool getIsClocked(GenericIntrinsic gi) {
770 return !gi.
getParamValue<IntegerAttr>(
"isClocked").getValue().isZero();
774 using IntrinsicConverter::IntrinsicConverter;
776 bool check(GenericIntrinsic gi)
override {
782 auto isClocked = getIsClocked(gi);
793 void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
794 PatternRewriter &rewriter)
override {
795 auto isClocked = getIsClocked(gi);
796 auto functionName = gi.
getParamValue<StringAttr>(
"functionName");
797 ArrayAttr inputNamesStrArray;
798 StringAttr outputStr = gi.
getParamValue<StringAttr>(
"outputName");
799 if (
auto inputNames = gi.
getParamValue<StringAttr>(
"inputNames")) {
800 SmallVector<StringRef> inputNamesTemporary;
801 inputNames.strref().split(inputNamesTemporary,
';', -1,
803 inputNamesStrArray = rewriter.getStrArrayAttr(inputNamesTemporary);
806 Value clock = isClocked ? adaptor.getOperands()[0] : Value();
807 Value enable = adaptor.getOperands()[
static_cast<size_t>(isClocked)];
810 adaptor.getOperands().drop_front(
static_cast<size_t>(isClocked) + 1);
812 rewriter.replaceOpWithNewOp<DPICallIntrinsicOp>(
813 gi.
op, gi.
op.getResultTypes(), functionName, inputNamesStrArray,
814 outputStr, clock, enable, inputs);
823A
tryGetAs(DictionaryAttr dict, Attribute root, StringRef key, Location loc,
824 Twine path = Twine()) {
826 "'info' attribute", path);
831std::optional<DictionaryAttr>
833 DictionaryAttr augmentedType, DictionaryAttr root,
834 StringAttr name, StringAttr defName,
835 std::optional<StringAttr> description, Twine path = {}) {
840 StringRef classBase = classAttr.getValue();
841 if (!classBase.consume_front(
"sifive.enterprise.grandcentral.Augmented")) {
843 "the 'class' was expected to start with "
844 "'sifive.enterprise.grandCentral.Augmented*', but was '" +
845 classAttr.getValue() +
"' (Did you misspell it?)")
847 <<
"see attribute: " << augmentedType;
854 if (classBase ==
"BundleType") {
863 SmallVector<Attribute> elements;
868 for (
size_t i = 0, e = elementsAttr.size(); i != e; ++i) {
869 auto field = dyn_cast_or_null<DictionaryAttr>(elementsAttr[i]);
873 "View 'info' attribute with path '.elements[" + Twine(i) +
874 "]' contained an unexpected type (expected a DictionaryAttr).")
876 <<
"The received element was: " << elementsAttr[i];
879 auto ePath = (path +
".elements[" + Twine(i) +
"]").str();
886 std::optional<StringAttr> description;
887 if (
auto maybeDescription = field.get(
"description"))
888 description = cast<StringAttr>(maybeDescription);
891 description, path +
"_" + name.getValue());
898 if (
auto maybeDescription = field.get(
"description"))
899 attrs.append(
"description", cast<StringAttr>(maybeDescription));
900 attrs.append(
"name", name);
901 auto tpeClass = tpe.getAs<StringAttr>(
"class");
903 mlir::emitError(loc,
"missing 'class' key in") << tpe;
906 attrs.append(
"tpe", tpeClass);
907 elements.push_back(*eltAttr);
913 attrs.append(
"class", classAttr);
914 attrs.append(
"defName", defName);
916 attrs.append(
"description", *description);
917 attrs.append(
"elements", ArrayAttr::get(
context, elements));
918 attrs.append(
"name", name);
923 if (classBase ==
"GroundType") {
924 NamedAttrList elementIface;
927 elementIface.append(
"class", classAttr);
929 elementIface.append(
"description", *description);
930 elementIface.append(
"name", name);
932 return DictionaryAttr::getWithSorted(
context, elementIface);
937 if (classBase ==
"VectorType") {
942 SmallVector<Attribute> elements;
943 for (
auto [i, elt] : llvm::enumerate(elementsAttr)) {
945 context, loc, cast<DictionaryAttr>(elt), root, name,
946 StringAttr::get(
context,
""), std::nullopt, path +
"_" + Twine(i));
949 elements.push_back(*eltAttr);
952 attrs.append(
"class", classAttr);
954 attrs.append(
"description", *description);
955 attrs.append(
"elements", ArrayAttr::get(
context, elements));
956 attrs.append(
"name", name);
962 mlir::emitError(loc,
"found unknown AugmentedType '" + classAttr.getValue() +
963 "' (Did you misspell it?)")
965 <<
"see attribute: " << augmentedType;
971 LogicalResult checkAndConvert(GenericIntrinsic gi,
972 GenericIntrinsicOpAdaptor adaptor,
973 PatternRewriter &rewriter)
override {
982 auto base = type_dyn_cast<FIRRTLBaseType>(ty);
983 return base && base.isGround();
989 llvm::json::parse(gi.
getParamValue<StringAttr>(
"info").getValue());
990 if (
auto err = view.takeError()) {
991 handleAllErrors(std::move(err), [&](
const llvm::json::ParseError &a) {
992 gi.
emitError() <<
": error parsing view JSON: " << a.message();
998 llvm::json::Path::Root root;
1000 assert(value &&
"JSON to attribute failed but should not ever fail");
1004 auto dict = dyn_cast<DictionaryAttr>(value);
1006 return gi.
emitError() <<
": 'info' parameter must be a dictionary";
1010 gi.
op.getContext(), gi.
op.getLoc(), dict, dict, nameAttr,
1017 auto augmentedType =
1018 AugmentedBundleTypeAttr::get(gi.
op.getContext(), *result);
1019 if (augmentedType.getClass() != augmentedBundleTypeAnnoClass)
1020 return gi.
emitError() <<
": 'info' must be augmented bundle";
1023 SmallVector<DictionaryAttr> worklist;
1024 worklist.push_back(augmentedType.getUnderlying());
1025 size_t numLeaves = 0;
1026 auto augGroundAttr =
1027 StringAttr::get(gi.
op.getContext(), augmentedGroundTypeAnnoClass);
1028 [[maybe_unused]]
auto augBundleAttr =
1029 StringAttr::get(gi.
op.getContext(), augmentedBundleTypeAnnoClass);
1030 [[maybe_unused]]
auto augVectorAttr =
1031 StringAttr::get(gi.
op.getContext(), augmentedVectorTypeAnnoClass);
1032 while (!worklist.empty()) {
1033 auto dict = worklist.pop_back_val();
1034 auto clazz = dict.getAs<StringAttr>(
"class");
1035 if (clazz == augGroundAttr) {
1039 assert(clazz == augBundleAttr || clazz == augVectorAttr);
1042 dict.getAs<ArrayAttr>(
"elements").getAsRange<DictionaryAttr>());
1047 <<
" has " << gi.
getNumInputs() <<
" operands but view 'info' has "
1048 << numLeaves <<
" leaf elements";
1052 rewriter.replaceOpWithNewOp<ViewIntrinsicOp>(
1053 gi.
op, nameAttr.getValue(), yaml, augmentedType, adaptor.getOperands());
1064#include "FIRRTLIntrinsics.cpp.inc"
1068 populateLowerings(lowering);
assert(baseType &&"element must be base type")
static std::unique_ptr< Context > context
static std::optional< DictionaryAttr > parseAugmentedType(ApplyState &state, DictionaryAttr augmentedType, DictionaryAttr root, StringAttr name, StringAttr defName, std::optional< IntegerAttr > id, std::optional< StringAttr > description, Twine clazz, StringAttr companionAttr, Twine path={})
Recursively walk a sifive.enterprise.grandcentral.AugmentedType to extract any annotations it may con...
static LogicalResult convert(arc::ExecuteOp op, arc::ExecuteOp::Adaptor adaptor, ConversionPatternRewriter &rewriter, const TypeConverter &converter)
false return failure()
Parse an optional keyword or string and set instance into 'result'.
Base class for Intrinsic Converters.
Lowering helper which collects all intrinsic converters.
FailureOr< size_t > lower(FModuleOp mod, bool allowUnknownIntrinsics=false)
Lowers all intrinsics in a module. Returns number converted or failure.
llvm::DenseMap< StringAttr, std::unique_ptr< IntrinsicConverter > > ConversionMapTy
MLIRContext * context
Reference to the MLIR context.
ConversionMapTy conversions
Mapping from intrinsic names to converters.
A tryGetAs(DictionaryAttr dict, Attribute root, StringRef key, Location loc, Twine clazz, Twine path=Twine())
Implements the same behavior as DictionaryAttr::getAs to return the value of a specific type associat...
bool areTypesEquivalent(FIRRTLType destType, FIRRTLType srcType, bool destOuterTypeIsConst=false, bool srcOuterTypeIsConst=false, bool requireSameWidths=false)
Returns whether the two types are equivalent.
bool isTypeLarger(FIRRTLBaseType dstType, FIRRTLBaseType srcType)
Returns true if the destination is at least as wide as a source.
void emitConnect(OpBuilder &builder, Location loc, Value lhs, Value rhs, bool warnOnTruncation=false)
Emit a connect between two values.
mlir::ParseResult parseFormatString(mlir::OpBuilder &builder, mlir::Location loc, llvm::StringRef formatString, llvm::ArrayRef< mlir::Value > specOperands, mlir::StringAttr &formatStringResult, llvm::SmallVectorImpl< mlir::Value > &operands)
BaseTy type_dyn_cast(Type type)
A tryGetAsBase(DictionaryAttr dict, Attribute root, StringRef key, Location loc, Twine whatSpecific, Twine whatFull, Twine path=Twine())
Implements the same behavior as DictionaryAttr::getAs to return the value of a specific type associat...
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Attribute convertJSONToAttribute(MLIRContext *context, llvm::json::Value &value, llvm::json::Path p)
Convert arbitrary JSON to an MLIR Attribute.
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)
ParseResult typedInput(unsigned n)
ParseResult hasNOutputElements(unsigned n)
InFlightDiagnostic emitError()
ParseResult namedIntParam(StringRef paramName, bool optional=false)
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, unsigned c=0)
ParseResult hasNoOutput()
A dialect interface to provide lowering conversions.
virtual void populateIntrinsicLowerings(IntrinsicLowerings &lowerings) const =0
void populateIntrinsicLowerings(IntrinsicLowerings &lowerings) const