Skip to content

Disable lexical-lifetimes with copy-propagation. #40519

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
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
17 changes: 10 additions & 7 deletions include/swift/AST/SILOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@
namespace swift {

enum class LexicalLifetimesOption : uint8_t {
// Do not insert any lexical lifetimes.
// Do not insert lexical markers.
Off = 0,

// Insert lexical lifetimes in SILGen, but remove them before leaving Raw SIL.
Early,
// Insert lexical markers via lexical borrow scopes and the lexical flag on
// alloc_stacks produced from alloc_boxes, but strip them when lowering out of
// Raw SIL.
DiagnosticMarkersOnly,

// Insert lexical lifetimes and do not remove them until OSSA is lowered. This
// is experimental.
ExperimentalLate,
// Insert lexical markers and use them to lengthen object lifetime based on
// lexical scope.
On,
};

class SILModule;
Expand All @@ -59,7 +61,8 @@ class SILOptions {
bool RemoveRuntimeAsserts = false;

/// Enable experimental support for emitting defined borrow scopes.
LexicalLifetimesOption LexicalLifetimes = LexicalLifetimesOption::Early;
LexicalLifetimesOption LexicalLifetimes =
LexicalLifetimesOption::DiagnosticMarkersOnly;

/// Force-run SIL copy propagation to shorten object lifetime in whatever
/// optimization pipeline is currently used.
Expand Down
15 changes: 9 additions & 6 deletions include/swift/SIL/SILModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -911,14 +911,17 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SILModule &M){
inline bool SILOptions::supportsLexicalLifetimes(const SILModule &mod) const {
switch (mod.getStage()) {
case SILStage::Raw:
// In Raw SIL, we support lexical lifetimes as long as lexical lifetimes is
// not turned off all the way. This means lexical lifetimes is set to either
// early or experimental late.
// In raw SIL, lexical markers are used for diagnostics. These markers are
// present as long as the lexical lifetimes feature is not disabled
// entirely.
return LexicalLifetimes != LexicalLifetimesOption::Off;
case SILStage::Canonical:
// In Canonical SIL, we only support lexical lifetimes when in experimental
// late mode.
return LexicalLifetimes == LexicalLifetimesOption::ExperimentalLate;
// In Canonical SIL, lexical markers are used to ensure that object
// lifetimes do not get observably shortened from the end of a lexical
// scope. That behavior only occurs when lexical lifetimes is (fully)
// enabled. (When only diagnostic markers are enabled, the markers are
// stripped as part of lowering from raw to canonical SIL.)
return LexicalLifetimes == LexicalLifetimesOption::On;
case SILStage::Lowered:
// We do not support OSSA in Lowered SIL, so this is always false.
return false;
Expand Down
14 changes: 9 additions & 5 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1517,23 +1517,27 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
// -enable-copy-propagation implies -enable-lexical-lifetimes unless
// otherwise specified.
if (Args.hasArg(OPT_enable_copy_propagation))
Opts.LexicalLifetimes = LexicalLifetimesOption::ExperimentalLate;
Opts.LexicalLifetimes = LexicalLifetimesOption::On;

// -disable-copy-propagation implies -enable-lexical-lifetimes=false
if (Args.hasArg(OPT_disable_copy_propagation))
Opts.LexicalLifetimes = LexicalLifetimesOption::DiagnosticMarkersOnly;

// If move-only is enabled, always enable lexical lifetime as well. Move-only
// depends on lexical lifetimes.
if (Args.hasArg(OPT_enable_experimental_move_only))
Opts.LexicalLifetimes = LexicalLifetimesOption::ExperimentalLate;
Opts.LexicalLifetimes = LexicalLifetimesOption::On;

if (enableLexicalLifetimesFlag) {
if (*enableLexicalLifetimesFlag) {
Opts.LexicalLifetimes = LexicalLifetimesOption::ExperimentalLate;
Opts.LexicalLifetimes = LexicalLifetimesOption::On;
} else {
Opts.LexicalLifetimes = LexicalLifetimesOption::Early;
Opts.LexicalLifetimes = LexicalLifetimesOption::DiagnosticMarkersOnly;
}
}
if (enableLexicalBorrowScopesFlag) {
if (*enableLexicalBorrowScopesFlag) {
Opts.LexicalLifetimes = LexicalLifetimesOption::Early;
Opts.LexicalLifetimes = LexicalLifetimesOption::DiagnosticMarkersOnly;
} else {
Opts.LexicalLifetimes = LexicalLifetimesOption::Off;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Mandatory/LexicalLifetimeEliminator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class LexicalLifetimeEliminatorPass : public SILFunctionTransform {
// run this pass since we want lexical lifetimes to exist later in the
// pipeline.
if (fn->getModule().getOptions().LexicalLifetimes ==
LexicalLifetimesOption::ExperimentalLate)
LexicalLifetimesOption::On)
return;

bool madeChange = false;
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/PassManager/PassPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ static void addMandatoryDiagnosticOptPipeline(SILPassPipelinePlan &P) {

// Now that we have finished performing diagnostics that rely on lexical
// scopes, if lexical lifetimes are not enabled, eliminate lexical lfietimes.
if (Options.LexicalLifetimes != LexicalLifetimesOption::ExperimentalLate) {
if (Options.LexicalLifetimes != LexicalLifetimesOption::On) {
P.addLexicalLifetimeEliminator();
}

Expand Down
3 changes: 1 addition & 2 deletions lib/SILOptimizer/Transforms/SILMem2Reg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,7 @@ static bool shouldAddLexicalLifetime(AllocStackInst *asi) {
asi->getFunction()
->getModule()
.getASTContext()
.SILOpts.LexicalLifetimes ==
LexicalLifetimesOption::ExperimentalLate &&
.SILOpts.LexicalLifetimes == LexicalLifetimesOption::On &&
asi->isLexical() &&
!asi->getElementType().isTrivial(*asi->getFunction());
}
Expand Down
6 changes: 4 additions & 2 deletions tools/sil-opt/SILOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,9 @@ int main(int argc, char **argv) {
SILOpts.DisableCopyPropagation = DisableCopyPropagation;

if (EnableCopyPropagation)
SILOpts.LexicalLifetimes = LexicalLifetimesOption::ExperimentalLate;
SILOpts.LexicalLifetimes = LexicalLifetimesOption::On;
if (DisableCopyPropagation)
SILOpts.LexicalLifetimes = LexicalLifetimesOption::DiagnosticMarkersOnly;

// Enable lexical lifetimes if it is set or if experimental move only is
// enabled. This is because move only depends on lexical lifetimes being
Expand All @@ -541,7 +543,7 @@ int main(int argc, char **argv) {
exit(-1);
}
if (enableLexicalLifetimes)
SILOpts.LexicalLifetimes = LexicalLifetimesOption::ExperimentalLate;
SILOpts.LexicalLifetimes = LexicalLifetimesOption::On;
if (!EnableLexicalBorrowScopes)
SILOpts.LexicalLifetimes = LexicalLifetimesOption::Off;

Expand Down