31 void populateConvertToEmitCConversionPatterns(
32 ConversionTarget &
target, TypeConverter &typeConverter,
33 RewritePatternSet &
patterns)
const final {
41 dialect->addInterfaces<FuncToEmitCDialectInterface>();
50class CallOpConversion final :
public OpConversionPattern<func::CallOp> {
52 using OpConversionPattern<func::CallOp>::OpConversionPattern;
55 matchAndRewrite(func::CallOp callOp, OpAdaptor adaptor,
56 ConversionPatternRewriter &rewriter)
const override {
58 if (callOp.getNumResults() > 1)
59 return rewriter.notifyMatchFailure(
60 callOp,
"only functions with zero or one result can be converted");
62 rewriter.replaceOpWithNewOp<emitc::CallOp>(callOp, callOp.getResultTypes(),
63 adaptor.getOperands(),
70class FuncOpConversion final :
public OpConversionPattern<func::FuncOp> {
72 using OpConversionPattern<func::FuncOp>::OpConversionPattern;
75 matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,
76 ConversionPatternRewriter &rewriter)
const override {
77 FunctionType fnType = funcOp.getFunctionType();
79 if (fnType.getNumResults() > 1)
80 return rewriter.notifyMatchFailure(
81 funcOp,
"only functions with zero or one result can be converted");
83 TypeConverter::SignatureConversion signatureConverter(
84 fnType.getNumInputs());
85 for (
const auto &argType :
enumerate(fnType.getInputs())) {
86 auto convertedType = getTypeConverter()->convertType(argType.value());
88 return rewriter.notifyMatchFailure(funcOp,
89 "argument type conversion failed");
90 signatureConverter.addInputs(argType.index(), convertedType);
94 if (fnType.getNumResults() == 1) {
95 resultType = getTypeConverter()->convertType(fnType.getResult(0));
97 return rewriter.notifyMatchFailure(funcOp,
98 "result type conversion failed");
102 emitc::FuncOp newFuncOp = emitc::FuncOp::create(
103 rewriter, funcOp.getLoc(), funcOp.getName(),
104 FunctionType::get(rewriter.getContext(),
105 signatureConverter.getConvertedTypes(),
109 for (
const auto &namedAttr : funcOp->getAttrs()) {
110 if (namedAttr.getName() != funcOp.getFunctionTypeAttrName() &&
112 newFuncOp->setAttr(namedAttr.getName(), namedAttr.getValue());
116 if (funcOp.isDeclaration()) {
117 ArrayAttr specifiers = rewriter.getStrArrayAttr({
"extern"});
118 newFuncOp.setSpecifiersAttr(specifiers);
123 if (funcOp.isPrivate() && !funcOp.isDeclaration()) {
124 ArrayAttr specifiers = rewriter.getStrArrayAttr({
"static"});
125 newFuncOp.setSpecifiersAttr(specifiers);
128 if (!funcOp.isDeclaration()) {
129 rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(),
131 if (
failed(rewriter.convertRegionTypes(
132 &newFuncOp.getBody(), *getTypeConverter(), &signatureConverter)))
135 rewriter.eraseOp(funcOp);
141class ReturnOpConversion final :
public OpConversionPattern<func::ReturnOp> {
143 using OpConversionPattern<func::ReturnOp>::OpConversionPattern;
146 matchAndRewrite(func::ReturnOp returnOp, OpAdaptor adaptor,
147 ConversionPatternRewriter &rewriter)
const override {
148 if (returnOp.getNumOperands() > 1)
149 return rewriter.notifyMatchFailure(
150 returnOp,
"only zero or one operand is supported");
152 rewriter.replaceOpWithNewOp<emitc::ReturnOp>(
154 returnOp.getNumOperands() ? adaptor.getOperands()[0] :
nullptr);
168 patterns.add<CallOpConversion, FuncOpConversion, ReturnOpConversion>(
ConvertToEmitCPatternInterface(Dialect *dialect)
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.
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)
const FrozenRewritePatternSet & patterns
void populateFuncToEmitCPatterns(const TypeConverter &typeConverter, RewritePatternSet &patterns)