Skip to content

Commit 3336083

Browse files
Merge pull request #67690 from nate-chandler/opaque-values/20230802/2/weak-copies
[SIL] Represent copies to and from @sil_weak values.
2 parents e1e81d5 + 8cea33a commit 3336083

26 files changed

+499
-110
lines changed

docs/SIL.rst

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5191,7 +5191,30 @@ case, the strong reference count will be incremented before any changes to the
51915191
weak reference count.
51925192

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

51975220
store_weak
@@ -5218,7 +5241,30 @@ currently be initialized. After the evaluation:
52185241

52195242
This operation must be atomic with respect to the final ``strong_release`` on
52205243
the operand (source) heap object. It need not be atomic with respect to
5221-
``store_weak`` or ``load_weak`` operations on the same address.
5244+
``store_weak``/``weak_copy_value`` or ``load_weak``/``strong_copy_weak_value``
5245+
operations on the same address.
5246+
5247+
weak_copy_value
5248+
```````````````
5249+
::
5250+
5251+
sil-instruction ::= 'weak_copy_value' sil-operand
5252+
5253+
%1 = weak_copy_value %0 : $Optional<T>
5254+
// %1 will be an @owned value of type $@sil_weak Optional<T>.
5255+
// $T must be a reference type
5256+
// $@sil_weak Optional<T> must be address-only
5257+
5258+
Only valid in opaque values mode. Lowered by AddressLowering to store_weak.
5259+
5260+
If ``%0`` is non-nil, produces the value ``@sil_weak Optional.some`` holding the
5261+
object and increments the weak reference count by 1. Otherwise, produces the
5262+
value ``Optional.none`` wrapped in a ``@sil_weak`` box.
5263+
5264+
This operation must be atomic with respect to the final ``strong_release`` on
5265+
the operand (source) heap object. It need not be atomic with respect to
5266+
``store_weak``/``weak_copy_value`` or ``load_weak``/``strong_copy_weak_value``
5267+
operations on the same address.
52225268

52235269
load_unowned
52245270
````````````

include/swift/SIL/SILBuilder.h

Lines changed: 65 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,20 +1061,38 @@ 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+
WeakCopyValueInst *createWeakCopyValue(SILLocation Loc, SILValue operand) {
1065+
assert(!getFunction().getModule().useLoweredAddresses());
1066+
auto type = operand->getType()
1067+
.getReferenceStorageType(getFunction().getASTContext(),
1068+
ReferenceOwnership::Weak)
1069+
.getObjectType();
1070+
return insert(new (getModule()) WeakCopyValueInst(getSILDebugLocation(Loc),
1071+
operand, type));
10771072
}
1073+
1074+
#define COPYABLE_STORAGE_HELPER(Name) \
1075+
StrongCopy##Name##ValueInst *createStrongCopy##Name##Value( \
1076+
SILLocation Loc, SILValue operand) { \
1077+
auto type = getFunction().getLoweredType( \
1078+
operand->getType().getASTType().getReferenceStorageReferent()); \
1079+
return insert(new (getModule()) StrongCopy##Name##ValueInst( \
1080+
getSILDebugLocation(Loc), operand, type)); \
1081+
}
1082+
1083+
#define LOADABLE_STORAGE_HELPER(Name) \
1084+
Load##Name##Inst *createLoad##Name(SILLocation Loc, SILValue src, \
1085+
IsTake_t isTake) { \
1086+
return insert(new (getModule()) Load##Name##Inst(getSILDebugLocation(Loc), \
1087+
src, isTake)); \
1088+
} \
1089+
Store##Name##Inst *createStore##Name(SILLocation Loc, SILValue value, \
1090+
SILValue dest, \
1091+
IsInitialization_t isInit) { \
1092+
return insert(new (getModule()) Store##Name##Inst( \
1093+
getSILDebugLocation(Loc), value, dest, isInit)); \
1094+
}
1095+
10781096
#define LOADABLE_REF_STORAGE_HELPER(Name) \
10791097
Name##ToRefInst *create##Name##ToRef(SILLocation Loc, SILValue op, \
10801098
SILType ty) { \
@@ -1085,41 +1103,45 @@ class SILBuilder {
10851103
SILType ty) { \
10861104
return insert(new (getModule()) \
10871105
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)); \
10951106
}
10961107

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, ...) \
1108+
#define RETAINABLE_STORAGE_HELPER(Name) \
1109+
StrongRetain##Name##Inst *createStrongRetain##Name( \
1110+
SILLocation Loc, SILValue Operand, Atomicity atomicity) { \
1111+
return insert(new (getModule()) StrongRetain##Name##Inst( \
1112+
getSILDebugLocation(Loc), Operand, atomicity)); \
1113+
} \
1114+
Name##RetainInst *create##Name##Retain(SILLocation Loc, SILValue Operand, \
1115+
Atomicity atomicity) { \
1116+
return insert(new (getModule()) Name##RetainInst(getSILDebugLocation(Loc), \
1117+
Operand, atomicity)); \
1118+
} \
1119+
Name##ReleaseInst *create##Name##Release(SILLocation Loc, SILValue Operand, \
1120+
Atomicity atomicity) { \
1121+
return insert(new (getModule()) Name##ReleaseInst( \
1122+
getSILDebugLocation(Loc), Operand, atomicity)); \
1123+
}
1124+
1125+
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1126+
COPYABLE_STORAGE_HELPER(Name) \
1127+
LOADABLE_REF_STORAGE_HELPER(Name) \
1128+
RETAINABLE_STORAGE_HELPER(Name)
1129+
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1130+
COPYABLE_STORAGE_HELPER(Name) \
1131+
LOADABLE_REF_STORAGE_HELPER(Name) \
1132+
LOADABLE_STORAGE_HELPER(Name) \
1133+
RETAINABLE_STORAGE_HELPER(Name)
1134+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
1135+
COPYABLE_STORAGE_HELPER(Name) \
1136+
LOADABLE_STORAGE_HELPER(Name)
1137+
#define UNCHECKED_REF_STORAGE(Name, ...) \
1138+
COPYABLE_STORAGE_HELPER(Name) \
11201139
LOADABLE_REF_STORAGE_HELPER(Name)
11211140
#include "swift/AST/ReferenceStorage.def"
1141+
#undef LOADABLE_STORAGE_HELPER
11221142
#undef LOADABLE_REF_STORAGE_HELPER
1143+
#undef COPYABLE_STORAGE_HELPER
1144+
#undef RETAINABLE_STORAGE_HELPER
11231145

11241146
CopyAddrInst *createCopyAddr(SILLocation Loc, SILValue srcAddr,
11251147
SILValue destAddr, IsTake_t isTake,

include/swift/SIL/SILCloner.h

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

1410-
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1410+
template <typename ImplClass>
1411+
void SILCloner<ImplClass>::visitWeakCopyValueInst(WeakCopyValueInst *Inst) {
1412+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1413+
recordClonedInstruction(
1414+
Inst, getBuilder().createWeakCopyValue(getOpLocation(Inst->getLoc()),
1415+
getOpValue(Inst->getOperand())));
1416+
}
1417+
1418+
#define COPYABLE_STORAGE_HELPER(Name, name) \
1419+
template <typename ImplClass> \
1420+
void SILCloner<ImplClass>::visitStrongCopy##Name##ValueInst( \
1421+
StrongCopy##Name##ValueInst *Inst) { \
1422+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); \
1423+
recordClonedInstruction(Inst, getBuilder().createStrongCopy##Name##Value( \
1424+
getOpLocation(Inst->getLoc()), \
1425+
getOpValue(Inst->getOperand()))); \
1426+
}
1427+
1428+
#define LOADABLE_STORAGE_HELPER(Name, name) \
14111429
template <typename ImplClass> \
14121430
void SILCloner<ImplClass>::visitLoad##Name##Inst(Load##Name##Inst *Inst) { \
14131431
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); \
@@ -1441,17 +1459,8 @@ SILCloner<ImplClass>::visitDebugStepInst(DebugStepInst *Inst) {
14411459
Inst, getBuilder().create##Name##ToRef(getOpLocation(Inst->getLoc()), \
14421460
getOpValue(Inst->getOperand()), \
14431461
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()))); \
14521462
}
1453-
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1454-
LOADABLE_REF_STORAGE_HELPER(Name, name) \
1463+
#define RETAINABLE_STORAGE_HELPER(Name, name) \
14551464
template <typename ImplClass> \
14561465
void SILCloner<ImplClass>::visitStrongRetain##Name##Inst( \
14571466
StrongRetain##Name##Inst *Inst) { \
@@ -1478,13 +1487,26 @@ SILCloner<ImplClass>::visitDebugStepInst(DebugStepInst *Inst) {
14781487
getOpValue(Inst->getOperand()), \
14791488
Inst->getAtomicity())); \
14801489
}
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, ...) \
1490+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1491+
COPYABLE_STORAGE_HELPER(Name, name) \
1492+
LOADABLE_STORAGE_HELPER(Name, name)
1493+
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1494+
COPYABLE_STORAGE_HELPER(Name, name) \
1495+
LOADABLE_REF_STORAGE_HELPER(Name, name) \
1496+
RETAINABLE_STORAGE_HELPER(Name, name)
1497+
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
1498+
COPYABLE_STORAGE_HELPER(Name, name) \
1499+
LOADABLE_REF_STORAGE_HELPER(Name, name) \
1500+
LOADABLE_STORAGE_HELPER(Name, name) \
1501+
RETAINABLE_STORAGE_HELPER(Name, name)
1502+
#define UNCHECKED_REF_STORAGE(Name, name, ...) \
1503+
COPYABLE_STORAGE_HELPER(Name, name) \
14851504
LOADABLE_REF_STORAGE_HELPER(Name, name)
14861505
#include "swift/AST/ReferenceStorage.def"
1506+
#undef LOADABLE_STORAGE_HELPER
14871507
#undef LOADABLE_REF_STORAGE_HELPER
1508+
#undef COPYABLE_STORAGE_HELPER
1509+
#undef RETAINABLE_STORAGE_HELPER
14881510

14891511
template<typename ImplClass>
14901512
void

include/swift/SIL/SILInstruction.h

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

8101+
class WeakCopyValueInst
8102+
: public UnaryInstructionBase<SILInstructionKind::WeakCopyValueInst,
8103+
SingleValueInstruction> {
8104+
friend class SILBuilder;
8105+
WeakCopyValueInst(SILDebugLocation DebugLoc, SILValue operand, SILType type)
8106+
: UnaryInstructionBase(DebugLoc, operand, type) {
8107+
assert(type.getReferenceStorageOwnership() == ReferenceOwnership::Weak);
8108+
assert(type.getReferenceStorageReferentType() == operand->getType());
8109+
}
8110+
};
8111+
8112+
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
8113+
class StrongCopy##Name##ValueInst \
8114+
: public UnaryInstructionBase< \
8115+
SILInstructionKind::StrongCopy##Name##ValueInst, \
8116+
SingleValueInstruction> { \
8117+
friend class SILBuilder; \
8118+
StrongCopy##Name##ValueInst(SILDebugLocation DebugLoc, SILValue operand, \
8119+
SILType type) \
8120+
: UnaryInstructionBase(DebugLoc, operand, \
8121+
type.getReferenceStorageReferentType()) {} \
8122+
};
81018123
#define UNCHECKED_REF_STORAGE(Name, ...) \
81028124
class StrongCopy##Name##ValueInst \
81038125
: public UnaryInstructionBase< \
@@ -8108,7 +8130,6 @@ class ExplicitCopyValueInst
81088130
SILType type) \
81098131
: UnaryInstructionBase(DebugLoc, operand, type) {} \
81108132
};
8111-
81128133
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
81138134
class StrongCopy##Name##ValueInst \
81148135
: public UnaryInstructionBase< \

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,10 +453,9 @@ 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, \
456+
SINGLE_VALUE_INST(WeakCopyValueInst, weak_copy_value,
458457
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
459-
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
458+
#define REF_STORAGE(Name, name, ...) \
460459
SINGLE_VALUE_INST(StrongCopy##Name##ValueInst, strong_copy_##name##_value, \
461460
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
462461
#include "swift/AST/ReferenceStorage.def"

0 commit comments

Comments
 (0)