[Support] Make isAncestor filterable

Add a function argument to the InstanceGraph::isAncestor member function
to allow this to skip over certain instances.  This is intended to be used
for things like checking if a module is an ancestor of another without
looking through binds.

This is currently not load bearing.

This may help with checks like #5530.

Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
This commit is contained in:
Schuyler Eldridge 2024-02-26 16:44:53 -05:00
parent 9a78825b45
commit 4695876d24
No known key found for this signature in database
GPG Key ID: 50C5E9936AAD536D
2 changed files with 9 additions and 3 deletions

View File

@ -210,7 +210,10 @@ public:
InstanceGraphNode *operator[](ModuleOpInterface op) { return lookup(op); }
/// Check if child is instantiated by a parent.
bool isAncestor(ModuleOpInterface child, ModuleOpInterface parent);
bool isAncestor(
ModuleOpInterface child, ModuleOpInterface parent,
llvm::function_ref<bool(InstanceRecord *)> skipInstance =
[](InstanceRecord *_) { return false; });
/// Get the node corresponding to the top-level module of a circuit.
virtual InstanceGraphNode *getTopLevelNode() { return nullptr; }

View File

@ -136,8 +136,9 @@ void InstanceGraph::replaceInstance(InstanceOpInterface inst,
}
}
bool InstanceGraph::isAncestor(ModuleOpInterface child,
ModuleOpInterface parent) {
bool InstanceGraph::isAncestor(
ModuleOpInterface child, ModuleOpInterface parent,
llvm::function_ref<bool(InstanceRecord *)> skipInstance) {
DenseSet<InstanceGraphNode *> seen;
SmallVector<InstanceGraphNode *> worklist;
auto *cn = lookup(child);
@ -149,6 +150,8 @@ bool InstanceGraph::isAncestor(ModuleOpInterface child,
if (node->getModule() == parent)
return true;
for (auto *use : node->uses()) {
if (skipInstance(use))
continue;
auto *mod = use->getParent();
if (!seen.count(mod)) {
seen.insert(mod);