Skip to content

Commit 268037e

Browse files
committed
Add a new -assume-single-threaded option
This is a hidden option. It should be used like: -Xllvm -assume-single-threaded When this function is provided, the compiler assumes that the code will be executed in the single threaded mode. It then performs certain optimizations that can benefit from it, e.g. it marks as non-atomic all reference counting instructions in the user code being compiled.
1 parent a3e56f8 commit 268037e

File tree

5 files changed

+117
-0
lines changed

5 files changed

+117
-0
lines changed

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ PASS(ArrayCountPropagation, "array-count-propagation",
4040
"Propagate the count of arrays")
4141
PASS(ArrayElementPropagation, "array-element-propagation",
4242
"Propagate the value of array elements")
43+
PASS(AssumeSingleThreaded, "sil-assume-single-threaded",
44+
"Assume that code will be executed in a single-threaded environment")
4345
PASS(BasicInstructionPropertyDumper, "basic-instruction-property-dump",
4446
"Dump MemBehavior and ReleaseBehavior results from calling "
4547
"SILInstruction::{getMemoryBehavior,getReleasingBehavior}()"

lib/SILOptimizer/PassManager/Passes.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ void swift::runSILOptimizationPasses(SILModule &Module) {
412412
// after FSO.
413413
PM.addLateReleaseHoisting();
414414

415+
// Has only an effect if the -assume-single-thread option is specified.
416+
PM.addAssumeSingleThreaded();
417+
415418
PM.runOneIteration();
416419

417420
PM.resetAndRemoveTransformations();
@@ -452,6 +455,9 @@ void swift::runSILPassesForOnone(SILModule &Module) {
452455
// eventually remove unused declarations.
453456
PM.addExternalDefsToDecls();
454457

458+
// Has only an effect if the -assume-single-thread option is specified.
459+
PM.addAssumeSingleThreaded();
460+
455461
// Has only an effect if the -gsil option is specified.
456462
PM.addSILDebugInfoGenerator();
457463

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===--- AssumeSingleThreaded.cpp - Assume single-threaded executution ---===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Assume that user code is single-thread
14+
//
15+
// Convert all reference counting operations into non-atomic ones.
16+
//
17+
//===----------------------------------------------------------------------===//
18+
19+
#include "swift/SILOptimizer/PassManager/Passes.h"
20+
#include "swift/SIL/SILFunction.h"
21+
#include "swift/SIL/SILInstruction.h"
22+
#include "swift/SIL/SILModule.h"
23+
#include "swift/SILOptimizer/Utils/Local.h"
24+
#include "swift/SILOptimizer/PassManager/Transforms.h"
25+
#include "llvm/Support/CommandLine.h"
26+
27+
using namespace swift;
28+
29+
llvm::cl::opt<bool> AssumeSingleThreadedFlag(
30+
"assume-single-threaded", llvm::cl::init(false),
31+
llvm::cl::Hidden,
32+
llvm::cl::desc(
33+
"Assume that code will be executed in a single-threaded environment"));
34+
35+
namespace {
36+
class AssumeSingleThreaded : public swift::SILFunctionTransform {
37+
/// The entry point to the transformation.
38+
void run() override {
39+
if (!AssumeSingleThreadedFlag)
40+
return;
41+
for (auto &BB : *getFunction()) {
42+
for (auto &I : BB) {
43+
if (auto RCInst = dyn_cast<RefCountingInst>(&I))
44+
RCInst->setNonAtomic();
45+
}
46+
}
47+
invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
48+
}
49+
50+
StringRef getName() override { return "Assume single threaded"; }
51+
};
52+
} // end anonymous namespace
53+
54+
55+
SILTransform *swift::createAssumeSingleThreaded() {
56+
return new AssumeSingleThreaded();
57+
}

lib/SILOptimizer/Transforms/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set(TRANSFORMS_SOURCES
33
Transforms/AllocBoxToStack.cpp
44
Transforms/ArrayCountPropagation.cpp
55
Transforms/ArrayElementValuePropagation.cpp
6+
Transforms/AssumeSingleThreaded.cpp
67
Transforms/CSE.cpp
78
Transforms/ConditionForwarding.cpp
89
Transforms/CopyForwarding.cpp
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: %target-swift-frontend -emit-sil -assume-parsing-unqualified-ownership-sil %s -Xllvm -assume-single-threaded | %FileCheck %s
2+
// RUN: %target-swift-frontend -emit-sil -assume-parsing-unqualified-ownership-sil %s -O -Xllvm -assume-single-threaded | %FileCheck %s
3+
4+
// Check that all reference counting instructions are converted to [nonatomic]
5+
// if -assume-single-threaded is used.
6+
7+
sil_stage canonical
8+
9+
import Builtin
10+
import Swift
11+
import SwiftShims
12+
13+
public class C {
14+
deinit
15+
init()
16+
}
17+
18+
19+
// CHECK-LABEL: sil{{.*}}@test_atomic_to_nonatomic_retain
20+
// CHECK: strong_retain [nonatomic]
21+
// CHECK: return
22+
sil @test_atomic_to_nonatomic_retain: $@convention(thin) () -> @owned C {
23+
bb0:
24+
%1 = alloc_ref $C
25+
strong_retain %1 : $C
26+
return %1 : $C
27+
}
28+
29+
// CHECK-LABEL: sil{{.*}}@test_atomic_to_nonatomic_release
30+
// CHECK: strong_release [nonatomic]
31+
// CHECK: return
32+
sil @test_atomic_to_nonatomic_release: $@convention(thin) (C) -> C {
33+
bb0(%0 : $C):
34+
strong_release %0 : $C
35+
return %0 : $C
36+
}
37+
38+
39+
40+
// C.__deallocating_deinit
41+
sil @_TFC28nonatomic_reference_counting1CD : $@convention(method) (@owned C) -> () {
42+
bb0(%0 : $C):
43+
dealloc_ref %0 : $C
44+
%4 = tuple ()
45+
return %4 : $()
46+
}
47+
48+
sil_vtable C {
49+
#C.deinit!deallocator: _TFC28nonatomic_reference_counting1CD // C.__deallocating_deinit
50+
}
51+

0 commit comments

Comments
 (0)