Skip to content

Commit

Permalink
[FIRRTL] Memoize calls to shouldCreateClass in LowerClasses, NFC.
Browse files Browse the repository at this point in the history
This is already called in multiple places, and we will soon use it in
another situation. This can be expensive, so it is worth memoizing to
avoid repeatedly traversing the module bodies in the slow case.
  • Loading branch information
mikeurbach committed Mar 13, 2024
1 parent e438ac0 commit 13b9456
Showing 1 changed file with 25 additions and 6 deletions.
31 changes: 25 additions & 6 deletions lib/Dialect/FIRRTL/Transforms/LowerClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ struct LowerClassesPass : public LowerClassesBase<LowerClassesPass> {
LogicalResult dialectConversion(
Operation *op, const PathInfoTable &pathInfoTable,
const DenseMap<StringAttr, firrtl::ClassType> &classTypeTable);

// State to memoize repeated calls to shouldCreateClass.
DenseMap<FModuleLike, bool> shouldCreateClassMemo;
};

} // namespace
Expand Down Expand Up @@ -437,29 +440,45 @@ std::unique_ptr<mlir::Pass> circt::firrtl::createLowerClassesPass() {

// Predicate to check if a module-like needs a Class to be created.
bool LowerClassesPass::shouldCreateClass(FModuleLike moduleLike) {
if (isa<firrtl::ClassLike>(moduleLike.getOperation()))
// Memoize calls using the extra state.
auto it = shouldCreateClassMemo.find(moduleLike);
if (it != shouldCreateClassMemo.end())
return it->second;

if (isa<firrtl::ClassLike>(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<PropertyType>(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<FInstanceLike>())
for (auto result : op->getResults())
if (type_isa<PropertyType>(result.getType()))
moduleLike.getOperation()->getRegion(0).getOps<FInstanceLike>()) {
for (auto result : op->getResults()) {
if (type_isa<PropertyType>(result.getType())) {
shouldCreateClassMemo.insert({moduleLike, true});
return true;
}
}
}

shouldCreateClassMemo.insert({moduleLike, false});
return false;
}

Expand Down

0 comments on commit 13b9456

Please sign in to comment.