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 =
81 llvm::formatv(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 newFuncOp.getBody().takeBody(funcOp.getBody());
121 std::vector<Value> newArguments;
122 newArguments.reserve(fields.size());
123 for (
auto &[fieldName, attr] : fields) {
125 GetFieldOp::create(rewriter, loc, attr.getValue(), fieldName);
126 newArguments.push_back(arg);
129 for (
auto [oldArg, newArg] :
130 llvm::zip(newFuncOp.getArguments(), newArguments)) {
134 llvm::BitVector argsToErase(newFuncOp.getNumArguments(),
true);
135 if (failed(newFuncOp.eraseArguments(argsToErase)))
136 newFuncOp->emitOpError(
"failed to erase all arguments using BitVector");
138 newFuncOp.walk([&](GetGlobalOp getGlobalOp) {
140 GetFieldOp getFieldOp =
141 GetFieldOp::create(rewriter, getGlobalOp.getLoc(),
142 getGlobalOp.
getType(), getGlobalOp.getNameAttr());
143 rewriter.
replaceOp(getGlobalOp, getFieldOp);
153 std::string funcName;
157 std::string classNameFormat;
168 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={})