Skip to content

Commit 4c37223

Browse files
committed
IRGen: don't use value witness functions in outlined value operations for functions with performance constraints
1 parent fcd5225 commit 4c37223

File tree

7 files changed

+70
-21
lines changed

7 files changed

+70
-21
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6216,7 +6216,8 @@ IRGenModule::getOrCreateHelperFunction(StringRef fnName, llvm::Type *resultTy,
62166216
ArrayRef<llvm::Type*> paramTys,
62176217
llvm::function_ref<void(IRGenFunction &IGF)> generate,
62186218
bool setIsNoInline,
6219-
bool forPrologue) {
6219+
bool forPrologue,
6220+
bool isPerformanceConstraint) {
62206221
llvm::FunctionType *fnTy =
62216222
llvm::FunctionType::get(resultTy, paramTys, false);
62226223

@@ -6225,7 +6226,7 @@ IRGenModule::getOrCreateHelperFunction(StringRef fnName, llvm::Type *resultTy,
62256226
Module.getOrInsertFunction(fnName, fnTy).getCallee());
62266227

62276228
if (llvm::Function *def = shouldDefineHelper(*this, fn, setIsNoInline)) {
6228-
IRGenFunction IGF(*this, def);
6229+
IRGenFunction IGF(*this, def, isPerformanceConstraint);
62296230
if (DebugInfo && !forPrologue)
62306231
DebugInfo->emitArtificialFunction(IGF, def);
62316232
generate(IGF);

lib/IRGen/IRGenFunction.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ static llvm::cl::opt<bool> EnableTrapDebugInfo(
4040
llvm::cl::desc("Generate failure-message functions in the debug info"));
4141

4242
IRGenFunction::IRGenFunction(IRGenModule &IGM, llvm::Function *Fn,
43+
bool isPerformanceConstraint,
4344
OptimizationMode OptMode,
4445
const SILDebugScope *DbgScope,
4546
llvm::Optional<SILLocation> DbgLoc)
4647
: IGM(IGM), Builder(IGM.getLLVMContext(),
4748
IGM.DebugInfo && !IGM.Context.LangOpts.DebuggerSupport),
48-
OptMode(OptMode), CurFn(Fn), DbgScope(DbgScope) {
49+
OptMode(OptMode), isPerformanceConstraint(isPerformanceConstraint),
50+
CurFn(Fn), DbgScope(DbgScope) {
4951

5052
// Make sure the instructions in this function are attached its debug scope.
5153
if (IGM.DebugInfo) {
@@ -83,6 +85,12 @@ bool IRGenFunction::canStackPromotePackMetadata() const {
8385
!packMetadataStackPromotionDisabled;
8486
}
8587

88+
bool IRGenFunction::outliningCanCallValueWitnesses() const {
89+
if (!IGM.getOptions().UseTypeLayoutValueHandling)
90+
return false;
91+
return !isPerformanceConstraint && !IGM.Context.LangOpts.hasFeature(Feature::Embedded);
92+
}
93+
8694
ModuleDecl *IRGenFunction::getSwiftModule() const {
8795
return IGM.getSwiftModule();
8896
}

lib/IRGen/IRGenFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class IRGenFunction {
7474
/// If != OptimizationMode::NotSet, the optimization mode specified with an
7575
/// function attribute.
7676
OptimizationMode OptMode;
77+
bool isPerformanceConstraint;
7778

7879
llvm::Function *CurFn;
7980
ModuleDecl *getSwiftModule() const;
@@ -82,6 +83,7 @@ class IRGenFunction {
8283
const IRGenOptions &getOptions() const;
8384

8485
IRGenFunction(IRGenModule &IGM, llvm::Function *fn,
86+
bool isPerformanceConstraint = false,
8587
OptimizationMode Mode = OptimizationMode::NotSet,
8688
const SILDebugScope *DbgScope = nullptr,
8789
llvm::Optional<SILLocation> DbgLoc = llvm::None);
@@ -252,6 +254,8 @@ class IRGenFunction {
252254
/// heapified.
253255
bool canStackPromotePackMetadata() const;
254256

257+
bool outliningCanCallValueWitnesses() const;
258+
255259
void setupAsync(unsigned asyncContextIndex);
256260
bool isAsync() const { return asyncContextLocation.isValid(); }
257261

lib/IRGen/IRGenModule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,8 @@ class IRGenModule {
11751175
ArrayRef<llvm::Type*> paramTypes,
11761176
llvm::function_ref<void(IRGenFunction &IGF)> generate,
11771177
bool setIsNoInline = false,
1178-
bool forPrologue = false);
1178+
bool forPrologue = false,
1179+
bool isPerformanceConstraint = false);
11791180

11801181
llvm::Constant *getOrCreateRetainFunction(const TypeInfo &objectTI, SILType t,
11811182
llvm::Type *llvmType, Atomicity atomicity);

lib/IRGen/IRGenSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,7 @@ IRGenSILFunction::IRGenSILFunction(IRGenModule &IGM, SILFunction *f)
18201820
: IRGenFunction(IGM,
18211821
IGM.getAddrOfSILFunction(f, ForDefinition,
18221822
f->isDynamicallyReplaceable()),
1823+
f->isPerformanceConstraint(),
18231824
f->getOptimizationMode(), f->getDebugScope(),
18241825
f->getLocation()),
18251826
CurSILFn(f) {

lib/IRGen/Outlining.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void TypeInfo::callOutlinedCopy(IRGenFunction &IGF, Address dest, Address src,
139139
SILType T, IsInitialization_t isInit,
140140
IsTake_t isTake) const {
141141
if (!T.hasLocalArchetype() &&
142-
!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
142+
!IGF.outliningCanCallValueWitnesses()) {
143143
OutliningMetadataCollector collector(IGF);
144144
if (T.hasArchetype()) {
145145
collectMetadataForOutlining(collector, T);
@@ -235,13 +235,13 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithTakeFunction(
235235
auto manglingBits = getTypeAndGenericSignatureForManglingOutlineFunction(T);
236236
auto funcName =
237237
IRGenMangler().mangleOutlinedInitializeWithTakeFunction(manglingBits.first,
238-
manglingBits.second);
238+
manglingBits.second, collector.IGF.isPerformanceConstraint);
239239

240240
return getOrCreateOutlinedCopyAddrHelperFunction(
241241
T, ti, collector, funcName,
242242
[this](IRGenFunction &IGF, Address dest, Address src, SILType T,
243243
const TypeInfo &ti) {
244-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
244+
if (!IGF.outliningCanCallValueWitnesses() ||
245245
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
246246
ti.initializeWithTake(IGF, dest, src, T, true);
247247
} else {
@@ -256,13 +256,13 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedInitializeWithCopyFunction(
256256
auto manglingBits = getTypeAndGenericSignatureForManglingOutlineFunction(T);
257257
auto funcName =
258258
IRGenMangler().mangleOutlinedInitializeWithCopyFunction(manglingBits.first,
259-
manglingBits.second);
259+
manglingBits.second, collector.IGF.isPerformanceConstraint);
260260

261261
return getOrCreateOutlinedCopyAddrHelperFunction(
262262
T, ti, collector, funcName,
263263
[this](IRGenFunction &IGF, Address dest, Address src, SILType T,
264264
const TypeInfo &ti) {
265-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
265+
if (!IGF.outliningCanCallValueWitnesses() ||
266266
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
267267
ti.initializeWithCopy(IGF, dest, src, T, true);
268268
} else {
@@ -277,13 +277,13 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithTakeFunction(
277277
auto manglingBits = getTypeAndGenericSignatureForManglingOutlineFunction(T);
278278
auto funcName =
279279
IRGenMangler().mangleOutlinedAssignWithTakeFunction(manglingBits.first,
280-
manglingBits.second);
280+
manglingBits.second, collector.IGF.isPerformanceConstraint);
281281

282282
return getOrCreateOutlinedCopyAddrHelperFunction(
283283
T, ti, collector, funcName,
284284
[this](IRGenFunction &IGF, Address dest, Address src, SILType T,
285285
const TypeInfo &ti) {
286-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
286+
if (!IGF.outliningCanCallValueWitnesses() ||
287287
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
288288
ti.assignWithTake(IGF, dest, src, T, true);
289289
} else {
@@ -298,13 +298,13 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedAssignWithCopyFunction(
298298
auto manglingBits = getTypeAndGenericSignatureForManglingOutlineFunction(T);
299299
auto funcName =
300300
IRGenMangler().mangleOutlinedAssignWithCopyFunction(manglingBits.first,
301-
manglingBits.second);
301+
manglingBits.second, collector.IGF.isPerformanceConstraint);
302302

303303
return getOrCreateOutlinedCopyAddrHelperFunction(
304304
T, ti, collector, funcName,
305305
[this](IRGenFunction &IGF, Address dest, Address src, SILType T,
306306
const TypeInfo &ti) {
307-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
307+
if (!IGF.outliningCanCallValueWitnesses() ||
308308
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
309309
ti.assignWithCopy(IGF, dest, src, T, true);
310310
} else {
@@ -334,7 +334,9 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedCopyAddrHelperFunction(
334334
generator(IGF, dest, src, T, ti);
335335
IGF.Builder.CreateRet(dest.getAddress());
336336
},
337-
true /*setIsNoInline*/);
337+
true /*setIsNoInline*/,
338+
false /*forPrologue*/,
339+
collector.IGF.isPerformanceConstraint);
338340
}
339341

340342
void TypeInfo::callOutlinedDestroy(IRGenFunction &IGF,
@@ -344,7 +346,7 @@ void TypeInfo::callOutlinedDestroy(IRGenFunction &IGF,
344346
return;
345347

346348
if (!T.hasLocalArchetype() &&
347-
!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
349+
!IGF.outliningCanCallValueWitnesses()) {
348350
OutliningMetadataCollector collector(IGF);
349351
if (T.hasArchetype()) {
350352
collectMetadataForOutlining(collector, T);
@@ -385,7 +387,7 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedDestroyFunction(
385387
IRGenMangler mangler;
386388
auto manglingBits = getTypeAndGenericSignatureForManglingOutlineFunction(T);
387389
auto funcName = mangler.mangleOutlinedDestroyFunction(manglingBits.first,
388-
manglingBits.second);
390+
manglingBits.second, collector.IGF.isPerformanceConstraint);
389391

390392
auto ptrTy = ti.getStorageType()->getPointerTo();
391393
llvm::SmallVector<llvm::Type *, 4> paramTys;
@@ -397,7 +399,7 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedDestroyFunction(
397399
Explosion params = IGF.collectParameters();
398400
Address addr = ti.getAddressForPointer(params.claimNext());
399401
collector.bindMetadataParameters(IGF, params);
400-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling ||
402+
if (!IGF.outliningCanCallValueWitnesses() ||
401403
T.hasArchetype() || !canUseValueWitnessForValueOp(*this, T)) {
402404
ti.destroy(IGF, addr, T, true);
403405
} else {
@@ -406,7 +408,9 @@ llvm::Constant *IRGenModule::getOrCreateOutlinedDestroyFunction(
406408

407409
IGF.Builder.CreateRet(addr.getAddress());
408410
},
409-
true /*setIsNoInline*/);
411+
true /*setIsNoInline*/,
412+
false /*forPrologue*/,
413+
collector.IGF.isPerformanceConstraint);
410414
}
411415

412416
llvm::Constant *IRGenModule::getOrCreateRetainFunction(const TypeInfo &ti,

test/IRGen/typelayout_based_value_operation.sil

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %target-swift-frontend -enable-type-layout %s -emit-ir -sil-verify-all | %FileCheck %s
2-
// RUN: %target-swift-frontend -disable-type-layout %s -emit-ir -sil-verify-all | %FileCheck %s --check-prefix=NOTYPELAYOUT
2+
// RUNx: %target-swift-frontend -disable-type-layout %s -emit-ir -sil-verify-all | %FileCheck %s --check-prefix=NOTYPELAYOUT
33

44
sil_stage canonical
55
import Builtin
@@ -51,14 +51,14 @@ entry(%arg : $*A<Builtin.Int32>):
5151
// NOTYPELAYOUT: swift_retain
5252
// NOTYPELAYOUT: swift_retain
5353
// NOTYPELAYOUT: swift_retain
54-
// CHECK: }
54+
// NOTYPELAYOUT: }
5555

5656
// NOTYPELAYOUT-LABEL: define{{.*}} ptr @"$s32typelayout_based_value_operation1AVyAA1CCGWOh"(
5757
// NOTYPELAYOUT: swift_release
5858
// NOTYPELAYOUT: swift_release
5959
// NOTYPELAYOUT: swift_release
6060
// NOTYPELAYOUT: swift_release
61-
// CHECK: }
61+
// NOTYPELAYOUT: }
6262

6363
sil @testValue : $@convention(thin) (@in A<C>) -> () {
6464
entry(%arg : $*A<C>):
@@ -71,4 +71,34 @@ entry(%arg : $*A<C>):
7171
return %ret : $()
7272
}
7373

74+
// CHECK-LABEL: define{{.*}} void @testValue_no_typelayout(
75+
// CHECK: call ptr @"$s32typelayout_based_value_operation1AVyAA1CCGWOC"(
76+
// CHECK: call ptr @"$s32typelayout_based_value_operation1AVyAA1CCGWOH"(
77+
// CHECK: call ptr @"$s32typelayout_based_value_operation1AVyAA1CCGWOH"(
78+
// CHECK: }
79+
sil [perf_constraint] @testValue_no_typelayout : $@convention(thin) (@in A<C>) -> () {
80+
entry(%arg : $*A<C>):
81+
%loc = alloc_stack $A<C>
82+
copy_addr %arg to [init] %loc : $*A<C>
83+
destroy_addr %arg : $*A<C>
84+
destroy_addr %loc : $*A<C>
85+
dealloc_stack %loc: $*A<C>
86+
%ret = tuple ()
87+
return %ret : $()
88+
}
89+
90+
// CHECK-LABEL: define{{.*}} ptr @"$s32typelayout_based_value_operation1AVyAA1CCGWOC"(
91+
// CHECK: swift_retain
92+
// CHECK: swift_retain
93+
// CHECK: swift_retain
94+
// CHECK: swift_retain
95+
// CHECK: }
96+
97+
// CHECK-LABEL: define{{.*}} ptr @"$s32typelayout_based_value_operation1AVyAA1CCGWOH"(
98+
// CHECK: swift_release
99+
// CHECK: swift_release
100+
// CHECK: swift_release
101+
// CHECK: swift_release
102+
// CHECK: }
103+
74104
sil_vtable C {}

0 commit comments

Comments
 (0)