Skip to content

[flang] Don't duplicate hermetic module file dependencies #143605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 11, 2025

Conversation

klausler
Copy link
Contributor

When emitting the modules on which a module depends under the -fhermetic-module-files options, eliminate duplicates by name rather than by symbol addresses. This way, when a dependent module is in the symbol table more than once due to the use of a nested hermetic module, it doesn't get emitted multiple times to the new module file.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:semantics labels Jun 10, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 10, 2025

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

Changes

When emitting the modules on which a module depends under the -fhermetic-module-files options, eliminate duplicates by name rather than by symbol addresses. This way, when a dependent module is in the symbol table more than once due to the use of a nested hermetic module, it doesn't get emitted multiple times to the new module file.


Full diff: https://github.com/llvm/llvm-project/pull/143605.diff

3 Files Affected:

  • (modified) flang/lib/Semantics/mod-file.cpp (+11-7)
  • (added) flang/test/Semantics/modfile76.F90 (+33)
  • (added) flang/test/Semantics/modfile77.F90 (+37)
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index a72641866aa15..9f9e9f5840456 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -143,18 +143,22 @@ void ModFileWriter::Write(const Symbol &symbol) {
   std::string path{context_.moduleDirectory() + '/' +
       ModFileName(symbol.name(), ancestorName, context_.moduleFileSuffix())};
 
-  UnorderedSymbolSet hermeticModules;
-  hermeticModules.insert(symbol);
+  std::set<std::string> hermeticModuleNames;
+  hermeticModuleNames.insert(symbol.name().ToString());
   UnorderedSymbolSet additionalModules;
   PutSymbols(DEREF(symbol.scope()),
       hermeticModuleFileOutput_ ? &additionalModules : nullptr);
   auto asStr{GetAsString(symbol)};
   while (!additionalModules.empty()) {
-    for (auto ref : UnorderedSymbolSet{std::move(additionalModules)}) {
-      if (hermeticModules.insert(*ref).second &&
-          !ref->owner().IsIntrinsicModules()) {
-        PutSymbols(DEREF(ref->scope()), &additionalModules);
-        asStr += GetAsString(*ref);
+    UnorderedSymbolSet nextPass{std::move(additionalModules)};
+    additionalModules.clear();
+    for (const Symbol &modSym : nextPass) {
+      if (!modSym.owner().IsIntrinsicModules() &&
+          hermeticModuleNames.find(modSym.name().ToString()) ==
+              hermeticModuleNames.end()) {
+        hermeticModuleNames.insert(modSym.name().ToString());
+        PutSymbols(DEREF(modSym.scope()), &additionalModules);
+        asStr += GetAsString(modSym);
       }
     }
   }
diff --git a/flang/test/Semantics/modfile76.F90 b/flang/test/Semantics/modfile76.F90
new file mode 100644
index 0000000000000..5b783e217e14d
--- /dev/null
+++ b/flang/test/Semantics/modfile76.F90
@@ -0,0 +1,33 @@
+!RUN: %flang -c -fhermetic-module-files -DWHICH=1 %s && %flang -c -fhermetic-module-files -DWHICH=2 %s && %flang -c -fhermetic-module-files %s && cat modfile76c.mod | FileCheck %s
+
+#if WHICH == 1
+module modfile76a
+  integer :: global_variable = 0
+end
+#elif WHICH == 2
+module modfile76b
+  use modfile76a
+ contains
+  subroutine test
+  end
+end
+#else
+module modfile76c
+  use modfile76a
+  use modfile76b
+end
+#endif
+
+!CHECK: module modfile76c
+!CHECK: use modfile76a,only:global_variable
+!CHECK: use modfile76b,only:test
+!CHECK: end
+!CHECK: module modfile76a
+!CHECK: integer(4)::global_variable
+!CHECK: end
+!CHECK: module modfile76b
+!CHECK: use modfile76a,only:global_variable
+!CHECK: contains
+!CHECK: subroutine test()
+!CHECK: end
+!CHECK: end
diff --git a/flang/test/Semantics/modfile77.F90 b/flang/test/Semantics/modfile77.F90
new file mode 100644
index 0000000000000..a82904ebbcc22
--- /dev/null
+++ b/flang/test/Semantics/modfile77.F90
@@ -0,0 +1,37 @@
+!RUN: %flang -c -fhermetic-module-files -DWHICH=1 %s && %flang -c -fhermetic-module-files -DWHICH=2 %s && %flang -c -fhermetic-module-files %s && cat modfile77c.mod | FileCheck %s
+
+#if WHICH == 1
+module modfile77a
+  interface gen
+    procedure proc
+  end interface
+ contains
+  subroutine proc
+    print *, 'ok'
+  end
+end
+#elif WHICH == 2
+module modfile77b
+  use modfile77a
+end
+#else
+module modfile77c
+  use modfile77a
+  use modfile77b
+end
+#endif
+
+!CHECK: module modfile77c
+!CHECK: use modfile77a,only:proc
+!CHECK: use modfile77a,only:gen
+!CHECK: interface gen
+!CHECK: end interface
+!CHECK: end
+!CHECK: module modfile77a
+!CHECK: interface gen
+!CHECK: procedure::proc
+!CHECK: end interface
+!CHECK: contains
+!CHECK: subroutine proc()
+!CHECK: end
+!CHECK: end

@klausler klausler requested a review from jeanPerier June 11, 2025 15:30
Copy link
Contributor

@akuhlens akuhlens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me.

When emitting the modules on which a module depends under the
-fhermetic-module-files options, eliminate duplicates by name rather
than by symbol addresses.  This way, when a dependent module is
in the symbol table more than once due to the use of a nested hermetic
module, it doesn't get emitted multiple times to the new module file.
@klausler klausler merged commit b42aef5 into llvm:main Jun 11, 2025
7 checks passed
@klausler klausler deleted the bug952-take2 branch June 11, 2025 20:13
tomtor pushed a commit to tomtor/llvm-project that referenced this pull request Jun 14, 2025
When emitting the modules on which a module depends under the
-fhermetic-module-files options, eliminate duplicates by name rather
than by symbol addresses. This way, when a dependent module is in the
symbol table more than once due to the use of a nested hermetic module,
it doesn't get emitted multiple times to the new module file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants