26struct FuncToEmitCDialectInterface :
public ConvertToEmitCPatternInterface {
27 FuncToEmitCDialectInterface(Dialect *dialect)
28 : ConvertToEmitCPatternInterface(dialect) {}
32 void populateConvertToEmitCConversionPatterns(
33 ConversionTarget &
target, TypeConverter &typeConverter,
34 RewritePatternSet &patterns)
const final {
42 dialect->addInterfaces<FuncToEmitCDialectInterface>();
51class CallOpConversion final :
public OpConversionPattern<func::CallOp> {
53 using OpConversionPattern<func::CallOp>::OpConversionPattern;
56 matchAndRewrite(func::CallOp callOp, OpAdaptor adaptor,
57 ConversionPatternRewriter &rewriter)
const override {
59 if (callOp.getNumResults() > 1)
60 return rewriter.notifyMatchFailure(
61 callOp,
"only functions with zero or one result can be converted");
63 rewriter.replaceOpWithNewOp<emitc::CallOp>(callOp, callOp.getResultTypes(),
64 adaptor.getOperands(),
71class FuncOpConversion final :
public OpConversionPattern<func::FuncOp> {
73 using OpConversionPattern<func::FuncOp>::OpConversionPattern;
76 matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,
77 ConversionPatternRewriter &rewriter)
const override {
78 FunctionType fnType = funcOp.getFunctionType();
80 if (fnType.getNumResults() > 1)
81 return rewriter.notifyMatchFailure(
82 funcOp,
"only functions with zero or one result can be converted");
84 TypeConverter::SignatureConversion signatureConverter(
85 fnType.getNumInputs());
86 for (
const auto &argType :
enumerate(fnType.getInputs())) {
87 auto convertedType = getTypeConverter()->convertType(argType.value());
89 return rewriter.notifyMatchFailure(funcOp,
90 "argument type conversion failed");
91 signatureConverter.addInputs(argType.index(), convertedType);
95 if (fnType.getNumResults() == 1) {
96 resultType = getTypeConverter()->convertType(fnType.getResult(0));
98 return rewriter.notifyMatchFailure(funcOp,
99 "result type conversion failed");
103 emitc::FuncOp newFuncOp = emitc::FuncOp::create(
104 rewriter, funcOp.getLoc(), funcOp.getName(),
105 FunctionType::get(rewriter.getContext(),
106 signatureConverter.getConvertedTypes(),
110 for (
const auto &namedAttr : funcOp->getAttrs()) {
111 if (namedAttr.getName() != funcOp.getFunctionTypeAttrName() &&
113 newFuncOp->setAttr(namedAttr.getName(), namedAttr.getValue());
117 if (funcOp.isDeclaration()) {
118 ArrayAttr specifiers = rewriter.getStrArrayAttr({
"extern"});
119 newFuncOp.setSpecifiersAttr(specifiers);
124 if (funcOp.isPrivate() && !funcOp.isDeclaration()) {
125 ArrayAttr specifiers = rewriter.getStrArrayAttr({
"static"});
126 newFuncOp.setSpecifiersAttr(specifiers);
129 if (!funcOp.isDeclaration()) {
130 rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(),
132 if (
failed(rewriter.convertRegionTypes(
133 &newFuncOp.getBody(), *getTypeConverter(), &signatureConverter)))
136 rewriter.eraseOp(funcOp);
142class ReturnOpConversion final :
public OpConversionPattern<func::ReturnOp> {
144 using OpConversionPattern<func::ReturnOp>::OpConversionPattern;
147 matchAndRewrite(func::ReturnOp returnOp, OpAdaptor adaptor,
148 ConversionPatternRewriter &rewriter)
const override {
149 if (returnOp.getNumOperands() > 1)
150 return rewriter.notifyMatchFailure(
151 returnOp,
"only zero or one operand is supported");
153 rewriter.replaceOpWithNewOp<emitc::ReturnOp>(
155 returnOp.getNumOperands() ? adaptor.getOperands()[0] :
nullptr);
169 patterns.
add<CallOpConversion, FuncOpConversion, ReturnOpConversion>(
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
MLIRContext is the top-level object for a collection of MLIR operations.
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
static StringRef getSymbolAttrName()
Return the name of the attribute used for symbol names.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
void registerConvertFuncToEmitCInterface(DialectRegistry ®istry)
void populateFuncToEmitCPatterns(const TypeConverter &typeConverter, RewritePatternSet &patterns)