15#include "mlir/Transforms/DialectConversion.h"
16#include "llvm/Support/JSON.h"
19using namespace firrtl;
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
116 IntrinsicOpConversion(TypeConverter &typeConverter, MLIRContext *context,
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) {
156 ConversionTarget target(*
context);
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>();
169 TypeConverter typeConverter;
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)
176 auto inputType = type_dyn_cast<FIRRTLBaseType>(inputs.front().getType());
184 auto w = builder.create<WireOp>(loc, resultType).getResult();
189 typeConverter.addSourceMaterialization(firrtlBaseTypeMaterialization);
191 typeConverter.addTargetMaterialization(firrtlBaseTypeMaterialization);
196 count, allowUnknownIntrinsics);
198 if (failed(mlir::applyPartialConversion(mod, target, std::move(
patterns))))
211 interface.populateIntrinsicLowerings(lowering);
222 using IntrinsicOpConverter::IntrinsicOpConverter;
231 using IntrinsicOpConverter::IntrinsicOpConverter;
240 using IntrinsicConverter::IntrinsicConverter;
248 PatternRewriter &rewriter)
override {
249 rewriter.replaceOpWithNewOp<PlusArgsTestIntrinsicOp>(
256 using IntrinsicConverter::IntrinsicConverter;
266 PatternRewriter &rewriter)
override {
268 auto newop = rewriter.create<PlusArgsValueIntrinsicOp>(
269 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;
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;
311 using IntrinsicConverter::IntrinsicConverter;
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>
343template <
typename OpTy>
356 using IntrinsicConverter::IntrinsicConverter;
365 PatternRewriter &rewriter)
override {
366 auto getI64Attr = [&](IntegerAttr val) {
368 return IntegerAttr();
369 return rewriter.getI64IntegerAttr(val.getValue().getZExtValue());
371 auto delay = getI64Attr(gi.
getParamValue<IntegerAttr>(
"delay"));
372 auto length = getI64Attr(gi.
getParamValue<IntegerAttr>(
"length"));
373 rewriter.replaceOpWithNewOp<LTLDelayIntrinsicOp>(
374 gi.
op, gi.
op.getResultTypes(), adaptor.getOperands()[0], delay, length);
378class CirctLTLClockConverter
381 using IntrinsicOpConverter::IntrinsicOpConverter;
392 using IntrinsicConverter::IntrinsicConverter;
401 PatternRewriter &rewriter)
override {
402 auto getI64Attr = [&](IntegerAttr val) {
404 return IntegerAttr();
405 return rewriter.getI64IntegerAttr(val.getValue().getZExtValue());
407 auto base = getI64Attr(gi.
getParamValue<IntegerAttr>(
"base"));
408 auto more = getI64Attr(gi.
getParamValue<IntegerAttr>(
"more"));
409 rewriter.replaceOpWithNewOp<LTLRepeatIntrinsicOp>(
410 gi.
op, gi.
op.getResultTypes(), adaptor.getOperands()[0], base, more);
416 using IntrinsicConverter::IntrinsicConverter;
425 PatternRewriter &rewriter)
override {
426 auto getI64Attr = [&](IntegerAttr val) {
428 return IntegerAttr();
429 return rewriter.getI64IntegerAttr(val.getValue().getZExtValue());
431 auto base = getI64Attr(gi.
getParamValue<IntegerAttr>(
"base"));
432 auto more = getI64Attr(gi.
getParamValue<IntegerAttr>(
"more"));
433 rewriter.replaceOpWithNewOp<LTLGoToRepeatIntrinsicOp>(
434 gi.
op, gi.
op.getResultTypes(), adaptor.getOperands()[0], base, more);
440 using IntrinsicConverter::IntrinsicConverter;
449 PatternRewriter &rewriter)
override {
450 auto getI64Attr = [&](IntegerAttr val) {
452 return IntegerAttr();
453 return rewriter.getI64IntegerAttr(val.getValue().getZExtValue());
455 auto base = getI64Attr(gi.
getParamValue<IntegerAttr>(
"base"));
456 auto more = getI64Attr(gi.
getParamValue<IntegerAttr>(
"more"));
457 rewriter.replaceOpWithNewOp<LTLNonConsecutiveRepeatIntrinsicOp>(
458 gi.
op, gi.
op.getResultTypes(), adaptor.getOperands()[0], base, more);
465 using IntrinsicConverter::IntrinsicConverter;
474 PatternRewriter &rewriter)
override {
476 auto operands = adaptor.getOperands();
481 enable = operands[1];
483 rewriter.replaceOpWithNewOp<Op>(gi.
op, operands[0], enable, label);
488 using IntrinsicConverter::IntrinsicConverter;
496 PatternRewriter &rewriter)
override {
497 auto operands = adaptor.getOperands();
498 rewriter.replaceOpWithNewOp<Mux2CellIntrinsicOp>(gi.
op, operands[0],
499 operands[1], operands[2]);
504 using IntrinsicConverter::IntrinsicConverter;
512 PatternRewriter &rewriter)
override {
513 auto operands = adaptor.getOperands();
514 rewriter.replaceOpWithNewOp<Mux4CellIntrinsicOp>(
515 gi.
op, operands[0], operands[1], operands[2], operands[3], operands[4]);
519class CirctHasBeenResetConverter
522 using IntrinsicOpConverter::IntrinsicOpConverter;
533 using IntrinsicOpConverter::IntrinsicOpConverter;
541template <
class OpTy,
bool ifElseFatal = false>
544 using IntrinsicConverter::IntrinsicConverter;
556 PatternRewriter &rewriter)
override {
561 auto clock = adaptor.getOperands()[0];
562 auto predicate = adaptor.getOperands()[1];
563 auto enable = adaptor.getOperands()[2];
565 auto substitutions = adaptor.getOperands().drop_front(3);
566 auto name = label ? label.strref() :
"";
568 auto message = format ? format : rewriter.getStringAttr(
"");
569 auto op = rewriter.template replaceOpWithNewOp<OpTy>(
570 gi.
op, clock, predicate, enable, message, substitutions, name,
573 SmallVector<StringRef> guardStrings;
574 guards.strref().split(guardStrings,
';', -1,
576 rewriter.startOpModification(op);
577 op->setAttr(
"guards", rewriter.getStrArrayAttr(guardStrings));
578 rewriter.finalizeOpModification(op);
581 if constexpr (ifElseFatal) {
582 rewriter.startOpModification(op);
583 op->setAttr(
"format", rewriter.getStringAttr(
"ifElseFatal"));
584 rewriter.finalizeOpModification(op);
591 using IntrinsicConverter::IntrinsicConverter;
602 PatternRewriter &rewriter)
override {
606 auto clock = adaptor.getOperands()[0];
607 auto predicate = adaptor.getOperands()[1];
608 auto enable = adaptor.getOperands()[2];
610 auto name = label ? label.strref() :
"";
612 auto message = rewriter.getStringAttr(
"");
613 auto op = rewriter.replaceOpWithNewOp<CoverOp>(
614 gi.
op, clock, predicate, enable, message, ValueRange{}, name,
617 SmallVector<StringRef> guardStrings;
618 guards.strref().split(guardStrings,
';', -1,
620 rewriter.startOpModification(op);
621 op->setAttr(
"guards", rewriter.getStrArrayAttr(guardStrings));
622 rewriter.finalizeOpModification(op);
629 using IntrinsicConverter::IntrinsicConverter;
640 PatternRewriter &rewriter)
override {
645 auto predicate = adaptor.getOperands()[0];
646 auto enable = adaptor.getOperands()[1];
648 auto substitutions = adaptor.getOperands().drop_front(2);
649 auto name = label ? label.strref() :
"";
651 auto message = format ? format : rewriter.getStringAttr(
"");
652 auto op = rewriter.template replaceOpWithNewOp<UnclockedAssumeIntrinsicOp>(
653 gi.
op, predicate, enable, message, substitutions, name);
655 SmallVector<StringRef> guardStrings;
656 guards.strref().split(guardStrings,
';', -1,
658 rewriter.startOpModification(op);
659 op->setAttr(
"guards", rewriter.getStrArrayAttr(guardStrings));
660 rewriter.finalizeOpModification(op);
667 return !gi.
getParamValue<IntegerAttr>(
"isClocked").getValue().isZero();
671 using IntrinsicConverter::IntrinsicConverter;
679 auto isClocked = getIsClocked(gi);
691 PatternRewriter &rewriter)
override {
692 auto isClocked = getIsClocked(gi);
693 auto functionName = gi.
getParamValue<StringAttr>(
"functionName");
694 ArrayAttr inputNamesStrArray;
695 StringAttr outputStr = gi.
getParamValue<StringAttr>(
"outputName");
696 if (
auto inputNames = gi.
getParamValue<StringAttr>(
"inputNames")) {
697 SmallVector<StringRef> inputNamesTemporary;
698 inputNames.strref().split(inputNamesTemporary,
';', -1,
700 inputNamesStrArray = rewriter.getStrArrayAttr(inputNamesTemporary);
703 Value clock = isClocked ? adaptor.getOperands()[0] : Value();
704 Value enable = adaptor.getOperands()[
static_cast<size_t>(isClocked)];
707 adaptor.getOperands().drop_front(
static_cast<size_t>(isClocked) + 1);
709 rewriter.replaceOpWithNewOp<DPICallIntrinsicOp>(
710 gi.
op, gi.
op.getResultTypes(), functionName, inputNamesStrArray,
711 outputStr, clock, enable, inputs);
720A
tryGetAs(DictionaryAttr dict, Attribute root, StringRef key, Location loc,
721 Twine path = Twine()) {
722 return tryGetAsBase<A>(dict, root, key, loc,
"View 'info'",
723 "'info' attribute", path);
728std::optional<DictionaryAttr>
730 DictionaryAttr augmentedType, DictionaryAttr root,
731 StringAttr name, StringAttr defName,
732 std::optional<StringAttr> description, Twine path = {}) {
734 tryGetAs<StringAttr>(augmentedType, root,
"class", loc, path);
737 StringRef classBase = classAttr.getValue();
738 if (!classBase.consume_front(
"sifive.enterprise.grandcentral.Augmented")) {
740 "the 'class' was expected to start with "
741 "'sifive.enterprise.grandCentral.Augmented*', but was '" +
742 classAttr.getValue() +
"' (Did you misspell it?)")
744 <<
"see attribute: " << augmentedType;
751 if (classBase ==
"BundleType") {
752 defName = tryGetAs<StringAttr>(augmentedType, root,
"defName", loc, path);
760 SmallVector<Attribute> elements;
762 tryGetAs<ArrayAttr>(augmentedType, root,
"elements", loc, path);
765 for (
size_t i = 0, e = elementsAttr.size(); i != e; ++i) {
766 auto field = dyn_cast_or_null<DictionaryAttr>(elementsAttr[i]);
770 "View 'info' attribute with path '.elements[" + Twine(i) +
771 "]' contained an unexpected type (expected a DictionaryAttr).")
773 <<
"The received element was: " << elementsAttr[i];
776 auto ePath = (path +
".elements[" + Twine(i) +
"]").str();
777 auto name = tryGetAs<StringAttr>(field, root,
"name", loc, ePath);
780 auto tpe = tryGetAs<DictionaryAttr>(field, root,
"tpe", loc, ePath);
783 std::optional<StringAttr> description;
784 if (
auto maybeDescription = field.get(
"description"))
785 description = cast<StringAttr>(maybeDescription);
788 description, path +
"_" + name.getValue());
795 if (
auto maybeDescription = field.get(
"description"))
796 attrs.append(
"description", cast<StringAttr>(maybeDescription));
797 attrs.append(
"name", name);
798 auto tpeClass = tpe.getAs<StringAttr>(
"class");
800 mlir::emitError(loc,
"missing 'class' key in") << tpe;
803 attrs.append(
"tpe", tpeClass);
804 elements.push_back(*eltAttr);
810 attrs.append(
"class", classAttr);
811 attrs.append(
"defName", defName);
813 attrs.append(
"description", *description);
814 attrs.append(
"elements", ArrayAttr::get(context, elements));
815 attrs.append(
"name", name);
816 return DictionaryAttr::getWithSorted(context, attrs);
820 if (classBase ==
"GroundType") {
821 NamedAttrList elementIface;
824 elementIface.append(
"class", classAttr);
826 elementIface.append(
"description", *description);
827 elementIface.append(
"name", name);
829 return DictionaryAttr::getWithSorted(context, elementIface);
834 if (classBase ==
"VectorType") {
836 tryGetAs<ArrayAttr>(augmentedType, root,
"elements", loc, path);
839 SmallVector<Attribute> elements;
840 for (
auto [i, elt] :
llvm::enumerate(elementsAttr)) {
842 context, loc, cast<DictionaryAttr>(elt), root, name,
843 StringAttr::get(context,
""), std::nullopt, path +
"_" + Twine(i));
846 elements.push_back(*eltAttr);
849 attrs.append(
"class", classAttr);
851 attrs.append(
"description", *description);
852 attrs.append(
"elements", ArrayAttr::get(context, elements));
853 attrs.append(
"name", name);
854 return DictionaryAttr::getWithSorted(context, attrs);
859 mlir::emitError(loc,
"found unknown AugmentedType '" + classAttr.getValue() +
860 "' (Did you misspell it?)")
862 <<
"see attribute: " << augmentedType;
869 GenericIntrinsicOpAdaptor adaptor,
870 PatternRewriter &rewriter)
override {
877 for (
auto idx :
llvm::
seq(gi.getNumInputs()))
878 if (gi.checkInputType(idx,
"must be ground type", [](auto ty) {
879 auto base = type_dyn_cast<FIRRTLBaseType>(ty);
880 return base && base.isGround();
886 llvm::json::parse(gi.
getParamValue<StringAttr>(
"info").getValue());
887 if (
auto err = view.takeError()) {
888 handleAllErrors(std::move(err), [&](
const llvm::json::ParseError &a) {
889 gi.
emitError() <<
": error parsing view JSON: " << a.message();
895 llvm::json::Path::Root root;
897 assert(value &&
"JSON to attribute failed but should not ever fail");
901 auto dict = dyn_cast<DictionaryAttr>(value);
903 return gi.
emitError() <<
": 'info' parameter must be a dictionary";
907 gi.
op.getContext(), gi.
op.getLoc(), dict, dict, nameAttr,
915 AugmentedBundleTypeAttr::get(gi.
op.getContext(), *result);
917 return gi.
emitError() <<
": 'info' must be augmented bundle";
920 SmallVector<DictionaryAttr> worklist;
921 worklist.push_back(augmentedType.getUnderlying());
922 size_t numLeaves = 0;
929 while (!worklist.empty()) {
930 auto dict = worklist.pop_back_val();
931 auto clazz = dict.getAs<StringAttr>(
"class");
932 if (clazz == augGroundAttr) {
936 assert(clazz == augBundleAttr || clazz == augVectorAttr);
939 dict.getAs<ArrayAttr>(
"elements").getAsRange<DictionaryAttr>());
944 <<
" has " << gi.
getNumInputs() <<
" operands but view 'info' has "
945 << numLeaves <<
" leaf elements";
949 rewriter.replaceOpWithNewOp<ViewIntrinsicOp>(
950 gi.
op, nameAttr.getValue(),
yaml, augmentedType, adaptor.getOperands());
963 lowering.
add<CirctSizeofConverter>(
"circt.sizeof",
"circt_sizeof");
964 lowering.
add<CirctIsXConverter>(
"circt.isX",
"circt_isX");
965 lowering.
add<CirctPlusArgTestConverter>(
"circt.plusargs.test",
966 "circt_plusargs_test");
967 lowering.
add<CirctPlusArgValueConverter>(
"circt.plusargs.value",
968 "circt_plusargs_value");
969 lowering.
add<CirctClockGateConverter>(
"circt.clock_gate",
"circt_clock_gate");
970 lowering.
add<CirctClockInverterConverter>(
"circt.clock_inv",
972 lowering.
add<CirctClockDividerConverter>(
"circt.clock_div",
974 lowering.
add<CirctLTLBinaryConverter<LTLAndIntrinsicOp>>(
"circt.ltl.and",
976 lowering.
add<CirctLTLBinaryConverter<LTLOrIntrinsicOp>>(
"circt.ltl.or",
978 lowering.
add<CirctLTLBinaryConverter<LTLIntersectIntrinsicOp>>(
979 "circt.ltl.intersect",
"circt_ltl_intersect");
980 lowering.
add<CirctLTLBinaryConverter<LTLConcatIntrinsicOp>>(
981 "circt.ltl.concat",
"circt_ltl_concat");
982 lowering.
add<CirctLTLBinaryConverter<LTLImplicationIntrinsicOp>>(
983 "circt.ltl.implication",
"circt_ltl_implication");
984 lowering.
add<CirctLTLBinaryConverter<LTLUntilIntrinsicOp>>(
"circt.ltl.until",
986 lowering.
add<CirctLTLUnaryConverter<LTLNotIntrinsicOp>>(
"circt.ltl.not",
988 lowering.
add<CirctLTLUnaryConverter<LTLEventuallyIntrinsicOp>>(
989 "circt.ltl.eventually",
"circt_ltl_eventually");
991 lowering.
add<CirctLTLDelayConverter>(
"circt.ltl.delay",
"circt_ltl_delay");
992 lowering.
add<CirctLTLRepeatConverter>(
"circt.ltl.repeat",
"circt_ltl_repeat");
993 lowering.
add<CirctLTLGoToRepeatConverter>(
"circt.ltl.goto_repeat",
994 "circt_ltl_goto_repeat");
995 lowering.
add<CirctLTLNonConsecutiveRepeatConverter>(
996 "circt.ltl.non_consecutive_repeat",
"circt_ltl_non_consecutive_repeat");
997 lowering.
add<CirctLTLClockConverter>(
"circt.ltl.clock",
"circt_ltl_clock");
999 lowering.
add<CirctVerifConverter<VerifAssertIntrinsicOp>>(
1000 "circt.verif.assert",
"circt_verif_assert");
1001 lowering.
add<CirctVerifConverter<VerifAssumeIntrinsicOp>>(
1002 "circt.verif.assume",
"circt_verif_assume");
1003 lowering.
add<CirctVerifConverter<VerifCoverIntrinsicOp>>(
"circt.verif.cover",
1004 "circt_verif_cover");
1005 lowering.
add<CirctVerifConverter<VerifRequireIntrinsicOp>>(
1006 "circt.verif.require",
"circt_verif_require");
1007 lowering.
add<CirctVerifConverter<VerifEnsureIntrinsicOp>>(
1008 "circt.verif.ensure",
"circt_verif_ensure");
1009 lowering.
add<CirctMux2CellConverter>(
"circt.mux2cell",
"circt_mux2cell");
1010 lowering.
add<CirctMux4CellConverter>(
"circt.mux4cell",
"circt_mux4cell");
1011 lowering.
add<CirctHasBeenResetConverter>(
"circt.has_been_reset",
1012 "circt_has_been_reset");
1013 lowering.
add<CirctProbeConverter>(
"circt.fpga_probe",
"circt_fpga_probe");
1014 lowering.
add<CirctAssertConverter<AssertOp>>(
"circt.chisel_assert",
1015 "circt_chisel_assert");
1016 lowering.
add<CirctAssertConverter<AssertOp,
true>>(
1017 "circt.chisel_ifelsefatal",
"circt_chisel_ifelsefatal");
1018 lowering.
add<CirctAssertConverter<AssumeOp>>(
"circt.chisel_assume",
1019 "circt_chisel_assume");
1020 lowering.
add<CirctCoverConverter>(
"circt.chisel_cover",
"circt_chisel_cover");
1021 lowering.
add<CirctUnclockedAssumeConverter>(
"circt.unclocked_assume",
1022 "circt_unclocked_assume");
1023 lowering.
add<CirctDPICallConverter>(
"circt.dpi_call",
"circt_dpi_call");
1025 lowering.
add<ViewConverter>(
"circt.view",
"circt_view");
assert(baseType &&"element must be base type")
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...
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
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.
constexpr const char * augmentedVectorTypeClass
constexpr const char * augmentedBundleTypeClass
A tryGetAs(DictionaryAttr dict, Attribute root, StringRef key, Location loc, Twine clazz, Twine path=Twine())
Implements the same behavior as DictionaryAttr::getAs<A> to return the value of a specific type assoc...
constexpr const char * augmentedGroundTypeClass
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)
Emit a connect between two values.
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 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.
void populateIntrinsicLowerings(IntrinsicLowerings &lowerings) const