mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
The test is using LLVM's `--debug-only=` but it is not marked as `REQUIRES: asserts`, so it will try to run in non-asserts compilers and fail.`
224 lines
5.5 KiB
Swift
224 lines
5.5 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-swift-frontend -module-name main -emit-sil -o %t/output.sil %s -O \
|
|
// RUN: -enable-noreturn-prediction \
|
|
// RUN: -enable-throws-prediction \
|
|
// RUN: -Xllvm --debug-only=cold-block-info 2> %t/debug.txt
|
|
|
|
// RUN: %FileCheck %s --input-file=%t/debug.txt \
|
|
// RUN: --implicit-check-not 'converged after {{[3-9]}} iters'
|
|
|
|
// REQUIRES: asserts
|
|
|
|
public enum MyError: Error { case err; case number(Int) }
|
|
|
|
@inline(never)
|
|
func dump(_ s: String) { print(s) }
|
|
|
|
@inline(never)
|
|
func random() -> Int { return Int.random(in: 0..<1024) }
|
|
|
|
@inline(never)
|
|
func listenForConnections() -> Never {
|
|
while true {
|
|
dump("listening!")
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: --> Final for $s4main14createLauncheryyF
|
|
// CHECK: {
|
|
// CHECK-NEXT: $s4main14createLauncheryyF::bb0 -> cold
|
|
// CHECK-NEXT: STATISTICS: warm 0 | cold 1
|
|
// CHECK-NEXT: }
|
|
public func createLauncher() {
|
|
dump("getting ready!")
|
|
listenForConnections()
|
|
}
|
|
|
|
// CHECK-LABEL: --> Final for $s4main6goBoomyS2iSgF
|
|
// CHECK: {
|
|
// CHECK-NEXT: $s4main6goBoomyS2iSgF::bb1 -> cold
|
|
// CHECK-NEXT: STATISTICS: warm 0 | cold 1
|
|
// CHECK-NEXT: }
|
|
public func goBoom(_ i: Int?) -> Int {
|
|
return i!
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: --> Stopping early in $s4main19goBoom_preconditionyySbF
|
|
public func goBoom_precondition(_ b: Bool) {
|
|
// NOTE: cond_fail instructions from preconditions aren't terminators,
|
|
// so there's nothing cold in this function!
|
|
precondition(b)
|
|
|
|
var x = random()
|
|
precondition(x >= 0)
|
|
|
|
if (x > 100) {
|
|
x = 0
|
|
}
|
|
|
|
for i in 0..<x {
|
|
precondition(i <= 100)
|
|
dump(i)
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: --> Final for $s4main17goBoom_fatalErroryySiF
|
|
// CHECK: {
|
|
// CHECK-DAG: $s4main17goBoom_fatalErroryySiF::bb1 -> cold
|
|
// CHECK-DAG: $s4main17goBoom_fatalErroryySiF::bb0 -> cold
|
|
// CHECK-DAG: $s4main17goBoom_fatalErroryySiF::bb3 -> cold
|
|
// CHECK-DAG: $s4main17goBoom_fatalErroryySiF::bb2 -> cold
|
|
// CHECK-NEXT: STATISTICS: warm 0
|
|
// CHECK: }
|
|
public func goBoom_fatalError(_ i: Int) {
|
|
for i in 0..<i {
|
|
dump("do something")
|
|
}
|
|
fatalError("kablam")
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: --> Final for $s4main13sirThrowsALotyS2iKF
|
|
// CHECK: {
|
|
// CHECK-DAG: $s4main13sirThrowsALotyS2iKF::bb3 -> cold
|
|
// CHECK-DAG: $s4main13sirThrowsALotyS2iKF::bb2 -> cold
|
|
// CHECK-DAG: $s4main13sirThrowsALotyS2iKF::bb4 -> cold
|
|
// CHECK-DAG: $s4main13sirThrowsALotyS2iKF::bb5 -> cold
|
|
// CHECK-NEXT: STATISTICS: warm 0
|
|
// CHECK: }
|
|
@inline(never)
|
|
public func sirThrowsALot(_ i: Int) throws -> Int {
|
|
dump("entry")
|
|
switch i {
|
|
case 0:
|
|
dump("case 0")
|
|
return random()
|
|
case 1:
|
|
dump("case 1")
|
|
throw MyError.err
|
|
default:
|
|
dump("case n")
|
|
throw MyError.number(i)
|
|
}
|
|
}
|
|
|
|
// CHECK-LABEL: --> Final for $s4main22catchTheseThrowsSimpleyS2iF
|
|
// CHECK: {
|
|
// CHECK-DAG: $s4main22catchTheseThrowsSimpleyS2iF::bb1 -> warm
|
|
// CHECK-DAG: $s4main22catchTheseThrowsSimpleyS2iF::bb2 -> cold
|
|
// CHECK: }
|
|
public func catchTheseThrowsSimple(_ i: Int) -> Int {
|
|
if let ans = try? sirThrowsALot(i) {
|
|
return ans
|
|
} else {
|
|
dump("did throw!")
|
|
return random()
|
|
}
|
|
}
|
|
|
|
// Make sure there's at least 3 cold blocks and no warm ones.
|
|
// Inlining and multiple runs of the analysis, and especially platform
|
|
// differences, can yield different numbers of blocks being analyzed!
|
|
|
|
// CHECK-LABEL: --> Final for $s4main012pleasePleaseC0yySiKF
|
|
// CHECK-COUNT-3: -> cold
|
|
// CHECK: STATISTICS: warm 0
|
|
// CHECK: }
|
|
public func pleasePleasePlease(_ i: Int) throws {
|
|
if i > random() {
|
|
fatalError("oof")
|
|
} else {
|
|
throw MyError.number(i)
|
|
}
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: --> Final for $s4main21nestedTreesOfThrowingyySi_S3itAA7MyErrorOYKF
|
|
// CHECK-NOT: bb0
|
|
// CHECK: }
|
|
public func nestedTreesOfThrowing(_ i: Int, _ j: Int, _ k: Int, _ l: Int) throws(MyError) {
|
|
switch i {
|
|
case 0:
|
|
switch j {
|
|
case 0:
|
|
switch k {
|
|
case 0:
|
|
switch l {
|
|
case 0: throw MyError.number(0)
|
|
case 1: throw MyError.number(1)
|
|
default: return // <-- the one non-throwing case that prevents bb0 from being cold!
|
|
}
|
|
case 1:
|
|
switch l {
|
|
case 0: throw MyError.number(1)
|
|
case 1: throw MyError.number(2)
|
|
default: throw MyError.err
|
|
}
|
|
default:
|
|
throw MyError.err
|
|
}
|
|
case 1:
|
|
switch k {
|
|
case 0:
|
|
switch l {
|
|
case 0: throw MyError.number(1)
|
|
case 1: throw MyError.number(2)
|
|
default: throw MyError.err
|
|
}
|
|
case 1:
|
|
switch l {
|
|
case 0: throw MyError.number(2)
|
|
case 1: throw MyError.number(3)
|
|
default: throw MyError.err
|
|
}
|
|
default:
|
|
throw MyError.err
|
|
}
|
|
default:
|
|
throw MyError.err
|
|
}
|
|
case 1:
|
|
switch j {
|
|
case 0:
|
|
switch k {
|
|
case 0:
|
|
switch l {
|
|
case 0: throw MyError.number(1)
|
|
case 1: throw MyError.number(2)
|
|
default: throw MyError.err
|
|
}
|
|
case 1:
|
|
switch l {
|
|
case 0: throw MyError.number(2)
|
|
case 1: throw MyError.number(3)
|
|
default: throw MyError.err
|
|
}
|
|
default:
|
|
throw MyError.err
|
|
}
|
|
case 1:
|
|
switch k {
|
|
case 0:
|
|
switch l {
|
|
case 0: throw MyError.number(2)
|
|
case 1: throw MyError.number(3)
|
|
default: throw MyError.err
|
|
}
|
|
case 1:
|
|
switch l {
|
|
case 0: throw MyError.number(3)
|
|
case 1: throw MyError.number(4)
|
|
default: throw MyError.err
|
|
}
|
|
default:
|
|
throw MyError.err
|
|
}
|
|
default:
|
|
throw MyError.err
|
|
}
|
|
default:
|
|
throw MyError.err
|
|
}
|
|
}
|