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

[embedded] Add a flag to specify whether the module is leaf or library #72688

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/swift/AST/DiagnosticsFrontend.def
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,8 @@ ERROR(objc_with_embedded,none,
"Objective-C interoperability cannot be enabled with embedded Swift.", ())
ERROR(no_allocations_without_embedded,none,
"-no-allocations is only applicable with embedded Swift.", ())
ERROR(optimize_embedded_module_without_embedded,none,
"-optimize-embedded-module-as is only applicable with embedded Swift.", ())
Copy link
Member

Choose a reason for hiding this comment

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

should this be restricted to just embedded? couldn't we perhaps also use this leaf vs lib optimization in non-embedded cases too?

Copy link
Member

Choose a reason for hiding this comment

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

yes, it would give benefits in regular swift, too. Assuming build systems, like swifpm, support this option

ERROR(no_swift_sources_with_embedded,none,
"embedded swift cannot be enabled in a compiler built without Swift sources", ())

Expand Down
11 changes: 11 additions & 0 deletions include/swift/AST/SILOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ enum class CrossModuleOptimizationMode : uint8_t {
Everything = 3,
};

enum class ModuleRoleOption : uint8_t {
Unknown = 0,
Library = 1,
Leaf = 2,
};

class SILModule;

class SILOptions {
Expand Down Expand Up @@ -174,6 +180,11 @@ class SILOptions {
/// and go from OSSA to non-ownership SIL.
bool StopOptimizationBeforeLoweringOwnership = false;

/// Whether this module is definitely a leaf module (cannot have other
/// modules depending on it), definitely a library module (will have
/// dependents), or we don't know.
ModuleRoleOption ModuleRole = ModuleRoleOption::Unknown;

/// Do we always serialize SIL in OSSA form?
///
/// If this is disabled we do not serialize in OSSA form when optimizing.
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,10 @@ def AssumeSingleThreaded : Flag<["-"], "assume-single-threaded">,
HelpText<"Assume that code will be executed in a single-threaded "
"environment">;

def OptimizeEmbeddedModuleAs : Joined<["-"], "optimize-embedded-module-as=">,
Flags<[FrontendOption, NoInteractiveOption]>,
HelpText<"Specify whether the module is 'leaf' or 'library'">;

// Debug info options

def g_Group : OptionGroup<"<debug info options>">;
Expand Down
17 changes: 17 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2409,6 +2409,19 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
}
}

if (const Arg *A = Args.getLastArg(options::OPT_OptimizeEmbeddedModuleAs)) {
auto ModuleRole =
llvm::StringSwitch<std::optional<ModuleRoleOption>>(A->getValue())
.Case("leaf", ModuleRoleOption::Leaf)
.Case("library", ModuleRoleOption::Library)
.Default(std::nullopt);
if (ModuleRole)
Opts.ModuleRole = ModuleRole.value();
else
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
A->getAsString(Args), A->getValue());
}

Opts.EnableStackProtection =
Args.hasFlag(OPT_enable_stack_protector, OPT_disable_stack_protector,
Opts.EnableStackProtection);
Expand Down Expand Up @@ -3398,6 +3411,10 @@ bool CompilerInvocation::parseArgs(
Diags.diagnose(SourceLoc(), diag::no_allocations_without_embedded);
return true;
}
if (SILOpts.ModuleRole != ModuleRoleOption::Unknown) {
Diags.diagnose(SourceLoc(), diag::optimize_embedded_module_without_embedded);
return true;
}
}

// With Swift 6, enable @_spiOnly by default and forbid the old version.
Expand Down