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,
89 auto argAttrs = funcOp.getArgAttrs();
90 for (
auto [idx, val] : llvm::enumerate(funcOp.getArguments())) {
91 StringAttr fieldName =
94 TypeAttr typeAttr = TypeAttr::get(val.getType());
95 fields.push_back({fieldName, typeAttr});
98 FieldOp::create(rewriter, funcOp->getLoc(), fieldName,
99 nullptr, typeAttr,
nullptr);
101 if (argAttrs && idx < argAttrs->size()) {
102 fieldop->setDiscardableAttrs(funcOp.getArgAttrDict(idx));
106 auto globalsIt = globalsToMove.find(funcOp);
107 if (globalsIt != globalsToMove.end()) {
108 for (
auto global : globalsIt->second) {
109 FieldOp::create(rewriter, funcOp->getLoc(), global.getSymNameAttr(),
110 nullptr, global.getTypeAttr(),
111 global.getInitialValueAttr());
116 FunctionType funcType = funcOp.getFunctionType();
118 FuncOp newFuncOp = FuncOp::create(rewriter, loc, (funcName), funcType);
121 funcOp.walk([&](GetGlobalOp getGlobalOp) {
123 GetFieldOp getFieldOp =
124 GetFieldOp::create(rewriter, getGlobalOp.getLoc(),
125 getGlobalOp.
getType(), getGlobalOp.getNameAttr());
126 rewriter.
replaceOp(getGlobalOp, getFieldOp);
130 newFuncOp.getBody().takeBody(funcOp.getBody());
133 std::vector<Value> newArguments;
134 newArguments.reserve(fields.size());
135 for (
auto &[fieldName, attr] : fields) {
137 GetFieldOp::create(rewriter, loc, attr.getValue(), fieldName);
138 newArguments.push_back(arg);
141 for (
auto [oldArg, newArg] :
142 llvm::zip(newFuncOp.getArguments(), newArguments)) {
146 llvm::BitVector argsToErase(newFuncOp.getNumArguments(),
true);
147 if (failed(newFuncOp.eraseArguments(argsToErase)))
148 newFuncOp->emitOpError(
"failed to erase all arguments using BitVector");
157 std::string funcName;
161 std::string classNameFormat;
172 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={})