Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIRRTL] Intrinsics: Add checkAndConvert, anchor vtable. #8082

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions include/circt/Dialect/FIRRTL/FIRRTLIntrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,18 +188,44 @@ struct GenericIntrinsic {
///
/// Intrinsic converters contain validation logic, along with a converter
/// method to transform generic intrinsic ops to their implementation.

/// Instances of a converter must be stateless and are expected to be able
/// to be used simultaneously on different intrinsic operations in parallel.
class IntrinsicConverter {
public:
virtual void anchor(); // vtable anchor

virtual ~IntrinsicConverter() = default;

/// Checks whether the intrinsic is well-formed.
///
/// This or's multiple ParseResults together, returning true on failure.
virtual bool check(GenericIntrinsic gi) = 0;
virtual bool check(GenericIntrinsic gi) {
llvm::report_fatal_error(
"check() or checkAndConvert() must be implemented");
return true;
}

/// Transform the intrinsic to its implementation.
virtual void convert(GenericIntrinsic gi, GenericIntrinsicOpAdaptor adaptor,
PatternRewriter &rewriter) = 0;
PatternRewriter &rewriter) {
llvm::report_fatal_error(
"convert() or checkAndConvert() must be implemented");
}

/// Perform both check and convert, defaults to using check() and convert().
/// Return failure if check fails (no changes to IR should be made).
/// Otherwise, transform the intrinsic and return success.
/// Prefer overriding check and convert, but overriding this can avoid
/// recomputing work done during check needed for the conversion.
virtual LogicalResult checkAndConvert(GenericIntrinsic gi,
GenericIntrinsicOpAdaptor adaptor,
PatternRewriter &rewriter) {
if (check(gi))
return failure();
convert(gi, adaptor, rewriter);
return success();
};
};

template <typename OpTy>
Expand Down
12 changes: 7 additions & 5 deletions lib/Dialect/FIRRTL/FIRRTLIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
using namespace circt;
using namespace firrtl;

// vtable anchor
void IntrinsicConverter::anchor() {}

//===----------------------------------------------------------------------===//
// GenericIntrinsic
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -126,11 +129,10 @@ class IntrinsicOpConversion final
}

auto &conv = *it->second;
if (conv.check(GenericIntrinsic(op)))
return failure();
conv.convert(GenericIntrinsic(op), adaptor, rewriter);
++numConversions;
return success();
auto result = conv.checkAndConvert(GenericIntrinsic(op), adaptor, rewriter);
if (succeeded(result))
++numConversions;
return result;
}

private:
Expand Down
Loading