@@ -45,8 +45,7 @@ struct LLVM_LIBRARY_VISIBILITY LValueWriteback {
45
45
SILLocation loc;
46
46
std::unique_ptr<LogicalPathComponent> component;
47
47
ManagedValue base;
48
- ManagedValue temp;
49
- SmallVector<SILValue, 2 > ExtraInfo;
48
+ MaterializedLValue materialized;
50
49
CleanupHandle cleanup;
51
50
52
51
~LValueWriteback () {}
@@ -56,13 +55,12 @@ struct LLVM_LIBRARY_VISIBILITY LValueWriteback {
56
55
LValueWriteback () = default ;
57
56
LValueWriteback (SILLocation loc,
58
57
std::unique_ptr<LogicalPathComponent> &&comp,
59
- ManagedValue base, ManagedValue temp,
60
- ArrayRef<SILValue> extraInfo ,
58
+ ManagedValue base,
59
+ MaterializedLValue materialized ,
61
60
CleanupHandle cleanup)
62
- : loc(loc), component(std::move(comp)), base(base), temp(temp),
63
- cleanup (cleanup) {
64
- ExtraInfo.append (extraInfo.begin (), extraInfo.end ());
65
- }
61
+ : loc(loc), component(std::move(comp)),
62
+ base (base), materialized(materialized),
63
+ cleanup(cleanup) { }
66
64
67
65
void diagnoseConflict (const LValueWriteback &rhs, SILGenFunction &SGF) const {
68
66
// If the two writebacks we're comparing are of different kinds (e.g.
@@ -82,7 +80,7 @@ struct LLVM_LIBRARY_VISIBILITY LValueWriteback {
82
80
83
81
void performWriteback (SILGenFunction &gen, bool isFinal) {
84
82
Scope S (gen.Cleanups , CleanupLocation::get (loc));
85
- component->writeback (gen, loc, base, temp, ExtraInfo , isFinal);
83
+ component->writeback (gen, loc, base, materialized , isFinal);
86
84
}
87
85
};
88
86
}
@@ -116,16 +114,16 @@ void SILGenFunction::freeWritebackStack() {
116
114
static void pushWriteback (SILGenFunction &gen,
117
115
SILLocation loc,
118
116
std::unique_ptr<LogicalPathComponent> &&comp,
119
- ManagedValue base, ManagedValue temp,
120
- ArrayRef<SILValue> extraInfo ) {
117
+ ManagedValue base,
118
+ MaterializedLValue materialized ) {
121
119
assert (gen.InWritebackScope );
122
120
123
121
// Push a cleanup to execute the writeback consistently.
124
122
auto &stack = gen.getWritebackStack ();
125
123
gen.Cleanups .pushCleanup <LValueWritebackCleanup>(stack.size ());
126
124
auto cleanup = gen.Cleanups .getTopCleanup ();
127
125
128
- stack.emplace_back (loc, std::move (comp), base, temp, extraInfo , cleanup);
126
+ stack.emplace_back (loc, std::move (comp), base, materialized , cleanup);
129
127
}
130
128
131
129
// ===----------------------------------------------------------------------===//
@@ -244,18 +242,23 @@ ManagedValue LogicalPathComponent::getMaterialized(SILGenFunction &gen,
244
242
std::move (*this ));
245
243
246
244
// Push a writeback for the temporary.
247
- pushWriteback (gen, loc, std::move (clonedComponent), base, temporary, {});
245
+ pushWriteback (gen, loc, std::move (clonedComponent), base,
246
+ MaterializedLValue (temporary));
248
247
return temporary.borrow ();
249
248
}
250
249
251
250
void LogicalPathComponent::writeback (SILGenFunction &gen, SILLocation loc,
252
- ManagedValue base, ManagedValue temporary,
253
- ArrayRef<SILValue> otherInfo, bool isFinal) {
254
- assert (otherInfo.empty () && " unexpected otherInfo parameter!" );
251
+ ManagedValue base,
252
+ MaterializedLValue materialized,
253
+ bool isFinal) {
254
+ assert (!materialized.callback &&
255
+ " unexpected materialized lvalue with callback!" );
255
256
256
257
// Load the value from the temporary unless the type is address-only
257
258
// and this is the final use, in which case we can just consume the
258
259
// value as-is.
260
+ auto temporary = materialized.temporary ;
261
+
259
262
assert (temporary.getType ().isAddress ());
260
263
auto &tempTL = gen.getTypeLowering (temporary.getType ());
261
264
if (!tempTL.isAddressOnly () || !isFinal) {
@@ -859,52 +862,44 @@ namespace {
859
862
860
863
auto args = std::move (*this ).prepareAccessorArgs (gen, loc, borrowedBase,
861
864
materializeForSet);
862
- auto addressAndCallback =
865
+ MaterializedLValue materialized =
863
866
gen.emitMaterializeForSetAccessor (loc, materializeForSet, substitutions,
864
867
std::move (args.base ), IsSuper,
865
868
IsDirectAccessorUse,
866
869
std::move (args.subscripts ),
867
870
buffer, callbackStorage);
868
871
869
- SILValue address = addressAndCallback.first ;
870
-
871
872
// Mark a value-dependence on the base. We do this regardless
872
873
// of whether the base is trivial because even a trivial base
873
874
// may be value-dependent on something non-trivial.
874
875
if (base) {
875
- address = gen.B .createMarkDependence (loc, address, base.getValue ());
876
+ SILValue temporary = materialized.temporary .getValue ();
877
+ materialized.temporary = ManagedValue::forUnmanaged (
878
+ gen.B .createMarkDependence (loc, temporary, base.getValue ()));
876
879
}
877
880
878
- SILValue extraInfo[] = {
879
- addressAndCallback.second ,
880
- callbackStorage,
881
- };
882
-
883
881
// TODO: maybe needsWriteback should be a thin function pointer
884
882
// to which we pass the base? That would let us use direct
885
883
// access for stored properties with didSet.
886
- pushWriteback (gen, loc, std::move (clonedComponent), base,
887
- ManagedValue::forUnmanaged (address), extraInfo);
884
+ pushWriteback (gen, loc, std::move (clonedComponent), base, materialized);
888
885
889
- return ManagedValue::forLValue (address );
886
+ return ManagedValue::forLValue (materialized. temporary . getValue () );
890
887
}
891
888
892
889
void writeback (SILGenFunction &gen, SILLocation loc,
893
- ManagedValue base, ManagedValue temporary ,
894
- ArrayRef<SILValue> extraInfo, bool isFinal) override {
895
- // If we don't have extraInfo , we don't have to conditionalize
890
+ ManagedValue base, MaterializedLValue materialized ,
891
+ bool isFinal) override {
892
+ // If we don't have a callback , we don't have to conditionalize
896
893
// the writeback.
897
- if (extraInfo.empty ()) {
898
- LogicalPathComponent::writeback (gen, loc, base, temporary, extraInfo,
894
+ if (!materialized.callback ) {
895
+ LogicalPathComponent::writeback (gen, loc,
896
+ base, materialized,
899
897
isFinal);
900
898
return ;
901
899
}
902
900
903
- // Otherwise, extraInfo holds an optional callback and the
901
+ // Otherwise, 'materialized' holds an optional callback and the
904
902
// callback storage.
905
- assert (extraInfo.size () == 2 );
906
- SILValue optionalCallback = extraInfo[0 ];
907
- SILValue callbackStorage = extraInfo[1 ];
908
903
909
904
// Mark the writeback as auto-generated so that we don't get
910
905
// warnings if we manage to devirtualize materializeForSet.
@@ -914,7 +909,7 @@ namespace {
914
909
915
910
SILBasicBlock *contBB = gen.createBasicBlock ();
916
911
SILBasicBlock *writebackBB = gen.createBasicBlock (gen.B .getInsertionBB ());
917
- gen.B .createSwitchEnum (loc, optionalCallback , /* defaultDest*/ nullptr ,
912
+ gen.B .createSwitchEnum (loc, materialized. callback , /* defaultDest*/ nullptr ,
918
913
{ { ctx.getOptionalSomeDecl (), writebackBB },
919
914
{ ctx.getOptionalNoneDecl (), contBB } });
920
915
@@ -926,8 +921,8 @@ namespace {
926
921
SILType::getPrimitiveObjectType (TupleType::getEmpty (ctx));
927
922
928
923
SILType callbackSILType = gen.getLoweredType (
929
- optionalCallback ->getType ().getSwiftRValueType ()
930
- .getAnyOptionalObjectType ());
924
+ materialized. callback ->getType ().getSwiftRValueType ()
925
+ .getAnyOptionalObjectType ());
931
926
932
927
// The callback is a BB argument from the switch_enum.
933
928
SILValue callback =
@@ -959,12 +954,14 @@ namespace {
959
954
}
960
955
961
956
SILValue temporaryPointer =
962
- gen.B .createAddressToPointer (loc, temporary.getValue (),
957
+ gen.B .createAddressToPointer (loc,
958
+ materialized.temporary .getValue (),
963
959
SILType::getRawPointerType (ctx));
964
960
961
+ // Apply the callback.
965
962
gen.B .createApply (loc, callback, {
966
963
temporaryPointer,
967
- callbackStorage,
964
+ materialized. callbackStorage ,
968
965
baseAddress,
969
966
baseMetatype
970
967
}, false );
@@ -1119,8 +1116,9 @@ namespace {
1119
1116
}
1120
1117
1121
1118
void writeback (SILGenFunction &gen, SILLocation loc,
1122
- ManagedValue base, ManagedValue temporary,
1123
- ArrayRef<SILValue> otherInfo, bool isFinal) override {
1119
+ ManagedValue base,
1120
+ MaterializedLValue materialized,
1121
+ bool isFinal) override {
1124
1122
// If this is final, we can consume the owner (stored as
1125
1123
// 'base'). If it isn't, we actually need to retain it, because
1126
1124
// we've still got a release active.
@@ -1194,7 +1192,7 @@ namespace {
1194
1192
std::unique_ptr<LogicalPathComponent>
1195
1193
component (new UnpinPseudoComponent (getTypeData ()));
1196
1194
pushWriteback (gen, loc, std::move (component), result.second ,
1197
- ManagedValue (), {} );
1195
+ MaterializedLValue () );
1198
1196
return result.first ;
1199
1197
}
1200
1198
}
0 commit comments