blob: 9e995df212d7d9b0b9362b0793afb33d1b3f49c0 [file] [log] [blame]
// RUN: %target-swift-frontend -O -enforce-exclusivity=checked -emit-sil -primary-file %s | %FileCheck %s --check-prefix=TESTSIL
// REQUIRES: optimized_stdlib,asserts
// REQUIRES: PTRSIZE=64
public var check: UInt64 = 0
@inline(never)
func sum(_ x: UInt64, _ y: UInt64) -> UInt64 {
return x &+ y
}
// FIXME: The optimization should be able to merge these accesses, but
// it must first prove that no other conflicting read accesses occur
// within the existing read access scopes.
//
// TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity10MergeTest1yySiF : $@convention(thin)
// TESTSIL: bb0
// TESTSIL: [[GLOBALVAR:%.*]] = global_addr @$s17merge_exclusivity5checks6UInt64Vvp
// TESTSIL: [[B1:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL: end_access [[B1]]
// TESTSIL: bb5
// TESTSIL: [[B2a:%.*]] = begin_access [read] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL-NEXT: load [[B2a]]
// TESTSIL: end_access [[B2a]]
// TESTSIL: [[B2b:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL: store {{.*}} to [[B2b]]
// TESTSIL: end_access [[B2b]]
// TESTSIL: bb6
// TESTSIL: [[B3a:%.*]] = begin_access [read] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL-NEXT: load [[B3a]]
// TESTSIL: end_access [[B3a]]
// TESTSIL: [[B3b:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL: store {{.*}} to [[B3b]]
// TESTSIL: end_access [[B3b]]
// TESTSIL: bb7
// TESTSIL: [[B4a:%.*]] = begin_access [read] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL-NEXT: load [[B4a]]
// TESTSIL: end_access [[B4a]]
// TESTSIL: [[B4b:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL: store {{.*}} to [[B4b]]
// TESTSIL: end_access [[B4b]]
// TESTSIL-NOT: begin_access
// TESTSIL-LABEL: } // end sil function '$s17merge_exclusivity10MergeTest1yySiF'
@inline(never)
public func MergeTest1(_ N: Int) {
let range = 0..<10000
check = 0
for _ in 1...N {
for e in range {
check = sum(check, UInt64(e))
if (e == 0) {
check = sum(check, UInt64(1))
}
else {
check = sum(check, UInt64(2))
}
}
}
}
// FIXME: The optimization should be able to merge these accesses, but
// it must first prove that no other conflicting read accesses occur
// within the existing read access scopes.
//
// TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity10MergeTest2yySiF : $@convention(thin)
// TESTSIL: bb0
// TESTSIL: [[GLOBALVAR:%.*]] = global_addr @$s17merge_exclusivity5checks6UInt64Vvp
// TESTSIL: [[B1:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL: end_access [[B1]]
// TESTSIL: bb6
// TESTSIL: [[B2a:%.*]] = begin_access [read] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL-NEXT: load [[B2a]]
// TESTSIL: end_access [[B2a]]
// TESTSIL: [[B2b:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL: store {{.*}} to [[B2b]]
// TESTSIL: end_access [[B2b]]
// TESTSIL: bb7
// TESTSIL: [[B3a:%.*]] = begin_access [read] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL-NEXT: load [[B3a]]
// TESTSIL: end_access [[B3a]]
// TESTSIL: [[B3b:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// TESTSIL: store {{.*}} to [[B3b]]
// TESTSIL: end_access [[B3b]]
// TESTSIL-NOT: begin_access
// TESTSIL-LABEL: } // end sil function '$s17merge_exclusivity10MergeTest2yySiF'
@inline(never)
public func MergeTest2(_ N: Int) {
let range = 0..<10000
check = 0
for _ in 1...N {
for e in range {
if (e == 0) {
check = sum(check, UInt64(1))
}
else {
check = sum(check, UInt64(2))
}
}
}
}
// FIXME: The optimization should be able to merge these accesses, but
// it must first prove that no other conflicting read accesses occur
// within the existing read access scopes.
//
// FIXME_TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity10MergeTest3yySiF : $@convention(thin)
// FIXME_TESTSIL: bb0
// FIXME_TESTSIL: [[GLOBALVAR:%.*]] = global_addr @$s17merge_exclusivity5checks6UInt64Vvp
// FIXME_TESTSIL: [[B1:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL: end_access [[B1]]
// FIXME_TESTSIL-NOT: begin_access
// FIXME_TESTSIL-LABEL: } // end sil function '$s17merge_exclusivity10MergeTest3yySiF'
@inline(never)
public func MergeTest3(_ N: Int) {
let range = 0..<10000
check = 0
for _ in 1...N {
for e in range {
check = sum(check, UInt64(e))
}
}
}
// FIXME: The optimization should be able to merge these accesses, but
// it must first prove that no other conflicting read accesses occur
// within the existing read access scopes.
//
// FIXME_TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity10MergeTest4yySiF : $@convention(thin)
// FIXME_TESTSIL: bb0
// FIXME_TESTSIL: [[GLOBALVAR:%.*]] = global_addr @$s17merge_exclusivity5checks6UInt64Vvp
// FIXME_TESTSIL: [[B1:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL: end_access [[B1]]
// FIXME_TESTSIL: bb7
// FIXME_TESTSIL: [[B2:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL-NEXT: load [[B2]]
// FIXME_TESTSIL: store {{.*}} to [[B2]]
// FIXME_TESTSIL: end_access [[B2]]
// FIXME_TESTSIL: bb8
// FIXME_TESTSIL: [[B3:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL-NEXT: load [[B3]]
// FIXME_TESTSIL: store {{.*}} to [[B3]]
// FIXME_TESTSIL: end_access [[B3]]
// FIXME_TESTSIL-NOT: begin_access
// FIXME_TESTSIL-LABEL: } // end sil function '$s17merge_exclusivity10MergeTest4yySiF'
@inline(never)
public func MergeTest4(_ N: Int) {
let range = 0..<10000
check = 0
for _ in 1...N {
for e in range {
if (e == 0) {
check = sum(check, UInt64(1))
}
check = sum(check, UInt64(e))
}
}
}
// FIXME: The optimization should be able to merge these accesses, but
// it must first prove that no other conflicting read accesses occur
// within the existing read access scopes.
//
// FIXME_TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity10MergeTest5yySiF : $@convention(thin)
// FIXME_TESTSIL: bb0
// FIXME_TESTSIL: [[GLOBALVAR:%.*]] = global_addr @$s17merge_exclusivity5checks6UInt64Vvp
// FIXME_TESTSIL: [[B1:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL: end_access [[B1]]
// FIXME_TESTSIL: bb6
// FIXME_TESTSIL: [[B2:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL-NEXT: load [[B2]]
// FIXME_TESTSIL: store {{.*}} to [[B2]]
// FIXME_TESTSIL: end_access [[B2]]
// FIXME_TESTSIL: bb7
// FIXME_TESTSIL: [[B3:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL-NEXT: load [[B3]]
// FIXME_TESTSIL: store {{.*}} to [[B3]]
// FIXME_TESTSIL: end_access [[B3]]
// FIXME_TESTSIL: bb8
// FIXME_TESTSIL: [[B4:%.*]] = begin_access [modify] [static] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL-NEXT: load [[B4]]
// FIXME_TESTSIL: store {{.*}} to [[B4]]
// FIXME_TESTSIL: end_access [[B4]]
// FIXME_TESTSIL-NOT: begin_access
// FIXME_TESTSIL-LABEL: } // end sil function '$s17merge_exclusivity10MergeTest5yySiF'
@inline(never)
public func MergeTest5(_ N: Int) {
let range = 0..<10000
check = 0
for _ in 1...N {
for e in range {
if (e == 0) {
check = sum(check, UInt64(1))
}
else {
check = sum(check, UInt64(2))
}
check = sum(check, UInt64(e))
}
}
}
// FIXME: The optimization should be able to merge these accesses, but
// it must first prove that no other conflicting read accesses occur
// within the existing read access scopes.
//
// FIXME_TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity10MergeTest6yySiF : $@convention(thin)
// FIXME_TESTSIL: bb0
// FIXME_TESTSIL: [[GLOBALVAR:%.*]] = global_addr @$s17merge_exclusivity5checks6UInt64Vvp
// FIXME_TESTSIL: [[B1:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL: end_access [[B1]]
// FIXME_TESTSIL-NOT: begin_access
// FIXME_TESTSIL-LABEL: } // end sil function '$s17merge_exclusivity10MergeTest6yySiF'
@inline(never)
public func MergeTest6(_ N: Int) {
let range = 0..<10000
check = 0
for _ in 1...N {
for e in range {
check = sum(check, UInt64(e))
for _ in range {
check = sum(check, UInt64(e))
}
check = sum(check, UInt64(e))
}
}
}
@inline(never)
public func foo() {
}
// FIXME: The optimization should be able to merge these accesses, but
// it must first prove that no other conflicting read accesses occur
// within the existing read access scopes.
//
// FIXME_TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity10MergeTest7yySiF : $@convention(thin)
// FIXME_TESTSIL: bb0
// FIXME_TESTSIL: [[GLOBALVAR:%.*]] = global_addr @$s17merge_exclusivity5checks6UInt64Vvp
// FIXME_TESTSIL: [[B1:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL: end_access [[B1]]
// FIXME_TESTSIL-NOT: begin_access
// FIXME_TESTSIL-LABEL: } // end sil function '$s17merge_exclusivity10MergeTest7yySiF'
@inline(never)
public func MergeTest7(_ N: Int) {
let range = 0..<10000
check = 0
for _ in 1...N {
for e in range {
check = sum(check, UInt64(e))
for _ in range {
foo()
}
check = sum(check, UInt64(e))
}
}
}
// FIXME: The optimization should be able to merge these accesses, but
// it must first prove that no other conflicting read accesses occur
// within the existing read access scopes.
//
// FIXME_TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity10MergeTest8yySiF : $@convention(thin)
// FIXME_TESTSIL: bb0
// FIXME_TESTSIL: [[GLOBALVAR:%.*]] = global_addr @$s17merge_exclusivity5checks6UInt64Vvp
// FIXME_TESTSIL: [[B1:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[GLOBALVAR]]
// FIXME_TESTSIL: end_access [[B1]]
// FIXME_TESTSIL-NOT: begin_access
// FIXME_TESTSIL-LABEL: } // end sil function '$s17merge_exclusivity10MergeTest8yySiF'
@inline(never)
public func MergeTest8(_ N: Int) {
let range = 0..<10000
check = 0
for _ in 1...N {
for e in range {
check = sum(check, UInt64(e))
for _ in range {
foo()
}
check = sum(check, UInt64(e))
}
}
for _ in 1...N {
for e in range {
check = sum(check, UInt64(e))
for _ in range {
foo()
}
check = sum(check, UInt64(e))
}
}
}
// Large, test that tests the interaction between access merging,
// and the rest of the access optimizations.
public protocol WriteProt {
func writeTo(_ stream: StreamClass)
}
public final class StreamClass {
private var buffer: [UInt8]
public init() {
self.buffer = []
}
public func write(_ byte: UInt8) {
buffer.append(byte)
}
public func write(_ value: WriteProt) {
value.writeTo(self)
}
public func writeEscaped(_ string: String) {
writeEscaped(string: string.utf8)
}
public func writeEscaped<T: Collection>(
string sequence: T
) where T.Iterator.Element == UInt8 {
for character in sequence {
buffer.append(character)
buffer.append(character)
}
}
}
public func toStream(_ stream: StreamClass, _ value: WriteProt) -> StreamClass {
stream.write(value)
return stream
}
extension UInt8: WriteProt {
public func writeTo(_ stream: StreamClass) {
stream.write(self)
}
}
public func asWriteProt(_ string: String) -> WriteProt {
return EscapedString(value: string)
}
private struct EscapedString: WriteProt {
let value: String
func writeTo(_ stream: StreamClass) {
_ = toStream(stream, UInt8(ascii: "a"))
stream.writeEscaped(value)
_ = toStream(stream, UInt8(ascii: "a"))
}
}
public func asWriteProt<T>(_ items: [T], transform: @escaping (T) -> String) -> WriteProt {
return EscapedTransforme(items: items, transform: transform)
}
private struct EscapedTransforme<T>: WriteProt {
let items: [T]
let transform: (T) -> String
func writeTo(_ stream: StreamClass) {
for (i, item) in items.enumerated() {
if i != 0 { _ = toStream(stream, asWriteProt(transform(item))) }
_ = toStream(stream, asWriteProt(transform(item)))
}
}
}
// TESTSIL-LABEL: sil [noinline] @$s17merge_exclusivity14run_MergeTest9yySiF : $@convention(thin)
// TESTSIL: [[REFADDR:%.*]] = ref_element_addr {{.*}} : $StreamClass, #StreamClass.buffer
// TESTSIL-NEXT: [[B1:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[REFADDR]]
// TESTSIL: end_access [[B1]]
// TESTSIL: [[BCONF:%.*]] = begin_access [modify] [dynamic] [[REFADDR]]
// TESTSIL: apply {{.*}} : $@convention(method) (Int, @inout Array<UInt8>) -> ()
// TESTSIL: end_access [[BCONF]]
// TESTSIL: [[BCONF:%.*]] = begin_access [modify] [dynamic] [[REFADDR]]
// TESTSIL: apply {{.*}} : $@convention(method) (Int, @inout Array<UInt8>) -> ()
// TESTSIL: end_access [[BCONF]]
// TESTSIL: [[BCONF:%.*]] = begin_access [modify] [dynamic] [[REFADDR]]
// TESTSIL: apply {{.*}} : $@convention(method) (Int, @inout Array<UInt8>) -> ()
// TESTSIL: end_access [[BCONF]]
// TESTSIL-LABEL: } // end sil function '$s17merge_exclusivity14run_MergeTest9yySiF'
@inline(never)
public func run_MergeTest9(_ N: Int) {
struct Thing {
var value: String
init(_ value: String) { self.value = value }
}
let listOfStrings: [String] = (0..<10).map { "This is the number: \($0)!\n" }
let listOfThings: [Thing] = listOfStrings.map(Thing.init)
for _ in 1...N {
let stream = StreamClass()
_ = toStream(stream, asWriteProt(listOfThings, transform: { $0.value }))
}
}