Skip to content
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

[flang] Add -fhermetic-module-files #98083

Merged
merged 1 commit into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -6667,6 +6667,9 @@ defm stack_arrays : BoolOptionWithoutMarshalling<"f", "stack-arrays",
defm loop_versioning : BoolOptionWithoutMarshalling<"f", "version-loops-for-stride",
PosFlag<SetTrue, [], [ClangOption], "Create unit-strided versions of loops">,
NegFlag<SetFalse, [], [ClangOption], "Do not create unit-strided loops (default)">>;

def fhermetic_module_files : Flag<["-"], "fhermetic-module-files">, Group<f_Group>,
HelpText<"Emit hermetic module files (no nested USE association)">;
} // let Visibility = [FC1Option, FlangOption]

def J : JoinedOrSeparate<["-"], "J">,
Expand Down
32 changes: 20 additions & 12 deletions clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,26 @@ static void addDashXForInput(const ArgList &Args, const InputInfo &Input,

void Flang::addFortranDialectOptions(const ArgList &Args,
ArgStringList &CmdArgs) const {
Args.addAllArgs(
CmdArgs, {options::OPT_ffixed_form, options::OPT_ffree_form,
options::OPT_ffixed_line_length_EQ, options::OPT_fopenacc,
options::OPT_finput_charset_EQ, options::OPT_fimplicit_none,
options::OPT_fno_implicit_none, options::OPT_fbackslash,
options::OPT_fno_backslash, options::OPT_flogical_abbreviations,
options::OPT_fno_logical_abbreviations,
options::OPT_fxor_operator, options::OPT_fno_xor_operator,
options::OPT_falternative_parameter_statement,
options::OPT_fdefault_real_8, options::OPT_fdefault_integer_8,
options::OPT_fdefault_double_8, options::OPT_flarge_sizes,
options::OPT_fno_automatic});
Args.addAllArgs(CmdArgs, {options::OPT_ffixed_form,
options::OPT_ffree_form,
options::OPT_ffixed_line_length_EQ,
options::OPT_fopenacc,
options::OPT_finput_charset_EQ,
options::OPT_fimplicit_none,
options::OPT_fno_implicit_none,
options::OPT_fbackslash,
options::OPT_fno_backslash,
options::OPT_flogical_abbreviations,
options::OPT_fno_logical_abbreviations,
options::OPT_fxor_operator,
options::OPT_fno_xor_operator,
options::OPT_falternative_parameter_statement,
options::OPT_fdefault_real_8,
options::OPT_fdefault_integer_8,
options::OPT_fdefault_double_8,
options::OPT_flarge_sizes,
options::OPT_fno_automatic,
options::OPT_fhermetic_module_files});
}

void Flang::addPreprocessingOptions(const ArgList &Args,
Expand Down
9 changes: 9 additions & 0 deletions flang/include/flang/Frontend/CompilerInvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class CompilerInvocation : public CompilerInvocationBase {
std::string moduleFileSuffix = ".mod";

bool debugModuleDir = false;
bool hermeticModuleFileOutput = false;

bool warnAsErr = false;

Expand Down Expand Up @@ -179,6 +180,11 @@ class CompilerInvocation : public CompilerInvocationBase {
bool &getDebugModuleDir() { return debugModuleDir; }
const bool &getDebugModuleDir() const { return debugModuleDir; }

bool &getHermeticModuleFileOutput() { return hermeticModuleFileOutput; }
const bool &getHermeticModuleFileOutput() const {
return hermeticModuleFileOutput;
}

bool &getWarnAsErr() { return warnAsErr; }
const bool &getWarnAsErr() const { return warnAsErr; }

Expand Down Expand Up @@ -244,6 +250,9 @@ class CompilerInvocation : public CompilerInvocationBase {
}

void setDebugModuleDir(bool flag) { debugModuleDir = flag; }
void setHermeticModuleFileOutput(bool flag) {
hermeticModuleFileOutput = flag;
}

void setWarnAsErr(bool flag) { warnAsErr = flag; }

Expand Down
10 changes: 6 additions & 4 deletions flang/include/flang/Semantics/semantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,11 @@ class SemanticsContext {

class Semantics {
public:
explicit Semantics(SemanticsContext &context, parser::Program &program,
bool debugModuleWriter = false)
: context_{context}, program_{program} {
context.set_debugModuleWriter(debugModuleWriter);
explicit Semantics(SemanticsContext &context, parser::Program &program)
: context_{context}, program_{program} {}
Semantics &set_hermeticModuleFileOutput(bool yes = true) {
hermeticModuleFileOutput_ = yes;
return *this;
}

SemanticsContext &context() const { return context_; }
Expand All @@ -326,6 +327,7 @@ class Semantics {
private:
SemanticsContext &context_;
parser::Program &program_;
bool hermeticModuleFileOutput_{false};
};

// Base class for semantics checkers.
Expand Down
5 changes: 5 additions & 0 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,11 @@ static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
res.setDebugModuleDir(true);
}

// -fhermetic-module-files option
if (args.hasArg(clang::driver::options::OPT_fhermetic_module_files)) {
res.setHermeticModuleFileOutput(true);
}

// -module-suffix
if (const auto *moduleSuffix =
args.getLastArg(clang::driver::options::OPT_module_suffix)) {
Expand Down
7 changes: 5 additions & 2 deletions flang/lib/Frontend/FrontendAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,14 @@ bool FrontendAction::runSemanticChecks() {
// so that they are merged and all printed in order.
auto &semanticsCtx{ci.getSemanticsContext()};
semanticsCtx.messages().Annex(std::move(ci.getParsing().messages()));
semanticsCtx.set_debugModuleWriter(ci.getInvocation().getDebugModuleDir());

// Prepare semantics
ci.setSemantics(std::make_unique<Fortran::semantics::Semantics>(
semanticsCtx, *parseTree, ci.getInvocation().getDebugModuleDir()));
ci.setSemantics(std::make_unique<Fortran::semantics::Semantics>(semanticsCtx,
*parseTree));
auto &semantics = ci.getSemantics();
semantics.set_hermeticModuleFileOutput(
ci.getInvocation().getHermeticModuleFileOutput());

// Run semantic checks
semantics.Perform();
Expand Down
42 changes: 32 additions & 10 deletions flang/lib/Semantics/mod-file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand All @@ -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_)) {
Expand Down Expand Up @@ -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()};
Expand All @@ -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};
Expand Down
7 changes: 6 additions & 1 deletion flang/lib/Semantics/mod-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class ModFileWriter {
bool WriteAll();
void WriteClosure(llvm::raw_ostream &, const Symbol &,
UnorderedSymbolSet &nonIntrinsicModulesWritten);
ModFileWriter &set_hermeticModuleFileOutput(bool yes = true) {
hermeticModuleFileOutput_ = yes;
return *this;
}

private:
SemanticsContext &context_;
Expand All @@ -57,13 +61,14 @@ class ModFileWriter {
llvm::raw_string_ostream decls_{declsBuf_};
llvm::raw_string_ostream contains_{containsBuf_};
bool isSubmodule_{false};
bool hermeticModuleFileOutput_{false};

void WriteAll(const Scope &);
void WriteOne(const Scope &);
void Write(const Symbol &);
std::string GetAsString(const Symbol &);
void PrepareRenamings(const Scope &);
void PutSymbols(const Scope &);
void PutSymbols(const Scope &, UnorderedSymbolSet *hermetic);
// Returns true if a derived type with bindings and "contains" was emitted
bool PutComponents(const Symbol &);
void PutSymbol(llvm::raw_ostream &, const Symbol &);
Expand Down
4 changes: 3 additions & 1 deletion flang/lib/Semantics/semantics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,9 @@ bool Semantics::Perform() {
CanonicalizeCUDA(program_) &&
CanonicalizeDirectives(context_.messages(), program_) &&
PerformStatementSemantics(context_, program_) &&
ModFileWriter{context_}.WriteAll();
ModFileWriter{context_}
.set_hermeticModuleFileOutput(hermeticModuleFileOutput_)
.WriteAll();
}

void Semantics::EmitMessages(llvm::raw_ostream &os) {
Expand Down
53 changes: 53 additions & 0 deletions flang/test/Semantics/modfile65.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
! RUN: %python %S/test_modfile.py %s %flang_fc1 -fhermetic-module-files
module m1
integer, parameter :: n = 123
end

module m2
use m1
end

module m3
use m1, m => n
end

module m4
use m2
use m3
end

!Expect: m1.mod
!module m1
!integer(4),parameter::n=123_4
!end

!Expect: m2.mod
!module m2
!use m1,only:n
!end
!module m1
!integer(4),parameter::n=123_4
!end

!Expect: m3.mod
!module m3
!use m1,only:m=>n
!end
!module m1
!integer(4),parameter::n=123_4
!end

!Expect: m4.mod
!module m4
!use m2,only:n
!use m3,only:m
!end
!module m2
!use m1,only:n
!end
!module m3
!use m1,only:m=>n
!end
!module m1
!integer(4),parameter::n=123_4
!end
Loading