Skip to content

Commit 8c67caa

Browse files
author
Joe Shajrawi
authored
Merge pull request #12687 from shajrawi/outline_copyddr
Code Size: Outline copy addr instruction
2 parents 34aca68 + d827187 commit 8c67caa

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 = 375; // Last change: added enum witness
57+
const uint16_t VERSION_MINOR = 376; // 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
@@ -420,6 +420,10 @@ class NodePrinter {
420420
case Node::Kind::OutlinedConsume:
421421
case Node::Kind::OutlinedRetain:
422422
case Node::Kind::OutlinedRelease:
423+
case Node::Kind::OutlinedInitializeWithTake:
424+
case Node::Kind::OutlinedInitializeWithCopy:
425+
case Node::Kind::OutlinedAssignWithTake:
426+
case Node::Kind::OutlinedAssignWithCopy:
423427
case Node::Kind::OutlinedVariable:
424428
case Node::Kind::AssocTypePath:
425429
return false;
@@ -813,6 +817,22 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
813817
Printer << "outlined release of ";
814818
print(Node->getChild(0));
815819
return nullptr;
820+
case Node::Kind::OutlinedInitializeWithTake:
821+
Printer << "outlined init with take of ";
822+
print(Node->getChild(0));
823+
return nullptr;
824+
case Node::Kind::OutlinedInitializeWithCopy:
825+
Printer << "outlined init with copy of ";
826+
print(Node->getChild(0));
827+
return nullptr;
828+
case Node::Kind::OutlinedAssignWithTake:
829+
Printer << "outlined assign with take of ";
830+
print(Node->getChild(0));
831+
return nullptr;
832+
case Node::Kind::OutlinedAssignWithCopy:
833+
Printer << "outlined assign with copy of ";
834+
print(Node->getChild(0));
835+
return nullptr;
816836
case Node::Kind::OutlinedVariable:
817837
Printer << "outlined variable #" << Node->getIndex() << " of ";
818838
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"
@@ -3513,6 +3514,7 @@ llvm::Constant *IRGenModule::getOrCreateRetainFunction(const TypeInfo &objectTI,
35133514
return getOrCreateHelperFunction(
35143515
funcName, llvmType, argTys,
35153516
[&](IRGenFunction &IGF) {
3517+
IGF.setInOutlinedFunction();
35163518
auto it = IGF.CurFn->arg_begin();
35173519
Address addr(&*it++, loadableTI->getFixedAlignment());
35183520
Explosion loaded;
@@ -3536,6 +3538,7 @@ IRGenModule::getOrCreateReleaseFunction(const TypeInfo &objectTI, Type t,
35363538
return getOrCreateHelperFunction(
35373539
funcName, llvmType, argTys,
35383540
[&](IRGenFunction &IGF) {
3541+
IGF.setInOutlinedFunction();
35393542
auto it = IGF.CurFn->arg_begin();
35403543
Address addr(&*it++, loadableTI->getFixedAlignment());
35413544
Explosion loaded;
@@ -3545,3 +3548,87 @@ IRGenModule::getOrCreateReleaseFunction(const TypeInfo &objectTI, Type t,
35453548
},
35463549
true /*setIsNoInline*/);
35473550
}
3551+
3552+
void IRGenModule::generateCallToOutlinedCopyAddr(
3553+
IRGenFunction &IGF, const TypeInfo &objectTI, Address dest, Address src,
3554+
SILType T, const OutlinedCopyAddrFunction MethodToCall) {
3555+
llvm::Type *llvmType = dest->getType();
3556+
auto *outlinedF = (this->*MethodToCall)(objectTI, llvmType, T);
3557+
llvm::Value *args[] = {src.getAddress(), dest.getAddress()};
3558+
llvm::CallInst *call = IGF.Builder.CreateCall(outlinedF, args);
3559+
call->setCallingConv(DefaultCC);
3560+
}
3561+
3562+
llvm::Constant *IRGenModule::getOrCreateOutlinedCopyAddrHelperFunction(
3563+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy,
3564+
std::string funcName,
3565+
llvm::function_ref<void(const TypeInfo &objectTI, IRGenFunction &IGF,
3566+
Address dest, Address src, SILType T)>
3567+
Generate) {
3568+
llvm::Type *argTys[] = {llvmType, llvmType};
3569+
return getOrCreateHelperFunction(
3570+
funcName, llvmType, argTys,
3571+
[&](IRGenFunction &IGF) {
3572+
IGF.setInOutlinedFunction();
3573+
auto it = IGF.CurFn->arg_begin();
3574+
Address src(&*it++, objectTI.getBestKnownAlignment());
3575+
Address dest(&*it++, objectTI.getBestKnownAlignment());
3576+
Generate(objectTI, IGF, dest, src, addrTy);
3577+
IGF.Builder.CreateRet(dest.getAddress());
3578+
},
3579+
true /*setIsNoInline*/);
3580+
}
3581+
3582+
llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction(
3583+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy) {
3584+
IRGenMangler mangler;
3585+
CanType canType = addrTy.getObjectType().getSwiftRValueType();
3586+
std::string funcName =
3587+
mangler.mangleOutlinedInitializeWithTakeFunction(canType);
3588+
auto GenFunc = [this](const TypeInfo &objectTI, IRGenFunction &IGF,
3589+
Address dest, Address src, SILType T) {
3590+
objectTI.initializeWithTake(IGF, dest, src, T);
3591+
};
3592+
return getOrCreateOutlinedCopyAddrHelperFunction(objectTI, llvmType, addrTy,
3593+
funcName, GenFunc);
3594+
}
3595+
3596+
llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithCopyFunction(
3597+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy) {
3598+
IRGenMangler mangler;
3599+
CanType canType = addrTy.getObjectType().getSwiftRValueType();
3600+
std::string funcName =
3601+
mangler.mangleOutlinedInitializeWithCopyFunction(canType);
3602+
auto GenFunc = [this](const TypeInfo &objectTI, IRGenFunction &IGF,
3603+
Address dest, Address src, SILType T) {
3604+
objectTI.initializeWithCopy(IGF, dest, src, T);
3605+
};
3606+
return getOrCreateOutlinedCopyAddrHelperFunction(objectTI, llvmType, addrTy,
3607+
funcName, GenFunc);
3608+
}
3609+
3610+
llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithTakeFunction(
3611+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy) {
3612+
IRGenMangler mangler;
3613+
CanType canType = addrTy.getObjectType().getSwiftRValueType();
3614+
std::string funcName = mangler.mangleOutlinedAssignWithTakeFunction(canType);
3615+
auto GenFunc = [this](const TypeInfo &objectTI, IRGenFunction &IGF,
3616+
Address dest, Address src, SILType T) {
3617+
objectTI.assignWithTake(IGF, dest, src, T);
3618+
};
3619+
return getOrCreateOutlinedCopyAddrHelperFunction(objectTI, llvmType, addrTy,
3620+
funcName, GenFunc);
3621+
}
3622+
3623+
llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithCopyFunction(
3624+
const TypeInfo &objectTI, llvm::Type *llvmType, SILType addrTy) {
3625+
IRGenMangler mangler;
3626+
CanType canType = addrTy.getObjectType().getSwiftRValueType();
3627+
std::string funcName = mangler.mangleOutlinedAssignWithCopyFunction(canType);
3628+
auto GenFunc = [this](const TypeInfo &objectTI, IRGenFunction &IGF,
3629+
Address dest, Address src, SILType T) {
3630+
objectTI.assignWithCopy(IGF, dest, src, T);
3631+
};
3632+
return getOrCreateOutlinedCopyAddrHelperFunction(objectTI, llvmType, addrTy,
3633+
funcName, GenFunc);
3634+
}

lib/IRGen/GenEnum.cpp

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

26022610
void assignWithTake(IRGenFunction &IGF, Address dest, Address src,
26032611
SILType T)
26042612
const override {
2605-
emitIndirectAssign(IGF, dest, src, T, IsTake);
2613+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
2614+
(T.hasArchetype())) {
2615+
emitIndirectAssign(IGF, dest, src, T, IsTake);
2616+
} else {
2617+
// Create an outlined function to avoid explosion
2618+
IGF.IGM.generateCallToOutlinedCopyAddr(
2619+
IGF, *TI, dest, src, T,
2620+
&IRGenModule::getOrCreateOutlinedAssignWithTakeFunction);
2621+
}
26062622
}
26072623

26082624
void initializeWithCopy(IRGenFunction &IGF, Address dest, Address src,
26092625
SILType T)
26102626
const override {
2611-
emitIndirectInitialize(IGF, dest, src, T, IsNotTake);
2627+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
2628+
(T.hasArchetype())) {
2629+
emitIndirectInitialize(IGF, dest, src, T, IsNotTake);
2630+
} else {
2631+
// Create an outlined function to avoid explosion
2632+
IGF.IGM.generateCallToOutlinedCopyAddr(
2633+
IGF, *TI, dest, src, T,
2634+
&IRGenModule::getOrCreateOutlinedInitializeWithCopyFunction);
2635+
}
26122636
}
26132637

26142638
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
26152639
SILType T)
26162640
const override {
2617-
emitIndirectInitialize(IGF, dest, src, T, IsTake);
2641+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
2642+
(T.hasArchetype())) {
2643+
emitIndirectInitialize(IGF, dest, src, T, IsTake);
2644+
} else {
2645+
// Create an outlined function to avoid explosion
2646+
IGF.IGM.generateCallToOutlinedCopyAddr(
2647+
IGF, *TI, dest, src, T,
2648+
&IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction);
2649+
}
26182650
}
26192651

26202652
void storeTag(IRGenFunction &IGF,
@@ -4206,25 +4238,57 @@ namespace {
42064238
void assignWithCopy(IRGenFunction &IGF, Address dest, Address src,
42074239
SILType T)
42084240
const override {
4209-
emitIndirectAssign(IGF, dest, src, T, IsNotTake);
4241+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
4242+
(T.hasArchetype())) {
4243+
emitIndirectAssign(IGF, dest, src, T, IsNotTake);
4244+
} else {
4245+
// Create an outlined function to avoid explosion
4246+
IGF.IGM.generateCallToOutlinedCopyAddr(
4247+
IGF, *TI, dest, src, T,
4248+
&IRGenModule::getOrCreateOutlinedAssignWithCopyFunction);
4249+
}
42104250
}
42114251

42124252
void assignWithTake(IRGenFunction &IGF, Address dest, Address src,
42134253
SILType T)
42144254
const override {
4215-
emitIndirectAssign(IGF, dest, src, T, IsTake);
4255+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
4256+
(T.hasArchetype())) {
4257+
emitIndirectAssign(IGF, dest, src, T, IsTake);
4258+
} else {
4259+
// Create an outlined function to avoid explosion
4260+
IGF.IGM.generateCallToOutlinedCopyAddr(
4261+
IGF, *TI, dest, src, T,
4262+
&IRGenModule::getOrCreateOutlinedAssignWithTakeFunction);
4263+
}
42164264
}
42174265

42184266
void initializeWithCopy(IRGenFunction &IGF, Address dest, Address src,
42194267
SILType T)
42204268
const override {
4221-
emitIndirectInitialize(IGF, dest, src, T, IsNotTake);
4269+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
4270+
(T.hasArchetype())) {
4271+
emitIndirectInitialize(IGF, dest, src, T, IsNotTake);
4272+
} else {
4273+
// Create an outlined function to avoid explosion
4274+
IGF.IGM.generateCallToOutlinedCopyAddr(
4275+
IGF, *TI, dest, src, T,
4276+
&IRGenModule::getOrCreateOutlinedInitializeWithCopyFunction);
4277+
}
42224278
}
42234279

42244280
void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
42254281
SILType T)
42264282
const override {
4227-
emitIndirectInitialize(IGF, dest, src, T, IsTake);
4283+
if (IGF.isInOutlinedFunction() || (TIK < Loadable) ||
4284+
(T.hasArchetype())) {
4285+
emitIndirectInitialize(IGF, dest, src, T, IsTake);
4286+
} else {
4287+
// Create an outlined function to avoid explosion
4288+
IGF.IGM.generateCallToOutlinedCopyAddr(
4289+
IGF, *TI, dest, src, T,
4290+
&IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction);
4291+
}
42284292
}
42294293

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

0 commit comments

Comments
 (0)