Skip to content

Commit 1a4bd76

Browse files
committed
Mangling: add specialization mangling for more complex constant propagated function arguments
So far, constant propagated arguments could only be builtin literals. Now we support arbitrary structs (with constant arguments), e.g. `Int`. This requires a small addition in the mangling scheme for function specializations. Also, the de-mangling tree now looks a bit different to support a "tree" of structs and literals.
1 parent 85381a5 commit 1a4bd76

File tree

12 files changed

+295
-159
lines changed

12 files changed

+295
-159
lines changed

SwiftCompilerSources/Sources/Optimizer/PassManager/FunctionPassContext.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ struct FunctionPassContext : MutatingContext {
109109
}
110110
}
111111

112+
func mangle(withConstantCaptureArguments constArgs: [(argumentIndex: Int, argument: Value)],
113+
from applySiteCallee: Function
114+
) -> String {
115+
let bridgedConstArgs = constArgs.map { ($0.argumentIndex, $0.argument.bridged) }
116+
return bridgedConstArgs.withBridgedArrayRef{ bridgedConstArgsArray in
117+
String(taking: bridgedPassContext.mangleWithConstCaptureArgs(bridgedConstArgsArray, applySiteCallee.bridged))
118+
}
119+
}
120+
112121
func mangle(withBoxToStackPromotedArguments argIndices: [Int], from original: Function) -> String {
113122
argIndices.withBridgedArrayRef { bridgedArgIndices in
114123
String(taking: bridgedPassContext.mangleWithBoxToStackPromotedArgs(bridgedArgIndices, original.bridged))

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,7 @@ Some kinds need arguments, which precede ``Tf``.
13741374
CONST-PROP ::= 'd' NATURAL-ZERO // float-as-64-bit-integer
13751375
CONST-PROP ::= 's' ENCODING // string literal. Consumes one identifier argument.
13761376
CONST-PROP ::= 'k' // keypath. Consumes one identifier - the SHA1 of the keypath and two types (root and value).
1377+
CONST-PROP ::= 'S' CONST-PROP* // struct with operands. Consumes one type argument - the struct type.
13771378

13781379
ENCODING ::= 'b' // utf8
13791380
ENCODING ::= 'w' // utf16

include/swift/Demangling/Demangle.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ enum class FunctionSigSpecializationParamKind : unsigned {
116116
BoxToStack = 7,
117117
InOutToOut = 8,
118118
ConstantPropKeyPath = 9,
119+
ConstantPropStruct = 10,
119120

120121
// Option Set Flags use bits 6-31. This gives us 26 bits to use for option
121122
// flags.
@@ -971,6 +972,9 @@ class NodePrinter {
971972
virtual void printGenericSignature(NodePointer Node, unsigned depth);
972973

973974
void printFunctionSigSpecializationParams(NodePointer Node, unsigned depth);
975+
void printNextParamChildNode(NodePointer nd, unsigned &idx,
976+
FunctionSigSpecializationParamKind kind,
977+
unsigned depth);
974978

975979
void printSpecializationPrefix(NodePointer node, StringRef Description,
976980
unsigned depth,

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ struct BridgedPassContext {
189189
BridgedOwnedString mangleWithDeadArgs(BridgedArrayRef bridgedDeadArgIndices, BridgedFunction function) const;
190190
BridgedOwnedString mangleWithClosureArgs(BridgedArrayRef closureArgIndices,
191191
BridgedFunction applySiteCallee) const;
192+
BridgedOwnedString mangleWithConstCaptureArgs(BridgedArrayRef bridgedConstArgs,
193+
BridgedFunction applySiteCallee) const;
192194
BridgedOwnedString mangleWithBoxToStackPromotedArgs(BridgedArrayRef bridgedPromotedArgIndices,
193195
BridgedFunction bridgedOriginalFunction) const;
194196

lib/Demangling/Demangler.cpp

Lines changed: 102 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3378,43 +3378,40 @@ NodePointer Demangler::demangleFunctionSpecialization() {
33783378
if (Param->getKind() != Node::Kind::FunctionSignatureSpecializationParam)
33793379
continue;
33803380

3381-
if (Param->getNumChildren() == 0)
3382-
continue;
3383-
NodePointer KindNd = Param->getFirstChild();
3384-
assert(KindNd->getKind() ==
3385-
Node::Kind::FunctionSignatureSpecializationParamKind);
3386-
auto ParamKind = (FunctionSigSpecializationParamKind)KindNd->getIndex();
3387-
switch (ParamKind) {
3388-
case FunctionSigSpecializationParamKind::ConstantPropFunction:
3389-
case FunctionSigSpecializationParamKind::ConstantPropGlobal:
3390-
case FunctionSigSpecializationParamKind::ConstantPropString:
3391-
case FunctionSigSpecializationParamKind::ConstantPropKeyPath:
3392-
case FunctionSigSpecializationParamKind::ClosureProp: {
3393-
size_t FixedChildren = Param->getNumChildren();
3394-
while (NodePointer Ty = popNode(Node::Kind::Type)) {
3395-
if (ParamKind != FunctionSigSpecializationParamKind::ClosureProp &&
3396-
ParamKind != FunctionSigSpecializationParamKind::ConstantPropKeyPath)
3397-
return nullptr;
3398-
Param = addChild(Param, Ty);
3399-
}
3400-
NodePointer Name = popNode(Node::Kind::Identifier);
3401-
if (!Name)
3402-
return nullptr;
3403-
StringRef Text = Name->getText();
3404-
if (ParamKind ==
3405-
FunctionSigSpecializationParamKind::ConstantPropString &&
3406-
!Text.empty() && Text[0] == '_') {
3407-
// A '_' escapes a leading digit or '_' of a string constant.
3408-
Text = Text.drop_front(1);
3381+
size_t fixedChildren = Param->getNumChildren();
3382+
NodePointer paramToAdd = Param;
3383+
for (size_t childIdx = 0; childIdx < fixedChildren; ++childIdx) {
3384+
NodePointer KindNd = Param->getChild(fixedChildren - childIdx - 1);
3385+
if (KindNd->getKind() != Node::Kind::FunctionSignatureSpecializationParamKind)
3386+
continue;
3387+
3388+
auto ParamKind = (FunctionSigSpecializationParamKind)KindNd->getIndex();
3389+
switch (ParamKind) {
3390+
case FunctionSigSpecializationParamKind::ClosureProp: {
3391+
while (NodePointer Ty = popNode(Node::Kind::Type)) {
3392+
paramToAdd = addChild(paramToAdd, Ty);
3393+
}
3394+
break;
34093395
}
3410-
addChild(Param, createNodeWithAllocatedText(
3411-
Node::Kind::FunctionSignatureSpecializationParamPayload, Text));
3412-
Param->reverseChildren(FixedChildren);
3413-
break;
3396+
case FunctionSigSpecializationParamKind::ConstantPropKeyPath:
3397+
paramToAdd = addChild(paramToAdd, popNode(Node::Kind::Type));
3398+
paramToAdd = addChild(paramToAdd, popNode(Node::Kind::Type));
3399+
break;
3400+
case FunctionSigSpecializationParamKind::ConstantPropStruct:
3401+
paramToAdd = addChild(paramToAdd, popNode(Node::Kind::Type));
3402+
continue;
3403+
case FunctionSigSpecializationParamKind::ConstantPropFunction:
3404+
case FunctionSigSpecializationParamKind::ConstantPropGlobal:
3405+
case FunctionSigSpecializationParamKind::ConstantPropString:
3406+
break;
3407+
default:
3408+
continue;
34143409
}
3415-
default:
3416-
break;
3410+
paramToAdd = addChild(paramToAdd, popNode(Node::Kind::Identifier));
34173411
}
3412+
if (!paramToAdd)
3413+
return nullptr;
3414+
Param->reverseChildren(fixedChildren);
34183415
}
34193416
return Spec;
34203417
}
@@ -3433,58 +3430,79 @@ NodePointer Demangler::demangleFuncSpecParam(Node::Kind Kind) {
34333430
Node::Kind::FunctionSignatureSpecializationParamKind,
34343431
uint64_t(FunctionSigSpecializationParamKind::ClosureProp)));
34353432
case 'p': {
3436-
switch (nextChar()) {
3437-
case 'f':
3438-
// Consumes an identifier parameter, which will be added later.
3439-
return addChild(
3440-
Param,
3441-
createNode(Node::Kind::FunctionSignatureSpecializationParamKind,
3442-
Node::IndexType(FunctionSigSpecializationParamKind::
3443-
ConstantPropFunction)));
3444-
case 'g':
3445-
// Consumes an identifier parameter, which will be added later.
3446-
return addChild(
3447-
Param,
3448-
createNode(
3449-
Node::Kind::FunctionSignatureSpecializationParamKind,
3450-
Node::IndexType(
3451-
FunctionSigSpecializationParamKind::ConstantPropGlobal)));
3452-
case 'i':
3453-
return addFuncSpecParamNumber(Param,
3454-
FunctionSigSpecializationParamKind::ConstantPropInteger);
3455-
case 'd':
3456-
return addFuncSpecParamNumber(Param,
3457-
FunctionSigSpecializationParamKind::ConstantPropFloat);
3458-
case 's': {
3459-
// Consumes an identifier parameter (the string constant),
3460-
// which will be added later.
3461-
const char *Encoding = nullptr;
3462-
switch (nextChar()) {
3463-
case 'b': Encoding = "u8"; break;
3464-
case 'w': Encoding = "u16"; break;
3465-
case 'c': Encoding = "objc"; break;
3466-
default: return nullptr;
3433+
for (;;) {
3434+
switch (nextChar()) {
3435+
case 'S':
3436+
// Consumes an identifier parameter, which will be added later.
3437+
addChild(
3438+
Param,
3439+
createNode(Node::Kind::FunctionSignatureSpecializationParamKind,
3440+
Node::IndexType(FunctionSigSpecializationParamKind::
3441+
ConstantPropStruct)));
3442+
break;
3443+
case 'f':
3444+
// Consumes an identifier parameter, which will be added later.
3445+
addChild(
3446+
Param,
3447+
createNode(Node::Kind::FunctionSignatureSpecializationParamKind,
3448+
Node::IndexType(FunctionSigSpecializationParamKind::
3449+
ConstantPropFunction)));
3450+
break;
3451+
case 'g':
3452+
// Consumes an identifier parameter, which will be added later.
3453+
addChild(
3454+
Param,
3455+
createNode(
3456+
Node::Kind::FunctionSignatureSpecializationParamKind,
3457+
Node::IndexType(
3458+
FunctionSigSpecializationParamKind::ConstantPropGlobal)));
3459+
break;
3460+
case 'i':
3461+
if (!addFuncSpecParamNumber(Param,
3462+
FunctionSigSpecializationParamKind::ConstantPropInteger)) {
3463+
return nullptr;
3464+
}
3465+
break;
3466+
case 'd':
3467+
if (!addFuncSpecParamNumber(Param,
3468+
FunctionSigSpecializationParamKind::ConstantPropFloat)) {
3469+
return nullptr;
3470+
}
3471+
break;
3472+
case 's': {
3473+
// Consumes an identifier parameter (the string constant),
3474+
// which will be added later.
3475+
const char *Encoding = nullptr;
3476+
switch (nextChar()) {
3477+
case 'b': Encoding = "u8"; break;
3478+
case 'w': Encoding = "u16"; break;
3479+
case 'c': Encoding = "objc"; break;
3480+
default: return nullptr;
3481+
}
3482+
addChild(Param,
3483+
createNode(
3484+
Node::Kind::FunctionSignatureSpecializationParamKind,
3485+
Node::IndexType(
3486+
swift::Demangle::FunctionSigSpecializationParamKind::
3487+
ConstantPropString)));
3488+
addChild(Param, createNode(
3489+
Node::Kind::FunctionSignatureSpecializationParamPayload,
3490+
Encoding));
3491+
break;
34673492
}
3468-
addChild(Param,
3469-
createNode(
3470-
Node::Kind::FunctionSignatureSpecializationParamKind,
3471-
Node::IndexType(
3472-
swift::Demangle::FunctionSigSpecializationParamKind::
3473-
ConstantPropString)));
3474-
return addChild(Param, createNode(
3475-
Node::Kind::FunctionSignatureSpecializationParamPayload,
3476-
Encoding));
3477-
}
3478-
case 'k': {
3479-
// Consumes two types and a SHA1 identifier.
3480-
return addChild(
3481-
Param,
3482-
createNode(Node::Kind::FunctionSignatureSpecializationParamKind,
3483-
Node::IndexType(FunctionSigSpecializationParamKind::
3484-
ConstantPropKeyPath)));
3493+
case 'k': {
3494+
// Consumes two types and a SHA1 identifier.
3495+
addChild(
3496+
Param,
3497+
createNode(Node::Kind::FunctionSignatureSpecializationParamKind,
3498+
Node::IndexType(FunctionSigSpecializationParamKind::
3499+
ConstantPropKeyPath)));
3500+
break;
3501+
}
3502+
default:
3503+
pushBack();
3504+
return Param;
34853505
}
3486-
default:
3487-
return nullptr;
34883506
}
34893507
}
34903508
case 'e': {

0 commit comments

Comments
 (0)