Skip to content

Commit 01654fd

Browse files
authored
Merge pull request #71775 from jkshtj/main
[Autodiff] Adds part of the Autodiff specific closure-specialization optimization pass
2 parents e74cfb0 + c6330a7 commit 01654fd

38 files changed

+3682
-91
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ swift_compiler_sources(Optimizer
1212
AsyncDemotion.swift
1313
BooleanLiteralFolding.swift
1414
CleanupDebugSteps.swift
15+
ClosureSpecialization.swift
1516
ComputeEscapeEffects.swift
1617
ComputeSideEffects.swift
1718
DeadStoreElimination.swift

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ClosureSpecialization.swift

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

SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ private func registerSwiftPasses() {
9393
registerPass(lifetimeDependenceDiagnosticsPass, { lifetimeDependenceDiagnosticsPass.run($0) })
9494
registerPass(lifetimeDependenceInsertionPass, { lifetimeDependenceInsertionPass.run($0) })
9595
registerPass(lifetimeDependenceScopeFixupPass, { lifetimeDependenceScopeFixupPass.run($0) })
96+
registerPass(generalClosureSpecialization, { generalClosureSpecialization.run($0) })
97+
registerPass(autodiffClosureSpecialization, { autodiffClosureSpecialization.run($0) })
98+
9699
// Instruction passes
97100
registerForSILCombine(BeginCOWMutationInst.self, { run(BeginCOWMutationInst.self, $0) })
98101
registerForSILCombine(GlobalValueInst.self, { run(GlobalValueInst.self, $0) })

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,23 @@ extension LoadInst {
398398
}
399399
}
400400

401+
extension PartialApplyInst {
402+
var isPartialApplyOfReabstractionThunk: Bool {
403+
// A partial_apply of a reabstraction thunk either has a single capture
404+
// (a function) or two captures (function and dynamic Self type).
405+
if self.numArguments == 1 || self.numArguments == 2,
406+
let fun = self.referencedFunction,
407+
fun.isReabstractionThunk,
408+
self.arguments[0].type.isFunction,
409+
self.arguments[0].type.isReferenceCounted(in: self.parentFunction) || self.callee.type.isThickFunction
410+
{
411+
return true
412+
}
413+
414+
return false
415+
}
416+
}
417+
401418
extension FunctionPassContext {
402419
/// Returns true if any blocks were removed.
403420
func removeDeadBlocks(in function: Function) -> Bool {
@@ -540,6 +557,10 @@ extension Function {
540557
}
541558
return nil
542559
}
560+
561+
var mayBindDynamicSelf: Bool {
562+
self.bridged.mayBindDynamicSelf()
563+
}
543564
}
544565

545566
extension FullApplySite {

SwiftCompilerSources/Sources/Optimizer/Utilities/Test.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ public func registerOptimizerTests() {
164164
lifetimeDependenceUseTest,
165165
linearLivenessTest,
166166
parseTestSpecificationTest,
167-
variableIntroducerTest
167+
variableIntroducerTest,
168+
gatherCallSitesTest
168169
)
169170

170171
// Finally register the thunk they all call through.

SwiftCompilerSources/Sources/SIL/ApplySite.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ public protocol ApplySite : Instruction {
108108
extension ApplySite {
109109
public var callee: Value { operands[ApplyOperandConventions.calleeIndex].value }
110110

111+
public var hasSubstitutions: Bool {
112+
return substitutionMap.hasAnySubstitutableParams
113+
}
114+
111115
public var isAsync: Bool {
112116
return callee.type.isAsyncFunction
113117
}
@@ -126,7 +130,15 @@ extension ApplySite {
126130
return false
127131
}
128132

129-
/// Returns the subset of operands that are argument operands.
133+
public var isCalleeNoReturn: Bool {
134+
bridged.ApplySite_isCalleeNoReturn()
135+
}
136+
137+
public var isCalleeTrapNoReturn: Bool {
138+
referencedFunction?.isTrapNoReturn ?? false
139+
}
140+
141+
/// Returns the subset of operands which are argument operands.
130142
///
131143
/// This does not include the callee function operand.
132144
public var argumentOperands: OperandArray {

SwiftCompilerSources/Sources/SIL/BasicBlock.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,26 @@ final public class BasicBlock : CustomStringConvertible, HasShortDescription, Ha
5757
successors.count == 1 ? successors[0] : nil
5858
}
5959

60+
/// All function exiting blocks except for ones with an `unreachable` terminator,
61+
/// not immediately preceded by an apply of a no-return function.
62+
public var isReachableExitBlock: Bool {
63+
switch terminator {
64+
case let termInst where termInst.isFunctionExiting:
65+
return true
66+
case is UnreachableInst:
67+
if let instBeforeUnreachable = terminator.previous,
68+
let ai = instBeforeUnreachable as? ApplyInst,
69+
ai.isCalleeNoReturn && !ai.isCalleeTrapNoReturn
70+
{
71+
return true
72+
}
73+
74+
return false
75+
default:
76+
return false
77+
}
78+
}
79+
6080
/// The index of the basic block in its function.
6181
/// This has O(n) complexity. Only use it for debugging
6282
public var index: Int {

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
3131
hasher.combine(ObjectIdentifier(self))
3232
}
3333

34+
public var isTrapNoReturn: Bool { bridged.isTrapNoReturn() }
35+
36+
public var isAutodiffVJP: Bool { bridged.isAutodiffVJP() }
37+
38+
public var specializationLevel: Int { bridged.specializationLevel() }
39+
3440
public var hasOwnership: Bool { bridged.hasOwnership() }
3541

3642
public var hasLoweredAddresses: Bool { bridged.hasLoweredAddresses() }
@@ -59,6 +65,10 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
5965
entryBlock.arguments.lazy.map { $0 as! FunctionArgument }
6066
}
6167

68+
public func argument(at index: Int) -> FunctionArgument {
69+
entryBlock.arguments[index] as! FunctionArgument
70+
}
71+
6272
/// All instructions of all blocks.
6373
public var instructions: LazySequence<FlattenSequence<LazyMapSequence<BasicBlockList, InstructionList>>> {
6474
blocks.lazy.flatMap { $0.instructions }
@@ -83,6 +93,8 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
8393

8494
public var isAsync: Bool { bridged.isAsync() }
8595

96+
public var isReabstractionThunk: Bool { bridged.isReabstractionThunk() }
97+
8698
/// True if this is a `[global_init]` function.
8799
///
88100
/// Such a function is typically a global addressor which calls the global's

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,16 @@ class ConvertFunctionInst : SingleValueInstruction, UnaryInstruction {
893893
}
894894

895895
final public
896-
class ThinToThickFunctionInst : SingleValueInstruction, UnaryInstruction {}
896+
class ThinToThickFunctionInst : SingleValueInstruction, UnaryInstruction {
897+
public var callee: Value { operand.value }
898+
899+
public var referencedFunction: Function? {
900+
if let fri = callee as? FunctionRefInst {
901+
return fri.referencedFunction
902+
}
903+
return nil
904+
}
905+
}
897906

898907
final public class ThickToObjCMetatypeInst : SingleValueInstruction {}
899908
final public class ObjCToThickMetatypeInst : SingleValueInstruction {}

SwiftCompilerSources/Sources/SIL/SubstitutionMap.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public struct SubstitutionMap {
2525

2626
public var isEmpty: Bool { bridged.isEmpty() }
2727

28+
public var hasAnySubstitutableParams: Bool { bridged.hasAnySubstitutableParams() }
29+
2830
public var replacementTypes: OptionalTypeArray {
2931
let types = BridgedTypeArray.fromReplacementTypes(bridged)
3032
return OptionalTypeArray(bridged: types)

0 commit comments

Comments
 (0)