Skip to content

Commit 79913b9

Browse files
committed
Don't "finalize" the empty-array singleton.
Array literals only need to be finalized, if the array is really allocated. In case of zero elements, no allocation is done, but the empty-array singleton is used. "Finalization" means to emit an end_cow_mutation instruction on the array. As the empty-array singleton is a read-only and shared object, it's not legal to do a end_cow_mutation on it.
1 parent 5f6f46f commit 79913b9

File tree

5 files changed

+24
-16
lines changed

5 files changed

+24
-16
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,7 +2109,8 @@ VarargsInfo Lowering::emitBeginVarargs(SILGenFunction &SGF, SILLocation loc,
21092109
}
21102110

21112111
ManagedValue Lowering::emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
2112-
VarargsInfo &&varargs) {
2112+
VarargsInfo &&varargs,
2113+
unsigned numElements) {
21132114
// Kill the abort cleanup.
21142115
SGF.Cleanups.setCleanupState(varargs.getAbortCleanup(), CleanupState::Dead);
21152116

@@ -2118,6 +2119,14 @@ ManagedValue Lowering::emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
21182119
if (array.hasCleanup())
21192120
SGF.Cleanups.setCleanupState(array.getCleanup(), CleanupState::Active);
21202121

2122+
// Array literals only need to be finalized, if the array is really allocated.
2123+
// In case of zero elements, no allocation is done, but the empty-array
2124+
// singleton is used. "Finalization" means to emit an end_cow_mutation
2125+
// instruction on the array. As the empty-array singleton is a read-only and
2126+
// shared object, it's not legal to do a end_cow_mutation on it.
2127+
if (numElements == 0)
2128+
return array;
2129+
21212130
return SGF.emitUninitializedArrayFinalization(loc, std::move(array));
21222131
}
21232132

@@ -3870,7 +3879,7 @@ RValue RValueEmitter::visitCollectionExpr(CollectionExpr *E, SGFContext C) {
38703879
SGF.Cleanups.setCleanupState(destCleanup, CleanupState::Dead);
38713880

38723881
RValue array(SGF, loc, arrayType,
3873-
emitEndVarargs(SGF, loc, std::move(varargsInfo)));
3882+
emitEndVarargs(SGF, loc, std::move(varargsInfo), E->getNumElements()));
38743883

38753884
array = scope.popPreservingValue(std::move(array));
38763885

lib/SILGen/Varargs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ VarargsInfo emitBeginVarargs(SILGenFunction &SGF, SILLocation loc,
6868

6969
/// Successfully end a varargs emission sequence.
7070
ManagedValue emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
71-
VarargsInfo &&varargs);
71+
VarargsInfo &&varargs,
72+
unsigned numElements);
7273

7374
} // end namespace Lowering
7475
} // end namespace swift

lib/SILOptimizer/Mandatory/OSLogOptimization.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -540,13 +540,15 @@ static SILValue emitCodeForConstantArray(ArrayRef<SILValue> elements,
540540
assert(arrayAllocateFun);
541541

542542
SILFunction *arrayFinalizeFun = nullptr;
543-
if (FuncDecl *arrayFinalizeDecl = astContext.getFinalizeUninitializedArray()) {
544-
std::string finalizeMangledName =
545-
SILDeclRef(arrayFinalizeDecl, SILDeclRef::Kind::Func).mangle();
546-
arrayFinalizeFun =
547-
module.findFunction(finalizeMangledName, SILLinkage::SharedExternal);
548-
assert(arrayFinalizeFun);
549-
module.linkFunction(arrayFinalizeFun);
543+
if (numElements != 0) {
544+
if (FuncDecl *arrayFinalizeDecl = astContext.getFinalizeUninitializedArray()) {
545+
std::string finalizeMangledName =
546+
SILDeclRef(arrayFinalizeDecl, SILDeclRef::Kind::Func).mangle();
547+
arrayFinalizeFun =
548+
module.findFunction(finalizeMangledName, SILLinkage::SharedExternal);
549+
assert(arrayFinalizeFun);
550+
module.linkFunction(arrayFinalizeFun);
551+
}
550552
}
551553

552554
// Call the _allocateUninitializedArray function with numElementsSIL. The

test/SILGen/keypaths.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,7 @@ func test_variadics() {
486486
// CHECK: [[FN_REF:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
487487
// CHECK: [[MAKE_ARR:%[0-9]+]] = apply [[FN_REF]]<Int>([[ARR_COUNT]])
488488
// CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array<Int>, Builtin.RawPointer)
489-
// CHECK: [[FIN_REF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
490-
// CHECK: [[FIN_ARR:%[0-9]+]] = apply [[FIN_REF]]<Int>([[ARR]])
491-
// CHECK: keypath $KeyPath<SubscriptVariadic1, Int>, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array<Int>, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array<Int> : $Array<Int>], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[FIN_ARR]])
489+
// CHECK: keypath $KeyPath<SubscriptVariadic1, Int>, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array<Int>, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array<Int> : $Array<Int>], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[ARR]])
492490
_ = \SubscriptVariadic1.[]
493491

494492
_ = \SubscriptVariadic2.["", "1"]

test/SILGen/scalar_to_tuple_args.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ variadicFirst(x)
6868
// CHECK: [[X:%.*]] = load [trivial] [[READ]]
6969
// CHECK: [[ALLOC_ARRAY:%.*]] = apply {{.*}} -> (@owned Array<τ_0_0>, Builtin.RawPointer)
7070
// CHECK: ([[ARRAY:%.*]], [[MEMORY:%.*]]) = destructure_tuple [[ALLOC_ARRAY]]
71-
// CHECK: [[FIN_FN:%.*]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
72-
// CHECK: [[FIN_ARR:%.*]] = apply [[FIN_FN]]<Int>([[ARRAY]])
7371
// CHECK: [[VARIADIC_SECOND:%.*]] = function_ref @$s20scalar_to_tuple_args14variadicSecondyySi_SidtF
74-
// CHECK: apply [[VARIADIC_SECOND]]([[X]], [[FIN_ARR]])
72+
// CHECK: apply [[VARIADIC_SECOND]]([[X]], [[ARRAY]])
7573
variadicSecond(x)

0 commit comments

Comments
 (0)