11 #include "mlir/Pass/Pass.h"
20 #include "mlir/Transforms/DialectConversion.h"
24 #define GEN_PASS_DEF_KANAGAWACONTAINERIZE
25 #include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc"
29 using namespace circt;
30 using namespace kanagawa;
35 OutlineContainerPattern(MLIRContext *context,
Namespace &ns)
41 matchAndRewrite(ContainerOp op, OpAdaptor adaptor,
42 ConversionPatternRewriter &rewriter)
const override {
46 dyn_cast_or_null<ClassOp>(op.getOperation()->getParentOp());
47 assert(parentClass &&
"This pattern should never be called on a container"
48 "that is not nested within a class.");
49 auto design = parentClass.getParentOp<DesignOp>();
50 assert(design &&
"Parent class should be nested within a design.");
52 rewriter.setInsertionPoint(parentClass);
53 StringAttr newContainerName = rewriter.getStringAttr(
54 ns.
newName(parentClass.getInnerNameAttr().strref() +
"_" +
55 op.getInnerNameAttr().strref()));
56 auto newContainer = rewriter.create<ContainerOp>(
57 op.getLoc(), newContainerName,
false);
59 rewriter.mergeBlocks(op.getBodyBlock(), newContainer.getBodyBlock(), {});
63 cast<ThisOp>(cast<ScopeOpInterface>(*newContainer.getOperation())
66 rewriter.setInsertionPoint(thisOp);
67 rewriter.replaceOpWithNewOp<ThisOp>(thisOp, design.getSymNameAttr(),
68 newContainer.getInnerSymAttr());
71 rewriter.setInsertionPoint(op);
72 rewriter.create<ContainerInstanceOp>(
74 newContainer.getInnerRef());
86 matchAndRewrite(ClassOp op, OpAdaptor adaptor,
87 ConversionPatternRewriter &rewriter)
const override {
90 rewriter.create<ContainerOp>(op.getLoc(), op.getInnerSymAttr(),
91 false, op.getNameAttr());
92 rewriter.mergeBlocks(op.getBodyBlock(), newContainer.getBodyBlock(), {});
98 struct InstanceToContainerInstancePattern
103 matchAndRewrite(InstanceOp op, OpAdaptor adaptor,
104 ConversionPatternRewriter &rewriter)
const override {
106 rewriter.replaceOpWithNewOp<ContainerInstanceOp>(op, op.getInnerSym(),
107 op.getTargetNameAttr());
113 struct ContainerizePass
114 :
public circt::kanagawa::impl::KanagawaContainerizeBase<ContainerizePass> {
115 void runOnOperation()
override;
119 LogicalResult outlineContainers();
122 LogicalResult containerizeClasses();
126 LogicalResult ContainerizePass::outlineContainers() {
127 auto *context = &getContext();
128 ConversionTarget target(*context);
129 target.addLegalDialect<KanagawaDialect>();
130 target.addDynamicallyLegalOp<ContainerOp>(
131 [&](
auto *op) {
return !isa<kanagawa::ClassOp>(op->getParentOp()); });
132 RewritePatternSet
patterns(context);
138 getOperation(), [&](StringAttr name,
const hw::InnerSymTarget &target) {
146 patterns.insert<OutlineContainerPattern>(context, ns);
147 return applyPartialConversion(getOperation(), target, std::move(
patterns));
150 LogicalResult ContainerizePass::containerizeClasses() {
151 auto *context = &getContext();
152 ConversionTarget target(*context);
153 target.addLegalDialect<KanagawaDialect>();
154 target.addIllegalOp<ClassOp, InstanceOp>();
155 RewritePatternSet
patterns(context);
156 patterns.insert<ClassToContainerPattern, InstanceToContainerInstancePattern>(
158 return applyPartialConversion(getOperation(), target, std::move(
patterns));
161 void ContainerizePass::runOnOperation() {
162 if (failed(outlineContainers()) || failed(containerizeClasses()))
167 return std::make_unique<ContainerizePass>();
assert(baseType &&"element must be base type")
A namespace that is used to store existing names and generate new names in some scope within the IR.
void add(mlir::ModuleOp module)
StringRef newName(const Twine &name)
Return a unique name, derived from the input name, and add the new name to the internal namespace.
void addDefinitions(mlir::Operation *top)
Populate the symbol cache with all symbol-defining operations within the 'top' operation.
Default symbol cache implementation; stores associations between names (StringAttr's) to mlir::Operat...
void addDefinition(mlir::Attribute key, mlir::Operation *op) override
In the building phase, add symbols.
static RetTy walkSymbols(Operation *op, FuncTy &&callback)
Walk the given IST operation and invoke the callback for all encountered inner symbols.
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
std::unique_ptr< mlir::Pass > createContainerizePass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.