18#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/DenseSet.h"
20#include "llvm/Support/FormatVariadic.h"
27#define GEN_PASS_DEF_WRAPFUNCINCLASSPASS
28#include "mlir/Dialect/EmitC/Transforms/Passes.h.inc"
31struct WrapFuncInClassPass
32 :
public impl::WrapFuncInClassPassBase<WrapFuncInClassPass> {
33 using WrapFuncInClassPassBase::WrapFuncInClassPassBase;
34 void runOnOperation()
override {
35 mlir::ModuleOp moduleOp = getOperation();
40 moduleOp.walk([&globalsUsedByFuncs, &symbolTable](FuncOp funcOp) {
41 funcOp.walk([&globalsUsedByFuncs, &symbolTable,
42 &funcOp](GetGlobalOp getGlobalOp) {
44 getGlobalOp, getGlobalOp.getNameAttr())) {
45 globalsUsedByFuncs[funcOp].insert(globalOp);
57 for (
auto &[_, globals] : globalsUsedByFuncs)
58 globalsToErase.insert_range(globals);
60 for (GlobalOp globalOp : globalsToErase)
72 MLIRContext *context, StringRef funcName, StringRef classNameFormat,
75 classNameFormat(classNameFormat), globalsToMove(globalsToMove) {}
80 std::string className = llvm::formatv(
81 false, classNameFormat.c_str(), funcOp.getName());
82 ClassOp newClassOp = ClassOp::create(rewriter, funcOp.getLoc(), className);
88 auto argAttrs = funcOp.getArgAttrs();
89 for (
auto [idx, val] : llvm::enumerate(funcOp.getArguments())) {
90 StringAttr fieldName =
93 TypeAttr typeAttr = TypeAttr::get(val.getType());
94 fields.push_back({fieldName, typeAttr});
96 FieldOp fieldop = FieldOp::create(rewriter, funcOp->getLoc(), fieldName,
99 if (argAttrs && idx < argAttrs->size()) {
100 fieldop->setDiscardableAttrs(funcOp.getArgAttrDict(idx));
104 auto globalsIt = globalsToMove.find(funcOp);
105 if (globalsIt != globalsToMove.end()) {
106 for (
auto global : globalsIt->second) {
107 FieldOp::create(rewriter, funcOp->getLoc(), global.getSymNameAttr(),
108 global.getTypeAttr(), global.getInitialValueAttr());
113 FunctionType funcType = funcOp.getFunctionType();
115 FuncOp newFuncOp = FuncOp::create(rewriter, loc, (funcName), funcType);
118 funcOp.walk([&](GetGlobalOp getGlobalOp) {
120 GetFieldOp getFieldOp =
121 GetFieldOp::create(rewriter, getGlobalOp.getLoc(),
122 getGlobalOp.
getType(), getGlobalOp.getNameAttr());
123 rewriter.
replaceOp(getGlobalOp, getFieldOp);
127 newFuncOp.getBody().takeBody(funcOp.getBody());
130 std::vector<Value> newArguments;
131 newArguments.reserve(fields.size());
132 for (
auto &[fieldName, attr] : fields) {
134 GetFieldOp::create(rewriter, loc, attr.getValue(), fieldName);
135 newArguments.push_back(arg);
138 for (
auto [oldArg, newArg] :
139 llvm::zip(newFuncOp.getArguments(), newArguments)) {
143 llvm::BitVector argsToErase(newFuncOp.getNumArguments(),
true);
144 if (failed(newFuncOp.eraseArguments(argsToErase)))
145 newFuncOp->emitOpError(
"failed to erase all arguments using BitVector");
154 std::string funcName;
158 std::string classNameFormat;
169 classNameFormat, globalsToMove);
LogicalResult matchAndRewrite(FuncOp funcOp, PatternRewriter &rewriter) const override
WrapFuncInClass(MLIRContext *context, StringRef funcName, StringRef classNameFormat, const DenseMap< FuncOp, llvm::DenseSet< GlobalOp > > &globalsToMove)
Ty getType(Args &&...args)
Get or construct an instance of the type Ty with provided arguments.
StringAttr getStringAttr(const Twine &bytes)
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes={}, ArrayRef< Location > locs={})
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
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.
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
virtual void replaceAllUsesWith(Value from, Value to)
Find uses of from and replace them with to.
This class represents a collection of SymbolTables.
virtual Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
void populateWrapFuncInClass(RewritePatternSet &patterns, StringRef funcName, StringRef classNameFormat, DenseMap< FuncOp, llvm::DenseSet< GlobalOp > > &globalsToMove)
Include the generated interface declarations.
llvm::DenseSet< ValueT, ValueInfoT > DenseSet
void walkAndApplyPatterns(Operation *op, const FrozenRewritePatternSet &patterns, RewriterBase::Listener *listener=nullptr)
A fast walk-based pattern rewrite driver.
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap
OpRewritePattern(MLIRContext *context, PatternBenefit benefit=1, ArrayRef< StringRef > generatedNames={})