MLIR  19.0.0git
FuncToEmitC.cpp
Go to the documentation of this file.
1 //===- FuncToEmitC.cpp - Func to EmitC Patterns -----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements patterns to convert the Func dialect to the EmitC
10 // dialect.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 
19 
20 using namespace mlir;
21 
22 //===----------------------------------------------------------------------===//
23 // Conversion Patterns
24 //===----------------------------------------------------------------------===//
25 
26 namespace {
27 class CallOpConversion final : public OpConversionPattern<func::CallOp> {
28 public:
30 
32  matchAndRewrite(func::CallOp callOp, OpAdaptor adaptor,
33  ConversionPatternRewriter &rewriter) const override {
34  // Multiple results func was not converted to `emitc.func`.
35  if (callOp.getNumResults() > 1)
36  return rewriter.notifyMatchFailure(
37  callOp, "only functions with zero or one result can be converted");
38 
39  rewriter.replaceOpWithNewOp<emitc::CallOp>(
40  callOp,
41  callOp.getNumResults() ? callOp.getResult(0).getType() : nullptr,
42  adaptor.getOperands(), callOp->getAttrs());
43 
44  return success();
45  }
46 };
47 
48 class FuncOpConversion final : public OpConversionPattern<func::FuncOp> {
49 public:
51 
53  matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,
54  ConversionPatternRewriter &rewriter) const override {
55 
56  if (funcOp.getFunctionType().getNumResults() > 1)
57  return rewriter.notifyMatchFailure(
58  funcOp, "only functions with zero or one result can be converted");
59 
60  // Create the converted `emitc.func` op.
61  emitc::FuncOp newFuncOp = rewriter.create<emitc::FuncOp>(
62  funcOp.getLoc(), funcOp.getName(), funcOp.getFunctionType());
63 
64  // Copy over all attributes other than the function name and type.
65  for (const auto &namedAttr : funcOp->getAttrs()) {
66  if (namedAttr.getName() != funcOp.getFunctionTypeAttrName() &&
67  namedAttr.getName() != SymbolTable::getSymbolAttrName())
68  newFuncOp->setAttr(namedAttr.getName(), namedAttr.getValue());
69  }
70 
71  // Add `extern` to specifiers if `func.func` is declaration only.
72  if (funcOp.isDeclaration()) {
73  ArrayAttr specifiers = rewriter.getStrArrayAttr({"extern"});
74  newFuncOp.setSpecifiersAttr(specifiers);
75  }
76 
77  // Add `static` to specifiers if `func.func` is private but not a
78  // declaration.
79  if (funcOp.isPrivate() && !funcOp.isDeclaration()) {
80  ArrayAttr specifiers = rewriter.getStrArrayAttr({"static"});
81  newFuncOp.setSpecifiersAttr(specifiers);
82  }
83 
84  if (!funcOp.isDeclaration())
85  rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(),
86  newFuncOp.end());
87  rewriter.eraseOp(funcOp);
88 
89  return success();
90  }
91 };
92 
93 class ReturnOpConversion final : public OpConversionPattern<func::ReturnOp> {
94 public:
96 
98  matchAndRewrite(func::ReturnOp returnOp, OpAdaptor adaptor,
99  ConversionPatternRewriter &rewriter) const override {
100  if (returnOp.getNumOperands() > 1)
101  return rewriter.notifyMatchFailure(
102  returnOp, "only zero or one operand is supported");
103 
104  rewriter.replaceOpWithNewOp<emitc::ReturnOp>(
105  returnOp,
106  returnOp.getNumOperands() ? adaptor.getOperands()[0] : nullptr);
107  return success();
108  }
109 };
110 } // namespace
111 
112 //===----------------------------------------------------------------------===//
113 // Pattern population
114 //===----------------------------------------------------------------------===//
115 
117  MLIRContext *ctx = patterns.getContext();
118 
119  patterns.add<CallOpConversion, FuncOpConversion, ReturnOpConversion>(ctx);
120 }
ArrayAttr getStrArrayAttr(ArrayRef< StringRef > values)
Definition: Builders.cpp:313
This class implements a pattern rewriter for use with ConversionPatterns.
void eraseOp(Operation *op) override
PatternRewriter hook for erasing a dead operation.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Definition: Builders.cpp:464
OpConversionPattern is a wrapper around ConversionPattern that allows for matching and rewriting agai...
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
Definition: Operation.h:577
MLIRContext * getContext() const
Definition: PatternMatch.h:822
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
Definition: PatternMatch.h:846
std::enable_if_t<!std::is_convertible< CallbackT, Twine >::value, LogicalResult > notifyMatchFailure(Location loc, CallbackT &&reasonCallback)
Used to notify the listener that the IR failed to be rewritten because of a match failure,...
Definition: PatternMatch.h:718
void inlineRegionBefore(Region &region, Region &parent, Region::iterator before)
Move the blocks that belong to "region" before the given position in another region "parent".
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
Definition: PatternMatch.h:536
static StringRef getSymbolAttrName()
Return the name of the attribute used for symbol names.
Definition: SymbolTable.h:76
Include the generated interface declarations.
void populateFuncToEmitCPatterns(RewritePatternSet &patterns)
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26