18 #include "mlir/Transforms/DialectConversion.h"
20 using namespace circt;
26 OutlineContainerPattern(MLIRContext *context,
Namespace &ns)
32 matchAndRewrite(ContainerOp op, OpAdaptor adaptor,
33 ConversionPatternRewriter &rewriter)
const override {
37 dyn_cast_or_null<ClassOp>(op.getOperation()->getParentOp());
38 assert(parentClass &&
"This pattern should never be called on a container"
39 "that is not nested within a class.");
40 auto design = parentClass.getParentOp<DesignOp>();
41 assert(design &&
"Parent class should be nested within a design.");
43 rewriter.setInsertionPoint(parentClass);
44 StringAttr newContainerName = rewriter.getStringAttr(
45 ns.newName(parentClass.getInnerNameAttr().strref() +
"_" +
46 op.getInnerNameAttr().strref()));
47 auto newContainer = rewriter.create<ContainerOp>(
48 op.getLoc(), newContainerName,
false);
50 rewriter.mergeBlocks(op.getBodyBlock(), newContainer.getBodyBlock(), {});
54 cast<ThisOp>(cast<ScopeOpInterface>(*newContainer.getOperation())
57 rewriter.setInsertionPoint(thisOp);
58 rewriter.replaceOpWithNewOp<ThisOp>(thisOp, design.getSymNameAttr(),
59 newContainer.getInnerSymAttr());
62 rewriter.setInsertionPoint(op);
63 rewriter.create<ContainerInstanceOp>(
65 newContainer.getInnerRef());
77 matchAndRewrite(ClassOp op, OpAdaptor adaptor,
78 ConversionPatternRewriter &rewriter)
const override {
81 rewriter.create<ContainerOp>(op.getLoc(), op.getInnerSymAttr(),
false);
82 rewriter.mergeBlocks(op.getBodyBlock(), newContainer.getBodyBlock(), {});
88 struct InstanceToContainerInstancePattern
93 matchAndRewrite(InstanceOp op, OpAdaptor adaptor,
94 ConversionPatternRewriter &rewriter)
const override {
96 rewriter.replaceOpWithNewOp<ContainerInstanceOp>(op, op.getInnerSym(),
97 op.getTargetNameAttr());
103 struct ContainerizePass :
public IbisContainerizeBase<ContainerizePass> {
104 void runOnOperation()
override;
108 LogicalResult outlineContainers();
111 LogicalResult containerizeClasses();
115 LogicalResult ContainerizePass::outlineContainers() {
116 auto *context = &getContext();
117 ConversionTarget target(*context);
118 target.addLegalDialect<IbisDialect>();
119 target.addDynamicallyLegalOp<ContainerOp>(
120 [&](
auto *op) {
return !isa<ibis::ClassOp>(op->getParentOp()); });
121 RewritePatternSet
patterns(context);
127 getOperation(), [&](StringAttr name,
const hw::InnerSymTarget &target) {
135 patterns.insert<OutlineContainerPattern>(context, ns);
136 return applyPartialConversion(getOperation(), target, std::move(
patterns));
139 LogicalResult ContainerizePass::containerizeClasses() {
140 auto *context = &getContext();
141 ConversionTarget target(*context);
142 target.addLegalDialect<IbisDialect>();
143 target.addIllegalOp<ClassOp, InstanceOp>();
144 RewritePatternSet
patterns(context);
145 patterns.insert<ClassToContainerPattern, InstanceToContainerInstancePattern>(
147 return applyPartialConversion(getOperation(), target, std::move(
patterns));
150 void ContainerizePass::runOnOperation() {
151 if (failed(outlineContainers()) || failed(containerizeClasses()))
156 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(SymbolCache &symCache)
SymbolCache initializer; initialize from every key that is convertible to a StringAttr in the SymbolC...
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.