Skip to content

Commit 647a276

Browse files
committed
Merge remote-tracking branch 'github/master' into HEAD
2 parents a06c01c + e35ae37 commit 647a276

File tree

7 files changed

+279
-44
lines changed

7 files changed

+279
-44
lines changed

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,4 +680,8 @@ def previous_module_installname_map_file
680680

681681
def enable_type_layouts : Flag<["-"], "enable-type-layout">,
682682
HelpText<"Enable type layout based lowering">;
683+
684+
def disable_type_layouts : Flag<["-"], "disable-type-layout">,
685+
HelpText<"Disable type layout based lowering">;
686+
683687
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

include/swift/SIL/SILModule.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,10 @@ class SILModule {
678678
/// the given module?
679679
bool isTypeMetadataAccessible(CanType type);
680680

681+
/// Can type metadata necessary for value operations for the given sil type be
682+
/// fetched in the given module?
683+
bool isTypeMetadataForLayoutAccessible(SILType type);
684+
681685
/// Run the SIL verifier to make sure that all Functions follow
682686
/// invariants.
683687
void verify() const;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1274,7 +1274,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
12741274
Opts.EnableDynamicReplacementChaining |=
12751275
Args.hasArg(OPT_enable_dynamic_replacement_chaining);
12761276

1277-
Opts.UseTypeLayoutValueHandling |= Args.hasArg(OPT_enable_type_layouts);
1277+
if (auto A = Args.getLastArg(OPT_enable_type_layouts,
1278+
OPT_disable_type_layouts)) {
1279+
Opts.UseTypeLayoutValueHandling
1280+
= A->getOption().matches(OPT_enable_type_layouts);
1281+
}
12781282

12791283
Opts.UseSwiftCall = Args.hasArg(OPT_enable_swiftcall);
12801284

lib/IRGen/GenEnum.cpp

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -275,20 +275,56 @@ void EnumImplStrategy::callOutlinedCopy(IRGenFunction &IGF,
275275
Address dest, Address src, SILType T,
276276
IsInitialization_t isInit,
277277
IsTake_t isTake) const {
278-
OutliningMetadataCollector collector(IGF);
279-
if (T.hasArchetype()) {
280-
collectMetadataForOutlining(collector, T);
278+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
279+
OutliningMetadataCollector collector(IGF);
280+
if (T.hasArchetype()) {
281+
collectMetadataForOutlining(collector, T);
282+
}
283+
collector.emitCallToOutlinedCopy(dest, src, T, *TI, isInit, isTake);
284+
return;
285+
}
286+
287+
if (!T.hasArchetype()) {
288+
// Call the outlined copy function (the implementation will call vwt in this
289+
// case).
290+
OutliningMetadataCollector collector(IGF);
291+
collector.emitCallToOutlinedCopy(dest, src, T, *TI, isInit, isTake);
292+
return;
281293
}
282-
collector.emitCallToOutlinedCopy(dest, src, T, *TI, isInit, isTake);
294+
295+
if (isInit == IsInitialization && isTake == IsTake) {
296+
return emitInitializeWithTakeCall(IGF, T, dest, src);
297+
} else if (isInit == IsInitialization && isTake == IsNotTake) {
298+
return emitInitializeWithCopyCall(IGF, T, dest, src);
299+
} else if (isInit == IsNotInitialization && isTake == IsTake) {
300+
return emitAssignWithTakeCall(IGF, T, dest, src);
301+
} else if (isInit == IsNotInitialization && isTake == IsNotTake) {
302+
return emitAssignWithCopyCall(IGF, T, dest, src);
303+
}
304+
llvm_unreachable("unknown case");
283305
}
284306

285307
void EnumImplStrategy::callOutlinedDestroy(IRGenFunction &IGF,
286308
Address addr, SILType T) const {
287-
OutliningMetadataCollector collector(IGF);
288-
if (T.hasArchetype()) {
289-
collectMetadataForOutlining(collector, T);
309+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
310+
OutliningMetadataCollector collector(IGF);
311+
if (T.hasArchetype()) {
312+
collectMetadataForOutlining(collector, T);
313+
}
314+
collector.emitCallToOutlinedDestroy(addr, T, *TI);
315+
return;
290316
}
291-
collector.emitCallToOutlinedDestroy(addr, T, *TI);
317+
318+
if (!T.hasArchetype()) {
319+
// Call the outlined copy function (the implementation will call vwt in this
320+
// case).
321+
OutliningMetadataCollector collector(IGF);
322+
collector.emitCallToOutlinedDestroy(addr, T, *TI);
323+
return;
324+
}
325+
326+
emitDestroyCall(IGF, T, addr);
327+
return;
292328
}
293329

294330
namespace {
@@ -2640,11 +2676,25 @@ namespace {
26402676
}
26412677
}
26422678
} else {
2643-
OutliningMetadataCollector collector(IGF);
2644-
if (T.hasArchetype()) {
2645-
collectMetadataForOutlining(collector, T);
2679+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
2680+
OutliningMetadataCollector collector(IGF);
2681+
if (T.hasArchetype()) {
2682+
collectMetadataForOutlining(collector, T);
2683+
}
2684+
collector.emitCallToOutlinedDestroy(addr, T, *TI);
2685+
return;
2686+
}
2687+
2688+
if (!T.hasArchetype()) {
2689+
// Call the outlined copy function (the implementation will call vwt
2690+
// in this case).
2691+
OutliningMetadataCollector collector(IGF);
2692+
collector.emitCallToOutlinedDestroy(addr, T, *TI);
2693+
return;
26462694
}
2647-
collector.emitCallToOutlinedDestroy(addr, T, *TI);
2695+
2696+
emitDestroyCall(IGF, T, addr);
2697+
return;
26482698
}
26492699
}
26502700

lib/IRGen/Outlining.cpp

Lines changed: 121 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@
1616

1717
#include "Outlining.h"
1818

19-
#include "swift/AST/GenericEnvironment.h"
2019
#include "Explosion.h"
20+
#include "GenOpaque.h"
2121
#include "GenProto.h"
2222
#include "IRGenFunction.h"
2323
#include "IRGenMangler.h"
2424
#include "IRGenModule.h"
2525
#include "LoadableTypeInfo.h"
2626
#include "LocalTypeDataKind.h"
2727
#include "MetadataRequest.h"
28+
#include "swift/AST/GenericEnvironment.h"
29+
#include "swift/AST/IRGenOptions.h"
30+
#include "swift/SIL/SILModule.h"
2831

2932
using namespace swift;
3033
using namespace irgen;
@@ -132,15 +135,36 @@ irgen::getTypeAndGenericSignatureForManglingOutlineFunction(SILType type) {
132135
return {loweredType, nullptr};
133136
}
134137

135-
void TypeInfo::callOutlinedCopy(IRGenFunction &IGF,
136-
Address dest, Address src, SILType T,
137-
IsInitialization_t isInit,
138+
void TypeInfo::callOutlinedCopy(IRGenFunction &IGF, Address dest, Address src,
139+
SILType T, IsInitialization_t isInit,
138140
IsTake_t isTake) const {
139-
OutliningMetadataCollector collector(IGF);
140-
if (T.hasArchetype()) {
141-
collectMetadataForOutlining(collector, T);
141+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
142+
OutliningMetadataCollector collector(IGF);
143+
if (T.hasArchetype()) {
144+
collectMetadataForOutlining(collector, T);
145+
}
146+
collector.emitCallToOutlinedCopy(dest, src, T, *this, isInit, isTake);
147+
return;
148+
}
149+
150+
if (!T.hasArchetype()) {
151+
// Call the outlined copy function (the implementation will call vwt in this
152+
// case).
153+
OutliningMetadataCollector collector(IGF);
154+
collector.emitCallToOutlinedCopy(dest, src, T, *this, isInit, isTake);
155+
return;
156+
}
157+
158+
if (isInit == IsInitialization && isTake == IsTake) {
159+
return emitInitializeWithTakeCall(IGF, T, dest, src);
160+
} else if (isInit == IsInitialization && isTake == IsNotTake) {
161+
return emitInitializeWithCopyCall(IGF, T, dest, src);
162+
} else if (isInit == IsNotInitialization && isTake == IsTake) {
163+
return emitAssignWithTakeCall(IGF, T, dest, src);
164+
} else if (isInit == IsNotInitialization && isTake == IsNotTake) {
165+
return emitAssignWithCopyCall(IGF, T, dest, src);
142166
}
143-
collector.emitCallToOutlinedCopy(dest, src, T, *this, isInit, isTake);
167+
llvm_unreachable("unknown case");
144168
}
145169

146170
void OutliningMetadataCollector::emitCallToOutlinedCopy(
@@ -173,6 +197,28 @@ void OutliningMetadataCollector::emitCallToOutlinedCopy(
173197
call->setCallingConv(IGF.IGM.DefaultCC);
174198
}
175199

200+
static bool needsSpecialOwnershipHandling(SILType t) {
201+
auto astType = t.getASTType();
202+
auto ref = dyn_cast<ReferenceStorageType>(astType);
203+
if (!ref) {
204+
return false;
205+
}
206+
return ref->getOwnership() != ReferenceOwnership::Strong;
207+
}
208+
209+
bool isTypeMetadataForLayoutAccessible(SILModule &M, SILType type);
210+
211+
static bool canUseValueWitnessForValueOp(IRGenModule &IGM, SILType T) {
212+
if (!IGM.getSILModule().isTypeMetadataForLayoutAccessible(T))
213+
return false;
214+
215+
if (needsSpecialOwnershipHandling(T))
216+
return false;
217+
if (T.getASTType()->hasDynamicSelfType())
218+
return false;
219+
return true;
220+
}
221+
176222
llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction(
177223
SILType T, const TypeInfo &ti,
178224
const OutliningMetadataCollector &collector) {
@@ -181,10 +227,16 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction(
181227
IRGenMangler().mangleOutlinedInitializeWithTakeFunction(manglingBits.first,
182228
manglingBits.second);
183229

184-
return getOrCreateOutlinedCopyAddrHelperFunction(T, ti, collector, funcName,
185-
[](IRGenFunction &IGF, Address dest, Address src,
186-
SILType T, const TypeInfo &ti) {
187-
ti.initializeWithTake(IGF, dest, src, T, true);
230+
return getOrCreateOutlinedCopyAddrHelperFunction(
231+
T, ti, collector, funcName,
232+
[this](IRGenFunction &IGF, Address dest, Address src, SILType T,
233+
const TypeInfo &ti) {
234+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
235+
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
236+
ti.initializeWithTake(IGF, dest, src, T, true);
237+
} else {
238+
emitInitializeWithTakeCall(IGF, T, dest, src);
239+
}
188240
});
189241
}
190242

@@ -196,10 +248,16 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithCopyFunction(
196248
IRGenMangler().mangleOutlinedInitializeWithCopyFunction(manglingBits.first,
197249
manglingBits.second);
198250

199-
return getOrCreateOutlinedCopyAddrHelperFunction(T, ti, collector, funcName,
200-
[](IRGenFunction &IGF, Address dest, Address src,
201-
SILType T, const TypeInfo &ti) {
202-
ti.initializeWithCopy(IGF, dest, src, T, true);
251+
return getOrCreateOutlinedCopyAddrHelperFunction(
252+
T, ti, collector, funcName,
253+
[this](IRGenFunction &IGF, Address dest, Address src, SILType T,
254+
const TypeInfo &ti) {
255+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
256+
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
257+
ti.initializeWithCopy(IGF, dest, src, T, true);
258+
} else {
259+
emitInitializeWithCopyCall(IGF, T, dest, src);
260+
}
203261
});
204262
}
205263

@@ -211,10 +269,16 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithTakeFunction(
211269
IRGenMangler().mangleOutlinedAssignWithTakeFunction(manglingBits.first,
212270
manglingBits.second);
213271

214-
return getOrCreateOutlinedCopyAddrHelperFunction(T, ti, collector, funcName,
215-
[](IRGenFunction &IGF, Address dest, Address src,
216-
SILType T, const TypeInfo &ti) {
217-
ti.assignWithTake(IGF, dest, src, T, true);
272+
return getOrCreateOutlinedCopyAddrHelperFunction(
273+
T, ti, collector, funcName,
274+
[this](IRGenFunction &IGF, Address dest, Address src, SILType T,
275+
const TypeInfo &ti) {
276+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
277+
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
278+
ti.assignWithTake(IGF, dest, src, T, true);
279+
} else {
280+
emitAssignWithTakeCall(IGF, T, dest, src);
281+
}
218282
});
219283
}
220284

@@ -226,10 +290,16 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithCopyFunction(
226290
IRGenMangler().mangleOutlinedAssignWithCopyFunction(manglingBits.first,
227291
manglingBits.second);
228292

229-
return getOrCreateOutlinedCopyAddrHelperFunction(T, ti, collector, funcName,
230-
[](IRGenFunction &IGF, Address dest, Address src,
231-
SILType T, const TypeInfo &ti) {
232-
ti.assignWithCopy(IGF, dest, src, T, true);
293+
return getOrCreateOutlinedCopyAddrHelperFunction(
294+
T, ti, collector, funcName,
295+
[this](IRGenFunction &IGF, Address dest, Address src, SILType T,
296+
const TypeInfo &ti) {
297+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
298+
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
299+
ti.assignWithCopy(IGF, dest, src, T, true);
300+
} else {
301+
emitAssignWithCopyCall(IGF, T, dest, src);
302+
}
233303
});
234304
}
235305

@@ -259,11 +329,28 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedCopyAddrHelperFunction(
259329

260330
void TypeInfo::callOutlinedDestroy(IRGenFunction &IGF,
261331
Address addr, SILType T) const {
262-
OutliningMetadataCollector collector(IGF);
263-
if (T.hasArchetype()) {
264-
collectMetadataForOutlining(collector, T);
332+
// Short-cut destruction of trivial values.
333+
if (IGF.IGM.getTypeLowering(T).isTrivial())
334+
return;
335+
336+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
337+
OutliningMetadataCollector collector(IGF);
338+
if (T.hasArchetype()) {
339+
collectMetadataForOutlining(collector, T);
340+
}
341+
collector.emitCallToOutlinedDestroy(addr, T, *this);
342+
return;
343+
}
344+
345+
if (!T.hasArchetype()) {
346+
// Call the outlined copy function (the implementation will call vwt in this
347+
// case).
348+
OutliningMetadataCollector collector(IGF);
349+
collector.emitCallToOutlinedDestroy(addr, T, *this);
350+
return;
265351
}
266-
collector.emitCallToOutlinedDestroy(addr, T, *this);
352+
353+
return emitDestroyCall(IGF, T, addr);
267354
}
268355

269356
void OutliningMetadataCollector::emitCallToOutlinedDestroy(
@@ -298,9 +385,13 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedDestroyFunction(
298385
Explosion params = IGF.collectParameters();
299386
Address addr = ti.getAddressForPointer(params.claimNext());
300387
collector.bindMetadataParameters(IGF, params);
388+
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
389+
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
390+
ti.destroy(IGF, addr, T, true);
391+
} else {
392+
emitDestroyCall(IGF, T, addr);
393+
}
301394

302-
ti.destroy(IGF, addr, T, true);
303-
304395
IGF.Builder.CreateRet(addr.getAddress());
305396
},
306397
true /*setIsNoInline*/);

lib/SIL/SIL.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,15 @@ bool SILModule::isTypeABIAccessible(SILType type,
197197
"unexpected SIL lowered-only type with non-fixed layout");
198198

199199
// Otherwise, we need to be able to fetch layout-metadata for the type.
200-
return isTypeMetadataForLayoutAccessible(*this, type);
200+
return isTypeMetadataForLayoutAccessible(type);
201+
}
202+
203+
bool SILModule::isTypeMetadataForLayoutAccessible(SILType type) {
204+
if (type.is<ReferenceStorageType>() || type.is<SILFunctionType>() ||
205+
type.is<AnyMetatypeType>())
206+
return false;
207+
208+
return ::isTypeMetadataForLayoutAccessible(*this, type);
201209
}
202210

203211
bool AbstractStorageDecl::exportsPropertyDescriptor() const {

0 commit comments

Comments
 (0)