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.
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)