Skip to content

Commit 2b9444e

Browse files
committed
Add mangling support for partial specializations.
1 parent 26c963f commit 2b9444e

File tree

3 files changed

+89
-13
lines changed

3 files changed

+89
-13
lines changed

include/swift/SIL/Mangle.h

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class AbstractClosureExpr;
3030
enum class SpecializationKind : uint8_t {
3131
Generic,
3232
NotReAbstractedGeneric,
33+
Partial,
34+
NotReAbstractedPartial,
3335
FunctionSignature,
3436
};
3537

@@ -73,6 +75,12 @@ class SpecializationManglerBase {
7375
case SpecializationKind::NotReAbstractedGeneric:
7476
M.append("r");
7577
break;
78+
case SpecializationKind::Partial:
79+
M.append("p");
80+
break;
81+
case SpecializationKind::NotReAbstractedPartial:
82+
M.append("P");
83+
break;
7684
case SpecializationKind::FunctionSignature:
7785
M.append("f");
7886
break;
@@ -145,14 +153,44 @@ class GenericSpecializationMangler :
145153
};
146154

147155
GenericSpecializationMangler(Mangle::Mangler &M, SILFunction *F,
148-
SubstitutionList Subs,
156+
SubstitutionList Subs, IsFragile_t Fragile,
157+
ReAbstractionMode isReAbstracted = ReAbstracted)
158+
: SpecializationMangler(isReAbstracted == ReAbstracted
159+
? SpecializationKind::Generic
160+
: SpecializationKind::NotReAbstractedGeneric,
161+
SpecializationPass::GenericSpecializer, M,
162+
Fragile, F),
163+
Subs(Subs) {
164+
}
165+
166+
private:
167+
void mangleSpecialization();
168+
};
169+
170+
class PartialSpecializationMangler :
171+
public SpecializationMangler<PartialSpecializationMangler> {
172+
173+
friend class SpecializationMangler<PartialSpecializationMangler>;
174+
175+
CanSILFunctionType SpecializedFnTy;
176+
public:
177+
178+
enum ReAbstractionMode {
179+
ReAbstracted,
180+
NotReabstracted
181+
};
182+
183+
PartialSpecializationMangler(Mangle::Mangler &M,
184+
SILFunction *F,
185+
CanSILFunctionType SpecializedFnTy,
149186
IsFragile_t Fragile,
150187
ReAbstractionMode isReAbstracted = ReAbstracted)
151188
: SpecializationMangler(isReAbstracted == ReAbstracted ?
152-
SpecializationKind::Generic :
153-
SpecializationKind::NotReAbstractedGeneric,
189+
SpecializationKind::Partial :
190+
SpecializationKind::NotReAbstractedPartial,
154191
SpecializationPass::GenericSpecializer,
155-
M, Fragile, F), Subs(Subs) {}
192+
M, Fragile, F), SpecializedFnTy(SpecializedFnTy) {
193+
}
156194

157195
private:
158196
void mangleSpecialization();

lib/SIL/Mangle.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static void mangleSubstitution(Mangler &M, Substitution Sub) {
5555

5656
void GenericSpecializationMangler::mangleSpecialization() {
5757
Mangler &M = getMangler();
58-
58+
// This is a full specialization.
5959
SILFunctionType *FTy = Function->getLoweredFunctionType();
6060
CanGenericSignature Sig = FTy->getGenericSignature();
6161

@@ -73,6 +73,25 @@ void GenericSpecializationMangler::mangleSpecialization() {
7373
assert(idx == Subs.size() && "subs not parallel to dependent types");
7474
}
7575

76+
void PartialSpecializationMangler::mangleSpecialization() {
77+
Mangler &M = getMangler();
78+
// If the only change to the generic signature during specialization is
79+
// addition of new same-type requirements, which happens in case of a
80+
// full specialization, it would be enough to mangle only the substitutions.
81+
//
82+
// If the types of function arguments have not changed, but some new
83+
// conformances were added to the generic parameters, e.g. in case of
84+
// a pre-specialization, then it would be enough to mangle only the new
85+
// generic signature.
86+
//
87+
// If the types of function arguments have changed as a result of a partial
88+
// specialization, we need to mangle the entire new function type.
89+
90+
// This is a partial specialization.
91+
M.mangleType(SpecializedFnTy, 0);
92+
M.append("_");
93+
}
94+
7695
//===----------------------------------------------------------------------===//
7796
// Function Signature Optimizations
7897
//===----------------------------------------------------------------------===//

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -294,16 +294,35 @@ GenericFuncSpecializer::GenericFuncSpecializer(SILFunction *GenericFunc,
294294
ReInfo(ReInfo) {
295295

296296
assert(GenericFunc->isDefinition() && "Expected definition to specialize!");
297+
auto FnTy = ReInfo.getSpecializedType();
297298

298-
Mangle::Mangler Mangler;
299-
GenericSpecializationMangler OldGenericMangler(Mangler, GenericFunc,
300-
ParamSubs, Fragile);
301-
OldGenericMangler.mangle();
302-
std::string Old = Mangler.finalize();
299+
std::string Old;
300+
301+
if (ReInfo.isPartialSpecialization()) {
302+
Mangle::Mangler Mangler;
303+
PartialSpecializationMangler OldGenericMangler(Mangler, GenericFunc, FnTy,
304+
Fragile);
305+
OldGenericMangler.mangle();
306+
Old = Mangler.finalize();
307+
} else {
308+
Mangle::Mangler Mangler;
309+
GenericSpecializationMangler OldGenericMangler(Mangler, GenericFunc,
310+
ParamSubs, Fragile);
311+
OldGenericMangler.mangle();
312+
Old = Mangler.finalize();
313+
}
314+
315+
std::string New;
316+
if (ReInfo.isPartialSpecialization()) {
317+
NewMangling::PartialSpecializationMangler NewGenericMangler(
318+
GenericFunc, FnTy, Fragile, /*isReAbstracted*/ true);
319+
New = NewGenericMangler.mangle();
320+
} else {
321+
NewMangling::GenericSpecializationMangler NewGenericMangler(
322+
GenericFunc, ParamSubs, Fragile, /*isReAbstracted*/ true);
323+
New = NewGenericMangler.mangle();
324+
}
303325

304-
NewMangling::GenericSpecializationMangler NewGenericMangler(GenericFunc,
305-
ParamSubs, Fragile, /*isReAbstracted*/ true);
306-
std::string New = NewGenericMangler.mangle();
307326
ClonedName = NewMangling::selectMangling(Old, New);
308327

309328
DEBUG(llvm::dbgs() << " Specialized function " << ClonedName << '\n');

0 commit comments

Comments
 (0)