Skip to content

Commit e135c5c

Browse files
committed
[SIL] Added strong_copy_weak_value.
The new instruction unwraps an `@sil_weak` box and produces an owned value. It is only legal in opaque values mode and is transformed by `AddressLowering` to `load_weak`.
1 parent c44b23c commit e135c5c

22 files changed

+266
-107
lines changed

docs/SIL.rst

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5192,7 +5192,28 @@ weak reference count.
51925192

51935193
This operation must be atomic with respect to the final ``strong_release`` on
51945194
the operand heap object. It need not be atomic with respect to ``store_weak``
5195-
or ``load_weak`` operations on the same address.
5195+
or ``load_weak``/``strong_copy_weak_value`` operations on the same address.
5196+
5197+
strong_copy_weak_value
5198+
``````````````````````
5199+
::
5200+
5201+
sil-instruction ::= 'strong_copy_weak_value' sil-operand
5202+
5203+
%1 = strong_copy_weak_value %0 : $@sil_weak Optional<T>
5204+
// %1 will be a strong @owned value of type $Optional<T>.
5205+
// $T must be a reference type
5206+
// $@sil_weak Optional<T> must be address-only
5207+
5208+
Only valid in opaque values mode. Lowered by AddressLowering to load_weak.
5209+
5210+
If the heap object referenced by ``%0`` has not begun deallocation, increments
5211+
its strong reference count and produces the value ``Optional.some`` holding the
5212+
object. Otherwise, produces the value ``Optional.none``.
5213+
5214+
This operation must be atomic with respect to the final ``strong_release`` on
5215+
the operand heap object. It need not be atomic with respect to ``store_weak``
5216+
or ``load_weak``/``strong_copy_weak_value`` operations on the same address.
51965217

51975218
store_weak
51985219
``````````
@@ -5218,7 +5239,8 @@ currently be initialized. After the evaluation:
52185239

52195240
This operation must be atomic with respect to the final ``strong_release`` on
52205241
the operand (source) heap object. It need not be atomic with respect to
5221-
``store_weak`` or ``load_weak`` operations on the same address.
5242+
``store_weak`` or ``load_weak``/``strong_copy_weak_value`` operations on the
5243+
same address.
52225244

52235245
load_unowned
52245246
````````````

include/swift/SIL/SILBuilder.h

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,20 +1061,28 @@ class SILBuilder {
10611061
getSILDebugLocation(Loc), ArgumentsSpecification, getModule()));
10621062
}
10631063

1064-
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1065-
Load##Name##Inst *createLoad##Name(SILLocation Loc, \
1066-
SILValue src, \
1067-
IsTake_t isTake) { \
1068-
return insert(new (getModule()) \
1069-
Load##Name##Inst(getSILDebugLocation(Loc), src, isTake)); \
1070-
} \
1071-
Store##Name##Inst *createStore##Name(SILLocation Loc, \
1072-
SILValue value, \
1073-
SILValue dest, \
1074-
IsInitialization_t isInit) { \
1075-
return insert(new (getModule()) \
1076-
Store##Name##Inst(getSILDebugLocation(Loc), value, dest, isInit)); \
1064+
#define COPYABLE_STORAGE_HELPER(Name) \
1065+
StrongCopy##Name##ValueInst *createStrongCopy##Name##Value( \
1066+
SILLocation Loc, SILValue operand) { \
1067+
auto type = getFunction().getLoweredType( \
1068+
operand->getType().getASTType().getReferenceStorageReferent()); \
1069+
return insert(new (getModule()) StrongCopy##Name##ValueInst( \
1070+
getSILDebugLocation(Loc), operand, type)); \
10771071
}
1072+
1073+
#define LOADABLE_STORAGE_HELPER(Name) \
1074+
Load##Name##Inst *createLoad##Name(SILLocation Loc, SILValue src, \
1075+
IsTake_t isTake) { \
1076+
return insert(new (getModule()) Load##Name##Inst(getSILDebugLocation(Loc), \
1077+
src, isTake)); \
1078+
} \
1079+
Store##Name##Inst *createStore##Name(SILLocation Loc, SILValue value, \
1080+
SILValue dest, \
1081+
IsInitialization_t isInit) { \
1082+
return insert(new (getModule()) Store##Name##Inst( \
1083+
getSILDebugLocation(Loc), value, dest, isInit)); \
1084+
}
1085+
10781086
#define LOADABLE_REF_STORAGE_HELPER(Name) \
10791087
Name##ToRefInst *create##Name##ToRef(SILLocation Loc, SILValue op, \
10801088
SILType ty) { \
@@ -1085,41 +1093,45 @@ class SILBuilder {
10851093
SILType ty) { \
10861094
return insert(new (getModule()) \
10871095
RefTo##Name##Inst(getSILDebugLocation(Loc), op, ty)); \
1088-
} \
1089-
StrongCopy##Name##ValueInst *createStrongCopy##Name##Value( \
1090-
SILLocation Loc, SILValue operand) { \
1091-
auto type = getFunction().getLoweredType( \
1092-
operand->getType().getASTType().getReferenceStorageReferent()); \
1093-
return insert(new (getModule()) StrongCopy##Name##ValueInst( \
1094-
getSILDebugLocation(Loc), operand, type)); \
10951096
}
10961097

1097-
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1098-
LOADABLE_REF_STORAGE_HELPER(Name) \
1099-
StrongRetain##Name##Inst *createStrongRetain##Name(SILLocation Loc, \
1100-
SILValue Operand, \
1101-
Atomicity atomicity) { \
1102-
return insert(new (getModule()) \
1103-
StrongRetain##Name##Inst(getSILDebugLocation(Loc), Operand, atomicity)); \
1104-
} \
1105-
Name##RetainInst *create##Name##Retain(SILLocation Loc, SILValue Operand, \
1106-
Atomicity atomicity) { \
1107-
return insert(new (getModule()) \
1108-
Name##RetainInst(getSILDebugLocation(Loc), Operand, atomicity)); \
1109-
} \
1110-
Name##ReleaseInst *create##Name##Release(SILLocation Loc, \
1111-
SILValue Operand, \
1112-
Atomicity atomicity) { \
1113-
return insert(new (getModule()) \
1114-
Name##ReleaseInst(getSILDebugLocation(Loc), Operand, atomicity)); \
1115-
}
1116-
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1117-
NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, "...") \
1118-
ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, "...")
1119-
#define UNCHECKED_REF_STORAGE(Name, ...) \
1098+
#define RETAINABLE_STORAGE_HELPER(Name) \
1099+
StrongRetain##Name##Inst *createStrongRetain##Name( \
1100+
SILLocation Loc, SILValue Operand, Atomicity atomicity) { \
1101+
return insert(new (getModule()) StrongRetain##Name##Inst( \
1102+
getSILDebugLocation(Loc), Operand, atomicity)); \
1103+
} \
1104+
Name##RetainInst *create##Name##Retain(SILLocation Loc, SILValue Operand, \
1105+
Atomicity atomicity) { \
1106+
return insert(new (getModule()) Name##RetainInst(getSILDebugLocation(Loc), \
1107+
Operand, atomicity)); \
1108+
} \
1109+
Name##ReleaseInst *create##Name##Release(SILLocation Loc, SILValue Operand, \
1110+
Atomicity atomicity) { \
1111+
return insert(new (getModule()) Name##ReleaseInst( \
1112+
getSILDebugLocation(Loc), Operand, atomicity)); \
1113+
}
1114+
1115+
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1116+
COPYABLE_STORAGE_HELPER(Name) \
1117+
LOADABLE_REF_STORAGE_HELPER(Name) \
1118+
RETAINABLE_STORAGE_HELPER(Name)
1119+
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1120+
COPYABLE_STORAGE_HELPER(Name) \
1121+
LOADABLE_REF_STORAGE_HELPER(Name) \
1122+
LOADABLE_STORAGE_HELPER(Name) \
1123+
RETAINABLE_STORAGE_HELPER(Name)
1124+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1125+
COPYABLE_STORAGE_HELPER(Name) \
1126+
LOADABLE_STORAGE_HELPER(Name)
1127+
#define UNCHECKED_REF_STORAGE(Name, ...) \
1128+
COPYABLE_STORAGE_HELPER(Name) \
11201129
LOADABLE_REF_STORAGE_HELPER(Name)
11211130
#include "swift/AST/ReferenceStorage.def"
1131+
#undef LOADABLE_STORAGE_HELPER
11221132
#undef LOADABLE_REF_STORAGE_HELPER
1133+
#undef COPYABLE_STORAGE_HELPER
1134+
#undef RETAINABLE_STORAGE_HELPER
11231135

11241136
CopyAddrInst *createCopyAddr(SILLocation Loc, SILValue srcAddr,
11251137
SILValue destAddr, IsTake_t isTake,

include/swift/SIL/SILCloner.h

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,17 @@ SILCloner<ImplClass>::visitDebugStepInst(DebugStepInst *Inst) {
14071407
recordClonedInstruction(Inst, getBuilder().createDebugStep(Inst->getLoc()));
14081408
}
14091409

1410-
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1410+
#define COPYABLE_STORAGE_HELPER(Name, name) \
1411+
template <typename ImplClass> \
1412+
void SILCloner<ImplClass>::visitStrongCopy##Name##ValueInst( \
1413+
StrongCopy##Name##ValueInst *Inst) { \
1414+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); \
1415+
recordClonedInstruction(Inst, getBuilder().createStrongCopy##Name##Value( \
1416+
getOpLocation(Inst->getLoc()), \
1417+
getOpValue(Inst->getOperand()))); \
1418+
}
1419+
1420+
#define LOADABLE_STORAGE_HELPER(Name, name) \
14111421
template <typename ImplClass> \
14121422
void SILCloner<ImplClass>::visitLoad##Name##Inst(Load##Name##Inst *Inst) { \
14131423
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); \
@@ -1441,17 +1451,8 @@ SILCloner<ImplClass>::visitDebugStepInst(DebugStepInst *Inst) {
14411451
Inst, getBuilder().create##Name##ToRef(getOpLocation(Inst->getLoc()), \
14421452
getOpValue(Inst->getOperand()), \
14431453
getOpType(Inst->getType()))); \
1444-
} \
1445-
template <typename ImplClass> \
1446-
void SILCloner<ImplClass>::visitStrongCopy##Name##ValueInst( \
1447-
StrongCopy##Name##ValueInst *Inst) { \
1448-
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); \
1449-
recordClonedInstruction(Inst, getBuilder().createStrongCopy##Name##Value( \
1450-
getOpLocation(Inst->getLoc()), \
1451-
getOpValue(Inst->getOperand()))); \
14521454
}
1453-
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1454-
LOADABLE_REF_STORAGE_HELPER(Name, name) \
1455+
#define RETAINABLE_STORAGE_HELPER(Name, name) \
14551456
template <typename ImplClass> \
14561457
void SILCloner<ImplClass>::visitStrongRetain##Name##Inst( \
14571458
StrongRetain##Name##Inst *Inst) { \
@@ -1478,13 +1479,26 @@ SILCloner<ImplClass>::visitDebugStepInst(DebugStepInst *Inst) {
14781479
getOpValue(Inst->getOperand()), \
14791480
Inst->getAtomicity())); \
14801481
}
1481-
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1482-
NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, "...") \
1483-
ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, "...")
1484-
#define UNCHECKED_REF_STORAGE(Name, name, ...) \
1482+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1483+
COPYABLE_STORAGE_HELPER(Name, name) \
1484+
LOADABLE_STORAGE_HELPER(Name, name)
1485+
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1486+
COPYABLE_STORAGE_HELPER(Name, name) \
1487+
LOADABLE_REF_STORAGE_HELPER(Name, name) \
1488+
RETAINABLE_STORAGE_HELPER(Name, name)
1489+
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1490+
COPYABLE_STORAGE_HELPER(Name, name) \
1491+
LOADABLE_REF_STORAGE_HELPER(Name, name) \
1492+
LOADABLE_STORAGE_HELPER(Name, name) \
1493+
RETAINABLE_STORAGE_HELPER(Name, name)
1494+
#define UNCHECKED_REF_STORAGE(Name, name, ...) \
1495+
COPYABLE_STORAGE_HELPER(Name, name) \
14851496
LOADABLE_REF_STORAGE_HELPER(Name, name)
14861497
#include "swift/AST/ReferenceStorage.def"
1498+
#undef LOADABLE_STORAGE_HELPER
14871499
#undef LOADABLE_REF_STORAGE_HELPER
1500+
#undef COPYABLE_STORAGE_HELPER
1501+
#undef RETAINABLE_STORAGE_HELPER
14881502

14891503
template<typename ImplClass>
14901504
void

include/swift/SIL/SILInstruction.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8098,6 +8098,17 @@ class ExplicitCopyValueInst
80988098
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {}
80998099
};
81008100

8101+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
8102+
class StrongCopy##Name##ValueInst \
8103+
: public UnaryInstructionBase< \
8104+
SILInstructionKind::StrongCopy##Name##ValueInst, \
8105+
SingleValueInstruction> { \
8106+
friend class SILBuilder; \
8107+
StrongCopy##Name##ValueInst(SILDebugLocation DebugLoc, SILValue operand, \
8108+
SILType type) \
8109+
: UnaryInstructionBase(DebugLoc, operand, \
8110+
type.getReferenceStorageReferentType()) {} \
8111+
};
81018112
#define UNCHECKED_REF_STORAGE(Name, ...) \
81028113
class StrongCopy##Name##ValueInst \
81038114
: public UnaryInstructionBase< \
@@ -8108,7 +8119,6 @@ class ExplicitCopyValueInst
81088119
SILType type) \
81098120
: UnaryInstructionBase(DebugLoc, operand, type) {} \
81108121
};
8111-
81128122
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
81138123
class StrongCopy##Name##ValueInst \
81148124
: public UnaryInstructionBase< \

include/swift/SIL/SILNodes.def

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,10 +453,7 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
453453
// alone by OSSA optimizations.
454454
SINGLE_VALUE_INST(ExplicitCopyValueInst, explicit_copy_value,
455455
SingleValueInstruction, None, DoesNotRelease)
456-
#define UNCHECKED_REF_STORAGE(Name, name, ...) \
457-
SINGLE_VALUE_INST(StrongCopy##Name##ValueInst, strong_copy_##name##_value, \
458-
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
459-
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
456+
#define REF_STORAGE(Name, name, ...) \
460457
SINGLE_VALUE_INST(StrongCopy##Name##ValueInst, strong_copy_##name##_value, \
461458
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
462459
#include "swift/AST/ReferenceStorage.def"

lib/IRGen/IRGenSIL.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,23 +1505,35 @@ class IRGenSILFunction :
15051505

15061506
#define LOADABLE_REF_STORAGE_HELPER(Name) \
15071507
void visitRefTo##Name##Inst(RefTo##Name##Inst *i); \
1508-
void visit##Name##ToRefInst(Name##ToRefInst *i); \
1508+
void visit##Name##ToRefInst(Name##ToRefInst *i);
1509+
#define COPYABLE_STORAGE_HELPER(Name) \
15091510
void visitStrongCopy##Name##ValueInst(StrongCopy##Name##ValueInst *i);
1510-
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1511-
void visitLoad##Name##Inst(Load##Name##Inst *i); \
1511+
#define LOADABLE_STORAGE_HELPER(Name) \
1512+
void visitLoad##Name##Inst(Load##Name##Inst *i); \
15121513
void visitStore##Name##Inst(Store##Name##Inst *i);
1513-
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1514-
LOADABLE_REF_STORAGE_HELPER(Name) \
1514+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1515+
LOADABLE_STORAGE_HELPER(Name) \
1516+
COPYABLE_STORAGE_HELPER(Name)
1517+
#define RETAINABLE_STORAGE_HELPER(Name) \
15151518
void visitStrongRetain##Name##Inst(StrongRetain##Name##Inst *i); \
15161519
void visit##Name##RetainInst(Name##RetainInst *i); \
15171520
void visit##Name##ReleaseInst(Name##ReleaseInst *i);
1518-
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1519-
NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, "...") \
1520-
ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, "...")
1521-
#define UNCHECKED_REF_STORAGE(Name, ...) \
1521+
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1522+
LOADABLE_REF_STORAGE_HELPER(Name) \
1523+
RETAINABLE_STORAGE_HELPER(Name)
1524+
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1525+
LOADABLE_STORAGE_HELPER(Name) \
1526+
COPYABLE_STORAGE_HELPER(Name) \
1527+
LOADABLE_REF_STORAGE_HELPER(Name) \
1528+
RETAINABLE_STORAGE_HELPER(Name)
1529+
#define UNCHECKED_REF_STORAGE(Name, ...) \
1530+
COPYABLE_STORAGE_HELPER(Name) \
15221531
LOADABLE_REF_STORAGE_HELPER(Name)
15231532
#include "swift/AST/ReferenceStorage.def"
15241533
#undef LOADABLE_REF_STORAGE_HELPER
1534+
#undef LOADABLE_STORAGE_HELPER
1535+
#undef COPYABLE_STORAGE_HELPER
1536+
#undef RETAINABLE_STORAGE_HELPER
15251537
};
15261538

15271539
} // end anonymous namespace
@@ -5338,6 +5350,12 @@ static const ReferenceTypeInfo &getReferentTypeInfo(IRGenFunction &IGF,
53385350
return cast<ReferenceTypeInfo>(IGF.getTypeInfoForLowered(type));
53395351
}
53405352

5353+
void IRGenSILFunction::visitStrongCopyWeakValueInst(
5354+
swift::StrongCopyWeakValueInst *i) {
5355+
llvm::report_fatal_error(
5356+
"strong_copy_weak_value not lowered by AddressLowering!?");
5357+
}
5358+
53415359
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
53425360
void IRGenSILFunction::visitLoad##Name##Inst(swift::Load##Name##Inst *i) { \
53435361
Address source = getLoweredAddress(i->getOperand()); \

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,7 @@ OPERAND_OWNERSHIP(InstantaneousUse, ClassMethod)
220220
OPERAND_OWNERSHIP(InstantaneousUse, SuperMethod)
221221
OPERAND_OWNERSHIP(InstantaneousUse, ClassifyBridgeObject)
222222
OPERAND_OWNERSHIP(InstantaneousUse, SetDeallocating)
223-
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
224-
OPERAND_OWNERSHIP(InstantaneousUse, StrongCopy##Name##Value)
225-
#define UNCHECKED_REF_STORAGE(Name, ...) \
223+
#define REF_STORAGE(Name, ...) \
226224
OPERAND_OWNERSHIP(InstantaneousUse, StrongCopy##Name##Value)
227225
#include "swift/AST/ReferenceStorage.def"
228226

0 commit comments

Comments
 (0)