Skip to content

Commit 8632e58

Browse files
committed
Create Pack Specialisation pass
1 parent c7af4c5 commit 8632e58

File tree

11 files changed

+1927
-0
lines changed

11 files changed

+1927
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ swift_compiler_sources(Optimizer
3838
StripObjectHeaders.swift
3939
TempLValueElimination.swift
4040
TempRValueElimination.swift
41+
PackSpecialization.swift
4142
)

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/PackSpecialization.swift

Lines changed: 1035 additions & 0 deletions
Large diffs are not rendered by default.

SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ private func registerSwiftPasses() {
108108
registerPass(closureSpecialization, { closureSpecialization.run($0) })
109109
registerPass(autodiffClosureSpecialization, { autodiffClosureSpecialization.run($0) })
110110
registerPass(loopInvariantCodeMotionPass, { loopInvariantCodeMotionPass.run($0) })
111+
registerPass(packSpecialization, { packSpecialization.run($0) })
111112

112113
// Instruction passes
113114
registerForSILCombine(BeginBorrowInst.self, { run(BeginBorrowInst.self, $0) })

benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ set(SWIFT_BENCH_MODULES
139139
single-source/ObserverUnappliedMethod
140140
single-source/OpaqueConsumingUsers
141141
single-source/OpenClose
142+
single-source/ParameterPacks
142143
single-source/Phonebook
143144
single-source/PointerArithmetics
144145
single-source/PolymorphicCalls
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===--- ParameterPacks.swift ---------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
// This benchmark serves to test the overhead of
14+
15+
import TestsUtils
16+
17+
public let benchmarks = [
18+
BenchmarkInfo(
19+
name: "ParameterPacks.VariadicFibonacci",
20+
runFunction: run_ParameterPacksVariadicFibonacci,
21+
tags: [.validation])
22+
]
23+
24+
@inline(never)
25+
func numericLoop<each T: BinaryInteger>(xs: repeat each T) -> (repeat each T) {
26+
return
27+
(repeat { x in
28+
// Recursive "Fibonacci" function prevents inlining
29+
if x <= 1 {
30+
return x
31+
} else {
32+
let (a, b) = numericLoop(xs: x - 1, x - 2)
33+
return a + b
34+
}
35+
}(each xs)
36+
37+
)
38+
}
39+
40+
let expectedResult = (610, 987, 1597)
41+
42+
@inline(never)
43+
public func run_ParameterPacksVariadicFibonacci(_ n: Int) {
44+
var result = (0, 0, 0)
45+
for _ in 1...n {
46+
result = numericLoop(xs: 15, 16, 17)
47+
if result != expectedResult {
48+
break
49+
}
50+
}
51+
52+
check(result == expectedResult)
53+
}

benchmark/utils/main.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ import ObserverPartiallyAppliedMethod
143143
import ObserverUnappliedMethod
144144
import OpaqueConsumingUsers
145145
import OpenClose
146+
import ParameterPacks
146147
import Phonebook
147148
import PointerArithmetics
148149
import PolymorphicCalls
@@ -343,6 +344,7 @@ register(ObserverPartiallyAppliedMethod.benchmarks)
343344
register(ObserverUnappliedMethod.benchmarks)
344345
register(OpaqueConsumingUsers.benchmarks)
345346
register(OpenClose.benchmarks)
347+
register(ParameterPacks.benchmarks)
346348
register(Phonebook.benchmarks)
347349
register(PointerArithmetics.benchmarks)
348350
register(PolymorphicCalls.benchmarks)

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,7 @@ Some kinds need arguments, which precede ``Tf``.
13601360
PASSID ::= '5' // GenericSpecializer,
13611361
PASSID ::= '6' // MoveDiagnosticInOutToOut,
13621362
PASSID ::= '7' // AsyncDemotion,
1363+
PASSID ::= '8' // PackSpecialization,
13631364

13641365
FRAGILE ::= 'q'
13651366

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ PASS(TempLValueElimination, "temp-lvalue-elimination",
152152
"Remove short-lived immutable temporary l-values")
153153
PASS(LoopInvariantCodeMotion, "loop-invariant-code-motion",
154154
"New Loop Invariant Code Motion")
155+
PASS(PackSpecialization, "pack-specialization",
156+
"Specialize uses of parameter packs")
155157

156158
PASS(ClosureSpecialization, "closure-specialization",
157159
"Specialize functions with closure arguments")

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ void addFunctionPasses(SILPassPipelinePlan &P,
525525
// of embedded Swift.
526526
if (!P.getOptions().EmbeddedSwift) {
527527
P.addGenericSpecializer();
528+
P.addPackSpecialization();
528529
// Run devirtualizer after the specializer, because many
529530
// class_method/witness_method instructions may use concrete types now.
530531
P.addDevirtualizer();

test/SILOptimizer/pack_specialization.sil

Lines changed: 791 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)