@@ -78,8 +78,30 @@ enum class EnforceExclusivityMode {
78
78
DynamicOnly,
79
79
None,
80
80
};
81
+
82
+ enum class SILOptStrictConcurrency {
83
+ None = 0 ,
84
+ Complete,
85
+ Targeted,
86
+ Minimal,
87
+ };
88
+
81
89
} // end anonymous namespace
82
90
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
+
83
105
namespace llvm {
84
106
85
107
inline raw_ostream &
@@ -489,15 +511,19 @@ struct SILOptOptions {
489
511
cl::value_desc(" format" ), cl::init(" yaml" ));
490
512
491
513
// Strict Concurrency
492
- llvm::cl::opt<StrictConcurrency > StrictConcurrencyLevel =
493
- llvm::cl::opt<StrictConcurrency >(
514
+ llvm::cl::opt<SILOptStrictConcurrency > StrictConcurrencyLevel =
515
+ llvm::cl::opt<SILOptStrictConcurrency >(
494
516
" strict-concurrency" , cl::desc(" strict concurrency level" ),
495
- llvm::cl::values (clEnumValN(StrictConcurrency::Complete, " complete" ,
496
- " Enable complete strict concurrency" ),
497
- clEnumValN(StrictConcurrency::Targeted, " targeted" ,
498
- " Enable targeted strict concurrency" ),
499
- clEnumValN(StrictConcurrency::Minimal, " minimal" ,
500
- " 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" )));
501
527
502
528
llvm::cl::opt<bool >
503
529
EnableCxxInterop = llvm::cl::opt<bool >(" enable-experimental-cxx-interop" ,
@@ -693,15 +719,26 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
693
719
options.BypassResilienceChecks ;
694
720
Invocation.getDiagnosticOptions ().PrintDiagnosticNames =
695
721
options.DebugDiagnosticNames ;
722
+
696
723
for (auto &featureName : options.UpcomingFeatures ) {
697
- if (auto feature = getUpcomingFeature (featureName)) {
698
- Invocation.getLangOptions ().enableFeature (*feature);
699
- } else {
724
+ auto feature = getUpcomingFeature (featureName);
725
+ if (!feature) {
700
726
llvm::errs () << " error: unknown upcoming feature "
701
727
<< QuotedString (featureName) << " \n " ;
702
728
exit (-1 );
703
729
}
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);
704
740
}
741
+
705
742
for (auto &featureName : options.ExperimentalFeatures ) {
706
743
if (auto feature = getExperimentalFeature (featureName)) {
707
744
Invocation.getLangOptions ().enableFeature (*feature);
@@ -735,13 +772,26 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
735
772
736
773
Invocation.getLangOptions ().UnavailableDeclOptimizationMode =
737
774
options.UnavailableDeclOptimization ;
738
- 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)) {
739
779
Invocation.getLangOptions ().StrictConcurrencyLevel =
740
- options.StrictConcurrencyLevel ;
741
- if (options.StrictConcurrencyLevel == StrictConcurrency::Complete &&
742
- !options.DisableRegionBasedIsolationWithStrictConcurrency ) {
743
- Invocation.getLangOptions ().enableFeature (Feature::RegionBasedIsolation);
744
- }
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);
745
795
}
746
796
747
797
Invocation.getDiagnosticOptions ().VerifyMode =
0 commit comments