Skip to content

Add a new -assume-single-threaded option #6041

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/swift/AST/SILOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ class SILOptions {

/// When parsing SIL, assume unqualified ownership.
bool AssumeUnqualifiedOwnershipWhenParsing = false;

/// Assume that code will be executed in a single-threaded environment.
bool AssumeSingleThreaded = false;
};

} // end namespace swift
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ def Oplayground : Flag<["-"], "Oplayground">, Group<O_Group>,
Flags<[HelpHidden, FrontendOption]>,
HelpText<"Compile with optimizations appropriate for a playground">;

def AssumeSingleThreaded : Flag<["-"], "assume-single-threaded">,
Flags<[FrontendOption, HelpHidden]>,
HelpText<"Assume that code will be executed in a single-threaded "
"environment">;

// Debug info options

Expand Down
2 changes: 2 additions & 0 deletions include/swift/SILOptimizer/PassManager/Passes.def
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ PASS(ArrayCountPropagation, "array-count-propagation",
"Propagate the count of arrays")
PASS(ArrayElementPropagation, "array-element-propagation",
"Propagate the value of array elements")
PASS(AssumeSingleThreaded, "sil-assume-single-threaded",
"Assume that code will be executed in a single-threaded environment")
PASS(BasicInstructionPropertyDumper, "basic-instruction-property-dump",
"Dump MemBehavior and ReleaseBehavior results from calling "
"SILInstruction::{getMemoryBehavior,getReleasingBehavior}()"
Expand Down
4 changes: 4 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,10 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
}
}

if (Args.getLastArg(OPT_AssumeSingleThreaded)) {
Opts.AssumeSingleThreaded = true;
}

// Parse the assert configuration identifier.
if (const Arg *A = Args.getLastArg(OPT_AssertConfig)) {
StringRef Configuration = A->getValue();
Expand Down
6 changes: 6 additions & 0 deletions lib/SILOptimizer/PassManager/Passes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@ void swift::runSILOptimizationPasses(SILModule &Module) {
// after FSO.
PM.addLateReleaseHoisting();

// Has only an effect if the -assume-single-thread option is specified.
PM.addAssumeSingleThreaded();

PM.runOneIteration();

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

// Has only an effect if the -assume-single-thread option is specified.
PM.addAssumeSingleThreaded();

// Has only an effect if the -gsil option is specified.
PM.addSILDebugInfoGenerator();

Expand Down
60 changes: 60 additions & 0 deletions lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//===--- AssumeSingleThreaded.cpp - Assume single-threaded execution ---===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Assume that user code is single-thread.
//
// Convert all reference counting operations into non-atomic ones.
//
// To get read of most atomic reference counting operations, the standard
// library should be compiled in this mode as well
//
// This pass affects only reference counting operations resulting from SIL
// instructions. It wouldn't affect places in the runtime C++ code which
// hard-code calls to retain/release. We could take advantage of the Instruments
// instrumentation stubs to redirect calls from the runtime if it was
// significant, or else just build a single-threaded variant of the runtime.
//
//===----------------------------------------------------------------------===//

#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILModule.h"
#include "swift/SILOptimizer/Utils/Local.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "llvm/Support/CommandLine.h"

using namespace swift;

namespace {
class AssumeSingleThreaded : public swift::SILFunctionTransform {
/// The entry point to the transformation.
void run() override {
if (!getOptions().AssumeSingleThreaded)
return;
for (auto &BB : *getFunction()) {
for (auto &I : BB) {
if (auto RCInst = dyn_cast<RefCountingInst>(&I))
RCInst->setNonAtomic();
}
}
invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
}

StringRef getName() override { return "Assume single threaded"; }
};
} // end anonymous namespace


SILTransform *swift::createAssumeSingleThreaded() {
return new AssumeSingleThreaded();
}
1 change: 1 addition & 0 deletions lib/SILOptimizer/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ set(TRANSFORMS_SOURCES
Transforms/AllocBoxToStack.cpp
Transforms/ArrayCountPropagation.cpp
Transforms/ArrayElementValuePropagation.cpp
Transforms/AssumeSingleThreaded.cpp
Transforms/CSE.cpp
Transforms/ConditionForwarding.cpp
Transforms/CopyForwarding.cpp
Expand Down
51 changes: 51 additions & 0 deletions test/SILOptimizer/assume_single_threaded.sil
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// RUN: %target-swift-frontend -emit-sil -assume-parsing-unqualified-ownership-sil %s -assume-single-threaded | %FileCheck %s
// RUN: %target-swift-frontend -emit-sil -assume-parsing-unqualified-ownership-sil %s -O -assume-single-threaded | %FileCheck %s

// Check that all reference counting instructions are converted to [nonatomic]
// if -assume-single-threaded is used.

sil_stage canonical

import Builtin
import Swift
import SwiftShims

public class C {
deinit
init()
}


// CHECK-LABEL: sil{{.*}}@test_atomic_to_nonatomic_retain
// CHECK: strong_retain [nonatomic]
// CHECK: return
sil @test_atomic_to_nonatomic_retain: $@convention(thin) () -> @owned C {
bb0:
%1 = alloc_ref $C
strong_retain %1 : $C
return %1 : $C
}

// CHECK-LABEL: sil{{.*}}@test_atomic_to_nonatomic_release
// CHECK: strong_release [nonatomic]
// CHECK: return
sil @test_atomic_to_nonatomic_release: $@convention(thin) (C) -> C {
bb0(%0 : $C):
strong_release %0 : $C
return %0 : $C
}



// C.__deallocating_deinit
sil @_TFC28nonatomic_reference_counting1CD : $@convention(method) (@owned C) -> () {
bb0(%0 : $C):
dealloc_ref %0 : $C
%4 = tuple ()
return %4 : $()
}

sil_vtable C {
#C.deinit!deallocator: _TFC28nonatomic_reference_counting1CD // C.__deallocating_deinit
}