Skip to content

Commit 95f1dfb

Browse files
authored
Merge pull request #78885 from eeckstein/fix-without-actually-escaping
Fix two problems with `withoutActuallyEscaping`
2 parents 6b58f8f + 3ec5d7d commit 95f1dfb

40 files changed

+149
-119
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ComputeSideEffects.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ private struct CollectedEffects {
9595
case is CopyValueInst, is RetainValueInst, is StrongRetainInst:
9696
addEffects(.copy, to: inst.operands[0].value, fromInitialPath: SmallProjectionPath(.anyValueFields))
9797

98-
case is DestroyValueInst, is ReleaseValueInst, is StrongReleaseInst:
98+
case is DestroyValueInst, is DestroyNotEscapedClosureInst, is ReleaseValueInst, is StrongReleaseInst:
9999
addDestroyEffects(ofValue: inst.operands[0].value)
100100

101101
case let da as DestroyAddrInst:
@@ -180,8 +180,8 @@ private struct CollectedEffects {
180180
is CondFailInst:
181181
break
182182

183-
case is BeginCOWMutationInst, is IsUniqueInst, is IsEscapingClosureInst:
184-
// Model reference count reading as "destroy" for now. Although we could intoduce a "read-refcount"
183+
case is BeginCOWMutationInst, is IsUniqueInst:
184+
// Model reference count reading as "destroy" for now. Although we could introduce a "read-refcount"
185185
// effect, it would not give any significant benefit in any of our current optimizations.
186186
addEffects(.destroy, to: inst.operands[0].value, fromInitialPath: SmallProjectionPath(.anyValueFields))
187187

SwiftCompilerSources/Sources/Optimizer/Utilities/LifetimeDependenceUtils.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ extension LifetimeDependenceDefUseWalker {
962962

963963
case is ExistentialMetatypeInst, is FixLifetimeInst, is WitnessMethodInst,
964964
is DynamicMethodBranchInst, is ValueMetatypeInst,
965-
is IsEscapingClosureInst, is ClassMethodInst, is SuperMethodInst,
965+
is DestroyNotEscapedClosureInst, is ClassMethodInst, is SuperMethodInst,
966966
is ClassifyBridgeObjectInst, is DebugValueInst,
967967
is ObjCMethodInst, is ObjCSuperMethodInst, is UnmanagedRetainValueInst,
968968
is UnmanagedReleaseValueInst, is SelectEnumInst:

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ final public class WitnessMethodInst : SingleValueInstruction {}
12051205

12061206
final public class IsUniqueInst : SingleValueInstruction, UnaryInstruction {}
12071207

1208-
final public class IsEscapingClosureInst : SingleValueInstruction, UnaryInstruction {}
1208+
final public class DestroyNotEscapedClosureInst : SingleValueInstruction, UnaryInstruction {}
12091209

12101210
final public class MarkUnresolvedNonCopyableValueInst: SingleValueInstruction, UnaryInstruction {}
12111211

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public func registerSILClasses() {
224224
register(ObjCSuperMethodInst.self)
225225
register(WitnessMethodInst.self)
226226
register(IsUniqueInst.self)
227-
register(IsEscapingClosureInst.self)
227+
register(DestroyNotEscapedClosureInst.self)
228228
register(AllocStackInst.self)
229229
register(AllocVectorInst.self)
230230
register(AllocPackInst.self)

docs/SIL/Instructions.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,18 +2084,19 @@ not replace this reference with a not uniquely reference object.
20842084

20852085
For details see [Copy-on-Write Representation](SIL.md#Copy-on-Write-Representation).
20862086

2087-
### is_escaping_closure
2087+
### destroy_not_escaped_closure
20882088

20892089
```
2090-
sil-instruction ::= 'is_escaping_closure' sil-operand
2090+
sil-instruction ::= 'destroy_not_escaped_closure' sil-operand
20912091
2092-
%1 = is_escaping_closure %0 : $@callee_guaranteed () -> ()
2092+
%1 = destroy_not_escaped_closure %0 : $@callee_guaranteed () -> ()
20932093
// %0 must be an escaping swift closure.
20942094
// %1 will be of type Builtin.Int1
20952095
```
20962096

2097-
Checks whether the context reference is not nil and bigger than one and
2098-
returns true if it is.
2097+
Checks if the closure context escaped and then destroys the context.
2098+
The escape-check is done by checking if its reference count is exactly 1.
2099+
Returns true if it is.
20992100

21002101
### copy_block
21012102

include/swift/SIL/SILBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2371,11 +2371,11 @@ class SILBuilder {
23712371
return insert(new (getModule()) EndCOWMutationInst(getSILDebugLocation(Loc),
23722372
operand, keepUnique));
23732373
}
2374-
IsEscapingClosureInst *createIsEscapingClosure(SILLocation Loc,
2374+
DestroyNotEscapedClosureInst *createDestroyNotEscapedClosure(SILLocation Loc,
23752375
SILValue operand,
23762376
unsigned VerificationType) {
23772377
auto Int1Ty = SILType::getBuiltinIntegerType(1, getASTContext());
2378-
return insert(new (getModule()) IsEscapingClosureInst(
2378+
return insert(new (getModule()) DestroyNotEscapedClosureInst(
23792379
getSILDebugLocation(Loc), operand, Int1Ty, VerificationType));
23802380
}
23812381

include/swift/SIL/SILCloner.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,11 +3185,11 @@ void SILCloner<ImplClass>::visitEndCOWMutationInst(EndCOWMutationInst *Inst) {
31853185
getOpValue(Inst->getOperand()), Inst->doKeepUnique()));
31863186
}
31873187
template <typename ImplClass>
3188-
void SILCloner<ImplClass>::visitIsEscapingClosureInst(
3189-
IsEscapingClosureInst *Inst) {
3188+
void SILCloner<ImplClass>::visitDestroyNotEscapedClosureInst(
3189+
DestroyNotEscapedClosureInst *Inst) {
31903190
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
31913191
recordClonedInstruction(
3192-
Inst, getBuilder().createIsEscapingClosure(getOpLocation(Inst->getLoc()),
3192+
Inst, getBuilder().createDestroyNotEscapedClosure(getOpLocation(Inst->getLoc()),
31933193
getOpValue(Inst->getOperand()),
31943194
Inst->getVerificationType()));
31953195
}

include/swift/SIL/SILInstruction.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9474,14 +9474,14 @@ class EndCOWMutationInst
94749474

94759475
/// Given an escaping closure return true iff it has a non-nil context and the
94769476
/// context has a strong reference count greater than 1.
9477-
class IsEscapingClosureInst
9478-
: public UnaryInstructionBase<SILInstructionKind::IsEscapingClosureInst,
9477+
class DestroyNotEscapedClosureInst
9478+
: public UnaryInstructionBase<SILInstructionKind::DestroyNotEscapedClosureInst,
94799479
SingleValueInstruction> {
94809480
friend SILBuilder;
94819481

94829482
unsigned VerificationType;
94839483

9484-
IsEscapingClosureInst(SILDebugLocation DebugLoc, SILValue Operand,
9484+
DestroyNotEscapedClosureInst(SILDebugLocation DebugLoc, SILValue Operand,
94859485
SILType BoolTy, unsigned VerificationType)
94869486
: UnaryInstructionBase(DebugLoc, Operand, BoolTy),
94879487
VerificationType(VerificationType) {}

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,8 +529,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
529529
SINGLE_VALUE_INST(EndCOWMutationInst, end_cow_mutation,
530530
SingleValueInstruction, None, DoesNotRelease)
531531

532-
SINGLE_VALUE_INST(IsEscapingClosureInst, is_escaping_closure,
533-
SingleValueInstruction, MayRead, DoesNotRelease)
532+
SINGLE_VALUE_INST(DestroyNotEscapedClosureInst, destroy_not_escaped_closure,
533+
SingleValueInstruction, MayHaveSideEffects, MayRelease)
534534

535535
// Accessing memory
536536
SINGLE_VALUE_INST(LoadInst, load,

lib/IRGen/IRGenSIL.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,7 +1411,7 @@ class IRGenSILFunction :
14111411
void visitIsUniqueInst(IsUniqueInst *i);
14121412
void visitBeginCOWMutationInst(BeginCOWMutationInst *i);
14131413
void visitEndCOWMutationInst(EndCOWMutationInst *i);
1414-
void visitIsEscapingClosureInst(IsEscapingClosureInst *i);
1414+
void visitDestroyNotEscapedClosureInst(DestroyNotEscapedClosureInst *i);
14151415
void visitDeallocStackInst(DeallocStackInst *i);
14161416
void visitDeallocStackRefInst(DeallocStackRefInst *i);
14171417
void visitDeallocPackInst(DeallocPackInst *i);
@@ -6335,8 +6335,8 @@ void IRGenSILFunction::visitEndCOWMutationInst(EndCOWMutationInst *i) {
63356335
setLoweredExplosion(i, v);
63366336
}
63376337

6338-
void IRGenSILFunction::visitIsEscapingClosureInst(
6339-
swift::IsEscapingClosureInst *i) {
6338+
void IRGenSILFunction::visitDestroyNotEscapedClosureInst(
6339+
swift::DestroyNotEscapedClosureInst *i) {
63406340
// The closure operand is allowed to be an optional closure.
63416341
auto operandType = i->getOperand()->getType();
63426342
if (operandType.getOptionalObjectType())
@@ -6348,21 +6348,19 @@ void IRGenSILFunction::visitIsEscapingClosureInst(
63486348

63496349
// This code relies on that an optional<()->()>'s tag fits in the function
63506350
// pointer.
6351-
auto &TI = cast<LoadableTypeInfo>(getTypeInfo(operandType));
6351+
auto &TI = cast<ReferenceTypeInfo>(getTypeInfo(operandType));
63526352
assert(TI.mayHaveExtraInhabitants(IGM) &&
63536353
"Must have extra inhabitants to be able to handle the optional "
63546354
"closure case");
63556355
(void)TI;
63566356

63576357
Explosion closure = getLoweredExplosion(i->getOperand());
6358-
auto func = closure.claimNext();
6359-
(void)func;
6360-
auto context = closure.claimNext();
6361-
assert(closure.empty());
6358+
auto context = closure.getAll()[1];
63626359
if (context->getType()->isIntegerTy())
63636360
context = Builder.CreateIntToPtr(context, IGM.RefCountedPtrTy);
63646361
auto result = emitIsEscapingClosureCall(context, i->getLoc().getSourceLoc(),
63656362
i->getVerificationType());
6363+
TI.strongRelease(*this, closure, irgen::Atomicity::Atomic);
63666364
Explosion out;
63676365
out.add(result);
63686366
setLoweredExplosion(i, out);

0 commit comments

Comments
 (0)