From 4695876d24db133845328f71b0bf2d7e5a6199e4 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 26 Feb 2024 16:44:53 -0500 Subject: [PATCH] [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 --- include/circt/Support/InstanceGraph.h | 5 ++++- lib/Support/InstanceGraph.cpp | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/circt/Support/InstanceGraph.h b/include/circt/Support/InstanceGraph.h index 4b6dcf210d..40a8196e8f 100644 --- a/include/circt/Support/InstanceGraph.h +++ b/include/circt/Support/InstanceGraph.h @@ -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 skipInstance = + [](InstanceRecord *_) { return false; }); /// Get the node corresponding to the top-level module of a circuit. virtual InstanceGraphNode *getTopLevelNode() { return nullptr; } diff --git a/lib/Support/InstanceGraph.cpp b/lib/Support/InstanceGraph.cpp index e05c81b11d..cac7dc5786 100644 --- a/lib/Support/InstanceGraph.cpp +++ b/lib/Support/InstanceGraph.cpp @@ -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 skipInstance) { DenseSet seen; SmallVector 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);