-
Notifications
You must be signed in to change notification settings - Fork 14k
[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
Conversation
@llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) ChangesWhen 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:
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
|
There was a problem hiding this 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.
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.
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.