SILOptimizer: Replace [].append(contentsOf:) with [].append(element:)

if the argument is an array literal.

For example:
  arr += [1, 2, 3]

is replaced by:
  arr.append(1)
  arr.append(2)
  arr.append(3)

This gives considerable speedups up to 10x (for our micro-benchmarks which test this).

This is based on the work of @ben-ng, who implemented the first version of this optimization (thanks!).
This commit is contained in:
Erik Eckstein
2017-03-31 10:48:15 -07:00
parent dc426bd885
commit 777f5aaf7a
6 changed files with 377 additions and 92 deletions

View File

@@ -0,0 +1,52 @@
// RUN: %target-swift-frontend -O -emit-sil %s | %FileCheck %s
// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
// This is an end-to-end test of the array(contentsOf) -> array(Element) optimization
// CHECK-LABEL: sil @{{.*}}testInt
// CHECK-NOT: apply
// CHECK: [[F:%[0-9]+]] = function_ref @_T0Sa6appendyxFSi_Tg
// CHECK-NOT: apply
// CHECK: apply [[F]]
// CHECK-NEXT: tuple
// CHECK-NEXT: return
public func testInt(_ a: inout [Int]) {
a += [1]
}
// CHECK-LABEL: sil @{{.*}}testThreeInt
// CHECK-NOT: apply
// CHECK: [[F:%[0-9]+]] = function_ref @_T0Sa6appendyxFSi_Tg
// CHECK-NOT: apply
// CHECK: apply [[F]]
// CHECK-NEXT: apply [[F]]
// CHECK-NEXT: apply [[F]]
// CHECK-NEXT: tuple
// CHECK-NEXT: return
public func testThreeInts(_ a: inout [Int]) {
a += [1, 2, 3]
}
// CHECK-LABEL: sil @{{.*}}testTooManyInts
// CHECK-NOT: apply
// CHECK: [[F:%[0-9]+]] = function_ref @_T0Sa6appendyqd__10contentsOf_t8Iterator_7ElementQYd__Rszs8SequenceRd__lF
// CHECK-NOT: apply
// CHECK: apply [[F]]
// CHECK-NOT: apply
// CHECK: return
public func testTooManyInts(_ a: inout [Int]) {
a += [1, 2, 3, 4, 5, 6, 7]
}
// CHECK-LABEL: sil @{{.*}}testString
// CHECK-NOT: apply
// CHECK: [[F:%[0-9]+]] = function_ref @_T0Sa6appendyxFSS_Tg
// CHECK-NOT: apply
// CHECK: apply [[F]]
// CHECK-NOT: apply
// CHECK: tuple
// CHECK-NEXT: return
public func testString(_ a: inout [String], s: String) {
a += [s]
}