Skip to content

Commit 3f7eaf6

Browse files
authored
Merge pull request swiftlang#73335 from gottesmm/pr-30cdb5ac62dd4f207eed5ee1192d173d966194ec
[sil-opt] Improvements to mąkę sil-opt behave like swift-frontend around language versions + some small other fixes
2 parents 7efc73e + 1eacf03 commit 3f7eaf6

File tree

3 files changed

+142
-24
lines changed

3 files changed

+142
-24
lines changed

lib/DriverTool/sil_opt_main.cpp

Lines changed: 108 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,27 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717

18-
#include "swift/Subsystems.h"
1918
#include "swift/AST/DiagnosticsFrontend.h"
2019
#include "swift/AST/SILOptions.h"
2120
#include "swift/Basic/FileTypes.h"
22-
#include "swift/Basic/LLVMInitialize.h"
2321
#include "swift/Basic/InitializeSwiftModules.h"
22+
#include "swift/Basic/LLVMInitialize.h"
2423
#include "swift/Basic/QuotedString.h"
2524
#include "swift/Frontend/DiagnosticVerifier.h"
2625
#include "swift/Frontend/Frontend.h"
2726
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
27+
#include "swift/IRGen/IRGenPublic.h"
28+
#include "swift/IRGen/IRGenSILPasses.h"
29+
#include "swift/Parse/ParseVersion.h"
2830
#include "swift/SIL/SILRemarkStreamer.h"
2931
#include "swift/SILOptimizer/Analysis/Analysis.h"
30-
#include "swift/SILOptimizer/PassManager/Passes.h"
3132
#include "swift/SILOptimizer/PassManager/PassManager.h"
33+
#include "swift/SILOptimizer/PassManager/Passes.h"
34+
#include "swift/Serialization/SerializationOptions.h"
3235
#include "swift/Serialization/SerializedModuleLoader.h"
3336
#include "swift/Serialization/SerializedSILLoader.h"
34-
#include "swift/Serialization/SerializationOptions.h"
37+
#include "swift/Subsystems.h"
3538
#include "swift/SymbolGraphGen/SymbolGraphOptions.h"
36-
#include "swift/IRGen/IRGenPublic.h"
37-
#include "swift/IRGen/IRGenSILPasses.h"
3839
#include "llvm/ADT/Statistic.h"
3940
#include "llvm/Support/CommandLine.h"
4041
#include "llvm/Support/FileSystem.h"
@@ -77,8 +78,30 @@ enum class EnforceExclusivityMode {
7778
DynamicOnly,
7879
None,
7980
};
81+
82+
enum class SILOptStrictConcurrency {
83+
None = 0,
84+
Complete,
85+
Targeted,
86+
Minimal,
87+
};
88+
8089
} // end anonymous namespace
8190

91+
std::optional<StrictConcurrency>
92+
convertSILOptToRawStrictConcurrencyLevel(SILOptStrictConcurrency level) {
93+
switch (level) {
94+
case SILOptStrictConcurrency::None:
95+
return {};
96+
case SILOptStrictConcurrency::Complete:
97+
return StrictConcurrency::Complete;
98+
case SILOptStrictConcurrency::Targeted:
99+
return StrictConcurrency::Targeted;
100+
case SILOptStrictConcurrency::Minimal:
101+
return StrictConcurrency::Minimal;
102+
}
103+
}
104+
82105
namespace llvm {
83106

84107
inline raw_ostream &
@@ -363,6 +386,12 @@ struct SILOptOptions {
363386
llvm::cl::desc("verify diagnostics against expected-"
364387
"{error|warning|note} annotations"));
365388

389+
llvm::cl::list<std::string> VerifyAdditionalPrefixes =
390+
llvm::cl::list<std::string>(
391+
"verify-additional-prefix",
392+
llvm::cl::desc("Check for diagnostics with the prefix "
393+
"expected-<PREFIX> as well as expected-"));
394+
366395
llvm::cl::opt<unsigned>
367396
AssertConfId = llvm::cl::opt<unsigned>("assert-conf-id", llvm::cl::Hidden,
368397
llvm::cl::init(0));
@@ -482,15 +511,19 @@ struct SILOptOptions {
482511
cl::value_desc("format"), cl::init("yaml"));
483512

484513
// Strict Concurrency
485-
llvm::cl::opt<StrictConcurrency> StrictConcurrencyLevel =
486-
llvm::cl::opt<StrictConcurrency>(
514+
llvm::cl::opt<SILOptStrictConcurrency> StrictConcurrencyLevel =
515+
llvm::cl::opt<SILOptStrictConcurrency>(
487516
"strict-concurrency", cl::desc("strict concurrency level"),
488-
llvm::cl::values(clEnumValN(StrictConcurrency::Complete, "complete",
489-
"Enable complete strict concurrency"),
490-
clEnumValN(StrictConcurrency::Targeted, "targeted",
491-
"Enable targeted strict concurrency"),
492-
clEnumValN(StrictConcurrency::Minimal, "minimal",
493-
"Enable minimal strict concurrency")));
517+
llvm::cl::init(SILOptStrictConcurrency::None),
518+
llvm::cl::values(
519+
clEnumValN(SILOptStrictConcurrency::Complete, "complete",
520+
"Enable complete strict concurrency"),
521+
clEnumValN(SILOptStrictConcurrency::Targeted, "targeted",
522+
"Enable targeted strict concurrency"),
523+
clEnumValN(SILOptStrictConcurrency::Minimal, "minimal",
524+
"Enable minimal strict concurrency"),
525+
clEnumValN(SILOptStrictConcurrency::None, "disabled",
526+
"Strict concurrency disabled")));
494527

495528
llvm::cl::opt<bool>
496529
EnableCxxInterop = llvm::cl::opt<bool>("enable-experimental-cxx-interop",
@@ -542,6 +575,11 @@ struct SILOptOptions {
542575
llvm::cl::opt<bool>(
543576
"disable-region-based-isolation-with-strict-concurrency",
544577
llvm::cl::init(false));
578+
579+
llvm::cl::opt<std::string> SwiftVersionString = llvm::cl::opt<std::string>(
580+
"swift-version",
581+
llvm::cl::desc(
582+
"The swift version to assume AST declarations correspond to"));
545583
};
546584

547585
/// Regular expression corresponding to the value given in one of the
@@ -641,6 +679,23 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
641679
// cache.
642680
Invocation.getClangImporterOptions().ModuleCachePath = options.ModuleCachePath;
643681
Invocation.setParseStdlib();
682+
if (options.SwiftVersionString.size()) {
683+
auto vers = VersionParser::parseVersionString(options.SwiftVersionString,
684+
SourceLoc(), nullptr);
685+
bool isValid = false;
686+
if (vers.has_value()) {
687+
if (auto effectiveVers = vers.value().getEffectiveLanguageVersion()) {
688+
Invocation.getLangOptions().EffectiveLanguageVersion =
689+
effectiveVers.value();
690+
isValid = true;
691+
}
692+
}
693+
if (!isValid) {
694+
llvm::errs() << "error: invalid swift version "
695+
<< options.SwiftVersionString << '\n';
696+
exit(-1);
697+
}
698+
}
644699
Invocation.getLangOptions().DisableAvailabilityChecking = true;
645700
Invocation.getLangOptions().EnableAccessControl = false;
646701
Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;
@@ -664,15 +719,26 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
664719
options.BypassResilienceChecks;
665720
Invocation.getDiagnosticOptions().PrintDiagnosticNames =
666721
options.DebugDiagnosticNames;
722+
667723
for (auto &featureName : options.UpcomingFeatures) {
668-
if (auto feature = getUpcomingFeature(featureName)) {
669-
Invocation.getLangOptions().enableFeature(*feature);
670-
} else {
724+
auto feature = getUpcomingFeature(featureName);
725+
if (!feature) {
671726
llvm::errs() << "error: unknown upcoming feature "
672727
<< QuotedString(featureName) << "\n";
673728
exit(-1);
674729
}
730+
731+
if (auto firstVersion = getFeatureLanguageVersion(*feature)) {
732+
if (Invocation.getLangOptions().isSwiftVersionAtLeast(*firstVersion)) {
733+
llvm::errs() << "error: upcoming feature " << QuotedString(featureName)
734+
<< " is already enabled as of Swift version "
735+
<< *firstVersion << '\n';
736+
exit(-1);
737+
}
738+
}
739+
Invocation.getLangOptions().enableFeature(*feature);
675740
}
741+
676742
for (auto &featureName : options.ExperimentalFeatures) {
677743
if (auto feature = getExperimentalFeature(featureName)) {
678744
Invocation.getLangOptions().enableFeature(*feature);
@@ -706,17 +772,35 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
706772

707773
Invocation.getLangOptions().UnavailableDeclOptimizationMode =
708774
options.UnavailableDeclOptimization;
709-
if (options.StrictConcurrencyLevel.hasArgStr()) {
775+
776+
// Enable strict concurrency if we have the feature specified or if it was
777+
// specified via a command line option to sil-opt.
778+
if (Invocation.getLangOptions().hasFeature(Feature::StrictConcurrency)) {
710779
Invocation.getLangOptions().StrictConcurrencyLevel =
711-
options.StrictConcurrencyLevel;
712-
if (options.StrictConcurrencyLevel == StrictConcurrency::Complete &&
713-
!options.DisableRegionBasedIsolationWithStrictConcurrency) {
714-
Invocation.getLangOptions().enableFeature(Feature::RegionBasedIsolation);
715-
}
780+
StrictConcurrency::Complete;
781+
} else if (auto level = convertSILOptToRawStrictConcurrencyLevel(
782+
options.StrictConcurrencyLevel)) {
783+
// If strict concurrency was enabled from the cmdline so the feature flag as
784+
// well.
785+
if (*level == StrictConcurrency::Complete)
786+
Invocation.getLangOptions().enableFeature(Feature::StrictConcurrency);
787+
Invocation.getLangOptions().StrictConcurrencyLevel = *level;
788+
}
789+
790+
// If we have strict concurrency set as a feature and were told to turn off
791+
// region based isolation... do so now.
792+
if (Invocation.getLangOptions().hasFeature(Feature::StrictConcurrency) &&
793+
!options.DisableRegionBasedIsolationWithStrictConcurrency) {
794+
Invocation.getLangOptions().enableFeature(Feature::RegionBasedIsolation);
716795
}
717796

718797
Invocation.getDiagnosticOptions().VerifyMode =
719-
options.VerifyMode ? DiagnosticOptions::Verify : DiagnosticOptions::NoVerify;
798+
options.VerifyMode ? DiagnosticOptions::Verify
799+
: DiagnosticOptions::NoVerify;
800+
for (auto &additionalPrefixes : options.VerifyAdditionalPrefixes) {
801+
Invocation.getDiagnosticOptions()
802+
.AdditionalDiagnosticVerifierPrefixes.push_back(additionalPrefixes);
803+
}
720804

721805
ClangImporterOptions &clangImporterOptions =
722806
Invocation.getClangImporterOptions();

test/sil-opt/swift-version.sil

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-sil-opt -transfer-non-sendable -strict-concurrency=complete -swift-version 5 %s -verify -verify-additional-prefix complete-
2+
// RUN: %target-sil-opt -transfer-non-sendable -swift-version 6 %s -verify -verify-additional-prefix tns-
3+
4+
// READ THIS: This test takes advantage of the semantics of concurrency to
5+
// validate that sil-opt can properly set the swift-version flag in a way that
6+
// the rest of the compiler can understand. Please do not add actual concurrency
7+
// code to this test and always keep it simple if additional code needs to be
8+
// added since we aren't actually trying to test concurrency here!
9+
10+
// REQUIRES: asserts
11+
// REQUIRES: concurrency
12+
13+
import Swift
14+
import _Concurrency
15+
16+
class NonSendableKlass {}
17+
18+
sil @transfer_to_main : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
19+
20+
sil [ossa] @test : $@convention(thin) @async (@guaranteed NonSendableKlass) -> () {
21+
bb0(%0 : @guaranteed $NonSendableKlass):
22+
%1 = function_ref @transfer_to_main : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
23+
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %1(%0) : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
24+
// expected-complete-warning @-1 {{task-isolated value of type 'NonSendableKlass' transferred to global actor '<null>'-isolated context; later accesses to value could race; this is an error in the Swift 6 language mode}}
25+
// expected-tns-error @-2 {{task-isolated value of type 'NonSendableKlass' transferred to global actor '<null>'-isolated context; later accesses to value could race}}
26+
%9999 = tuple ()
27+
return %9999 : $()
28+
}

test/sil-opt/upcoming-feature.sil

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: not %target-sil-opt %s -enable-upcoming-feature RegionBasedIsolation -swift-version 6 2>&1 | %FileCheck %s
2+
3+
// READ THIS: This test makes sure that we error if an upcoming feature is
4+
// enabled in a language mode where it is enabled by default.
5+
6+
// CHECK: error: upcoming feature "RegionBasedIsolation" is already enabled as of Swift version 6

0 commit comments

Comments
 (0)