Skip to content

Commit 1c3445b

Browse files
committed
Introduce end_cow_mutation_addr instruction
1 parent 40dfda5 commit 1c3445b

25 files changed

+82
-6
lines changed

SwiftCompilerSources/Sources/Optimizer/TestPasses/MemBehaviorDumper.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ private extension Instruction {
6363
is BeginAccessInst,
6464
is EndAccessInst,
6565
is EndCOWMutationInst,
66+
is EndCOWMutationAddrInst,
6667
is CopyValueInst,
6768
is DestroyValueInst,
6869
is StrongReleaseInst,

SwiftCompilerSources/Sources/Optimizer/Utilities/AddressUtils.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ extension AddressUseVisitor {
131131
is DestroyAddrInst, is DeallocStackInst,
132132
is DeinitExistentialAddrInst,
133133
is IsUniqueInst, is MarkFunctionEscapeInst,
134-
is PackElementSetInst:
134+
is PackElementSetInst, is EndCOWMutationAddrInst:
135135
return leafAddressUse(of: operand)
136136

137137
case is LoadInst, is LoadUnownedInst, is LoadWeakInst, is ValueMetatypeInst, is ExistentialMetatypeInst,

SwiftCompilerSources/Sources/SIL/Builder.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,11 @@ public struct Builder {
575575
return notifyNew(endMutation.getAs(EndCOWMutationInst.self))
576576
}
577577

578+
public func createEndCOWMutationAddr(instance: Value) -> EndCOWMutationAddrInst {
579+
let endMutation = bridged.createEndCOWMutationAddr(instance.bridged)
580+
return notifyNew(endMutation.getAs(EndCOWMutationAddrInst.self))
581+
}
582+
578583
public func createMarkDependence(value: Value, base: Value, kind: MarkDependenceKind) -> MarkDependenceInst {
579584
let markDependence = bridged.createMarkDependence(value.bridged, base.bridged,
580585
BridgedInstruction.MarkDependenceKind(rawValue: kind.rawValue)!)

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,10 @@ final public class EndCOWMutationInst : SingleValueInstruction, UnaryInstruction
12241224
public var doKeepUnique: Bool { bridged.EndCOWMutationInst_doKeepUnique() }
12251225
}
12261226

1227+
final public class EndCOWMutationAddrInst : Instruction, UnaryInstruction {
1228+
public var instance: Value { operand.value }
1229+
}
1230+
12271231
final public
12281232
class ClassifyBridgeObjectInst : SingleValueInstruction, UnaryInstruction {}
12291233

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ public func registerSILClasses() {
215215
register(MoveValueInst.self)
216216
register(DropDeinitInst.self)
217217
register(EndCOWMutationInst.self)
218+
register(EndCOWMutationAddrInst.self)
218219
register(ClassifyBridgeObjectInst.self)
219220
register(PartialApplyInst.self)
220221
register(ApplyInst.self)

include/swift/SIL/AddressWalker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ TransitiveAddressWalker<Impl>::walk(SILValue projectedAddress) {
229229
isa<PackElementSetInst>(user) || isa<PackElementGetInst>(user) ||
230230
isa<DeinitExistentialAddrInst>(user) || isa<LoadBorrowInst>(user) ||
231231
isa<TupleAddrConstructorInst>(user) || isa<DeallocPackInst>(user) ||
232-
isa<MergeIsolationRegionInst>(user)) {
232+
isa<MergeIsolationRegionInst>(user) || isa<EndCOWMutationAddrInst>(user)) {
233233
callVisitUse(op);
234234
continue;
235235
}

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,7 @@ struct BridgedBuilder{
12781278
BridgedASTType::MetatypeRepresentation representation) const;
12791279
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createEndCOWMutation(BridgedValue instance,
12801280
bool keepUnique) const;
1281+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createEndCOWMutationAddr(BridgedValue instance) const;
12811282
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createMarkDependence(
12821283
BridgedValue value, BridgedValue base, BridgedInstruction::MarkDependenceKind dependenceKind) const;
12831284

include/swift/SIL/SILBridgingImpl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2498,6 +2498,12 @@ BridgedInstruction BridgedBuilder::createEndCOWMutation(BridgedValue instance, b
24982498
keepUnique)};
24992499
}
25002500

2501+
BridgedInstruction
2502+
BridgedBuilder::createEndCOWMutationAddr(BridgedValue instance) const {
2503+
return {unbridged().createEndCOWMutationAddr(regularLoc(),
2504+
instance.getSILValue())};
2505+
}
2506+
25012507
BridgedInstruction BridgedBuilder::createMarkDependence(BridgedValue value, BridgedValue base, BridgedInstruction::MarkDependenceKind kind) const {
25022508
return {unbridged().createMarkDependence(regularLoc(), value.getSILValue(), base.getSILValue(), swift::MarkDependenceKind(kind))};
25032509
}

include/swift/SIL/SILBuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,6 +2383,11 @@ class SILBuilder {
23832383
return insert(new (getModule()) EndCOWMutationInst(getSILDebugLocation(Loc),
23842384
operand, keepUnique));
23852385
}
2386+
EndCOWMutationAddrInst *createEndCOWMutationAddr(SILLocation Loc,
2387+
SILValue operand) {
2388+
return insert(new (getModule()) EndCOWMutationAddrInst(
2389+
getSILDebugLocation(Loc), operand));
2390+
}
23862391
DestroyNotEscapedClosureInst *createDestroyNotEscapedClosure(SILLocation Loc,
23872392
SILValue operand,
23882393
unsigned VerificationType) {

include/swift/SIL/SILCloner.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3167,6 +3167,14 @@ void SILCloner<ImplClass>::visitEndCOWMutationInst(EndCOWMutationInst *Inst) {
31673167
getOpValue(Inst->getOperand()), Inst->doKeepUnique()));
31683168
}
31693169
template <typename ImplClass>
3170+
void SILCloner<ImplClass>::visitEndCOWMutationAddrInst(
3171+
EndCOWMutationAddrInst *Inst) {
3172+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
3173+
recordClonedInstruction(
3174+
Inst, getBuilder().createEndCOWMutationAddr(
3175+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
3176+
}
3177+
template <typename ImplClass>
31703178
void SILCloner<ImplClass>::visitDestroyNotEscapedClosureInst(
31713179
DestroyNotEscapedClosureInst *Inst) {
31723180
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));

include/swift/SIL/SILInstruction.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9579,6 +9579,14 @@ class EndCOWMutationInst
95799579
sharedUInt8().EndCOWMutationInst.keepUnique = keepUnique;
95809580
}
95819581
};
9582+
class EndCOWMutationAddrInst
9583+
: public UnaryInstructionBase<SILInstructionKind::EndCOWMutationAddrInst,
9584+
NonValueInstruction> {
9585+
friend SILBuilder;
9586+
9587+
EndCOWMutationAddrInst(SILDebugLocation debugLoc, SILValue address)
9588+
: UnaryInstructionBase(debugLoc, address) {}
9589+
};
95829590

95839591
/// Given an escaping closure return true iff it has a non-nil context and the
95849592
/// context has a strong reference count greater than 1.

include/swift/SIL/SILNodes.def

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
528528

529529
SINGLE_VALUE_INST(EndCOWMutationInst, end_cow_mutation,
530530
SingleValueInstruction, None, DoesNotRelease)
531-
531+
532532
SINGLE_VALUE_INST(DestroyNotEscapedClosureInst, destroy_not_escaped_closure,
533533
SingleValueInstruction, MayHaveSideEffects, MayRelease)
534534

@@ -908,7 +908,9 @@ NON_VALUE_INST(IncrementProfilerCounterInst, increment_profiler_counter,
908908
NON_VALUE_INST(MarkDependenceAddrInst, mark_dependence_addr,
909909
SILInstruction, None, DoesNotRelease)
910910

911-
NODE_RANGE(NonValueInstruction, UnreachableInst, MarkDependenceAddrInst)
911+
NON_VALUE_INST(EndCOWMutationAddrInst, end_cow_mutation_addr,
912+
SILInstruction, MayHaveSideEffects, DoesNotRelease)
913+
NODE_RANGE(NonValueInstruction, UnreachableInst, EndCOWMutationAddrInst)
912914

913915
ABSTRACT_INST(MultipleValueInstruction, SILInstruction)
914916
MULTIPLE_VALUE_INST(BeginApplyInst, begin_apply,

lib/IRGen/IRGenSIL.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,7 @@ class IRGenSILFunction :
14381438
void visitIsUniqueInst(IsUniqueInst *i);
14391439
void visitBeginCOWMutationInst(BeginCOWMutationInst *i);
14401440
void visitEndCOWMutationInst(EndCOWMutationInst *i);
1441+
void visitEndCOWMutationAddrInst(EndCOWMutationAddrInst *i);
14411442
void visitDestroyNotEscapedClosureInst(DestroyNotEscapedClosureInst *i);
14421443
void visitDeallocStackInst(DeallocStackInst *i);
14431444
void visitDeallocStackRefInst(DeallocStackRefInst *i);
@@ -6365,6 +6366,10 @@ void IRGenSILFunction::visitEndCOWMutationInst(EndCOWMutationInst *i) {
63656366
setLoweredExplosion(i, v);
63666367
}
63676368

6369+
void IRGenSILFunction::visitEndCOWMutationAddrInst(EndCOWMutationAddrInst *i) {
6370+
// end_cow_mutation_addr is purely for SIL.
6371+
}
6372+
63686373
void IRGenSILFunction::visitDestroyNotEscapedClosureInst(
63696374
swift::DestroyNotEscapedClosureInst *i) {
63706375
// The closure operand is allowed to be an optional closure.

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ OPERAND_OWNERSHIP(DestroyingConsume, DestroyNotEscapedClosure)
301301
OPERAND_OWNERSHIP(DestroyingConsume, EndLifetime)
302302
OPERAND_OWNERSHIP(DestroyingConsume, BeginCOWMutation)
303303
OPERAND_OWNERSHIP(DestroyingConsume, EndCOWMutation)
304+
OPERAND_OWNERSHIP(TrivialUse, EndCOWMutationAddr)
304305
OPERAND_OWNERSHIP(DestroyingConsume, EndInitLetRef)
305306
// The move_value instruction creates a distinct lifetime.
306307
OPERAND_OWNERSHIP(DestroyingConsume, MoveValue)

lib/SIL/IR/SILPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,6 +2763,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
27632763
*this << "[keep_unique] ";
27642764
*this << getIDAndType(ECMI->getOperand());
27652765
}
2766+
void visitEndCOWMutationAddrInst(EndCOWMutationAddrInst *ECMI) {
2767+
*this << getIDAndType(ECMI->getOperand());
2768+
}
27662769
void visitEndInitLetRefInst(EndInitLetRefInst *I) {
27672770
*this << getIDAndType(I->getOperand());
27682771
}

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3470,6 +3470,12 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
34703470
ResultVal = B.createEndCOWMutation(InstLoc, Val, keepUnique);
34713471
break;
34723472
}
3473+
case SILInstructionKind::EndCOWMutationAddrInst: {
3474+
if (parseTypedValueRef(Val, B) || parseSILDebugLocation(InstLoc, B))
3475+
return true;
3476+
ResultVal = B.createEndCOWMutationAddr(InstLoc, Val);
3477+
break;
3478+
}
34733479
case SILInstructionKind::DestroyNotEscapedClosureInst: {
34743480
bool IsObjcVerificationType = false;
34753481
if (parseSILOptional(IsObjcVerificationType, *this, "objc"))

lib/SIL/Utils/InstructionUtils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
628628
case SILInstructionKind::DifferentiabilityWitnessFunctionInst:
629629
case SILInstructionKind::IncrementProfilerCounterInst:
630630
case SILInstructionKind::EndCOWMutationInst:
631+
case SILInstructionKind::EndCOWMutationAddrInst:
631632
case SILInstructionKind::HasSymbolInst:
632633
case SILInstructionKind::DynamicPackIndexInst:
633634
case SILInstructionKind::PackPackIndexInst:

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,6 +2809,7 @@ void swift::visitAccessedAddress(SILInstruction *I,
28092809
case SILInstructionKind::BeginBorrowInst:
28102810
case SILInstructionKind::BeginCOWMutationInst:
28112811
case SILInstructionKind::EndCOWMutationInst:
2812+
case SILInstructionKind::EndCOWMutationAddrInst:
28122813
case SILInstructionKind::BeginUnpairedAccessInst:
28132814
case SILInstructionKind::BindMemoryInst:
28142815
case SILInstructionKind::RebindMemoryInst:

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,6 +3376,7 @@ CONSTANT_TRANSLATION(BridgeObjectToRefInst, LookThrough)
33763376
CONSTANT_TRANSLATION(CopyValueInst, LookThrough)
33773377
CONSTANT_TRANSLATION(ExplicitCopyValueInst, LookThrough)
33783378
CONSTANT_TRANSLATION(EndCOWMutationInst, LookThrough)
3379+
CONSTANT_TRANSLATION(EndCOWMutationAddrInst, Ignored)
33793380
CONSTANT_TRANSLATION(ProjectBoxInst, LookThrough)
33803381
CONSTANT_TRANSLATION(EndInitLetRefInst, LookThrough)
33813382
CONSTANT_TRANSLATION(InitEnumDataAddrInst, LookThrough)

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2186,7 +2186,12 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
21862186
// Ignore end_access.
21872187
if (isa<EndAccessInst>(user))
21882188
return true;
2189-
2189+
2190+
// Ignore end_cow_mutation_addr.
2191+
if (isa<EndCOWMutationAddrInst>(user)) {
2192+
return true;
2193+
}
2194+
21902195
// Ignore sanitizer markers.
21912196
if (auto bu = dyn_cast<BuiltinInst>(user)) {
21922197
if (bu->getBuiltinKind() == BuiltinValueKind::TSanInoutAccess) {

lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ static bool hasOpaqueArchetype(TypeExpansionContext context,
321321
case SILInstructionKind::DifferentiabilityWitnessFunctionInst:
322322
case SILInstructionKind::BeginCOWMutationInst:
323323
case SILInstructionKind::EndCOWMutationInst:
324+
case SILInstructionKind::EndCOWMutationAddrInst:
324325
case SILInstructionKind::IncrementProfilerCounterInst:
325326
case SILInstructionKind::GetAsyncContinuationInst:
326327
case SILInstructionKind::GetAsyncContinuationAddrInst:

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) {
10231023
case SILInstructionKind::UnwindInst:
10241024
case SILInstructionKind::YieldInst:
10251025
case SILInstructionKind::EndCOWMutationInst:
1026+
case SILInstructionKind::EndCOWMutationAddrInst:
10261027
return InlineCost::Free;
10271028

10281029
// Turning the task reference into a continuation should be basically free.

lib/Serialization/DeserializeSIL.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,6 +2726,15 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
27262726
break;
27272727
}
27282728

2729+
case SILInstructionKind::EndCOWMutationAddrInst: {
2730+
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
2731+
ResultInst = Builder.createEndCOWMutationAddr(
2732+
Loc, getLocalValue(Builder.maybeGetFunction(), ValID,
2733+
getSILType(MF->getType(TyID),
2734+
(SILValueCategory)TyCategory, Fn)));
2735+
break;
2736+
}
2737+
27292738
case SILInstructionKind::DestructureTupleInst: {
27302739
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
27312740
SILValue Operand = getLocalValue(

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 944; // specialized witness tables
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 945; // end_cow_mutation_addr
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///

lib/Serialization/SerializeSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,6 +1706,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
17061706
case SILInstructionKind::IsUniqueInst:
17071707
case SILInstructionKind::BeginCOWMutationInst:
17081708
case SILInstructionKind::EndCOWMutationInst:
1709+
case SILInstructionKind::EndCOWMutationAddrInst:
17091710
case SILInstructionKind::EndInitLetRefInst:
17101711
case SILInstructionKind::HopToExecutorInst:
17111712
case SILInstructionKind::ExtractExecutorInst:

0 commit comments

Comments
 (0)