Skip to content

Commit f67b21a

Browse files
authored
Merge pull request #72867 from gottesmm/release/6.0-region-iso
[6.0][region-isolation] Enable region isolation when strict concurrency is enabled
2 parents a3f50ff + 1efd846 commit f67b21a

File tree

54 files changed

+1346
-883
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1346
-883
lines changed

cmake/modules/AddSwiftUnittests.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ function(add_swift_unittest test_dirname)
111111
endif()
112112
endif()
113113

114+
is_build_type_with_debuginfo("${CMAKE_BUILD_TYPE}" HAS_DEBUG_INFO)
115+
target_compile_options("${test_dirname}" PRIVATE $<$<BOOL:${HAS_DEBUG_INFO}>:-g>)
116+
114117
file(RELATIVE_PATH relative_lib_path "${CMAKE_CURRENT_BINARY_DIR}" "${SWIFT_LIBRARY_OUTPUT_INTDIR}")
115118

116119
if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_DARWIN_PLATFORMS)

include/swift/AST/ActorIsolation.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ class ActorIsolation {
111111

112112
static ActorIsolation forActorInstanceSelf(ValueDecl *decl);
113113

114+
/// Create an ActorIsolation appropriate for a type that is self.
115+
static ActorIsolation forActorInstanceSelf(NominalTypeDecl *decl);
116+
114117
static ActorIsolation forActorInstanceParameter(NominalTypeDecl *actor,
115118
unsigned parameterIndex) {
116119
return ActorIsolation(ActorInstance, actor, parameterIndex + 1);

include/swift/AST/DiagnosticsSIL.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ ERROR(bridging_objcbridgeable_broken,none,
4646
ERROR(sil_function_redefinition,none,
4747
"multiple definitions of symbol '%0'",
4848
(StringRef))
49+
NOTE(sil_function_redefinition_note,none,
50+
"other definition here",
51+
())
4952

5053
ERROR(invalid_sil_builtin,none,
5154
"INTERNAL ERROR: invalid use of builtin: %0",

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,4 +1332,9 @@ def disable_experimental_parser_round_trip : Flag<["-"],
13321332
"disable-experimental-parser-round-trip">,
13331333
HelpText<"Disable round trip through the new swift parser">;
13341334

1335+
def disable_strict_concurrency_region_based_isolation : Flag<["-"],
1336+
"disable-region-based-isolation-with-strict-concurrency">,
1337+
HelpText<"Disable region based isolation when running with strict concurrency enabled. Only enabled with asserts">,
1338+
Flags<[HelpHidden]>;
1339+
13351340
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

include/swift/SIL/SILFunction.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ class SILFunction
348348
unsigned BlockListChangeIdx = 0;
349349

350350
/// The isolation of this function.
351-
std::optional<ActorIsolation> actorIsolation;
351+
ActorIsolation actorIsolation = ActorIsolation::forUnspecified();
352352

353353
/// The function's bare attribute. Bare means that the function is SIL-only
354354
/// and does not require debug info.
@@ -1374,9 +1374,7 @@ class SILFunction
13741374
actorIsolation = newActorIsolation;
13751375
}
13761376

1377-
std::optional<ActorIsolation> getActorIsolation() const {
1378-
return actorIsolation;
1379-
}
1377+
ActorIsolation getActorIsolation() const { return actorIsolation; }
13801378

13811379
//===--------------------------------------------------------------------===//
13821380
// Block List Access

include/swift/SILOptimizer/Analysis/RegionAnalysis.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ class regionanalysisimpl::TrackableValueState {
162162
}
163163

164164
ActorIsolation getActorIsolation() const {
165-
return regionInfo.getActorIsolation().value();
165+
return regionInfo.getActorIsolation();
166166
}
167167

168168
void mergeIsolationRegionInfo(SILIsolationInfo newRegionInfo) {

include/swift/SILOptimizer/Utils/PartitionUtils.h

Lines changed: 24 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,19 @@ class SILIsolationInfo {
110110
// clang-format off
111111
std::variant<
112112
// Used for actor isolated when we have ActorIsolation info from the AST.
113-
std::optional<ActorIsolation>,
114-
// Used for actor isolation when we infer the actor at the SIL level.
115-
NominalTypeDecl *,
113+
ActorIsolation,
116114
// The task isolated parameter when we find a task isolated value.
117115
SILValue
118116
> data;
119117
// clang-format on
120118

121-
SILIsolationInfo(Kind kind, std::optional<ActorIsolation> actorIsolation)
122-
: kind(kind), data(actorIsolation) {}
123-
SILIsolationInfo(Kind kind, NominalTypeDecl *decl) : kind(kind), data(decl) {}
119+
SILIsolationInfo(ActorIsolation actorIsolation)
120+
: kind(Actor), data(actorIsolation) {}
124121

125122
SILIsolationInfo(Kind kind, SILValue value) : kind(kind), data(value) {}
126123

124+
SILIsolationInfo(Kind kind) : kind(kind), data() {}
125+
127126
public:
128127
SILIsolationInfo() : kind(Kind::Unknown), data() {}
129128

@@ -146,18 +145,11 @@ class SILIsolationInfo {
146145

147146
void printForDiagnostics(llvm::raw_ostream &os) const;
148147

149-
std::optional<ActorIsolation> getActorIsolation() const {
148+
ActorIsolation getActorIsolation() const {
150149
assert(kind == Actor);
151-
assert(std::holds_alternative<std::optional<ActorIsolation>>(data) &&
150+
assert(std::holds_alternative<ActorIsolation>(data) &&
152151
"Doesn't have an actor isolation?!");
153-
return std::get<std::optional<ActorIsolation>>(data);
154-
}
155-
156-
NominalTypeDecl *getActorInstance() const {
157-
assert(kind == Actor);
158-
assert(std::holds_alternative<NominalTypeDecl *>(data) &&
159-
"Doesn't have an actor instance?!");
160-
return std::get<NominalTypeDecl *>(data);
152+
return std::get<ActorIsolation>(data);
161153
}
162154

163155
SILValue getTaskIsolatedValue() const {
@@ -167,45 +159,35 @@ class SILIsolationInfo {
167159
return std::get<SILValue>(data);
168160
}
169161

170-
bool hasActorIsolation() const {
171-
return kind == Actor &&
172-
std::holds_alternative<std::optional<ActorIsolation>>(data);
173-
}
174-
175-
bool hasActorInstance() const {
176-
return kind == Actor && std::holds_alternative<NominalTypeDecl *>(data);
177-
}
162+
bool hasActorIsolation() const { return kind == Actor; }
178163

179164
bool hasTaskIsolatedValue() const {
180165
return kind == Task && std::holds_alternative<SILValue>(data);
181166
}
182167

183-
/// If we actually have an actor decl, return that. Otherwise, see if we have
184-
/// an actor isolation if we can find one in there. Returns nullptr if we
185-
/// fail.
186-
NominalTypeDecl *tryInferActorDecl() const;
187-
188168
[[nodiscard]] SILIsolationInfo merge(SILIsolationInfo other) const;
189169

190170
SILIsolationInfo withActorIsolated(ActorIsolation isolation) {
191171
return SILIsolationInfo::getActorIsolated(isolation);
192172
}
193173

194-
static SILIsolationInfo getDisconnected() { return {Kind::Disconnected, {}}; }
174+
static SILIsolationInfo getDisconnected() { return {Kind::Disconnected}; }
195175

196176
static SILIsolationInfo getActorIsolated(ActorIsolation actorIsolation) {
197-
return {Kind::Actor, actorIsolation};
177+
return {actorIsolation};
198178
}
199179

200-
/// Sometimes we may have something that is actor isolated or that comes from
201-
/// a type. First try getActorIsolation and otherwise, just use the type.
202-
static SILIsolationInfo getActorIsolated(NominalTypeDecl *nomDecl) {
203-
auto actorIsolation = swift::getActorIsolation(nomDecl);
204-
if (actorIsolation.isActorIsolated())
205-
return getActorIsolated(actorIsolation);
206-
if (nomDecl->isActor())
207-
return {Kind::Actor, nomDecl};
208-
return SILIsolationInfo();
180+
static SILIsolationInfo getActorIsolated(NominalTypeDecl *typeDecl) {
181+
if (typeDecl->isActor())
182+
return {ActorIsolation::forActorInstanceSelf(typeDecl)};
183+
auto isolation = swift::getActorIsolation(typeDecl);
184+
if (isolation.isGlobalActor())
185+
return {isolation};
186+
return {};
187+
}
188+
189+
static SILIsolationInfo getGlobalActorIsolated(Type globalActorType) {
190+
return getActorIsolated(ActorIsolation::forGlobalActor(globalActorType));
209191
}
210192

211193
static SILIsolationInfo getTaskIsolated(SILValue value) {
@@ -901,8 +883,8 @@ struct PartitionOpEvaluator {
901883
// our transferring operand. If so, we can squelch this.
902884
if (auto functionIsolation =
903885
transferringOp->getUser()->getFunction()->getActorIsolation()) {
904-
if (functionIsolation->isActorIsolated() &&
905-
SILIsolationInfo::getActorIsolated(*functionIsolation) ==
886+
if (functionIsolation.isActorIsolated() &&
887+
SILIsolationInfo::getActorIsolated(functionIsolation) ==
906888
SILIsolationInfo::get(transferringOp->getUser()))
907889
return;
908890
}

lib/AST/Decl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11387,6 +11387,10 @@ ActorIsolation::forActorInstanceSelf(ValueDecl *decl) {
1138711387
return ActorIsolation(ActorInstance, dc->getSelfNominalTypeDecl(), 0);
1138811388
}
1138911389

11390+
ActorIsolation ActorIsolation::forActorInstanceSelf(NominalTypeDecl *selfDecl) {
11391+
return ActorIsolation(ActorInstance, selfDecl, 0);
11392+
}
11393+
1139011394
NominalTypeDecl *ActorIsolation::getActor() const {
1139111395
assert(getKind() == ActorInstance ||
1139211396
getKind() == GlobalActor);

lib/DriverTool/sil_opt_main.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,11 @@ struct SILOptOptions {
534534
llvm::cl::list<std::string> ClangXCC = llvm::cl::list<std::string>(
535535
"Xcc",
536536
llvm::cl::desc("option to pass to clang"));
537+
538+
llvm::cl::opt<bool> DisableRegionBasedIsolationWithStrictConcurrency =
539+
llvm::cl::opt<bool>(
540+
"disable-region-based-isolation-with-strict-concurrency",
541+
llvm::cl::init(false));
537542
};
538543

539544
/// Regular expression corresponding to the value given in one of the
@@ -698,9 +703,14 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
698703

699704
Invocation.getLangOptions().UnavailableDeclOptimizationMode =
700705
options.UnavailableDeclOptimization;
701-
if (options.StrictConcurrencyLevel.hasArgStr())
706+
if (options.StrictConcurrencyLevel.hasArgStr()) {
702707
Invocation.getLangOptions().StrictConcurrencyLevel =
703708
options.StrictConcurrencyLevel;
709+
if (options.StrictConcurrencyLevel == StrictConcurrency::Complete &&
710+
!options.DisableRegionBasedIsolationWithStrictConcurrency) {
711+
Invocation.getLangOptions().enableFeature(Feature::RegionBasedIsolation);
712+
}
713+
}
704714

705715
Invocation.getDiagnosticOptions().VerifyMode =
706716
options.VerifyMode ? DiagnosticOptions::Verify : DiagnosticOptions::NoVerify;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,16 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
10601060
if (Opts.StrictConcurrencyLevel == StrictConcurrency::Complete) {
10611061
Opts.enableFeature(Feature::IsolatedDefaultValues);
10621062
Opts.enableFeature(Feature::GlobalConcurrency);
1063+
1064+
// If asserts are enabled, allow for region based isolation to be disabled
1065+
// with a flag. This is intended only to be used with tests.
1066+
bool enableRegionIsolation = true;
1067+
#ifndef NDEBUG
1068+
enableRegionIsolation =
1069+
!Args.hasArg(OPT_disable_strict_concurrency_region_based_isolation);
1070+
#endif
1071+
if (enableRegionIsolation)
1072+
Opts.enableFeature(Feature::RegionBasedIsolation);
10631073
}
10641074

10651075
Opts.WarnImplicitOverrides =

0 commit comments

Comments
 (0)