Skip to content

Commit df87a49

Browse files
committed
[SIL] Add originator to assign_by_wrapper instruction
Originator of this temporary instruction could be either type or property wrapper.
1 parent 0692203 commit df87a49

13 files changed

+149
-52
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -883,14 +883,30 @@ class SILBuilder {
883883
Qualifier));
884884
}
885885

886-
AssignByWrapperInst *createAssignByWrapper(SILLocation Loc,
887-
SILValue Src, SILValue Dest,
888-
SILValue Initializer,
889-
SILValue Setter,
890-
AssignByWrapperInst::Mode mode) {
886+
AssignByWrapperInst *
887+
createAssignByPropertyWrapper(SILLocation Loc, SILValue Src, SILValue Dest,
888+
SILValue Initializer, SILValue Setter,
889+
AssignByWrapperInst::Mode mode) {
890+
return createAssignByWrapper(
891+
Loc, AssignByWrapperInst::Originator::PropertyWrapper, Src, Dest,
892+
Initializer, Setter, mode);
893+
}
894+
895+
AssignByWrapperInst *
896+
createAssignByTypeWrapper(SILLocation Loc, SILValue Src, SILValue Dest,
897+
SILValue Setter, AssignByWrapperInst::Mode mode) {
898+
return createAssignByWrapper(
899+
Loc, AssignByWrapperInst::Originator::TypeWrapper, Src, Dest,
900+
SILUndef::get(Dest->getType(), getModule()), Setter, mode);
901+
}
902+
903+
AssignByWrapperInst *
904+
createAssignByWrapper(SILLocation Loc, AssignByWrapperInst::Originator origin,
905+
SILValue Src, SILValue Dest, SILValue Initializer,
906+
SILValue Setter, AssignByWrapperInst::Mode mode) {
891907
return insert(new (getModule())
892-
AssignByWrapperInst(getSILDebugLocation(Loc), Src, Dest,
893-
Initializer, Setter, mode));
908+
AssignByWrapperInst(getSILDebugLocation(Loc), origin, Src,
909+
Dest, Initializer, Setter, mode));
894910
}
895911

896912
StoreBorrowInst *createStoreBorrow(SILLocation Loc, SILValue Src,

include/swift/SIL/SILCloner.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,12 +1242,11 @@ template <typename ImplClass>
12421242
void SILCloner<ImplClass>::visitAssignByWrapperInst(AssignByWrapperInst *Inst) {
12431243
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
12441244
recordClonedInstruction(
1245-
Inst, getBuilder().createAssignByWrapper(getOpLocation(Inst->getLoc()),
1246-
getOpValue(Inst->getSrc()),
1247-
getOpValue(Inst->getDest()),
1248-
getOpValue(Inst->getInitializer()),
1249-
getOpValue(Inst->getSetter()),
1250-
Inst->getMode()));
1245+
Inst, getBuilder().createAssignByWrapper(
1246+
getOpLocation(Inst->getLoc()), Inst->getOriginator(),
1247+
getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()),
1248+
getOpValue(Inst->getInitializer()),
1249+
getOpValue(Inst->getSetter()), Inst->getMode()));
12511250
}
12521251

12531252
template<typename ImplClass>

include/swift/SIL/SILInstruction.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4677,6 +4677,9 @@ class AssignByWrapperInst
46774677
USE_SHARED_UINT8;
46784678

46794679
public:
4680+
/// The kind of a wrapper that is being applied.
4681+
enum class Originator : uint8_t { TypeWrapper, PropertyWrapper };
4682+
46804683
enum Mode {
46814684
/// The mode is not decided yet (by DefiniteInitialization).
46824685
Unknown,
@@ -4696,13 +4699,18 @@ class AssignByWrapperInst
46964699
};
46974700

46984701
private:
4699-
AssignByWrapperInst(SILDebugLocation DebugLoc, SILValue Src, SILValue Dest,
4700-
SILValue Initializer, SILValue Setter, Mode mode);
4702+
Originator originator;
4703+
4704+
AssignByWrapperInst(SILDebugLocation DebugLoc, Originator origin,
4705+
SILValue Src, SILValue Dest, SILValue Initializer,
4706+
SILValue Setter, Mode mode);
47014707

47024708
public:
47034709
SILValue getInitializer() { return Operands[2].get(); }
47044710
SILValue getSetter() { return Operands[3].get(); }
47054711

4712+
Originator getOriginator() const { return originator; }
4713+
47064714
Mode getMode() const {
47074715
return Mode(sharedUInt8().AssignByWrapperInst.mode);
47084716
}

lib/SIL/IR/SILInstructions.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,12 +1164,13 @@ AssignInst::AssignInst(SILDebugLocation Loc, SILValue Src, SILValue Dest,
11641164
}
11651165

11661166
AssignByWrapperInst::AssignByWrapperInst(SILDebugLocation Loc,
1167-
SILValue Src, SILValue Dest,
1168-
SILValue Initializer,
1169-
SILValue Setter,
1170-
AssignByWrapperInst::Mode mode) :
1171-
AssignInstBase(Loc, Src, Dest, Initializer, Setter) {
1172-
assert(Initializer->getType().is<SILFunctionType>());
1167+
AssignByWrapperInst::Originator origin,
1168+
SILValue Src, SILValue Dest,
1169+
SILValue Initializer, SILValue Setter,
1170+
AssignByWrapperInst::Mode mode)
1171+
: AssignInstBase(Loc, Src, Dest, Initializer, Setter), originator(origin) {
1172+
assert(Initializer->getType().is<SILFunctionType>() ||
1173+
(isa<SILUndef>(Initializer) && originator == Originator::TypeWrapper));
11731174
sharedUInt8().AssignByWrapperInst.mode = uint8_t(mode);
11741175
}
11751176

lib/SIL/IR/SILPrinter.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,6 +1687,20 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
16871687
}
16881688

16891689
void visitAssignByWrapperInst(AssignByWrapperInst *AI) {
1690+
{
1691+
*this << "origin ";
1692+
1693+
switch (AI->getOriginator()) {
1694+
case AssignByWrapperInst::Originator::TypeWrapper:
1695+
*this << "type_wrapper";
1696+
break;
1697+
case AssignByWrapperInst::Originator::PropertyWrapper:
1698+
*this << "property_wrapper";
1699+
}
1700+
1701+
*this << ", ";
1702+
}
1703+
16901704
*this << getIDAndType(AI->getSrc()) << " to ";
16911705
switch (AI->getMode()) {
16921706
case AssignByWrapperInst::Unknown:
@@ -1701,9 +1715,13 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
17011715
*this << "[assign_wrapped_value] ";
17021716
break;
17031717
}
1704-
*this << getIDAndType(AI->getDest())
1705-
<< ", init " << getIDAndType(AI->getInitializer())
1706-
<< ", set " << getIDAndType(AI->getSetter());
1718+
1719+
*this << getIDAndType(AI->getDest());
1720+
1721+
if (AI->getOriginator() == AssignByWrapperInst::Originator::PropertyWrapper)
1722+
*this << ", init " << getIDAndType(AI->getInitializer());
1723+
1724+
*this << ", set " << getIDAndType(AI->getSetter());
17071725
}
17081726

17091727
void visitMarkUninitializedInst(MarkUninitializedInst *MU) {

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,6 +2200,35 @@ bool SILParser::parseSILDebugLocation(SILLocation &L, SILBuilder &B) {
22002200
return false;
22012201
}
22022202

2203+
static bool
2204+
parseAssignByWrapperOriginator(AssignByWrapperInst::Originator &Result,
2205+
SILParser &P) {
2206+
if (P.parseVerbatim("origin"))
2207+
return true;
2208+
2209+
SourceLoc loc;
2210+
Identifier origin;
2211+
2212+
if (P.parseSILIdentifier(origin, loc, diag::expected_in_attribute_list))
2213+
return true;
2214+
2215+
// Then try to parse one of our other initialization kinds. We do not support
2216+
// parsing unknown here so we use that as our fail value.
2217+
auto Tmp =
2218+
llvm::StringSwitch<Optional<AssignByWrapperInst::Originator>>(
2219+
origin.str())
2220+
.Case("type_wrapper", AssignByWrapperInst::Originator::TypeWrapper)
2221+
.Case("property_wrapper",
2222+
AssignByWrapperInst::Originator::PropertyWrapper)
2223+
.Default(None);
2224+
2225+
if (!Tmp)
2226+
return true;
2227+
2228+
Result = *Tmp;
2229+
return false;
2230+
}
2231+
22032232
static bool parseAssignByWrapperMode(AssignByWrapperInst::Mode &Result,
22042233
SILParser &P) {
22052234
StringRef Str;
@@ -4174,13 +4203,30 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
41744203
case SILInstructionKind::AssignByWrapperInst: {
41754204
SILValue Src, DestAddr, InitFn, SetFn;
41764205
SourceLoc DestLoc;
4206+
AssignByWrapperInst::Originator originator;
41774207
AssignByWrapperInst::Mode mode;
4208+
4209+
if (parseAssignByWrapperOriginator(originator, *this))
4210+
return true;
4211+
4212+
if (P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ","))
4213+
return true;
4214+
41784215
if (parseTypedValueRef(Src, B) || parseVerbatim("to") ||
41794216
parseAssignByWrapperMode(mode, *this) ||
4180-
parseTypedValueRef(DestAddr, DestLoc, B) ||
4181-
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
4182-
parseVerbatim("init") || parseTypedValueRef(InitFn, B) ||
4183-
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
4217+
parseTypedValueRef(DestAddr, DestLoc, B))
4218+
return true;
4219+
4220+
if (originator == AssignByWrapperInst::Originator::PropertyWrapper) {
4221+
if (P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
4222+
parseVerbatim("init") || parseTypedValueRef(InitFn, B))
4223+
return true;
4224+
} else {
4225+
assert(originator == AssignByWrapperInst::Originator::TypeWrapper);
4226+
InitFn = SILUndef::get(DestAddr->getType(), B.getModule());
4227+
}
4228+
4229+
if (P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
41844230
parseVerbatim("set") || parseTypedValueRef(SetFn, B) ||
41854231
parseSILDebugLocation(InstLoc, B))
41864232
return true;
@@ -4191,8 +4237,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
41914237
return true;
41924238
}
41934239

4194-
ResultVal = B.createAssignByWrapper(InstLoc, Src, DestAddr, InitFn, SetFn,
4195-
mode);
4240+
ResultVal = B.createAssignByWrapper(InstLoc, originator, Src, DestAddr,
4241+
InitFn, SetFn, mode);
41964242
break;
41974243
}
41984244

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,11 +2510,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
25102510
"assign instruction can only exist in raw SIL");
25112511
require(Dest->getType().isAddress(), "Must store to an address dest");
25122512

2513-
SILValue initFn = AI->getInitializer();
2514-
CanSILFunctionType initTy = initFn->getType().castTo<SILFunctionType>();
2515-
SILFunctionConventions initConv(initTy, AI->getModule());
2516-
checkAssignByWrapperArgs(Src->getType(), initConv);
2517-
switch (initConv.getNumIndirectSILResults()) {
2513+
if (AI->getOriginator() ==
2514+
AssignByWrapperInst::Originator::PropertyWrapper) {
2515+
SILValue initFn = AI->getInitializer();
2516+
CanSILFunctionType initTy = initFn->getType().castTo<SILFunctionType>();
2517+
SILFunctionConventions initConv(initTy, AI->getModule());
2518+
checkAssignByWrapperArgs(Src->getType(), initConv);
2519+
switch (initConv.getNumIndirectSILResults()) {
25182520
case 0:
25192521
require(initConv.getNumDirectSILResults() == 1,
25202522
"wrong number of init function results");
@@ -2535,6 +2537,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
25352537
break;
25362538
default:
25372539
require(false, "wrong number of indirect init function results");
2540+
}
2541+
} else {
2542+
require(AI->getOriginator() ==
2543+
AssignByWrapperInst::Originator::TypeWrapper,
2544+
"wrong originator");
2545+
require(isa<SILUndef>(AI->getInitializer()),
2546+
"assignment via type wrapper does not have initializer");
25382547
}
25392548

25402549
SILValue setterFn = AI->getSetter();

lib/SILGen/SILGenLValue.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,9 +1618,9 @@ namespace {
16181618
Mval = Mval.materialize(SGF, loc);
16191619
}
16201620

1621-
SGF.B.createAssignByWrapper(loc, Mval.forward(SGF), proj.forward(SGF),
1622-
initFn.getValue(), setterFn.getValue(),
1623-
AssignByWrapperInst::Unknown);
1621+
SGF.B.createAssignByPropertyWrapper(
1622+
loc, Mval.forward(SGF), proj.forward(SGF), initFn.getValue(),
1623+
setterFn.getValue(), AssignByWrapperInst::Unknown);
16241624

16251625
return;
16261626
}

test/SILGen/objc_properties.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,10 @@ class SomeWrapperTests {
290290
// CHECK-LABEL: sil hidden [ossa] @$s15objc_properties16SomeWrapperTestsCyACSScfc : $@convention(method) (@owned String, @owned SomeWrapperTests) -> @owned SomeWrapperTests {
291291
// CHECK: [[M:%.*]] = function_ref @$s15objc_properties16SomeWrapperTestsC04someD0SivsTD
292292
// CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[M]]({{.*}})
293-
// CHECK: assign_by_wrapper {{%.*}}: $Int to {{%.*}} : $*SomeWrapper, init {{.*}} : $@callee_guaranteed (Int) -> SomeWrapper, set [[C]] : $@callee_guaranteed (Int) -> ()
293+
// CHECK: assign_by_wrapper origin property_wrapper, {{%.*}}: $Int to {{%.*}} : $*SomeWrapper, init {{.*}} : $@callee_guaranteed (Int) -> SomeWrapper, set [[C]] : $@callee_guaranteed (Int) -> ()
294294
// CHECK: [[M:%.*]] = function_ref @$s15objc_properties16SomeWrapperTestsC1sSSSgvsTD
295295
// CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[M]](
296-
// CHECK: assign_by_wrapper {{.*}} : $Optional<String> to {{.*}} : $*W<Optional<String>>, init {{.*}} : $@callee_guaranteed (@owned Optional<String>) -> @owned W<Optional<String>>, set [[C]] : $@callee_guaranteed (@owned Optional<String>) -> ()
296+
// CHECK: assign_by_wrapper origin property_wrapper, {{.*}} : $Optional<String> to {{.*}} : $*W<Optional<String>>, init {{.*}} : $@callee_guaranteed (@owned Optional<String>) -> @owned W<Optional<String>>, set [[C]] : $@callee_guaranteed (@owned Optional<String>) -> ()
297297
init(_ s: String) {
298298
someWrapper = 1000
299299
self.s = s

test/SILGen/property_wrapper_local.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func testLocalWrapper() {
2626
// CHECK-NEXT: [[C:%.*]] = copy_value [[W]] : ${ var Wrapper<Int> }
2727
// CHECK-NOT: mark_function_escape
2828
// CHECK-NEXT: [[SPA:%.*]] = partial_apply [callee_guaranteed] [[S]]([[C]]) : $@convention(thin) (Int, @guaranteed { var Wrapper<Int> }) -> ()
29-
// CHECK-NEXT: assign_by_wrapper {{%.*}} : $Int to [[P]] : $*Wrapper<Int>, init [[IPA]] : $@callee_guaranteed (Int) -> Wrapper<Int>, set [[SPA]] : $@callee_guaranteed (Int) -> ()
29+
// CHECK-NEXT: assign_by_wrapper origin property_wrapper, {{%.*}} : $Int to [[P]] : $*Wrapper<Int>, init [[IPA]] : $@callee_guaranteed (Int) -> Wrapper<Int>, set [[SPA]] : $@callee_guaranteed (Int) -> ()
3030

3131
_ = value
3232
// CHECK: mark_function_escape [[P]] : $*Wrapper<Int>
@@ -45,7 +45,7 @@ func testLocalWrapper() {
4545
// CHECK: [[OP:%.*]] = function_ref @$sSi2peoiyySiz_SitFZ : $@convention(method) (@inout Int, Int, @thin Int.Type) -> ()
4646
// CHECK: apply [[OP]]({{%.*}}) : $@convention(method) (@inout Int, Int, @thin Int.Type) -> ()
4747
// CHECK: [[RESULT:%.*]] = load [trivial] [[TMP]] : $*Int
48-
// CHECK: assign_by_wrapper [[RESULT]] : $Int to [[P]]
48+
// CHECK: assign_by_wrapper origin property_wrapper, [[RESULT]] : $Int to [[P]]
4949

5050
// Check local property wrapper backing initializer and accessors
5151

0 commit comments

Comments
 (0)