Skip to content

Commit 291373f

Browse files
authored
Merge pull request swiftlang#32134 from eeckstein/cow-support2
stdlib, SIL optimizer: use the SIL copy-on-write representation in the Array types.
2 parents 13f6885 + f071136 commit 291373f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1475
-557
lines changed

include/swift/AST/KnownDecls.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ FUNC_DECL(AllocateUninitializedArray,
4444
"_allocateUninitializedArray")
4545
FUNC_DECL(DeallocateUninitializedArray,
4646
"_deallocateUninitializedArray")
47+
FUNC_DECL(FinalizeUninitializedArray,
48+
"_finalizeUninitializedArray")
4749

4850
FUNC_DECL(ForceBridgeFromObjectiveC,
4951
"_forceBridgeFromObjectiveC")

include/swift/AST/SemanticAttrs.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ SEMANTICS_ATTR(ARRAY_WITH_UNSAFE_MUTABLE_BUFFER_POINTER, "array.withUnsafeMutabl
6060
SEMANTICS_ATTR(ARRAY_COUNT, "array.count")
6161
SEMANTICS_ATTR(ARRAY_DEALLOC_UNINITIALIZED, "array.dealloc_uninitialized")
6262
SEMANTICS_ATTR(ARRAY_UNINITIALIZED_INTRINSIC, "array.uninitialized_intrinsic")
63+
SEMANTICS_ATTR(ARRAY_FINALIZE_INTRINSIC, "array.finalize_intrinsic")
6364

6465
SEMANTICS_ATTR(SEQUENCE_FOR_EACH, "sequence.forEach")
6566

include/swift/AST/SemanticAttrs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifndef SWIFT_SEMANTICS_H
2020
#define SWIFT_SEMANTICS_H
2121

22+
#include "swift/Basic/LLVM.h"
2223
#include "llvm/ADT/StringRef.h"
2324

2425
namespace swift {

include/swift/SIL/SILNodes.def

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,8 +880,13 @@ NODE_RANGE(NonValueInstruction, UnreachableInst, CondFailInst)
880880
ABSTRACT_INST(MultipleValueInstruction, SILInstruction)
881881
FULLAPPLYSITE_MULTIPLE_VALUE_INST(BeginApplyInst, begin_apply,
882882
MultipleValueInstruction, MayHaveSideEffects, MayRelease)
883+
884+
// begin_cow_mutation is defined to have side effects, because it has
885+
// dependencies with instructions which retain the buffer operand. This prevents
886+
// optimizations from moving begin_cow_mutation instructions across such retain
887+
// instructions.
883888
MULTIPLE_VALUE_INST(BeginCOWMutationInst, begin_cow_mutation,
884-
MultipleValueInstruction, None, DoesNotRelease)
889+
MultipleValueInstruction, MayHaveSideEffects, DoesNotRelease)
885890
MULTIPLE_VALUE_INST(DestructureStructInst, destructure_struct,
886891
MultipleValueInstruction, None, DoesNotRelease)
887892
MULTIPLE_VALUE_INST(DestructureTupleInst, destructure_tuple,

include/swift/SILOptimizer/Differentiation/Common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
#ifndef SWIFT_SILOPTIMIZER_UTILS_DIFFERENTIATION_COMMON_H
1818
#define SWIFT_SILOPTIMIZER_UTILS_DIFFERENTIATION_COMMON_H
1919

20+
#include "swift/AST/SemanticAttrs.h"
2021
#include "swift/SIL/SILDifferentiabilityWitness.h"
2122
#include "swift/SIL/SILFunction.h"
2223
#include "swift/SIL/SILModule.h"
2324
#include "swift/SIL/TypeSubstCloner.h"
25+
#include "swift/SILOptimizer/Analysis/ArraySemantic.h"
2426
#include "swift/SILOptimizer/Analysis/DifferentiableActivityAnalysis.h"
2527

2628
namespace swift {

lib/SIL/IR/SILModule.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ bool SILModule::linkFunction(SILFunction *F, SILModule::LinkingMode Mode) {
355355

356356
SILFunction *SILModule::findFunction(StringRef Name, SILLinkage Linkage) {
357357
assert((Linkage == SILLinkage::Public ||
358+
Linkage == SILLinkage::SharedExternal ||
358359
Linkage == SILLinkage::PublicExternal) &&
359360
"Only a lookup of public functions is supported currently");
360361

@@ -405,6 +406,9 @@ SILFunction *SILModule::findFunction(StringRef Name, SILLinkage Linkage) {
405406
// compilation, simply convert it into an external declaration,
406407
// so that a compiled version from the shared library is used.
407408
if (F->isDefinition() &&
409+
// Don't eliminate bodies of _alwaysEmitIntoClient functions
410+
// (PublicNonABI linkage is de-serialized as SharedExternal)
411+
F->getLinkage() != SILLinkage::SharedExternal &&
408412
!F->getModule().getOptions().shouldOptimize()) {
409413
F->convertToDeclaration();
410414
}

lib/SILGen/SILGenApply.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4962,6 +4962,22 @@ void SILGenFunction::emitUninitializedArrayDeallocation(SILLocation loc,
49624962
SGFContext());
49634963
}
49644964

4965+
ManagedValue SILGenFunction::emitUninitializedArrayFinalization(SILLocation loc,
4966+
SILValue array) {
4967+
auto &Ctx = getASTContext();
4968+
auto finalize = Ctx.getFinalizeUninitializedArray();
4969+
4970+
CanType arrayTy = array->getType().getASTType();
4971+
4972+
// Invoke the intrinsic.
4973+
auto subMap = arrayTy->getContextSubstitutionMap(SGM.M.getSwiftModule(),
4974+
Ctx.getArrayDecl());
4975+
RValue result = emitApplyOfLibraryIntrinsic(loc, finalize, subMap,
4976+
ManagedValue::forUnmanaged(array),
4977+
SGFContext());
4978+
return std::move(result).getScalarValue();
4979+
}
4980+
49654981
namespace {
49664982
/// A cleanup that deallocates an uninitialized array.
49674983
class DeallocateUninitializedArray: public Cleanup {

lib/SILGen/SILGenExpr.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,10 +2113,11 @@ ManagedValue Lowering::emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
21132113
SGF.Cleanups.setCleanupState(varargs.getAbortCleanup(), CleanupState::Dead);
21142114

21152115
// Reactivate the result cleanup.
2116-
auto result = varargs.getArray();
2117-
if (result.hasCleanup())
2118-
SGF.Cleanups.setCleanupState(result.getCleanup(), CleanupState::Active);
2119-
return result;
2116+
auto array = varargs.getArray();
2117+
if (array.hasCleanup())
2118+
SGF.Cleanups.setCleanupState(array.getCleanup(), CleanupState::Active);
2119+
2120+
return SGF.emitUninitializedArrayFinalization(loc, array.forward(SGF));
21202121
}
21212122

21222123
RValue RValueEmitter::visitTupleExpr(TupleExpr *E, SGFContext C) {

lib/SILGen/SILGenFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
11871187

11881188
CleanupHandle enterDeallocateUninitializedArrayCleanup(SILValue array);
11891189
void emitUninitializedArrayDeallocation(SILLocation loc, SILValue array);
1190+
ManagedValue emitUninitializedArrayFinalization(SILLocation loc, SILValue array);
11901191

11911192
/// Emit a cleanup for an owned value that should be written back at end of
11921193
/// scope if the value is not forwarded.

lib/SILOptimizer/Analysis/MemoryBehavior.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ class MemoryBehaviorVisitor
180180
MemBehavior visitStrongReleaseInst(StrongReleaseInst *BI);
181181
MemBehavior visitReleaseValueInst(ReleaseValueInst *BI);
182182
MemBehavior visitSetDeallocatingInst(SetDeallocatingInst *BI);
183+
MemBehavior visitBeginCOWMutationInst(BeginCOWMutationInst *BCMI);
183184
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
184185
MemBehavior visit##Name##ReleaseInst(Name##ReleaseInst *BI);
185186
#include "swift/AST/ReferenceStorage.def"
@@ -395,6 +396,14 @@ MemBehavior MemoryBehaviorVisitor::visitSetDeallocatingInst(SetDeallocatingInst
395396
return MemBehavior::None;
396397
}
397398

399+
MemBehavior MemoryBehaviorVisitor::
400+
visitBeginCOWMutationInst(BeginCOWMutationInst *BCMI) {
401+
// begin_cow_mutation is defined to have side effects, because it has
402+
// dependencies with instructions which retain the buffer operand.
403+
// But it never interferes with any memory address.
404+
return MemBehavior::None;
405+
}
406+
398407
//===----------------------------------------------------------------------===//
399408
// Top Level Entrypoint
400409
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)