From e3de408716dac096b3d2afd3219d339527a3eb06 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Thu, 1 Aug 2024 13:37:26 +0200 Subject: [PATCH 1/2] Simplification: remove `builtin "destroyArray"` with trivial element types --- .../InstructionSimplification/SimplifyBuiltin.swift | 11 +++++++++-- test/SILOptimizer/simplify_builtin.sil | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift b/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift index b9aa698fb945f..ae608f8c66f4c 100644 --- a/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift +++ b/SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift @@ -32,8 +32,15 @@ extension BuiltinInst : OnoneSimplifyable { .Strideof, .Alignof: optimizeTargetTypeConst(context) - case .DestroyArray, - .CopyArray, + case .DestroyArray: + if let elementType = substitutionMap.replacementTypes[0], + elementType.isTrivial(in: parentFunction) + { + context.erase(instruction: self) + return + } + optimizeArgumentToThinMetatype(argument: 0, context) + case .CopyArray, .TakeArrayNoAlias, .TakeArrayFrontToBack, .TakeArrayBackToFront, diff --git a/test/SILOptimizer/simplify_builtin.sil b/test/SILOptimizer/simplify_builtin.sil index 53a7c985a570f..9e74677d8575b 100644 --- a/test/SILOptimizer/simplify_builtin.sil +++ b/test/SILOptimizer/simplify_builtin.sil @@ -605,3 +605,12 @@ bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word): return %0 : $Builtin.RawPointer } +// CHECK-LABEL: sil @remove_trivial_destroy_array +// CHECK-NOT: builtin +// CHECK: } // end sil function 'remove_trivial_destroy_array' +sil @remove_trivial_destroy_array : $@convention(thin) (Builtin.RawPointer, Builtin.Word) -> Builtin.RawPointer { +bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word): + %2 = metatype $@thin Int.Type + %3 = builtin "destroyArray"(%2 : $@thin Int.Type, %0 : $Builtin.RawPointer, %1 : $Builtin.Word) : $() + return %0 : $Builtin.RawPointer +} From 50e22f986ca7b3ba57c471534772c7f0d5dbb74e Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Thu, 1 Aug 2024 13:38:18 +0200 Subject: [PATCH 2/2] SIL: allow atomic operations in `@_noLocks` functions https://github.com/swiftlang/swift/issues/74407 --- lib/SIL/Utils/InstructionUtils.cpp | 5 ++-- .../performance-annotations-atomics.swift | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 test/SILOptimizer/performance-annotations-atomics.swift diff --git a/lib/SIL/Utils/InstructionUtils.cpp b/lib/SIL/Utils/InstructionUtils.cpp index c05b85d6218f7..d7e6fdfe87435 100644 --- a/lib/SIL/Utils/InstructionUtils.cpp +++ b/lib/SIL/Utils/InstructionUtils.cpp @@ -728,8 +728,7 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType) case SILInstructionKind::AllocStackInst: case SILInstructionKind::AllocVectorInst: case SILInstructionKind::ProjectBoxInst: - if (!cast(inst)->getType(). - isLoadable(*inst->getFunction())) { + if (cast(inst)->getType().hasArchetype()) { impactType = cast(inst)->getType(); return RuntimeEffect::MetaData; } @@ -1028,7 +1027,7 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType) case BuiltinValueKind::AtomicLoad: case BuiltinValueKind::AtomicStore: case BuiltinValueKind::AtomicRMW: - return RuntimeEffect::Locking; + return RuntimeEffect::NoEffect; case BuiltinValueKind::DestroyArray: return RuntimeEffect::Releasing; case BuiltinValueKind::CopyArray: diff --git a/test/SILOptimizer/performance-annotations-atomics.swift b/test/SILOptimizer/performance-annotations-atomics.swift new file mode 100644 index 0000000000000..9340373e8db0b --- /dev/null +++ b/test/SILOptimizer/performance-annotations-atomics.swift @@ -0,0 +1,30 @@ +// RUN: %target-swift-frontend -parse-as-library -disable-availability-checking -emit-sil %s -o /dev/null + +// REQUIRES: synchronization + +import Synchronization + +// Check that atomics work in no-locks mode. + +@_noLocks +func testFence() { + atomicMemoryFence(ordering: .acquiring) + atomicMemoryFence(ordering: .releasing) + atomicMemoryFence(ordering: .acquiringAndReleasing) + atomicMemoryFence(ordering: .sequentiallyConsistent) +} + +@_noLocks +func testLoadStore() -> Int { + let x = Atomic(0) + x.store(27, ordering: .relaxed) + x.compareExchange(expected: 27, desired: 42, successOrdering: .relaxed, failureOrdering: .relaxed) + return x.load(ordering: .acquiring) +} + +@_noLocks +func testRMW(_ b: Bool) -> (Bool, Bool) { + let x = Atomic(false) + return x.logicalOr(true, ordering: .relaxed) +} +