@@ -972,45 +972,49 @@ struct EagerInliner : public OpReduction<firrtl::InstanceOp> {
972972 auto *tableOp = SymbolTable::getNearestSymbolTable (instOp);
973973 auto *moduleOp =
974974 instOp.getReferencedOperation (symbols.getSymbolTable (tableOp));
975- if (!isa<firrtl::FModuleOp>(moduleOp))
976- return 0 ;
977- return symbols.getSymbolUserMap (tableOp).getUsers (moduleOp).size () == 1 ;
975+
976+ return isa<firrtl::FModuleOp>(moduleOp);
978977 }
979978
980979 LogicalResult rewrite (firrtl::InstanceOp instOp) override {
981- LLVM_DEBUG (llvm::dbgs ()
982- << " Inlining instance `" << instOp.getName () << " `\n " );
983- SmallVector<Value> argReplacements;
984- ImplicitLocOpBuilder builder (instOp.getLoc (), instOp);
980+ auto *tableOp = SymbolTable::getNearestSymbolTable (instOp);
981+ auto moduleOp = cast<firrtl::FModuleOp>(
982+ instOp.getReferencedOperation (symbols.getSymbolTable (tableOp)));
983+ bool isLastUse =
984+ (symbols.getSymbolUserMap (tableOp).getUsers (moduleOp).size () == 1 );
985+ auto clonedModuleOp = isLastUse ? moduleOp : moduleOp.clone ();
986+
987+ // Create wires to replace the instance results.
988+ IRRewriter rewriter (instOp);
989+ SmallVector<Value> argWires;
985990 for (unsigned i = 0 , e = instOp.getNumResults (); i != e; ++i) {
986991 auto result = instOp.getResult (i);
987- auto name = builder .getStringAttr (Twine (instOp.getName ()) + " _" +
988- instOp.getPortNameStr (i));
992+ auto name = rewriter .getStringAttr (Twine (instOp.getName ()) + " _" +
993+ instOp.getPortNameStr (i));
989994 auto wire =
990- firrtl::WireOp::create (builder, result. getType (), name ,
991- firrtl::NameKindEnum::DroppableName,
995+ firrtl::WireOp::create (rewriter, instOp. getLoc (), result. getType () ,
996+ name, firrtl::NameKindEnum::DroppableName,
992997 instOp.getPortAnnotation (i), StringAttr{})
993998 .getResult ();
994999 result.replaceAllUsesWith (wire);
995- argReplacements.push_back (wire);
996- }
997- auto *tableOp = SymbolTable::getNearestSymbolTable (instOp);
998- auto moduleOp = cast<firrtl::FModuleOp>(
999- instOp.getReferencedOperation (symbols.getSymbolTable (tableOp)));
1000- for (auto &op : llvm::make_early_inc_range (*moduleOp.getBodyBlock ())) {
1001- op.remove ();
1002- builder.insert (&op);
1003- for (auto &operand : op.getOpOperands ())
1004- if (auto blockArg = dyn_cast<BlockArgument>(operand.get ()))
1005- operand.set (argReplacements[blockArg.getArgNumber ()]);
1000+ argWires.push_back (wire);
10061001 }
1002+
1003+ // Splice in the cloned module body.
1004+ rewriter.inlineBlockBefore (clonedModuleOp.getBodyBlock (), instOp, argWires);
1005+
1006+ // Make sure we remove any NLAs that go through this instance, and the
1007+ // module if we're about the delete the module.
10071008 nlaRemover.markNLAsInOperation (instOp);
1008- instOp->erase ();
1009- moduleOp->erase ();
1009+ if (isLastUse)
1010+ nlaRemover.markNLAsInOperation (moduleOp);
1011+
1012+ instOp.erase ();
1013+ clonedModuleOp.erase ();
10101014 return success ();
10111015 }
10121016
1013- std::string getName () const override { return " eager-inliner" ; }
1017+ std::string getName () const override { return " firrtl- eager-inliner" ; }
10141018 bool acceptSizeIncrease () const override { return true ; }
10151019
10161020 ::detail::SymbolCache symbols;
0 commit comments