@@ -407,13 +407,19 @@ struct ModuleVisitor : public BaseVisitor {
407407 using slang::ast::MultiPortSymbol;
408408 using slang::ast::PortSymbol;
409409
410+ // Always operate on the canonical instance body if there is one.
411+ // This means any symbols we record will be the symbols from the
412+ // canonical body, which will match up with the symbols encountered
413+ // by analyses which visit the canonical bodies.
414+ const slang::ast::InstanceBodySymbol *body = getCanonicalBody (instNode);
415+
410416 // Interface instances are expanded inline into individual variable/net ops
411417 // rather than creating a moore.instance op.
412- auto defKind = instNode. body . getDefinition ().definitionKind ;
418+ auto defKind = body-> getDefinition ().definitionKind ;
413419 if (defKind == slang::ast::DefinitionKind::Interface)
414420 return expandInterfaceInstance (instNode);
415421
416- auto *moduleLowering = context.convertModuleHeader (&instNode. body );
422+ auto *moduleLowering = context.convertModuleHeader (body);
417423 if (!moduleLowering)
418424 return failure ();
419425 auto module = moduleLowering->op ;
@@ -952,11 +958,13 @@ LogicalResult Context::convertCompilation() {
952958 // Interfaces are not lowered as modules; they are expanded inline at each
953959 // use site, so skip them here.
954960 SmallVector<const slang::ast::InstanceSymbol *> topInstances;
955- for (auto *inst : root.topInstances )
956- if (inst->body .getDefinition ().definitionKind !=
961+ for (auto *inst : root.topInstances ) {
962+ const slang::ast::InstanceBodySymbol *body = getCanonicalBody (*inst);
963+ if (body->getDefinition ().definitionKind !=
957964 slang::ast::DefinitionKind::Interface)
958- if (!convertModuleHeader (&inst-> body ))
965+ if (!convertModuleHeader (body))
959966 return failure ();
967+ }
960968
961969 // Convert all the root module definitions.
962970 while (!moduleWorklist.empty ()) {
@@ -1006,10 +1014,6 @@ LogicalResult Context::convertCompilation() {
10061014 return success ();
10071015}
10081016
1009- // / Convert a module and its ports to an empty module op in the IR. Also adds
1010- // / the op to the worklist of module bodies to be lowered. This acts like a
1011- // / module "declaration", allowing instances to already refer to a module even
1012- // / before its body has been lowered.
10131017ModuleLowering *
10141018Context::convertModuleHeader (const slang::ast::InstanceBodySymbol *module ) {
10151019 using slang::ast::ArgumentDirection;
@@ -1024,53 +1028,8 @@ Context::convertModuleHeader(const slang::ast::InstanceBodySymbol *module) {
10241028 timeScale = module ->getTimeScale ().value_or (slang::TimeScale ());
10251029 llvm::scope_exit timeScaleGuard ([&] { timeScale = prevTimeScale; });
10261030
1027- auto parameters = module ->getParameters ();
1028- bool hasModuleSame = false ;
1029- // If there is already exist a module that has the same name with this
1030- // module ,has the same parent scope and has the same parameters we can
1031- // define this module is a duplicate module
1032- for (auto const &existingModule : modules) {
1033- if (module ->getDeclaringDefinition () ==
1034- existingModule.getFirst ()->getDeclaringDefinition ()) {
1035- auto moduleParameters = existingModule.getFirst ()->getParameters ();
1036- hasModuleSame = true ;
1037- for (auto it1 = parameters.begin (), it2 = moduleParameters.begin ();
1038- it1 != parameters.end () && it2 != moduleParameters.end ();
1039- it1++, it2++) {
1040- // Parameters size different
1041- if (it1 == parameters.end () || it2 == moduleParameters.end ()) {
1042- hasModuleSame = false ;
1043- break ;
1044- }
1045- const auto *para1 = (*it1)->symbol .as_if <ParameterSymbol>();
1046- const auto *para2 = (*it2)->symbol .as_if <ParameterSymbol>();
1047- // Parameters kind different
1048- if ((para1 == nullptr ) ^ (para2 == nullptr )) {
1049- hasModuleSame = false ;
1050- break ;
1051- }
1052- // Compare ParameterSymbol
1053- if (para1 != nullptr ) {
1054- hasModuleSame = para1->getValue () == para2->getValue ();
1055- }
1056- // Compare TypeParameterSymbol
1057- if (para1 == nullptr ) {
1058- auto para1Type = convertType (
1059- (*it1)->symbol .as <TypeParameterSymbol>().getTypeAlias ());
1060- auto para2Type = convertType (
1061- (*it2)->symbol .as <TypeParameterSymbol>().getTypeAlias ());
1062- hasModuleSame = para1Type == para2Type;
1063- }
1064- if (!hasModuleSame)
1065- break ;
1066- }
1067- if (hasModuleSame) {
1068- module = existingModule.first ;
1069- break ;
1070- }
1071- }
1072- }
1073-
1031+ // `module` is the canonical module body if it exists (i.e. deduplicated by
1032+ // slang).
10741033 auto &slot = modules[module ];
10751034 if (slot)
10761035 return slot.get ();
@@ -1273,8 +1232,6 @@ Context::convertModuleHeader(const slang::ast::InstanceBodySymbol *module) {
12731232 return &lowering;
12741233}
12751234
1276- // / Convert a module's body to the corresponding IR ops. The module op must have
1277- // / already been created earlier through a `convertModuleHeader` call.
12781235LogicalResult
12791236Context::convertModuleBody (const slang::ast::InstanceBodySymbol *module ) {
12801237 auto &lowering = *modules[module ];
0 commit comments