mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
* access * accessed * accesses * accessor * acquiring * across * activated * additive * address * addresses' * aggregated * analysis * and * appropriately * archetype * argument * associated * availability * barriers * because * been * beginning * belongs * beneficial * blocks * borrow * builtin * cannot * canonical * canonicalize * clazz * cleanup * coalesceable * coalesced * comparisons * completely * component * computed * concrete * conjunction * conservatively * constituent * construct * consuming * containing * covered * creates * critical * dataflow * declaration * defined * defining * definition * deinitialization * deliberately * dependencies * dependent * deserialized * destroy * deterministic * deterministically * devirtualizes * diagnostic * diagnostics * differentiation * disable * discipline * dominate * dominates * don't * element * eliminate * eliminating * elimination * embedded * encounter * epilogue * epsilon * escape * escaping * essential * evaluating * evaluation * evaluator * executing * existential * existentials * explicit * expression * extended * extension * extract * for * from * function * generic * guarantee * guaranteed * happened * heuristic * however * identifiable * immediately * implementation * improper * include * infinite * initialize * initialized * initializer * inside * instruction * interference * interferes * interleaved * internal * intersection * intractable * intrinsic * invalidates * irreducible * irrelevant * language * lifetime * literal * looks * materialize * meaning * mergeable * might * mimics * modification * modifies * multiple * mutating * necessarily * necessary * needsmultiplecopies * nonetheless * nothing * occurred * occurs * optimization * optimizing * original * outside * overflow * overlapping * overridden * owned * ownership * parallel * parameter * paths * patterns * pipeline * plottable * possible * potentially * practically * preamble * precede * preceding * predecessor * preferable * preparation * probably * projection * properties * property * protocol * reabstraction * reachable * recognized * recursive * recursively * redundant * reentrancy * referenced * registry * reinitialization * reload * represent * requires * response * responsible * retrieving * returned * returning * returns * rewriting * rewritten * sample * scenarios * scope * should * sideeffects * similar * simplify * simplifycfg * somewhat * spaghetti * specialization * specializations * specialized * specially * statistically * substitute * substitution * succeeds * successful * successfully * successor * superfluous * surprisingly * suspension * swift * targeted * that * that our * the * therefore * this * those * threshold * through * transform * transformation * truncated * ultimate * unchecked * uninitialized * unlikely * unmanaged * unoptimized key * updataflow * usefulness * utilities * villain * whenever * writes Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
150 lines
4.2 KiB
Swift
150 lines
4.2 KiB
Swift
// RUN: %target-swift-frontend -O -emit-sil -Xllvm -sil-print-generic-specialization-loops %s 2>&1 | %FileCheck --check-prefix=CHECK %s
|
|
|
|
// Check that the generic specializer does not hang a compiler by
|
|
// creating and infinite loop of generic specializations.
|
|
|
|
// Tests in this file should not result in any detected specialization loops at all.
|
|
// CHECK-NOT: generic specialization loop
|
|
|
|
// Check specializations of mutually recursive functions, where
|
|
// there is no specialization loop.
|
|
// CHECK-LABEL: sil{{.*}}testFooBar1{{.*}}convention
|
|
@inline(never)
|
|
public func foo1<T>(_ x: [T]) {
|
|
bar1([5,6])
|
|
}
|
|
|
|
public func bar1<T>(_ x: [T]) {
|
|
foo1(x)
|
|
}
|
|
|
|
public func testFooBar1() {
|
|
foo1([1,2,3])
|
|
}
|
|
|
|
// Another example, where there is no specialization loop.
|
|
func foo6<T>(_ t: T) {
|
|
bar6(t)
|
|
}
|
|
|
|
func bar6<T>(_ t: T) {
|
|
foo6(t)
|
|
}
|
|
|
|
public func testFooBar6() {
|
|
foo6(1)
|
|
}
|
|
|
|
// Check specializations of mutually recursive functions, where
|
|
// there is no specialization loop.
|
|
@inline(never)
|
|
public func foo2<T>(_ x: [T]) {
|
|
foo2(x.reversed())
|
|
}
|
|
|
|
public func testFoo2() {
|
|
foo2([1,2,3])
|
|
}
|
|
|
|
// Check specializations of mutually recursive functions where
|
|
// there is no specialization loop, because no new specializations
|
|
// are required after 3-4 rounds of specializations.
|
|
func foo5<T, S>(_ t: T, _ s: S) {
|
|
bar5([UInt8(1)], [t])
|
|
}
|
|
|
|
func bar5<T, S>(_ t: T, _ s: S) {
|
|
foo5([t], [s])
|
|
}
|
|
|
|
public func testFooBar5() {
|
|
foo5(1, 2.0)
|
|
}
|
|
|
|
// Yet another example of creating a lot of generic specializations for
|
|
// deeply nested generics. But it should not produce any specialization loops.
|
|
protocol Pingable {}
|
|
|
|
struct Some1<T> {
|
|
init() {}
|
|
func foo(_ x: T) {}
|
|
}
|
|
struct Some0<T> {
|
|
init() {}
|
|
func foo(_ x: T) {}
|
|
}
|
|
|
|
@inline(never)
|
|
func flood<T>(_ x: T) {
|
|
_ = Some1<Some1<Some1<Some1<T>>>>() is Pingable
|
|
_ = Some1<Some1<Some1<Some0<T>>>>() is Pingable
|
|
_ = Some1<Some1<Some0<Some1<T>>>>() is Pingable
|
|
_ = Some1<Some1<Some0<Some0<T>>>>() is Pingable
|
|
_ = Some1<Some0<Some1<Some1<T>>>>() is Pingable
|
|
_ = Some1<Some0<Some1<Some0<T>>>>() is Pingable
|
|
_ = Some1<Some0<Some0<Some1<T>>>>() is Pingable
|
|
_ = Some1<Some0<Some0<Some0<T>>>>() is Pingable
|
|
_ = Some0<Some1<Some1<Some1<T>>>>() is Pingable
|
|
_ = Some0<Some1<Some1<Some0<T>>>>() is Pingable
|
|
_ = Some0<Some1<Some0<Some1<T>>>>() is Pingable
|
|
_ = Some0<Some1<Some0<Some0<T>>>>() is Pingable
|
|
_ = Some0<Some0<Some1<Some1<T>>>>() is Pingable
|
|
_ = Some0<Some0<Some1<Some0<T>>>>() is Pingable
|
|
_ = Some0<Some0<Some0<Some1<T>>>>() is Pingable
|
|
_ = Some0<Some0<Some0<Some0<T>>>>() is Pingable
|
|
}
|
|
|
|
@inline(never)
|
|
func flood3<T>(_ x: T) {
|
|
flood(Some1<Some1<Some1<Some1<T>>>>())
|
|
flood(Some1<Some1<Some1<Some0<T>>>>())
|
|
flood(Some1<Some1<Some0<Some1<T>>>>())
|
|
flood(Some1<Some1<Some0<Some0<T>>>>())
|
|
flood(Some1<Some0<Some1<Some1<T>>>>())
|
|
flood(Some1<Some0<Some1<Some0<T>>>>())
|
|
flood(Some1<Some0<Some0<Some1<T>>>>())
|
|
flood(Some1<Some0<Some0<Some0<T>>>>())
|
|
flood(Some0<Some1<Some1<Some1<T>>>>())
|
|
flood(Some0<Some1<Some1<Some0<T>>>>())
|
|
flood(Some0<Some1<Some0<Some1<T>>>>())
|
|
flood(Some0<Some1<Some0<Some0<T>>>>())
|
|
flood(Some0<Some0<Some1<Some1<T>>>>())
|
|
flood(Some0<Some0<Some1<Some0<T>>>>())
|
|
flood(Some0<Some0<Some0<Some1<T>>>>())
|
|
flood(Some0<Some0<Some0<Some0<T>>>>())
|
|
}
|
|
|
|
@inline(never)
|
|
func flood2<T>(_ x: T) {
|
|
flood3(Some1<Some1<Some1<Some1<T>>>>())
|
|
flood3(Some1<Some1<Some1<Some0<T>>>>())
|
|
flood3(Some1<Some1<Some0<Some1<T>>>>())
|
|
flood3(Some1<Some1<Some0<Some0<T>>>>())
|
|
flood3(Some1<Some0<Some1<Some1<T>>>>())
|
|
flood3(Some1<Some0<Some1<Some0<T>>>>())
|
|
flood3(Some1<Some0<Some0<Some1<T>>>>())
|
|
flood3(Some1<Some0<Some0<Some0<T>>>>())
|
|
flood3(Some0<Some1<Some1<Some1<T>>>>())
|
|
flood3(Some0<Some1<Some1<Some0<T>>>>())
|
|
flood3(Some0<Some1<Some0<Some1<T>>>>())
|
|
flood3(Some0<Some1<Some0<Some0<T>>>>())
|
|
flood3(Some0<Some0<Some1<Some1<T>>>>())
|
|
flood3(Some0<Some0<Some1<Some0<T>>>>())
|
|
flood3(Some0<Some0<Some0<Some1<T>>>>())
|
|
flood3(Some0<Some0<Some0<Some0<T>>>>())
|
|
}
|
|
|
|
@inline(never)
|
|
public func run_TypeFlood(_ N: Int) {
|
|
for _ in 1...N {
|
|
flood2(Some1<Some1<Some1<Int>>>())
|
|
flood2(Some1<Some1<Some0<Int>>>())
|
|
flood2(Some1<Some0<Some1<Int>>>())
|
|
flood2(Some1<Some0<Some0<Int>>>())
|
|
flood2(Some0<Some1<Some1<Int>>>())
|
|
flood2(Some0<Some1<Some0<Int>>>())
|
|
flood2(Some0<Some0<Some1<Int>>>())
|
|
flood2(Some0<Some0<Some0<Int>>>())
|
|
}
|
|
}
|