Skip to content

Commit 737b5ec

Browse files
authored
Merge pull request #79674 from eeckstein/simplify-open-existential-metatype
Optimizer: Rework peephole optimizations to replace existential (archetypes) with concrete types
2 parents d2fe619 + 26c7310 commit 737b5ec

File tree

56 files changed

+1987
-512
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1987
-512
lines changed

SwiftCompilerSources/Sources/AST/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_swift_compiler_module(AST
1212
SOURCES
1313
Declarations.swift
1414
Conformance.swift
15+
GenericSignature.swift
1516
Registration.swift
1617
SubstitutionMap.swift
1718
Type.swift)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===--- GenericSignature.swift -------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 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+
import Basic
14+
import ASTBridging
15+
16+
/// Describes the generic signature of a particular declaration, including both the generic type
17+
/// parameters and the requirements placed on those generic parameters.
18+
public struct GenericSignature: CustomStringConvertible, NoReflectionChildren {
19+
public let bridged: BridgedGenericSignature
20+
21+
public init(bridged: BridgedGenericSignature) {
22+
self.bridged = bridged
23+
}
24+
25+
public var description: String {
26+
return String(taking: bridged.getDebugDescription())
27+
}
28+
}

SwiftCompilerSources/Sources/AST/SubstitutionMap.swift

+8-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import ASTBridging
1818
///
1919
/// Substitution maps are primarily used when performing substitutions into any entity that
2020
/// can reference type parameters and conformances.
21-
public struct SubstitutionMap: CustomStringConvertible {
21+
public struct SubstitutionMap: CustomStringConvertible, NoReflectionChildren {
2222
public let bridged: BridgedSubstitutionMap
2323

2424
public init(bridged: BridgedSubstitutionMap) {
@@ -28,6 +28,13 @@ public struct SubstitutionMap: CustomStringConvertible {
2828
public init() {
2929
self.bridged = BridgedSubstitutionMap()
3030
}
31+
32+
public init(genericSignature: GenericSignature, replacementTypes: [Type]) {
33+
let bridgedReplTypes = replacementTypes.map { $0.bridged }
34+
self.bridged = bridgedReplTypes.withBridgedArrayRef {
35+
return BridgedSubstitutionMap.get(genericSignature.bridged, $0)
36+
}
37+
}
3138

3239
public var description: String {
3340
return String(taking: bridged.getDebugDescription())

SwiftCompilerSources/Sources/AST/Type.swift

+97-25
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,23 @@ import ASTBridging
1515

1616
/// A Swift type.
1717
/// It is not necessarily canoncial, e.g. typealiases are not resolved.
18-
public struct Type: CustomStringConvertible, NoReflectionChildren {
18+
public struct Type: TypeProperties, CustomStringConvertible, NoReflectionChildren {
19+
public enum TraitResult {
20+
case isNot
21+
case canBe
22+
case `is`
23+
}
24+
25+
public enum MetatypeRepresentation {
26+
case thin
27+
case thick
28+
case objC
29+
};
30+
1931
public let bridged: BridgedASTType
2032

33+
public var type: Type { self }
34+
2135
public init?(bridgedOrNil: BridgedASTType) {
2236
if bridgedOrNil.type == nil {
2337
return nil
@@ -30,47 +44,81 @@ public struct Type: CustomStringConvertible, NoReflectionChildren {
3044
}
3145

3246
public var canonical: CanonicalType { CanonicalType(bridged: bridged.getCanonicalType()) }
33-
public var description: String { String(taking: bridged.getDebugDescription()) }
3447

35-
public var hasTypeParameter: Bool { bridged.hasTypeParameter() }
36-
public var isOpenedExistentialWithError: Bool { bridged.isOpenedExistentialWithError() }
37-
public var isEscapable: Bool { bridged.isEscapable() }
38-
public var isNoEscape: Bool { bridged.isNoEscape() }
39-
public var isInteger: Bool { bridged.isInteger() }
48+
public var instanceTypeOfMetatype: Type { Type(bridged: bridged.getInstanceTypeOfMetatype()) }
4049

4150
public func subst(with substitutionMap: SubstitutionMap) -> Type {
4251
return Type(bridged: bridged.subst(substitutionMap.bridged))
4352
}
53+
54+
public func subst(type: Type, with targetType: Type) -> Type {
55+
return Type(bridged: bridged.subst(type.bridged, targetType.bridged))
56+
}
4457
}
4558

4659
/// A Type that is statically known to be canonical.
4760
/// For example, typealiases are resolved.
48-
public struct CanonicalType: CustomStringConvertible, NoReflectionChildren {
49-
public enum TraitResult {
50-
case isNot
51-
case canBe
52-
case `is`
53-
}
54-
61+
public struct CanonicalType: TypeProperties, CustomStringConvertible, NoReflectionChildren {
5562
public let bridged: BridgedCanType
5663

5764
public init(bridged: BridgedCanType) { self.bridged = bridged }
5865

5966
public var type: Type { Type(bridged: bridged.getType()) }
6067

61-
public var description: String { type.description }
62-
63-
public var hasTypeParameter: Bool { type.hasTypeParameter }
64-
public var isOpenedExistentialWithError: Bool { type.isOpenedExistentialWithError }
65-
public var isEscapable: Bool { type.isEscapable }
66-
public var isNoEscape: Bool { type.isNoEscape }
67-
public var isInteger: Bool { type.isInteger }
68-
68+
public var instanceTypeOfMetatype: CanonicalType { type.instanceTypeOfMetatype.canonical }
69+
6970
public func subst(with substitutionMap: SubstitutionMap) -> CanonicalType {
7071
return type.subst(with: substitutionMap).canonical
7172
}
7273

73-
public var canBeClass: TraitResult { bridged.canBeClass().result }
74+
public func subst(type: CanonicalType, with targetType: CanonicalType) -> CanonicalType {
75+
return self.type.subst(type: type.type, with: targetType.type).canonical
76+
}
77+
}
78+
79+
/// Contains common properties of AST.Type and AST.CanonicalType
80+
public protocol TypeProperties {
81+
var type: Type { get }
82+
}
83+
84+
extension TypeProperties {
85+
public var description: String { String(taking: type.bridged.getDebugDescription()) }
86+
87+
public var isLegalFormalType: Bool { type.bridged.isLegalFormalType() }
88+
public var hasTypeParameter: Bool { type.bridged.hasTypeParameter() }
89+
public var hasLocalArchetype: Bool { type.bridged.hasLocalArchetype() }
90+
public var isExistentialArchetype: Bool { type.bridged.isExistentialArchetype() }
91+
public var isExistentialArchetypeWithError: Bool { type.bridged.isExistentialArchetypeWithError() }
92+
public var isExistential: Bool { type.bridged.isExistential() }
93+
public var isEscapable: Bool { type.bridged.isEscapable() }
94+
public var isNoEscape: Bool { type.bridged.isNoEscape() }
95+
public var isInteger: Bool { type.bridged.isInteger() }
96+
public var isMetatypeType: Bool { type.bridged.isMetatypeType() }
97+
public var isExistentialMetatypeType: Bool { type.bridged.isExistentialMetatypeType() }
98+
public var representationOfMetatype: AST.`Type`.MetatypeRepresentation {
99+
type.bridged.getRepresentationOfMetatype().representation
100+
}
101+
public var invocationGenericSignatureOfFunctionType: GenericSignature {
102+
GenericSignature(bridged: type.bridged.getInvocationGenericSignatureOfFunctionType())
103+
}
104+
105+
public var canBeClass: Type.TraitResult { type.bridged.canBeClass().result }
106+
107+
public var anyNominal: NominalTypeDecl? { type.bridged.getAnyNominal().getAs(NominalTypeDecl.self) }
108+
109+
/// Performas a global conformance lookup for this type for `protocol`.
110+
/// It checks conditional requirements.
111+
///
112+
/// This type must be a contextualized type. It must not contain type parameters.
113+
///
114+
/// The resulting conformance reference does not include "missing" conformances, which are synthesized for
115+
/// some protocols as an error recovery mechanism.
116+
///
117+
/// Returns an invalid conformance if the search failed, otherwise an
118+
/// abstract, concrete or pack conformance, depending on the lookup type.
119+
public func checkConformance(to protocol: ProtocolDecl) -> Conformance {
120+
return Conformance(bridged: type.bridged.checkConformance(`protocol`.bridged))
121+
}
74122
}
75123

76124
public struct TypeArray : RandomAccessCollection, CustomReflectable {
@@ -93,8 +141,8 @@ public struct TypeArray : RandomAccessCollection, CustomReflectable {
93141
}
94142
}
95143

96-
extension BridgedCanType.TraitResult {
97-
var result: CanonicalType.TraitResult {
144+
extension BridgedASTType.TraitResult {
145+
var result: Type.TraitResult {
98146
switch self {
99147
case .IsNot: return .isNot
100148
case .CanBe: return .canBe
@@ -104,3 +152,27 @@ extension BridgedCanType.TraitResult {
104152
}
105153
}
106154
}
155+
156+
extension BridgedASTType.MetatypeRepresentation {
157+
var representation: Type.MetatypeRepresentation {
158+
switch self {
159+
case .Thin: return .thin
160+
case .Thick: return .thick
161+
case .ObjC: return .objC
162+
default:
163+
fatalError("wrong type MetatypeRepresentation enum case")
164+
}
165+
}
166+
}
167+
168+
extension Type: Equatable {
169+
public static func ==(lhs: Type, rhs: Type) -> Bool {
170+
lhs.bridged.type == rhs.bridged.type
171+
}
172+
}
173+
174+
extension CanonicalType: Equatable {
175+
public static func ==(lhs: CanonicalType, rhs: CanonicalType) -> Bool {
176+
lhs.type == rhs.type
177+
}
178+
}

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
swift_compiler_sources(Optimizer
1010
SimplifyAllocRefDynamic.swift
11+
SimplifyAllocStack.swift
1112
SimplifyApply.swift
1213
SimplifyBeginAndLoadBorrow.swift
1314
SimplifyBeginCOWMutation.swift
@@ -38,4 +39,5 @@ swift_compiler_sources(Optimizer
3839
SimplifyTuple.swift
3940
SimplifyTupleExtract.swift
4041
SimplifyUncheckedEnumData.swift
41-
SimplifyValueToBridgeObject.swift)
42+
SimplifyValueToBridgeObject.swift
43+
SimplifyWitnessMethod.swift)

0 commit comments

Comments
 (0)