Skip to content

Commit c007bae

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

21 files changed

+140
-7
lines changed

docs/SIL.rst

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5191,8 +5191,9 @@ 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``
5195-
or ``load_weak``/``strong_copy_weak_value`` operations on the same address.
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.
51965197

51975198
strong_copy_weak_value
51985199
``````````````````````
@@ -5212,8 +5213,9 @@ its strong reference count and produces the value ``Optional.some`` holding the
52125213
object. Otherwise, produces the value ``Optional.none``.
52135214

52145215
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.
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``
5218+
operations on the same address.
52175219

52185220
store_weak
52195221
``````````
@@ -5239,8 +5241,30 @@ currently be initialized. After the evaluation:
52395241

52405242
This operation must be atomic with respect to the final ``strong_release`` on
52415243
the operand (source) heap object. It need not be atomic with respect to
5242-
``store_weak`` or ``load_weak``/``strong_copy_weak_value`` operations on the
5243-
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.
52445268

52455269
load_unowned
52465270
````````````

include/swift/SIL/SILBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,16 @@ class SILBuilder {
10611061
getSILDebugLocation(Loc), ArgumentsSpecification, getModule()));
10621062
}
10631063

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));
1072+
}
1073+
10641074
#define COPYABLE_STORAGE_HELPER(Name) \
10651075
StrongCopy##Name##ValueInst *createStrongCopy##Name##Value( \
10661076
SILLocation Loc, SILValue operand) { \

include/swift/SIL/SILCloner.h

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

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+
14101418
#define COPYABLE_STORAGE_HELPER(Name, name) \
14111419
template <typename ImplClass> \
14121420
void SILCloner<ImplClass>::visitStrongCopy##Name##ValueInst( \

include/swift/SIL/SILInstruction.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8098,6 +8098,17 @@ 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+
81018112
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
81028113
class StrongCopy##Name##ValueInst \
81038114
: public UnaryInstructionBase< \

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ 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+
SINGLE_VALUE_INST(WeakCopyValueInst, weak_copy_value,
457+
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
456458
#define REF_STORAGE(Name, name, ...) \
457459
SINGLE_VALUE_INST(StrongCopy##Name##ValueInst, strong_copy_##name##_value, \
458460
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)

lib/IRGen/IRGenSIL.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,7 @@ class IRGenSILFunction :
15031503

15041504
void visitHasSymbolInst(HasSymbolInst *i);
15051505

1506+
void visitWeakCopyValueInst(swift::WeakCopyValueInst *i);
15061507
#define LOADABLE_REF_STORAGE_HELPER(Name) \
15071508
void visitRefTo##Name##Inst(RefTo##Name##Inst *i); \
15081509
void visit##Name##ToRefInst(Name##ToRefInst *i);
@@ -5356,6 +5357,10 @@ void IRGenSILFunction::visitStrongCopyWeakValueInst(
53565357
"strong_copy_weak_value not lowered by AddressLowering!?");
53575358
}
53585359

5360+
void IRGenSILFunction::visitWeakCopyValueInst(swift::WeakCopyValueInst *i) {
5361+
llvm::report_fatal_error("weak_copy_value not lowered by AddressLowering!?");
5362+
}
5363+
53595364
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
53605365
void IRGenSILFunction::visitLoad##Name##Inst(swift::Load##Name##Inst *i) { \
53615366
Address source = getLoweredAddress(i->getOperand()); \

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ OPERAND_OWNERSHIP(InstantaneousUse, ClassMethod)
220220
OPERAND_OWNERSHIP(InstantaneousUse, SuperMethod)
221221
OPERAND_OWNERSHIP(InstantaneousUse, ClassifyBridgeObject)
222222
OPERAND_OWNERSHIP(InstantaneousUse, SetDeallocating)
223+
OPERAND_OWNERSHIP(InstantaneousUse, WeakCopyValue)
223224
#define REF_STORAGE(Name, ...) \
224225
OPERAND_OWNERSHIP(InstantaneousUse, StrongCopy##Name##Value)
225226
#include "swift/AST/ReferenceStorage.def"

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,6 +2141,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
21412141
*this << getIDAndType(I->getOperand());
21422142
}
21432143

2144+
void visitWeakCopyValueInst(WeakCopyValueInst *I) {
2145+
*this << getIDAndType(I->getOperand());
2146+
}
2147+
21442148
#define REF_STORAGE(Name, ...) \
21452149
void visitStrongCopy##Name##ValueInst(StrongCopy##Name##ValueInst *I) { \
21462150
*this << getIDAndType(I->getOperand()); \

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class ValueOwnershipKindClassifier
4949
return OwnershipKind::OWNERSHIP; \
5050
}
5151

52+
CONSTANT_OWNERSHIP_INST(Owned, WeakCopyValue)
5253
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
5354
CONSTANT_OWNERSHIP_INST(Owned, StrongCopy##Name##Value) \
5455
CONSTANT_OWNERSHIP_INST(Owned, Load##Name)

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3646,6 +3646,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
36463646
REFCOUNTING_INSTRUCTION(RetainValue)
36473647
REFCOUNTING_INSTRUCTION(ReleaseValueAddr)
36483648
REFCOUNTING_INSTRUCTION(RetainValueAddr)
3649+
UNARY_INSTRUCTION(WeakCopyValue)
36493650
#define UNCHECKED_REF_STORAGE(Name, ...) \
36503651
UNARY_INSTRUCTION(StrongCopy##Name##Value)
36513652
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \

0 commit comments

Comments
 (0)