Merge pull request #16832 from gottesmm/pr-769c02db89f9caceec9c48e9e9f081fe78655b9a

[func-sig-opts][+0->+1] Add a benchmark that requires the optimizer t…
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 90212e6..6774f7c 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -110,6 +110,7 @@
     single-source/ObserverForwarderStruct
     single-source/ObserverPartiallyAppliedMethod
     single-source/ObserverUnappliedMethod
+    single-source/OpaqueConsumingUsers
     single-source/OpenClose
     single-source/PartialApplyDynamicType
     single-source/Phonebook
diff --git a/benchmark/single-source/OpaqueConsumingUsers.swift b/benchmark/single-source/OpaqueConsumingUsers.swift
new file mode 100644
index 0000000..88eeb3e
--- /dev/null
+++ b/benchmark/single-source/OpaqueConsumingUsers.swift
@@ -0,0 +1,88 @@
+//===--- OpaqueConsumingUsers.swift ---------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 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 TestsUtils
+
+public let OpaqueConsumingUsers = BenchmarkInfo(
+  name: "OpaqueConsumingUsers",
+  runFunction: run_OpaqueConsumingUsers,
+  tags: [.regression, .abstraction, .refcount],
+  setUpFunction: setup_OpaqueConsumingUsers)
+
+// This test exercises the ability of the optimizer to propagate the +1 from a
+// consuming argument of a non-inlineable through multiple non-inlinable call
+// frames.
+//
+// We are trying to simulate a user application that calls into a resilient
+// setter or initialization. We want to be able to propagate the +1 from the
+// setter through the app as far as we can.
+
+class Klass {}
+
+class ConsumingUser {
+  var _innerValue: Klass = Klass()
+
+  var value: Klass {
+    @inline(never) get {
+      return _innerValue
+    }
+    @inline(never) set {
+      _innerValue = newValue
+    }
+  }
+}
+
+var data: Klass? = nil
+var user: ConsumingUser? = nil
+
+func setup_OpaqueConsumingUsers() {
+  switch (data, user) {
+  case (let x?, let y?):
+    let _ = x
+    let _ = y
+    return
+  case (nil, nil):
+    data = Klass()
+    user = ConsumingUser()
+  default:
+    fatalError("Data and user should both be .none or .some")
+  }
+}
+
+@inline(never)
+func callFrame1(_ data: Klass, _ user: ConsumingUser) {
+  callFrame2(data, user)
+}
+
+@inline(never)
+func callFrame2(_ data: Klass, _ user: ConsumingUser) {
+  callFrame3(data, user)
+}
+
+@inline(never)
+func callFrame3(_ data: Klass, _ user: ConsumingUser) {
+  callFrame4(data, user)
+}
+
+@inline(never)
+func callFrame4(_ data: Klass, _ user: ConsumingUser) {
+  user.value = data
+}
+
+@inline(never)
+public func run_OpaqueConsumingUsers(_ N: Int) {
+  let d = data._unsafelyUnwrappedUnchecked
+  let u = user._unsafelyUnwrappedUnchecked
+  for _ in 0..<N*200000 {
+    callFrame4(d, u)
+  }
+}
diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift
index bd37728..7f82ac9 100644
--- a/benchmark/utils/main.swift
+++ b/benchmark/utils/main.swift
@@ -97,6 +97,7 @@
 import ObserverForwarderStruct
 import ObserverPartiallyAppliedMethod
 import ObserverUnappliedMethod
+import OpaqueConsumingUsers
 import OpenClose
 import PartialApplyDynamicType
 import Phonebook
@@ -255,6 +256,7 @@
 registerBenchmark(ObserverForwarderStruct)
 registerBenchmark(ObserverPartiallyAppliedMethod)
 registerBenchmark(ObserverUnappliedMethod)
+registerBenchmark(OpaqueConsumingUsers)
 registerBenchmark(OpenClose)
 registerBenchmark(PartialApplyDynamicType)
 registerBenchmark(Phonebook)