Skip to content

Commit 19a7fa6

Browse files
committed
[SILGen] Put actor data-race checking behind a flag.
Introduce flags `-enable-actor-data-race-checks` and `-disable-actor-data-race-checks` to enable/disable emission of code that checks that we are on the correct actor. Default to `false` for now but make it easy to enable in the future.
1 parent 4d6f07e commit 19a7fa6

File tree

7 files changed

+29
-6
lines changed

7 files changed

+29
-6
lines changed

include/swift/AST/SILOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ class SILOptions {
6565
/// It is turned off by default.
6666
bool EnableSpeculativeDevirtualization = false;
6767

68+
/// Controls whether to emit actor data-race checks.
69+
bool EnableActorDataRaceChecks = false;
70+
6871
/// Should we run any SIL performance optimizations
6972
///
7073
/// Useful when you want to enable -O LLVM opts but not -O SIL opts.

include/swift/Option/Options.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,16 @@ def warn_swift3_objc_inference_minimal :
607607
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
608608
HelpText<"Warn about deprecated @objc inference in Swift 3 based on direct uses of the Objective-C entrypoint">;
609609

610+
def enable_actor_data_race_checks :
611+
Flag<["-"], "enable-actor-data-race-checks">,
612+
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
613+
HelpText<"Emit runtime checks for actor data races">;
614+
615+
def disable_actor_data_race_checks :
616+
Flag<["-"], "disable-actor-data-race-checks">,
617+
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
618+
HelpText<"Disable runtime checks for actor data races">;
619+
610620
def warn_implicit_overrides :
611621
Flag<["-"], "warn-implicit-overrides">,
612622
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,

lib/Driver/ToolChains.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
218218
inputArgs.AddLastArg(arguments,
219219
options::OPT_warn_swift3_objc_inference_minimal,
220220
options::OPT_warn_swift3_objc_inference_complete);
221+
inputArgs.AddLastArg(arguments,
222+
options::OPT_enable_actor_data_race_checks,
223+
options::OPT_disable_actor_data_race_checks);
221224
inputArgs.AddLastArg(arguments, options::OPT_warn_concurrency);
222225
inputArgs.AddLastArg(arguments, options::OPT_warn_implicit_overrides);
223226
inputArgs.AddLastArg(arguments, options::OPT_typo_correction_limit);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,9 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
12221222
Opts.EnableOSSAModules |= Args.hasArg(OPT_enable_ossa_modules);
12231223
Opts.EnableOSSAOptimizations &= !Args.hasArg(OPT_disable_ossa_opts);
12241224
Opts.EnableSpeculativeDevirtualization |= Args.hasArg(OPT_enable_spec_devirt);
1225+
Opts.EnableActorDataRaceChecks |= Args.hasFlag(
1226+
OPT_enable_actor_data_race_checks,
1227+
OPT_disable_actor_data_race_checks, /*default=*/false);
12251228
Opts.DisableSILPerfOptimizations |= Args.hasArg(OPT_disable_sil_perf_optzns);
12261229
Opts.CrossModuleOptimization |= Args.hasArg(OPT_CrossModuleOptimization);
12271230
Opts.VerifyAll |= Args.hasArg(OPT_sil_verify_all);

lib/SILGen/SILGenProlog.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,10 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
492492

493493
// Initialize ExpectedExecutor if the function is an actor-isolated
494494
// function or closure.
495+
bool wantDataRaceChecks = getOptions().EnableActorDataRaceChecks &&
496+
!F.isAsync() &&
497+
!isInActorDestructor(FunctionDC);
498+
495499
if (auto *funcDecl =
496500
dyn_cast_or_null<AbstractFunctionDecl>(FunctionDC->getAsDecl())) {
497501
auto actorIsolation = getActorIsolation(funcDecl);
@@ -508,7 +512,7 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
508512
// are prone to dynamic data races in code that does not enforce Sendable
509513
// completely.
510514
if (F.isAsync() ||
511-
(funcDecl->isLocalCapture() && !isInActorDestructor(funcDecl))) {
515+
(wantDataRaceChecks && funcDecl->isLocalCapture())) {
512516
auto loc = RegularLocation::getAutoGeneratedLocation(F.getLocation());
513517
ManagedValue selfArg = ManagedValue::forUnmanaged(F.getSelfArgument());
514518
ExpectedExecutor = emitLoadActorExecutor(loc, selfArg);
@@ -517,15 +521,15 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
517521
}
518522

519523
case ActorIsolation::GlobalActor:
520-
if (F.isAsync() || !isInActorDestructor(funcDecl)) {
524+
if (F.isAsync() || wantDataRaceChecks) {
521525
ExpectedExecutor =
522526
emitLoadGlobalActorExecutor(actorIsolation.getGlobalActor());
523527
}
524528
break;
525529
}
526530
} else if (auto *closureExpr = dyn_cast<AbstractClosureExpr>(FunctionDC)) {
527531
bool wantExecutor = F.isAsync() ||
528-
(!isInActorDestructor(closureExpr) &&
532+
(wantDataRaceChecks &&
529533
!(isa<ClosureExpr>(closureExpr) &&
530534
cast<ClosureExpr>(closureExpr)->isUnsafeMainActor()));
531535
auto actorIsolation = closureExpr->getActorIsolation();

test/Concurrency/Runtime/data_race_detection.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-concurrency %import-libdispatch -parse-as-library) > %t.log 2>&1
1+
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-concurrency -enable-actor-data-race-checks %import-libdispatch -parse-as-library) > %t.log 2>&1
22
// RUN: %FileCheck %s < %t.log
33

44
// REQUIRES: executable_test

test/SILGen/check_executor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 -enable-experimental-concurrency | %FileCheck --enable-var-scope %s --check-prefix=CHECK-RAW
2-
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 -enable-experimental-concurrency > %t.sil
1+
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 -enable-experimental-concurrency -enable-actor-data-race-checks | %FileCheck --enable-var-scope %s --check-prefix=CHECK-RAW
2+
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 -enable-experimental-concurrency -enable-actor-data-race-checks > %t.sil
33
// RUN: %target-sil-opt -enable-sil-verify-all %t.sil -lower-hop-to-actor -enable-experimental-concurrency | %FileCheck --enable-var-scope %s --check-prefix=CHECK-CANONICAL
44
// REQUIRES: concurrency
55

0 commit comments

Comments
 (0)