From 42e6fac1ea5128359efed515c4e93dc8230fe31c Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Sun, 9 Jan 2022 21:04:24 +0000 Subject: [PATCH] libswift: reimplement `AssumeSingleThreaded` pass --- .../FunctionPasses/AssumeSingleThreaded.swift | 25 ++++++++ .../Optimizer/FunctionPasses/CMakeLists.txt | 1 + .../PassManager/PassRegistration.swift | 1 + .../Optimizer/PassManager/PassUtils.swift | 6 ++ include/swift/SIL/SILBridging.h | 1 + .../swift/SILOptimizer/PassManager/Passes.def | 2 +- lib/SIL/Utils/SILBridging.cpp | 5 ++ lib/SILOptimizer/PassManager/PassPipeline.cpp | 8 ++- .../Transforms/AssumeSingleThreaded.cpp | 59 ------------------- lib/SILOptimizer/Transforms/CMakeLists.txt | 1 - 10 files changed, 46 insertions(+), 63 deletions(-) create mode 100644 SwiftCompilerSources/Sources/Optimizer/FunctionPasses/AssumeSingleThreaded.swift delete mode 100644 lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp diff --git a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/AssumeSingleThreaded.swift b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/AssumeSingleThreaded.swift new file mode 100644 index 00000000000..56a87ce8a46 --- /dev/null +++ b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/AssumeSingleThreaded.swift @@ -0,0 +1,25 @@ +//===--- AssumeSingleThreaded.swift - Assume single-threaded execution ----===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2022 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 +// +//===----------------------------------------------------------------------===// + +import SIL + +let assumeSingleThreadedPass = FunctionPass( + name: "sil-assume-single-threaded", { function, context in + for block in function.blocks { + for inst in block.instructions { + guard let rcInst = inst as? RefCountingInst else { continue } + + context.setAtomicity(of: rcInst, isAtomic: false) + } + } + } +) diff --git a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt index a0e76eb487c..c36c22e4041 100644 --- a/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt +++ b/SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt @@ -7,6 +7,7 @@ # See http://swift.org/CONTRIBUTORS.txt for Swift project authors swift_compiler_sources(Optimizer + AssumeSingleThreaded.swift SILPrinter.swift MergeCondFails.swift ) diff --git a/SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift b/SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift index bf6e6cff444..3819d1cb911 100644 --- a/SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift +++ b/SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift @@ -50,4 +50,5 @@ private func registerSwiftPasses() { registerPass(simplifyGlobalValuePass, { simplifyGlobalValuePass.run($0) }) registerPass(simplifyStrongRetainPass, { simplifyStrongRetainPass.run($0) }) registerPass(simplifyStrongReleasePass, { simplifyStrongReleasePass.run($0) }) + registerPass(assumeSingleThreadedPass, { assumeSingleThreadedPass.run($0) }) } diff --git a/SwiftCompilerSources/Sources/Optimizer/PassManager/PassUtils.swift b/SwiftCompilerSources/Sources/Optimizer/PassManager/PassUtils.swift index e05bad59811..047465725af 100644 --- a/SwiftCompilerSources/Sources/Optimizer/PassManager/PassUtils.swift +++ b/SwiftCompilerSources/Sources/Optimizer/PassManager/PassUtils.swift @@ -78,6 +78,12 @@ struct PassContext { SILInstruction_setOperand(instruction.bridged, index, value.bridged) } + + func setAtomicity(of instruction: RefCountingInst, isAtomic: Bool) { + PassContext_notifyChanges(passContext, instructionsChanged) + + RefCountingInst_setIsAtomic(instruction.bridged, isAtomic) + } } struct FunctionPass { diff --git a/include/swift/SIL/SILBridging.h b/include/swift/SIL/SILBridging.h index 61f9495c31b..fe9adedee28 100644 --- a/include/swift/SIL/SILBridging.h +++ b/include/swift/SIL/SILBridging.h @@ -233,6 +233,7 @@ BridgedBasicBlock BranchInst_getTargetBlock(BridgedInstruction bi); SwiftInt SwitchEnumInst_getNumCases(BridgedInstruction se); SwiftInt SwitchEnumInst_getCaseIndex(BridgedInstruction se, SwiftInt idx); SwiftInt StoreInst_getStoreOwnership(BridgedInstruction store); +void RefCountingInst_setIsAtomic(BridgedInstruction rc, bool isAtomic); BridgedInstruction SILBuilder_createBuiltinBinaryFunction( BridgedInstruction insertionPoint, diff --git a/include/swift/SILOptimizer/PassManager/Passes.def b/include/swift/SILOptimizer/PassManager/Passes.def index aed5bf61ce4..0d49e032477 100644 --- a/include/swift/SILOptimizer/PassManager/Passes.def +++ b/include/swift/SILOptimizer/PassManager/Passes.def @@ -131,7 +131,7 @@ PASS(ArrayCountPropagation, "array-count-propagation", "Array Count Propagation") PASS(ArrayElementPropagation, "array-element-propagation", "Array Element Propagation") -PASS(AssumeSingleThreaded, "sil-assume-single-threaded", +SWIFT_FUNCTION_PASS(AssumeSingleThreaded, "sil-assume-single-threaded", "Assume Single-Threaded Environment") PASS(BasicInstructionPropertyDumper, "basic-instruction-property-dump", "Print SIL Instruction MemBehavior and ReleaseBehavior Information") diff --git a/lib/SIL/Utils/SILBridging.cpp b/lib/SIL/Utils/SILBridging.cpp index 73cdb6ba519..87fd5f79908 100644 --- a/lib/SIL/Utils/SILBridging.cpp +++ b/lib/SIL/Utils/SILBridging.cpp @@ -483,6 +483,11 @@ SwiftInt StoreInst_getStoreOwnership(BridgedInstruction store) { return (SwiftInt)castToInst(store)->getOwnershipQualifier(); } +void RefCountingInst_setIsAtomic(BridgedInstruction rc, bool isAtomic) { + castToInst(rc)->setAtomicity( + isAtomic ? RefCountingInst::Atomicity::Atomic + : RefCountingInst::Atomicity::NonAtomic); +} //===----------------------------------------------------------------------===// // SILBuilder diff --git a/lib/SILOptimizer/PassManager/PassPipeline.cpp b/lib/SILOptimizer/PassManager/PassPipeline.cpp index 23c88d6ea43..cc9fa35c9af 100644 --- a/lib/SILOptimizer/PassManager/PassPipeline.cpp +++ b/lib/SILOptimizer/PassManager/PassPipeline.cpp @@ -766,7 +766,9 @@ static void addLastChanceOptPassPipeline(SILPassPipelinePlan &P) { #endif // Only has an effect if the -assume-single-thread option is specified. - P.addAssumeSingleThreaded(); + if (P.getOptions().AssumeSingleThreaded) { + P.addAssumeSingleThreaded(); + } // Emits remarks on all functions with @_assemblyVision attribute. P.addAssemblyVisionRemarkGenerator(); @@ -925,7 +927,9 @@ SILPassPipelinePlan::getOnonePassPipeline(const SILOptions &Options) { P.addUsePrespecialized(); // Has only an effect if the -assume-single-thread option is specified. - P.addAssumeSingleThreaded(); + if (P.getOptions().AssumeSingleThreaded) { + P.addAssumeSingleThreaded(); + } // Create pre-specializations. P.addOnonePrespecializations(); diff --git a/lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp b/lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp deleted file mode 100644 index 8668a6971fc..00000000000 --- a/lib/SILOptimizer/Transforms/AssumeSingleThreaded.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===--- AssumeSingleThreaded.cpp - Assume single-threaded execution -----===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2017 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/SIL/SILFunction.h" -#include "swift/SIL/SILInstruction.h" -#include "swift/SIL/SILModule.h" -#include "swift/SILOptimizer/PassManager/Passes.h" -#include "swift/SILOptimizer/PassManager/Transforms.h" -#include "swift/SILOptimizer/Utils/InstOptUtils.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(&I)) - RCInst->setNonAtomic(); - } - } - invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions); - } - -}; -} // end anonymous namespace - - -SILTransform *swift::createAssumeSingleThreaded() { - return new AssumeSingleThreaded(); -} diff --git a/lib/SILOptimizer/Transforms/CMakeLists.txt b/lib/SILOptimizer/Transforms/CMakeLists.txt index 9b6fa3075db..0e41ae2c19f 100644 --- a/lib/SILOptimizer/Transforms/CMakeLists.txt +++ b/lib/SILOptimizer/Transforms/CMakeLists.txt @@ -7,7 +7,6 @@ target_sources(swiftSILOptimizer PRIVATE AllocBoxToStack.cpp ArrayCountPropagation.cpp ArrayElementValuePropagation.cpp - AssumeSingleThreaded.cpp COWOpts.cpp CSE.cpp ConditionForwarding.cpp