diff options
author | Peter Klausler <35819229+klausler@users.noreply.github.com> | 2024-07-11 14:02:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-11 14:02:44 -0700 |
commit | 65987954d9903e4fa3dfbf1ccac9d942d4af1fbb (patch) | |
tree | 88ef4bf668cd4edfb7d338ba3f8b502b600cae0b /flang/lib/Semantics/mod-file.cpp | |
parent | c9a4a27b9e490aff8d6ec21e55b22af0c882adb6 (diff) | |
download | llvm-65987954d9903e4fa3dfbf1ccac9d942d4af1fbb.zip llvm-65987954d9903e4fa3dfbf1ccac9d942d4af1fbb.tar.gz llvm-65987954d9903e4fa3dfbf1ccac9d942d4af1fbb.tar.bz2 |
[flang] Add -fhermetic-module-files (#98083)
Module files emitted by this Fortran compiler are valid Fortran source
files. Symbols that are USE-associated into modules are represented in
their module files with USE statements and special comments with hash
codes in them to ensure that those USE statements resolve to the same
modules that were used to build the module when its module file was
generated.
This scheme prevents unchecked module file growth in large applications
by not emitting USE-associated symbols redundantly. This problem can be
especially bad when derived type definitions must be repeated in the
module files of their clients, and the clients of those modules, and so
on. However, this scheme has the disadvantage that clients of modules
must be compiled with dependent modules in the module search path.
This new -fhermetic-module-files option causes module file output to be
free of dependences on any non-intrinsic module files; dependent modules
are instead emitted as part of the module file, rather than being
USE-associated. It is intended for top level library module files that
are shipped with binary libraries when it is not convenient to collect
and ship their dependent module files as well.
Fixes https://github.com/llvm/llvm-project/issues/97398.
Diffstat (limited to 'flang/lib/Semantics/mod-file.cpp')
-rw-r--r-- | flang/lib/Semantics/mod-file.cpp | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index d7f1494..a1c4c03 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -141,10 +141,26 @@ void ModFileWriter::Write(const Symbol &symbol) { auto ancestorName{ancestor ? ancestor->GetName().value().ToString() : ""s}; auto path{context_.moduleDirectory() + '/' + ModFileName(symbol.name(), ancestorName, context_.moduleFileSuffix())}; - PutSymbols(DEREF(symbol.scope())); + + UnorderedSymbolSet hermeticModules; + hermeticModules.insert(symbol); + 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); + } + } + } + ModuleCheckSumType checkSum; - if (std::error_code error{WriteFile( - path, GetAsString(symbol), checkSum, context_.debugModuleWriter())}) { + if (std::error_code error{ + WriteFile(path, asStr, checkSum, context_.debugModuleWriter())}) { context_.Say( symbol.name(), "Error writing %s: %s"_err_en_US, path, error.message()); } @@ -157,7 +173,7 @@ void ModFileWriter::WriteClosure(llvm::raw_ostream &out, const Symbol &symbol, !nonIntrinsicModulesWritten.insert(symbol).second) { return; } - PutSymbols(DEREF(symbol.scope())); + PutSymbols(DEREF(symbol.scope()), /*hermeticModules=*/nullptr); needsBuf_.clear(); // omit module checksums auto str{GetAsString(symbol)}; for (auto depRef : std::move(usedNonIntrinsicModules_)) { @@ -338,7 +354,8 @@ void ModFileWriter::PrepareRenamings(const Scope &scope) { } // Put out the visible symbols from scope. -void ModFileWriter::PutSymbols(const Scope &scope) { +void ModFileWriter::PutSymbols( + const Scope &scope, UnorderedSymbolSet *hermeticModules) { SymbolVector sorted; SymbolVector uses; auto &renamings{context_.moduleFileOutputRenamings()}; @@ -349,11 +366,16 @@ void ModFileWriter::PutSymbols(const Scope &scope) { // Write module files for dependencies first so that their // hashes are known. for (auto ref : modules) { - Write(*ref); - needs_ << ModHeader::need - << CheckSumString(ref->get<ModuleDetails>().moduleFileHash().value()) - << (ref->owner().IsIntrinsicModules() ? " i " : " n ") - << ref->name().ToString() << '\n'; + if (hermeticModules) { + hermeticModules->insert(*ref); + } else { + Write(*ref); + needs_ << ModHeader::need + << CheckSumString( + ref->get<ModuleDetails>().moduleFileHash().value()) + << (ref->owner().IsIntrinsicModules() ? " i " : " n ") + << ref->name().ToString() << '\n'; + } } std::string buf; // stuff after CONTAINS in derived type llvm::raw_string_ostream typeBindings{buf}; |