Skip to content

Commit f4db364

Browse files
author
Joe Shajrawi
committed
Code Size: Outline copy addr instruction
1 parent 24f74f2 commit f4db364

22 files changed

+466
-229
lines changed

docs/ABI/Mangling.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ Globals
8383
global ::= type 'We' // Outlined Consume Function Type
8484
global ::= type 'Wr' // Outlined Retain Function Type
8585
global ::= type 'Ws' // Outlined Release Function Type
86+
global ::= type 'Wb' // Outlined InitializeWithTake Function Type
87+
global ::= type 'Wc' // Outlined InitializeWithCopy Function Type
88+
global ::= type 'Wd' // Outlined AssignWithTake Function Type
89+
global ::= type 'Wf' // Outlined AssignWithCopy Function Type
8690

8791
assoc_type_path ::= identifier '_' identifier*
8892

include/swift/Demangling/DemangleNodes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ NODE(OutlinedCopy)
189189
NODE(OutlinedConsume)
190190
NODE(OutlinedRetain)
191191
NODE(OutlinedRelease)
192+
NODE(OutlinedInitializeWithTake)
193+
NODE(OutlinedInitializeWithCopy)
194+
NODE(OutlinedAssignWithTake)
195+
NODE(OutlinedAssignWithCopy)
192196
NODE(OutlinedVariable)
193197
NODE(AssocTypePath)
194198
#undef CONTEXT_NODE

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// in source control, you should also update the comment to briefly
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
57-
const uint16_t VERSION_MINOR = 372; // Last change: VTable serialized
57+
const uint16_t VERSION_MINOR = 373; // Last change: Outlined CopyAddr
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;

lib/Demangling/Demangler.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,23 @@ NodePointer Demangler::demangleWitness() {
16871687
return createWithChild(Node::Kind::OutlinedRelease,
16881688
popNode(Node::Kind::Type));
16891689
}
1690+
case 'b': {
1691+
return createWithChild(Node::Kind::OutlinedInitializeWithTake,
1692+
popNode(Node::Kind::Type));
1693+
}
1694+
case 'c': {
1695+
return createWithChild(Node::Kind::OutlinedInitializeWithCopy,
1696+
popNode(Node::Kind::Type));
1697+
}
1698+
case 'd': {
1699+
return createWithChild(Node::Kind::OutlinedAssignWithTake,
1700+
popNode(Node::Kind::Type));
1701+
}
1702+
case 'f': {
1703+
return createWithChild(Node::Kind::OutlinedAssignWithCopy,
1704+
popNode(Node::Kind::Type));
1705+
}
1706+
16901707
default:
16911708
return nullptr;
16921709
}

lib/Demangling/NodePrinter.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,10 @@ class NodePrinter {
416416
case Node::Kind::OutlinedConsume:
417417
case Node::Kind::OutlinedRetain:
418418
case Node::Kind::OutlinedRelease:
419+
case Node::Kind::OutlinedInitializeWithTake:
420+
case Node::Kind::OutlinedInitializeWithCopy:
421+
case Node::Kind::OutlinedAssignWithTake:
422+
case Node::Kind::OutlinedAssignWithCopy:
419423
case Node::Kind::OutlinedVariable:
420424
case Node::Kind::AssocTypePath:
421425
return false;
@@ -809,6 +813,22 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
809813
Printer << "outlined release of ";
810814
print(Node->getChild(0));
811815
return nullptr;
816+
case Node::Kind::OutlinedInitializeWithTake:
817+
Printer << "outlined init with take of ";
818+
print(Node->getChild(0));
819+
return nullptr;
820+
case Node::Kind::OutlinedInitializeWithCopy:
821+
Printer << "outlined init with copy of ";
822+
print(Node->getChild(0));
823+
return nullptr;
824+
case Node::Kind::OutlinedAssignWithTake:
825+
Printer << "outlined assign with take of ";
826+
print(Node->getChild(0));
827+
return nullptr;
828+
case Node::Kind::OutlinedAssignWithCopy:
829+
Printer << "outlined assign with copy of ";
830+
print(Node->getChild(0));
831+
return nullptr;
812832
case Node::Kind::OutlinedVariable:
813833
Printer << "outlined variable #" << Node->getIndex() << " of ";
814834
return nullptr;

lib/Demangling/OldRemangler.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,6 +1700,26 @@ void Remangler::mangleOutlinedRelease(Node *node) {
17001700
mangleSingleChildNode(node);
17011701
}
17021702

1703+
void Remangler::mangleOutlinedInitializeWithTake(Node *node) {
1704+
Out << "Wb";
1705+
mangleSingleChildNode(node);
1706+
}
1707+
1708+
void Remangler::mangleOutlinedInitializeWithCopy(Node *node) {
1709+
Out << "Wc";
1710+
mangleSingleChildNode(node);
1711+
}
1712+
1713+
void Remangler::mangleOutlinedAssignWithTake(Node *node) {
1714+
Out << "Wd";
1715+
mangleSingleChildNode(node);
1716+
}
1717+
1718+
void Remangler::mangleOutlinedAssignWithCopy(Node *node) {
1719+
Out << "Wf";
1720+
mangleSingleChildNode(node);
1721+
}
1722+
17031723
void Remangler::mangleOutlinedVariable(Node *node) {
17041724
Out << "Tv" << node->getIndex();
17051725
mangleSingleChildNode(node);

lib/Demangling/Remangler.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,26 @@ void Remangler::mangleOutlinedRelease(Node *node) {
17471747
Buffer << "Ws";
17481748
}
17491749

1750+
void Remangler::mangleOutlinedInitializeWithTake(Node *node) {
1751+
mangleSingleChildNode(node);
1752+
Buffer << "Wb";
1753+
}
1754+
1755+
void Remangler::mangleOutlinedInitializeWithCopy(Node *node) {
1756+
mangleSingleChildNode(node);
1757+
Buffer << "Wc";
1758+
}
1759+
1760+
void Remangler::mangleOutlinedAssignWithTake(Node *node) {
1761+
mangleSingleChildNode(node);
1762+
Buffer << "Wd";
1763+
}
1764+
1765+
void Remangler::mangleOutlinedAssignWithCopy(Node *node) {
1766+
mangleSingleChildNode(node);
1767+
Buffer << "Wf";
1768+
}
1769+
17501770
void Remangler::mangleOutlinedVariable(Node *node) {
17511771
Buffer << "Tv";
17521772
mangleIndex(node->getIndex());

lib/IRGen/GenDecl.cpp

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/Decl.h"
2020
#include "swift/AST/DiagnosticEngine.h"
2121
#include "swift/AST/DiagnosticsIRGen.h"
22+
#include "swift/AST/GenericEnvironment.h"
2223
#include "swift/AST/GenericSignature.h"
2324
#include "swift/AST/IRGenOptions.h"
2425
#include "swift/AST/Module.h"
@@ -39,10 +40,10 @@
3940
#include "clang/AST/GlobalDecl.h"
4041
#include "llvm/ADT/SmallString.h"
4142
#include "llvm/IR/GlobalAlias.h"
43+
#include "llvm/IR/InlineAsm.h"
4244
#include "llvm/IR/Module.h"
4345
#include "llvm/IR/TypeBuilder.h"
4446
#include "llvm/IR/Value.h"
45-
#include "llvm/IR/InlineAsm.h"
4647
#include "llvm/Support/Compiler.h"
4748
#include "llvm/Support/ConvertUTF.h"
4849
#include "llvm/Support/Path.h"
@@ -3517,6 +3518,7 @@ llvm::Constant *IRGenModule::getOrCreateRetainFunction(const TypeInfo &objectTI,
35173518
return getOrCreateHelperFunction(
35183519
funcName, llvmType, argTys,
35193520
[&](IRGenFunction &IGF) {
3521+
IGF.setInOutlinedFunction();
35203522
auto it = IGF.CurFn->arg_begin();
35213523
Address addr(&*it++, loadableTI->getFixedAlignment());
35223524
Explosion loaded;
@@ -3540,6 +3542,7 @@ IRGenModule::getOrCreateReleaseFunction(const TypeInfo &objectTI, Type t,
35403542
return getOrCreateHelperFunction(
35413543
funcName, llvmType, argTys,
35423544
[&](IRGenFunction &IGF) {
3545+
IGF.setInOutlinedFunction();
35433546
auto it = IGF.CurFn->arg_begin();
35443547
Address addr(&*it++, loadableTI->getFixedAlignment());
35453548
Explosion loaded;
@@ -3549,3 +3552,87 @@ IRGenModule::getOrCreateReleaseFunction(const TypeInfo &objectTI, Type t,
35493552
},
35503553
true /*setIsNoInline*/);
35513554
}
3555+
3556+
void IRGenModule::generateCallToOutlinedCopyAddr(
3557+
IRGenFunction &IGF, const TypeInfo &objectTI, Address dest, Address src,
3558+
SILType T, const OutlinedCopyAddrFunction MethodToCall) {
3559+
llvm::Type *llvmType = dest->getType();
3560+
auto *outlinedF = (this->*MethodToCall)(objectTI, llvmType, T);
3561+
llvm::Value *args[] = {src.getAddress(), dest.getAddress()};
3562+
llvm::CallInst *call = IGF.Builder.CreateCall(outlinedF, args);
3563+
call->setCallingConv(DefaultCC);
3564+
}
3565+
3566+
llvm::Constant *IRGenModule::getOrCreateOutlinedCopyAddrHelperFunction(
3567+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy,
3568+
std::string funcName,
3569+
llvm::function_ref<void(const TypeInfo &objectTI, IRGenFunction &IGF,
3570+
Address dest, Address src, SILType T)>
3571+
Generate) {
3572+
llvm::Type *argTys[] = {llvmType, llvmType};
3573+
return getOrCreateHelperFunction(
3574+
funcName, llvmType, argTys,
3575+
[&](IRGenFunction &IGF) {
3576+
IGF.setInOutlinedFunction();
3577+
auto it = IGF.CurFn->arg_begin();
3578+
Address src(&*it++, objectTI.getBestKnownAlignment());
3579+
Address dest(&*it++, objectTI.getBestKnownAlignment());
3580+
Generate(objectTI, IGF, dest, src, addrTy);
3581+
IGF.Builder.CreateRet(dest.getAddress());
3582+
},
3583+
true /*setIsNoInline*/);
3584+
}
3585+
3586+
llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction(
3587+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy) {
3588+
IRGenMangler mangler;
3589+
CanType canType = addrTy.getObjectType().getSwiftRValueType();
3590+
std::string funcName =
3591+
mangler.mangleOutlinedInitializeWithTakeFunction(canType);
3592+
auto GenFunc = [this](const TypeInfo &objectTI, IRGenFunction &IGF,
3593+
Address dest, Address src, SILType T) {
3594+
objectTI.initializeWithTake(IGF, dest, src, T);
3595+
};
3596+
return getOrCreateOutlinedCopyAddrHelperFunction(objectTI, llvmType, addrTy,
3597+
funcName, GenFunc);
3598+
}
3599+
3600+
llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithCopyFunction(
3601+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy) {
3602+
IRGenMangler mangler;
3603+
CanType canType = addrTy.getObjectType().getSwiftRValueType();
3604+
std::string funcName =
3605+
mangler.mangleOutlinedInitializeWithCopyFunction(canType);
3606+
auto GenFunc = [this](const TypeInfo &objectTI, IRGenFunction &IGF,
3607+
Address dest, Address src, SILType T) {
3608+
objectTI.initializeWithCopy(IGF, dest, src, T);
3609+
};
3610+
return getOrCreateOutlinedCopyAddrHelperFunction(objectTI, llvmType, addrTy,
3611+
funcName, GenFunc);
3612+
}
3613+
3614+
llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithTakeFunction(
3615+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy) {
3616+
IRGenMangler mangler;
3617+
CanType canType = addrTy.getObjectType().getSwiftRValueType();
3618+
std::string funcName = mangler.mangleOutlinedAssignWithTakeFunction(canType);
3619+
auto GenFunc = [this](const TypeInfo &objectTI, IRGenFunction &IGF,
3620+
Address dest, Address src, SILType T) {
3621+
objectTI.assignWithTake(IGF, dest, src, T);
3622+
};
3623+
return getOrCreateOutlinedCopyAddrHelperFunction(objectTI, llvmType, addrTy,
3624+
funcName, GenFunc);
3625+
}
3626+
3627+
llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithCopyFunction(
3628+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy) {
3629+
IRGenMangler mangler;
3630+
CanType canType = addrTy.getObjectType().getSwiftRValueType();
3631+
std::string funcName = mangler.mangleOutlinedAssignWithCopyFunction(canType);
3632+
auto GenFunc = [this](const TypeInfo &objectTI, IRGenFunction &IGF,
3633+
Address dest, Address src, SILType T) {
3634+
objectTI.assignWithCopy(IGF, dest, src, T);
3635+
};
3636+
return getOrCreateOutlinedCopyAddrHelperFunction(objectTI, llvmType, addrTy,
3637+
funcName, GenFunc);
3638+
}

lib/IRGen/GenEnum.cpp

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2598,25 +2598,57 @@ namespace {
25982598
void assignWithCopy(IRGenFunction &IGF, Address dest, Address src,
25992599
SILType T)
26002600
const override {
2601-
emitIndirectAssign(IGF, dest, src, T, IsNotTake);
2601+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
2602+
(T.hasArchetype())) {
2603+
emitIndirectAssign(IGF, dest, src, T, IsNotTake);
2604+
} else {
2605+
// Create an outlined function to avoid explosion
2606+
IGF.IGM.generateCallToOutlinedCopyAddr(
2607+
IGF, *TI, dest, src, T,
2608+
&IRGenModule::getOrCreateOutlinedAssignWithCopyFunction);
2609+
}
26022610
}
26032611

26042612
void assignWithTake(IRGenFunction &IGF, Address dest, Address src,
26052613
SILType T)
26062614
const override {
2607-
emitIndirectAssign(IGF, dest, src, T, IsTake);
2615+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
2616+
(T.hasArchetype())) {
2617+
emitIndirectAssign(IGF, dest, src, T, IsTake);
2618+
} else {
2619+
// Create an outlined function to avoid explosion
2620+
IGF.IGM.generateCallToOutlinedCopyAddr(
2621+
IGF, *TI, dest, src, T,
2622+
&IRGenModule::getOrCreateOutlinedAssignWithTakeFunction);
2623+
}
26082624
}
26092625

26102626
void initializeWithCopy(IRGenFunction &IGF, Address dest, Address src,
26112627
SILType T)
26122628
const override {
2613-
emitIndirectInitialize(IGF, dest, src, T, IsNotTake);
2629+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
2630+
(T.hasArchetype())) {
2631+
emitIndirectInitialize(IGF, dest, src, T, IsNotTake);
2632+
} else {
2633+
// Create an outlined function to avoid explosion
2634+
IGF.IGM.generateCallToOutlinedCopyAddr(
2635+
IGF, *TI, dest, src, T,
2636+
&IRGenModule::getOrCreateOutlinedInitializeWithCopyFunction);
2637+
}
26142638
}
26152639

26162640
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
26172641
SILType T)
26182642
const override {
2619-
emitIndirectInitialize(IGF, dest, src, T, IsTake);
2643+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
2644+
(T.hasArchetype())) {
2645+
emitIndirectInitialize(IGF, dest, src, T, IsTake);
2646+
} else {
2647+
// Create an outlined function to avoid explosion
2648+
IGF.IGM.generateCallToOutlinedCopyAddr(
2649+
IGF, *TI, dest, src, T,
2650+
&IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction);
2651+
}
26202652
}
26212653

26222654
void storeTag(IRGenFunction &IGF,
@@ -4211,25 +4243,57 @@ namespace {
42114243
void assignWithCopy(IRGenFunction &IGF, Address dest, Address src,
42124244
SILType T)
42134245
const override {
4214-
emitIndirectAssign(IGF, dest, src, T, IsNotTake);
4246+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
4247+
(T.hasArchetype())) {
4248+
emitIndirectAssign(IGF, dest, src, T, IsNotTake);
4249+
} else {
4250+
// Create an outlined function to avoid explosion
4251+
IGF.IGM.generateCallToOutlinedCopyAddr(
4252+
IGF, *TI, dest, src, T,
4253+
&IRGenModule::getOrCreateOutlinedAssignWithCopyFunction);
4254+
}
42154255
}
42164256

42174257
void assignWithTake(IRGenFunction &IGF, Address dest, Address src,
42184258
SILType T)
42194259
const override {
4220-
emitIndirectAssign(IGF, dest, src, T, IsTake);
4260+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
4261+
(T.hasArchetype())) {
4262+
emitIndirectAssign(IGF, dest, src, T, IsTake);
4263+
} else {
4264+
// Create an outlined function to avoid explosion
4265+
IGF.IGM.generateCallToOutlinedCopyAddr(
4266+
IGF, *TI, dest, src, T,
4267+
&IRGenModule::getOrCreateOutlinedAssignWithTakeFunction);
4268+
}
42214269
}
42224270

42234271
void initializeWithCopy(IRGenFunction &IGF, Address dest, Address src,
42244272
SILType T)
42254273
const override {
4226-
emitIndirectInitialize(IGF, dest, src, T, IsNotTake);
4274+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
4275+
(T.hasArchetype())) {
4276+
emitIndirectInitialize(IGF, dest, src, T, IsNotTake);
4277+
} else {
4278+
// Create an outlined function to avoid explosion
4279+
IGF.IGM.generateCallToOutlinedCopyAddr(
4280+
IGF, *TI, dest, src, T,
4281+
&IRGenModule::getOrCreateOutlinedInitializeWithCopyFunction);
4282+
}
42274283
}
42284284

42294285
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
42304286
SILType T)
42314287
const override {
4232-
emitIndirectInitialize(IGF, dest, src, T, IsTake);
4288+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
4289+
(T.hasArchetype())) {
4290+
emitIndirectInitialize(IGF, dest, src, T, IsTake);
4291+
} else {
4292+
// Create an outlined function to avoid explosion
4293+
IGF.IGM.generateCallToOutlinedCopyAddr(
4294+
IGF, *TI, dest, src, T,
4295+
&IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction);
4296+
}
42334297
}
42344298

42354299
void destroy(IRGenFunction &IGF, Address addr, SILType T) const override {

0 commit comments

Comments
 (0)