Skip to content

Commit d342041

Browse files
committed
Mangling: use ‘Tm’ mangling for merged functions
Previously merged functions just got the name with a “_merged” suffix
1 parent 9228c04 commit d342041

File tree

11 files changed

+55
-33
lines changed

11 files changed

+55
-33
lines changed

docs/ABI.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,8 @@ types where the metadata itself has unknown layout.)
826826
global ::= protocol-conformance entity 'TW' // protocol witness thunk
827827
global ::= context identifier identifier 'TB' // property behavior initializer thunk (not used currently)
828828
global ::= context identifier identifier 'Tb' // property behavior setter thunk (not used currently)
829-
global ::= global 'T_' specialization // reset substitutions before demangling specialization
829+
global ::= global specialization // function specialization
830+
global ::= global 'Tm' // merged function
830831
global ::= entity // some identifiable thing
831832
global ::= type type generic-signature? 'T' REABSTRACT-THUNK-TYPE // reabstraction thunk helper function
832833

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ NODE(LazyProtocolWitnessTableAccessor)
101101
NODE(LazyProtocolWitnessTableCacheVariable)
102102
NODE(LocalDeclName)
103103
CONTEXT_NODE(MaterializeForSet)
104+
NODE(MergedFunction)
104105
NODE(Metatype)
105106
NODE(MetatypeRepresentation)
106107
NODE(Metaclass)

lib/Demangling/Demangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static bool isFunctionAttr(Node::Kind kind) {
100100
case Node::Kind::VTableAttribute:
101101
case Node::Kind::PartialApplyForwarder:
102102
case Node::Kind::PartialApplyObjCForwarder:
103+
case Node::Kind::MergedFunction:
103104
return true;
104105
default:
105106
return false;
@@ -1219,6 +1220,7 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
12191220
case 'd': return createNode(Node::Kind::DirectMethodReferenceAttribute);
12201221
case 'a': return createNode(Node::Kind::PartialApplyObjCForwarder);
12211222
case 'A': return createNode(Node::Kind::PartialApplyForwarder);
1223+
case 'm': return createNode(Node::Kind::MergedFunction);
12221224
case 'V': {
12231225
NodePointer Base = popNode(isEntity);
12241226
NodePointer Derived = popNode(isEntity);

lib/Demangling/NodePrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ class NodePrinter {
347347
case Node::Kind::LocalDeclName:
348348
case Node::Kind::PrivateDeclName:
349349
case Node::Kind::MaterializeForSet:
350+
case Node::Kind::MergedFunction:
350351
case Node::Kind::Metaclass:
351352
case Node::Kind::NativeOwningAddressor:
352353
case Node::Kind::NativeOwningMutableAddressor:
@@ -1238,6 +1239,11 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
12381239
print(Node->getChild(Node->getNumChildren() - 1));
12391240
return nullptr;
12401241
}
1242+
case Node::Kind::MergedFunction:
1243+
if (!Options.ShortenThunk) {
1244+
Printer << "merged ";
1245+
}
1246+
return nullptr;
12411247
case Node::Kind::GenericTypeMetadataPattern:
12421248
Printer << "generic type metadata pattern for ";
12431249
print(Node->getChild(0));

lib/Demangling/OldRemangler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,10 @@ void Remangler::manglePartialApplyObjCForwarder(Node *node) {
653653
mangleSingleChildNode(node); // global
654654
}
655655

656+
void Remangler::mangleMergedFunction(Node *node) {
657+
Out << "Tm";
658+
}
659+
656660
void Remangler::mangleDirectness(Node *node) {
657661
auto getChar = [](Directness d) -> char {
658662
switch (d) {

lib/Demangling/Remangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,7 @@ void Remangler::mangleGlobal(Node *node) {
10631063
case Node::Kind::DynamicAttribute:
10641064
case Node::Kind::VTableAttribute:
10651065
case Node::Kind::DirectMethodReferenceAttribute:
1066+
case Node::Kind::MergedFunction:
10661067
mangleInReverseOrder = true;
10671068
break;
10681069
default:
@@ -1368,6 +1369,10 @@ void Remangler::manglePartialApplyObjCForwarder(Node *node) {
13681369
Buffer << "Ta";
13691370
}
13701371

1372+
void Remangler::mangleMergedFunction(Node *node) {
1373+
Buffer << "Tm";
1374+
}
1375+
13711376
void Remangler::manglePostfixOperator(Node *node) {
13721377
mangleIdentifierImpl(node, /*isOperator*/ true);
13731378
Buffer << "oP";

lib/LLVMPasses/LLVMMergeFunctions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ void SwiftMergeFunctions::mergeWithParams(const FunctionInfos &FInfos,
861861
// a name which can be demangled in a meaningful way.
862862
Function *NewFunction = Function::Create(funcType,
863863
FirstF->getLinkage(),
864-
FirstF->getName() + "_merged");
864+
FirstF->getName() + "Tm");
865865
NewFunction->copyAttributesFrom(FirstF);
866866
// NOTE: this function is not externally available, do ensure that we reset
867867
// the DLL storage

test/Demangle/Inputs/manglings.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,5 @@ _T0Rml ---> _T0Rml
258258
_T0Tk ---> _T0Tk
259259
_T0A8 ---> _T0A8
260260
_T0s30ReversedRandomAccessCollectionVyxGTfq3nnpf_nTfq1cn_nTfq4x_n ---> _T0s30ReversedRandomAccessCollectionVyxGTfq3nnpf_nTfq1cn_nTfq4x_n
261+
_T03abc6testitySiFTm ---> merged abc.testit(Swift.Int) -> ()
261262

test/Demangle/Inputs/simplified-manglings.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,5 @@ _TFC4testP33_83378C430F65473055F1BD53F3ADCDB71C5doFoofT_T_ ---> C.doFoo()
203203
_TTRXFo_oCSo13SKPhysicsBodydVSC7CGPointdVSC8CGVectordGSpV10ObjectiveC8ObjCBool___XFdCb_dS_dS0_dS1_dGSpS3____ ---> thunk for @callee_owned (@owned SKPhysicsBody, @unowned CGPoint, @unowned CGVector, @unowned UnsafeMutablePointer<ObjCBool>) -> ()
204204
_T0So13SKPhysicsBodyCSC7CGPointVSC8CGVectorVSpy10ObjectiveC8ObjCBoolVGIxxyyy_AbdFSpyAIGIyByyyy_TR ---> thunk for @callee_owned (@owned SKPhysicsBody, @unowned CGPoint, @unowned CGVector, @unowned UnsafeMutablePointer<ObjCBool>) -> ()
205205
_T04main1_yyF ---> _()
206+
_T03abc6testitySiFTm ---> testit(_:)
207+

test/LLVMPasses/merge_func.ll

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
; Test the most trivial example.
1010

1111
; CHECK-LABEL: define i32 @simple_func1(i32 %x, i32 %y)
12-
; CHECK: %1 = tail call i32 @simple_func1_merged(i32 %x, i32 %y, i32* @g1)
12+
; CHECK: %1 = tail call i32 @simple_func1Tm(i32 %x, i32 %y, i32* @g1)
1313
; CHECK: ret i32 %1
1414
define i32 @simple_func1(i32 %x, i32 %y) {
1515
%sum = add i32 %x, %y
@@ -20,7 +20,7 @@ define i32 @simple_func1(i32 %x, i32 %y) {
2020
}
2121

2222
; CHECK-LABEL: define i32 @simple_func2(i32 %x, i32 %y)
23-
; CHECK: %1 = tail call i32 @simple_func1_merged(i32 %x, i32 %y, i32* @g2)
23+
; CHECK: %1 = tail call i32 @simple_func1Tm(i32 %x, i32 %y, i32* @g2)
2424
; CHECK: ret i32 %1
2525
define i32 @simple_func2(i32 %x, i32 %y) {
2626
%sum = add i32 %x, %y
@@ -30,15 +30,15 @@ define i32 @simple_func2(i32 %x, i32 %y) {
3030
ret i32 %sum3
3131
}
3232

33-
; CHECK-LABEL: define internal i32 @simple_func1_merged(i32, i32, i32*)
33+
; CHECK-LABEL: define internal i32 @simple_func1Tm(i32, i32, i32*)
3434
; CHECK: %l = load i32, i32* %2
3535
; CHECK: ret
3636

3737

3838
; Merge 3 functions with 3 types of differing instructions: load, store and call.
3939

4040
; CHECK-LABEL: define i32 @func1_of_3(i32 %x)
41-
; CHECK: %1 = tail call i32 @func1_of_3_merged(i32 %x, i32* @g1, i32* @g1, void (i32)* @callee1)
41+
; CHECK: %1 = tail call i32 @func1_of_3Tm(i32 %x, i32* @g1, i32* @g1, void (i32)* @callee1)
4242
; CHECK: ret i32 %1
4343
define i32 @func1_of_3(i32 %x) {
4444
%l1 = load i32, i32* @g1, align 4
@@ -52,7 +52,7 @@ define i32 @func1_of_3(i32 %x) {
5252
}
5353

5454
; CHECK-LABEL: define i32 @func2_of_3(i32 %x)
55-
; CHECK: %1 = tail call i32 @func1_of_3_merged(i32 %x, i32* @g2, i32* @g2, void (i32)* @callee2)
55+
; CHECK: %1 = tail call i32 @func1_of_3Tm(i32 %x, i32* @g2, i32* @g2, void (i32)* @callee2)
5656
; CHECK: ret i32 %1
5757
define i32 @func2_of_3(i32 %x) {
5858
%l1 = load i32, i32* @g2, align 4
@@ -66,7 +66,7 @@ define i32 @func2_of_3(i32 %x) {
6666
}
6767

6868
; CHECK-LABEL: define i32 @func3_of_3(i32 %x)
69-
; CHECK: %1 = tail call i32 @func1_of_3_merged(i32 %x, i32* @g3, i32* @g1, void (i32)* @callee3)
69+
; CHECK: %1 = tail call i32 @func1_of_3Tm(i32 %x, i32* @g3, i32* @g1, void (i32)* @callee3)
7070
; CHECK: ret i32 %1
7171
define i32 @func3_of_3(i32 %x) {
7272
%l1 = load i32, i32* @g3, align 4
@@ -79,7 +79,7 @@ define i32 @func3_of_3(i32 %x) {
7979
ret i32 %sum3
8080
}
8181

82-
; CHECK-LABEL: define internal i32 @func1_of_3_merged(i32, i32*, i32*, void (i32)*)
82+
; CHECK-LABEL: define internal i32 @func1_of_3Tm(i32, i32*, i32*, void (i32)*)
8383
; CHECK: %l1 = load i32, i32* %1
8484
; CHECK: %l2 = load i32, i32* %2
8585
; CHECK: store i32 %sum2, i32* %1
@@ -93,7 +93,7 @@ declare void @callee3(i32 %x)
9393
; Preserve attributes
9494

9595
; CHECK-LABEL: define void @sret_func1(i32* sret %p, i32 %x, i32 %y)
96-
; CHECK: tail call void @sret_func1_merged(i32* sret %p, i32 %x, i32 %y, i32* @g1)
96+
; CHECK: tail call void @sret_func1Tm(i32* sret %p, i32 %x, i32 %y, i32* @g1)
9797
; CHECK: ret void
9898
define void @sret_func1(i32* sret %p, i32 %x, i32 %y) {
9999
%sum = add i32 %x, %y
@@ -104,7 +104,7 @@ define void @sret_func1(i32* sret %p, i32 %x, i32 %y) {
104104
}
105105

106106
; CHECK-LABEL: define void @sret_func2(i32* sret %p, i32 %x, i32 %y)
107-
; CHECK: tail call void @sret_func1_merged(i32* sret %p, i32 %x, i32 %y, i32* @g2)
107+
; CHECK: tail call void @sret_func1Tm(i32* sret %p, i32 %x, i32 %y, i32* @g2)
108108
; CHECK: ret void
109109
define void @sret_func2(i32* sret %p, i32 %x, i32 %y) {
110110
%sum = add i32 %x, %y
@@ -114,7 +114,7 @@ define void @sret_func2(i32* sret %p, i32 %x, i32 %y) {
114114
ret void
115115
}
116116

117-
; CHECK-LABEL: define internal void @sret_func1_merged(i32* sret, i32, i32, i32*)
117+
; CHECK-LABEL: define internal void @sret_func1Tm(i32* sret, i32, i32, i32*)
118118
; CHECK: %l = load i32, i32* %3, align 4
119119
; CHECK: store i32 %sum2, i32* %0
120120
; CHECK: ret
@@ -124,7 +124,7 @@ define void @sret_func2(i32* sret %p, i32 %x, i32 %y) {
124124
; Instead merge those functions which match best.
125125

126126
; CHECK-LABEL: define i32 @func1_merged_with3(i32 %x)
127-
; CHECK: %1 = tail call i32 @func1_merged_with3_merged(i32 %x, i32* @g1)
127+
; CHECK: %1 = tail call i32 @func1_merged_with3Tm(i32 %x, i32* @g1)
128128
; CHECK: ret i32 %1
129129
define i32 @func1_merged_with3(i32 %x) {
130130
%l1 = load i32, i32* @g1, align 4
@@ -141,7 +141,7 @@ define i32 @func1_merged_with3(i32 %x) {
141141
}
142142

143143
; CHECK-LABEL: define i32 @func2_merged_with4(i32 %x)
144-
; CHECK: %1 = tail call i32 @func2_merged_with4_merged(i32 %x, i32* @g2)
144+
; CHECK: %1 = tail call i32 @func2_merged_with4Tm(i32 %x, i32* @g2)
145145
; CHECK: ret i32 %1
146146
define i32 @func2_merged_with4(i32 %x) {
147147
%l1 = load i32, i32* @g2, align 4
@@ -158,7 +158,7 @@ define i32 @func2_merged_with4(i32 %x) {
158158
}
159159

160160
; CHECK-LABEL: define i32 @func3_merged_with1(i32 %x)
161-
; CHECK: %1 = tail call i32 @func1_merged_with3_merged(i32 %x, i32* @g2)
161+
; CHECK: %1 = tail call i32 @func1_merged_with3Tm(i32 %x, i32* @g2)
162162
; CHECK: ret i32 %1
163163
define i32 @func3_merged_with1(i32 %x) {
164164
%l1 = load i32, i32* @g2, align 4
@@ -174,7 +174,7 @@ define i32 @func3_merged_with1(i32 %x) {
174174
ret i32 %sum5
175175
}
176176

177-
; CHECK-LABEL: define internal i32 @func1_merged_with3_merged(i32, i32*)
177+
; CHECK-LABEL: define internal i32 @func1_merged_with3Tm(i32, i32*)
178178
; CHECK: load i32, i32* %1, align 4
179179
; CHECK: load i32, i32* @g2, align 4
180180
; CHECK: load i32, i32* @g3, align 4
@@ -183,7 +183,7 @@ define i32 @func3_merged_with1(i32 %x) {
183183
; CHECK: ret i32
184184

185185
; CHECK-LABEL: define i32 @func4_merged_with2(i32 %x) {
186-
; CHECK: %1 = tail call i32 @func2_merged_with4_merged(i32 %x, i32* @g1)
186+
; CHECK: %1 = tail call i32 @func2_merged_with4Tm(i32 %x, i32* @g1)
187187
; CHECK: ret i32 %1
188188
define i32 @func4_merged_with2(i32 %x) {
189189
%l1 = load i32, i32* @g1, align 4
@@ -205,7 +205,7 @@ define i32 @func4_merged_with2(i32 %x) {
205205
; Also check that the calling convention is preserved.
206206

207207
; CHECK-LABEL: define fastcc i32 @callee1_a(i32 %x, i32 %y)
208-
; CHECK: %1 = tail call fastcc i32 @callee1_a_merged(i32 %x, i32 %y, i32* @g1)
208+
; CHECK: %1 = tail call fastcc i32 @callee1_aTm(i32 %x, i32 %y, i32* @g1)
209209
; CHECK: ret i32 %1
210210
define fastcc i32 @callee1_a(i32 %x, i32 %y) {
211211
%sum = add i32 %x, %y
@@ -216,7 +216,7 @@ define fastcc i32 @callee1_a(i32 %x, i32 %y) {
216216
}
217217

218218
; CHECK-LABEL: define fastcc i32 @callee1_b(i32 %x, i32 %y)
219-
; CHECK: %1 = tail call fastcc i32 @callee1_a_merged(i32 %x, i32 %y, i32* @g2)
219+
; CHECK: %1 = tail call fastcc i32 @callee1_aTm(i32 %x, i32 %y, i32* @g2)
220220
; CHECK: ret i32 %1
221221
define fastcc i32 @callee1_b(i32 %x, i32 %y) {
222222
%sum = add i32 %x, %y
@@ -226,8 +226,8 @@ define fastcc i32 @callee1_b(i32 %x, i32 %y) {
226226
ret i32 %sum3
227227
}
228228

229-
; CHECK-LABEL: define internal fastcc i32 @callee1_a_merged(i32, i32, i32*)
230-
; CHECK: call i32 @callee2_a_merged(i32 %sum2, i32 %1, i32* %2)
229+
; CHECK-LABEL: define internal fastcc i32 @callee1_aTm(i32, i32, i32*)
230+
; CHECK: call i32 @callee2_aTm(i32 %sum2, i32 %1, i32* %2)
231231
; CHECK: ret
232232

233233
; CHECK-NOT: @callee2_a(
@@ -249,7 +249,7 @@ define internal i32 @callee2_b(i32 %x, i32 %y) {
249249
}
250250

251251
; CHECK-LABEL: define i32 @caller_a(i32 %x, i32 %y)
252-
; CHECK: %1 = tail call i32 @caller_a_merged(i32 %x, i32 %y, i32* @g1)
252+
; CHECK: %1 = tail call i32 @caller_aTm(i32 %x, i32 %y, i32* @g1)
253253
; CHECK: ret i32 %1
254254
define i32 @caller_a(i32 %x, i32 %y) {
255255
%sum = add i32 %x, %y
@@ -260,7 +260,7 @@ define i32 @caller_a(i32 %x, i32 %y) {
260260
}
261261

262262
; CHECK-LABEL: define i32 @caller_b(i32 %x, i32 %y)
263-
; CHECK: %1 = tail call i32 @caller_a_merged(i32 %x, i32 %y, i32* @g2)
263+
; CHECK: %1 = tail call i32 @caller_aTm(i32 %x, i32 %y, i32* @g2)
264264
; CHECK: ret i32 %1
265265
define i32 @caller_b(i32 %x, i32 %y) {
266266
%sum = add i32 %x, %y
@@ -270,8 +270,8 @@ define i32 @caller_b(i32 %x, i32 %y) {
270270
ret i32 %sum3
271271
}
272272

273-
; CHECK-LABEL: define internal i32 @caller_a_merged(i32, i32, i32*)
274-
; CHECK: call fastcc i32 @callee1_a_merged(i32 %sum2, i32 %1, i32* %2)
273+
; CHECK-LABEL: define internal i32 @caller_aTm(i32, i32, i32*)
274+
; CHECK: call fastcc i32 @callee1_aTm(i32 %sum2, i32 %1, i32* %2)
275275
; CHECK: ret
276276

277277

@@ -327,7 +327,7 @@ done:
327327
; Check self recursive functions
328328

329329
; CHECK-LABEL: define internal void @recursive1(i32 %x, i32 %y)
330-
; CHECK: tail call void @recursive1_merged(i32 %x, i32 %y, i32* @g1, void (i32, i32)* @recursive1)
330+
; CHECK: tail call void @recursive1Tm(i32 %x, i32 %y, i32* @g1, void (i32, i32)* @recursive1)
331331
; CHECK: ret void
332332
define internal void @recursive1(i32 %x, i32 %y) {
333333
br i1 undef, label %bb1, label %bb2
@@ -342,7 +342,7 @@ bb2:
342342
}
343343

344344
; CHECK-LABEL: define internal void @recursive2(i32 %x, i32 %y)
345-
; CHECK: tail call void @recursive1_merged(i32 %x, i32 %y, i32* @g2, void (i32, i32)* @recursive2)
345+
; CHECK: tail call void @recursive1Tm(i32 %x, i32 %y, i32* @g2, void (i32, i32)* @recursive2)
346346
; CHECK: ret void
347347
define internal void @recursive2(i32 %x, i32 %y) {
348348
br i1 undef, label %bb1, label %bb2
@@ -355,14 +355,14 @@ bb1:
355355
bb2:
356356
ret void
357357
}
358-
; CHECK-LABEL: define internal void @recursive1_merged(i32, i32, i32*, void (i32, i32)*)
358+
; CHECK-LABEL: define internal void @recursive1Tm(i32, i32, i32*, void (i32, i32)*)
359359
; CHECK: load i32, i32* %2
360360
; CHECK: call void %3(i32 %0, i32 %1)
361361
; CHECK: ret void
362362

363363

364364
; CHECK-LABEL: define internal void @another_recursive_func(i32 %x)
365-
; CHECK: tail call void @another_recursive_func_merged(i32 %x, i32* @g1, void (i32)* @another_recursive_func)
365+
; CHECK: tail call void @another_recursive_funcTm(i32 %x, i32* @g1, void (i32)* @another_recursive_func)
366366
; CHECK: ret void
367367
define internal void @another_recursive_func(i32 %x) {
368368
br i1 undef, label %bb1, label %bb2
@@ -377,7 +377,7 @@ bb2:
377377
}
378378
; CHECK-NOT: @not_really_recursive(
379379

380-
; CHECK-LABEL: define internal void @another_recursive_func_merged(i32, i32*, void (i32)*)
380+
; CHECK-LABEL: define internal void @another_recursive_funcTm(i32, i32*, void (i32)*)
381381
; CHECK: store i32 %0, i32* %1
382382
; CHECK: call void %2(i32 %0)
383383
; CHECK: ret void
@@ -398,7 +398,7 @@ bb2:
398398
; CHECK: call void @recursive1(i32 %x, i32 %x)
399399
; CHECK: call void @recursive2(i32 %x, i32 %x)
400400
; CHECK: call void @another_recursive_func(i32 %x)
401-
; CHECK: call void @another_recursive_func_merged(i32 %x, i32* @g2, void (i32)* @callee1)
401+
; CHECK: call void @another_recursive_funcTm(i32 %x, i32* @g2, void (i32)* @callee1)
402402
; CHECK: ret void
403403
define void @call_recursive_funcs(i32 %x) {
404404
call void @recursive1(i32 %x, i32 %x)

test/LLVMPasses/merge_func_coff.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ define dllexport i32 @h(i32 %x, i32 %y) {
1818
ret i32 %sum3
1919
}
2020

21-
; CHECK-NOT: define internal dllexport i32 @f_merged(i32, i32)
22-
; CHECK-LABEL: define internal i32 @f_merged(i32, i32)
21+
; CHECK-NOT: define internal dllexport i32 @fTm(i32, i32)
22+
; CHECK-LABEL: define internal i32 @fTm(i32, i32)
2323

0 commit comments

Comments
 (0)