18#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/DenseSet.h"
26#define GEN_PASS_DEF_WRAPFUNCINCLASSPASS
27#include "mlir/Dialect/EmitC/Transforms/Passes.h.inc"
30struct WrapFuncInClassPass
31 :
public impl::WrapFuncInClassPassBase<WrapFuncInClassPass> {
32 using WrapFuncInClassPassBase::WrapFuncInClassPassBase;
33 void runOnOperation()
override {
34 mlir::ModuleOp moduleOp = getOperation();
39 moduleOp.walk([&globalsUsedByFuncs, &symbolTable](FuncOp funcOp) {
40 funcOp.walk([&globalsUsedByFuncs, &symbolTable,
41 &funcOp](GetGlobalOp getGlobalOp) {
43 getGlobalOp, getGlobalOp.getNameAttr())) {
44 globalsUsedByFuncs[funcOp].insert(globalOp);
55 for (
auto &[_, globals] : globalsUsedByFuncs)
56 globalsToErase.insert_range(globals);
58 for (GlobalOp globalOp : globalsToErase)
73 globalsToMove(globalsToMove) {}
78 auto className = funcOp.getSymNameAttr().str() +
"Class";
79 ClassOp newClassOp = ClassOp::create(rewriter, funcOp.getLoc(), className);
85 auto argAttrs = funcOp.getArgAttrs();
86 for (
auto [idx, val] : llvm::enumerate(funcOp.getArguments())) {
87 StringAttr fieldName =
90 TypeAttr typeAttr = TypeAttr::get(val.getType());
91 fields.push_back({fieldName, typeAttr});
93 FieldOp fieldop = FieldOp::create(rewriter, funcOp->getLoc(), fieldName,
96 if (argAttrs && idx < argAttrs->size()) {
97 fieldop->setDiscardableAttrs(funcOp.getArgAttrDict(idx));
101 auto globalsIt = globalsToMove.find(funcOp);
102 if (globalsIt != globalsToMove.end()) {
103 for (
auto global : globalsIt->second) {
104 FieldOp::create(rewriter, funcOp->getLoc(), global.getSymNameAttr(),
105 global.getTypeAttr(), global.getInitialValueAttr());
110 FunctionType funcType = funcOp.getFunctionType();
112 FuncOp newFuncOp = FuncOp::create(rewriter, loc, (
funcName), funcType);
115 newFuncOp.getBody().takeBody(funcOp.getBody());
118 std::vector<Value> newArguments;
119 newArguments.reserve(fields.size());
120 for (
auto &[fieldName, attr] : fields) {
122 GetFieldOp::create(rewriter, loc, attr.getValue(), fieldName);
123 newArguments.push_back(arg);
126 for (
auto [oldArg, newArg] :
127 llvm::zip(newFuncOp.getArguments(), newArguments)) {
131 llvm::BitVector argsToErase(newFuncOp.getNumArguments(),
true);
132 if (failed(newFuncOp.eraseArguments(argsToErase)))
133 newFuncOp->emitOpError(
"failed to erase all arguments using BitVector");
135 newFuncOp.walk([&](GetGlobalOp getGlobalOp) {
137 GetFieldOp getFieldOp =
138 GetFieldOp::create(rewriter, getGlobalOp.getLoc(),
139 getGlobalOp.
getType(), getGlobalOp.getNameAttr());
150 std::string funcName;
WrapFuncInClass(MLIRContext *context, StringRef funcName, const DenseMap< FuncOp, llvm::DenseSet< GlobalOp > > &globalsToMove)
LogicalResult matchAndRewrite(FuncOp funcOp, PatternRewriter &rewriter) const override
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,...
::mlir::Pass::Option< std::string > funcName
void populateWrapFuncInClass(RewritePatternSet &patterns, StringRef funcName, 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={})