From 5d43f75173ce5ac0afa24aee6d578df96c8acf95 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 3 May 2023 14:30:57 +0200 Subject: [PATCH] stdlib: force inlining of ContiguousArray.endIndex and ContiguousArray._getCount This let the optimizer generate efficient code for generic array loops (note that generic functions are not inlined by default). Note that the same change is not done for `Array` because this might increase code size due to Array's bridging code. rdar://108746069 --- stdlib/public/core/ContiguousArray.swift | 2 ++ test/SILOptimizer/array_loop.swift | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 test/SILOptimizer/array_loop.swift diff --git a/stdlib/public/core/ContiguousArray.swift b/stdlib/public/core/ContiguousArray.swift index aece9e1b57e71..0d41e4b0f1592 100644 --- a/stdlib/public/core/ContiguousArray.swift +++ b/stdlib/public/core/ContiguousArray.swift @@ -53,6 +53,7 @@ public struct ContiguousArray: _DestructorSafeContainer { //===--- private helpers---------------------------------------------------===// extension ContiguousArray { @inlinable + @inline(__always) @_semantics("array.get_count") internal func _getCount() -> Int { return _buffer.immutableCount @@ -204,6 +205,7 @@ extension ContiguousArray: RandomAccessCollection, MutableCollection { /// If the array is empty, `endIndex` is equal to `startIndex`. public var endIndex: Int { @inlinable + @inline(__always) get { return _getCount() } diff --git a/test/SILOptimizer/array_loop.swift b/test/SILOptimizer/array_loop.swift new file mode 100644 index 0000000000000..2b13c93e690eb --- /dev/null +++ b/test/SILOptimizer/array_loop.swift @@ -0,0 +1,20 @@ +// RUN: %target-swift-frontend -O -module-name=test -emit-sil -primary-file %s | %FileCheck %s + +// REQUIRES: swift_stdlib_no_asserts +// REQUIRES: swift_in_compiler + + +// Test that even with a generic array the iteration is done efficiently. + +// CHECK-LABEL: sil @$s4test0A15ContiguousArrayySis0bC0VyxG_SixXEtlF : $@convention(thin) (@guaranteed ContiguousArray, @guaranteed @noescape @callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> Int for ) -> Int { +// CHECK-NOT: function_ref +// CHECK-NOT: method +// CHECK: } // end sil function '$s4test0A15ContiguousArrayySis0bC0VyxG_SixXEtlF' +public func testContiguousArray(_ a: ContiguousArray, _ c: (Element) -> Int) -> Int { + var s = 0 + for x in a { + s += c(x) + } + return s +} +