diff --git a/lib/Dialect/FIRRTL/Transforms/LowerClasses.cpp b/lib/Dialect/FIRRTL/Transforms/LowerClasses.cpp index 308327745966..f9d56c6f0d1f 100644 --- a/lib/Dialect/FIRRTL/Transforms/LowerClasses.cpp +++ b/lib/Dialect/FIRRTL/Transforms/LowerClasses.cpp @@ -109,6 +109,9 @@ struct LowerClassesPass : public LowerClassesBase { LogicalResult dialectConversion( Operation *op, const PathInfoTable &pathInfoTable, const DenseMap &classTypeTable); + + // State to memoize repeated calls to shouldCreateClass. + DenseMap shouldCreateClassMemo; }; } // namespace @@ -437,29 +440,45 @@ std::unique_ptr circt::firrtl::createLowerClassesPass() { // Predicate to check if a module-like needs a Class to be created. bool LowerClassesPass::shouldCreateClass(FModuleLike moduleLike) { - if (isa(moduleLike.getOperation())) + // Memoize calls using the extra state. + auto it = shouldCreateClassMemo.find(moduleLike); + if (it != shouldCreateClassMemo.end()) + return it->second; + + if (isa(moduleLike.getOperation())) { + shouldCreateClassMemo.insert({moduleLike, true}); return true; + } // Always create a class for public modules. - if (moduleLike.isPublic()) + if (moduleLike.isPublic()) { + shouldCreateClassMemo.insert({moduleLike, true}); return true; + } // Create a class for modules with property ports. bool hasClassPorts = llvm::any_of(moduleLike.getPorts(), [](PortInfo port) { return isa(port.type); }); - if (hasClassPorts) + if (hasClassPorts) { + shouldCreateClassMemo.insert({moduleLike, true}); return true; + } // Create a class for modules that instantiate classes or modules with // property ports. for (auto op : - moduleLike.getOperation()->getRegion(0).getOps()) - for (auto result : op->getResults()) - if (type_isa(result.getType())) + moduleLike.getOperation()->getRegion(0).getOps()) { + for (auto result : op->getResults()) { + if (type_isa(result.getType())) { + shouldCreateClassMemo.insert({moduleLike, true}); return true; + } + } + } + shouldCreateClassMemo.insert({moduleLike, false}); return false; }