12using namespace ImportVerilog;
17 :
public slang::ast::ASTVisitor<InstBodyVisitor,
21 Context &context,
const slang::ast::Symbol &outermostModule,
22 DenseSet<const slang::ast::InstanceBodySymbol *> &visitedBodies)
23 : context(context), outermostModule(outermostModule),
24 visitedBodies(visitedBodies) {}
26 void handle(
const slang::ast::InstanceSymbol &instNode) {
27 traverseInstanceBody(context, instNode, visitedBodies);
30 for (
auto *conn : instNode.getPortConnections())
31 if (auto *connExpr =
conn->getExpression())
32 connExpr->visit(*this);
35 void handle(
const slang::ast::HierarchicalValueExpression &expr) {
36 auto builder = context.builder;
37 auto *currentInstBody =
38 expr.symbol.getParentScope()->getContainingInstance();
39 auto *outermostInstBody =
40 outermostModule.as_if<slang::ast::InstanceBodySymbol>();
44 if (currentInstBody == outermostInstBody)
52 if (expr.ref.isViaIfacePort())
55 auto hierName = builder.getStringAttr(expr.symbol.name);
56 const slang::ast::InstanceBodySymbol *parentInstBody =
nullptr;
59 std::function<void(
const slang::ast::InstanceBodySymbol *,
bool)>
60 collectHierarchicalPaths = [&](
auto sym,
bool isUpward) {
63 if (context.hierPaths.contains(sym)) {
64 for (
auto &path : context.hierPaths[sym]) {
65 if (path.hierName == hierName) {
73 context.hierPaths[sym].push_back(
76 isUpward ? slang::ast::ArgumentDirection::Out
77 : slang::ast::ArgumentDirection::In,
82 if (!llvm::is_contained(existing->
valueSyms, &expr.symbol))
83 existing->
valueSyms.push_back(&expr.symbol);
89 sym->parentInstance->getParentScope()->getContainingInstance();
95 if (parentInstBody && parentInstBody != outermostInstBody) {
97 builder.getStringAttr(sym->parentInstance->name +
98 llvm::Twine(
".") + hierName.getValue());
99 collectHierarchicalPaths(parentInstBody, isUpward);
102 if (parentInstBody && parentInstBody != currentInstBody)
103 collectHierarchicalPaths(parentInstBody, isUpward);
108 auto *tempInstBody = currentInstBody;
109 while (tempInstBody) {
110 tempInstBody = tempInstBody->parentInstance->getParentScope()
111 ->getContainingInstance();
112 if (tempInstBody == outermostInstBody) {
113 collectHierarchicalPaths(currentInstBody,
true);
118 hierName = builder.getStringAttr(currentInstBody->parentInstance->name +
119 llvm::Twine(
".") + hierName.getValue());
120 collectHierarchicalPaths(outermostInstBody,
false);
124 const slang::ast::Symbol &outermostModule;
125 DenseSet<const slang::ast::InstanceBodySymbol *> &visitedBodies;
127 static void traverseInstanceBody(
128 Context &context,
const slang::ast::InstanceSymbol &symbol,
129 DenseSet<const slang::ast::InstanceBodySymbol *> &visitedBodies) {
131 if (visitedBodies.insert(body).second) {
132 for (
auto &member : body->members()) {
133 auto &outermostModule = member.getParentScope()->asSymbol();
134 InstBodyVisitor visitor(context, outermostModule, visitedBodies);
135 member.visit(visitor);
143void Context::traverseInstanceBody(
const slang::ast::InstanceSymbol &symbol) {
146 DenseSet<const slang::ast::InstanceBodySymbol *> visitedBodies;
147 InstBodyVisitor::traverseInstanceBody(*
this, symbol, visitedBodies);
const slang::ast::InstanceBodySymbol * getCanonicalBody(const slang::ast::InstanceSymbol &inst)
Get the slang canonical body for the given instance, if there is one.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
A helper class to facilitate the conversion from a Slang AST to MLIR operations.
Hierarchical path information.
llvm::SmallVector< const slang::ast::ValueSymbol *, 2 > valueSyms
The value symbols associated with this hierarchical path.