@@ -26,32 +26,49 @@ RValue &ArgumentSource::forceAndPeekRValue(SILGenFunction &SGF) & {
26
26
return peekRValue ();
27
27
}
28
28
29
- auto expr = asKnownExpr ();
29
+ // Extract an r-value.
30
+ SILLocation loc = getLocation ();
31
+ RValue value = std::move (*this ).getAsRValue (SGF);
32
+
33
+ // Destroy the current state.
34
+ Storage.destruct (StoredKind);
35
+
36
+ // Emplace the r-value back into the source.
30
37
StoredKind = Kind::RValue;
31
- new (& Storage.TheRV . Value ) RValue (SGF. emitRValue (expr) );
32
- Storage. TheRV . Loc = expr;
33
- return Storage. TheRV . Value ;
38
+ Storage.emplaceAggregate <RValueStorage>(StoredKind, std::move (value), loc );
39
+
40
+ return peekRValue () ;
34
41
}
35
42
36
43
RValue &ArgumentSource::peekRValue () & {
37
44
assert (isRValue () && " Undefined behavior to call this method without the "
38
45
" ArgumentSource actually being an RValue" );
39
- return Storage.TheRV .Value ;
46
+ return Storage.get <RValueStorage>(StoredKind) .Value ;
40
47
}
41
48
42
49
void ArgumentSource::rewriteType (CanType newType) & {
43
- assert (!isLValue ());
44
- if (isRValue ()) {
45
- Storage.TheRV .Value .rewriteType (newType);
46
- } else {
47
- Expr *expr = Storage.TheExpr ;
50
+ switch (StoredKind) {
51
+ case Kind::Invalid:
52
+ llvm_unreachable (" argument source is invalid" );
53
+ case Kind::LValue:
54
+ llvm_unreachable (" cannot rewrite type of l-value" );
55
+ case Kind::Tuple:
56
+ llvm_unreachable (" cannot rewrite type of tuple" );
57
+ case Kind::RValue:
58
+ Storage.get <RValueStorage>(StoredKind).Value .rewriteType (newType);
59
+ return ;
60
+ case Kind::Expr:
61
+ Expr *expr = Storage.get <Expr*>(StoredKind);
48
62
if (expr->getType ()->isEqual (newType)) return ;
49
63
llvm_unreachable (" unimplemented! hope it doesn't happen" );
50
64
}
65
+ llvm_unreachable (" bad kind" );
51
66
}
52
67
53
- bool ArgumentSource::requiresCalleeToEvaluate () {
68
+ bool ArgumentSource::requiresCalleeToEvaluate () const {
54
69
switch (StoredKind) {
70
+ case Kind::Invalid:
71
+ llvm_unreachable (" argument source is invalid" );
55
72
case Kind::RValue:
56
73
case Kind::LValue:
57
74
return false ;
@@ -85,38 +102,103 @@ bool ArgumentSource::requiresCalleeToEvaluate() {
85
102
}
86
103
}
87
104
return false ;
105
+ case Kind::Tuple:
106
+ for (auto &source : Storage.get <TupleStorage>(StoredKind).Elements ) {
107
+ if (source.requiresCalleeToEvaluate ())
108
+ return true ;
109
+ }
110
+ return false ;
88
111
}
89
-
90
- llvm_unreachable (" Unhandled Kind in switch." );
112
+ llvm_unreachable (" bad kind" );
91
113
}
92
114
93
115
RValue ArgumentSource::getAsRValue (SILGenFunction &SGF, SGFContext C) && {
94
- assert (!isLValue ());
95
- if (isRValue ())
116
+ switch (StoredKind) {
117
+ case Kind::Invalid:
118
+ llvm_unreachable (" argument source is invalid" );
119
+ case Kind::LValue:
120
+ llvm_unreachable (" cannot get l-value as r-value" );
121
+ case Kind::RValue:
96
122
return std::move (*this ).asKnownRValue ();
123
+ case Kind::Expr:
124
+ return SGF.emitRValue (std::move (*this ).asKnownExpr (), C);
125
+ case Kind::Tuple:
126
+ return std::move (*this ).getKnownTupleAsRValue (SGF, C);
127
+ }
128
+ llvm_unreachable (" bad kind" );
129
+ }
130
+
131
+ RValue
132
+ ArgumentSource::getKnownTupleAsRValue (SILGenFunction &SGF, SGFContext C) && {
133
+
134
+ return std::move (*this ).withKnownTupleElementSources <RValue>(
135
+ [&](SILLocation loc, CanTupleType type,
136
+ MutableArrayRef<ArgumentSource> elements) {
137
+ // If there's a target initialization, and we can split it, do so.
138
+ if (auto init = C.getEmitInto ()) {
139
+ if (init->canSplitIntoTupleElements ()) {
140
+ // Split the tuple.
141
+ SmallVector<InitializationPtr, 4 > scratch;
142
+ auto eltInits = init->splitIntoTupleElements (SGF, loc, type, scratch);
143
+
144
+ // Emit each element into the corresponding element initialization.
145
+ for (auto i : indices (eltInits)) {
146
+ std::move (elements[i]).forwardInto (SGF, eltInits[i].get ());
147
+ }
148
+
149
+ // Finish initialization.
150
+ init->finishInitialization (SGF);
97
151
98
- return SGF.emitRValue (std::move (*this ).asKnownExpr (), C);
152
+ return RValue::forInContext ();
153
+ }
154
+ }
155
+
156
+ // Otherwise, emit all of the elements into a single big r-value.
157
+ RValue result (type);
158
+ for (auto &element : elements) {
159
+ result.addElement (std::move (element).getAsRValue (SGF));
160
+ }
161
+ return result;
162
+ });
99
163
}
100
164
101
165
ManagedValue ArgumentSource::getAsSingleValue (SILGenFunction &SGF,
102
166
SGFContext C) && {
103
- if (isRValue ()) {
104
- auto loc = getKnownRValueLocation ();
105
- return std::move (*this ).asKnownRValue ().getAsSingleValue (SGF, loc);
106
- }
107
- if (isLValue ()) {
167
+ switch (StoredKind) {
168
+ case Kind::Invalid:
169
+ llvm_unreachable (" argument source is invalid" );
170
+ case Kind::LValue: {
108
171
auto loc = getKnownLValueLocation ();
109
172
return SGF.emitAddressOfLValue (loc, std::move (*this ).asKnownLValue (),
110
173
AccessKind::ReadWrite);
111
174
}
112
-
113
- auto e = std::move (*this ).asKnownExpr ();
114
- if (e->getType ()->is <InOutType>()) {
115
- return SGF.emitAddressOfLValue (e, SGF.emitLValue (e, AccessKind::ReadWrite),
116
- AccessKind::ReadWrite);
117
- } else {
118
- return SGF.emitRValueAsSingleValue (e, C);
175
+ case Kind::RValue: {
176
+ auto loc = getKnownRValueLocation ();
177
+ if (auto init = C.getEmitInto ()) {
178
+ std::move (*this ).asKnownRValue ().forwardInto (SGF, loc, init);
179
+ return ManagedValue::forInContext ();
180
+ } else {
181
+ return std::move (*this ).asKnownRValue ().getAsSingleValue (SGF, loc);
182
+ }
183
+ }
184
+ case Kind::Expr: {
185
+ auto e = std::move (*this ).asKnownExpr ();
186
+ if (e->getType ()->is <InOutType>()) {
187
+ return SGF.emitAddressOfLValue (e, SGF.emitLValue (e, AccessKind::ReadWrite),
188
+ AccessKind::ReadWrite);
189
+ } else {
190
+ return SGF.emitRValueAsSingleValue (e, C);
191
+ }
192
+ }
193
+ case Kind::Tuple: {
194
+ auto loc = getKnownTupleLocation ();
195
+ auto rvalue = std::move (*this ).getKnownTupleAsRValue (SGF, C);
196
+ if (rvalue.isInContext ())
197
+ return ManagedValue::forInContext ();
198
+ return std::move (rvalue).getAsSingleValue (SGF, loc);
199
+ }
119
200
}
201
+ llvm_unreachable (" bad kind" );
120
202
}
121
203
122
204
@@ -131,40 +213,58 @@ ManagedValue ArgumentSource::getAsSingleValue(SILGenFunction &SGF,
131
213
ManagedValue ArgumentSource::getConverted (SILGenFunction &SGF,
132
214
const Conversion &conversion,
133
215
SGFContext C) && {
134
- assert (!isLValue ());
135
-
136
- if (isRValue ()) {
137
- auto loc = getKnownRValueLocation ();
138
- auto result = std::move (*this ).asKnownRValue ().getAsSingleValue (SGF, loc);
139
- return conversion.emit (SGF, loc, result, C);
216
+ switch (StoredKind) {
217
+ case Kind::Invalid:
218
+ llvm_unreachable (" argument source is invalid" );
219
+ case Kind::LValue:
220
+ llvm_unreachable (" cannot get converted l-value" );
221
+ case Kind::RValue:
222
+ case Kind::Expr:
223
+ case Kind::Tuple:
224
+ return SGF.emitConvertedRValue (getLocation (), conversion, C,
225
+ [&](SILGenFunction &SGF, SILLocation loc, SGFContext C) {
226
+ return std::move (*this ).getAsSingleValue (SGF, C);
227
+ });
140
228
}
141
-
142
- auto e = std::move (*this ).asKnownExpr ();
143
- assert (!e->getType ()->is <InOutType>());
144
- return SGF.emitConvertedRValue (e, conversion, C);
229
+ llvm_unreachable (" bad kind" );
145
230
}
146
231
147
232
void ArgumentSource::forwardInto (SILGenFunction &SGF, Initialization *dest) && {
148
- assert (!isLValue ());
149
- if (isRValue ()) {
233
+ switch (StoredKind) {
234
+ case Kind::Invalid:
235
+ llvm_unreachable (" argument source is invalid" );
236
+ case Kind::LValue:
237
+ llvm_unreachable (" cannot forward an l-value" );
238
+ case Kind::RValue: {
150
239
auto loc = getKnownRValueLocation ();
151
- return std::move (*this ).asKnownRValue ().forwardInto (SGF, loc, dest);
240
+ std::move (*this ).asKnownRValue ().forwardInto (SGF, loc, dest);
241
+ return ;
152
242
}
153
-
154
- auto e = std::move (*this ).asKnownExpr ();
155
- return SGF.emitExprInto (e, dest);
243
+ case Kind::Expr: {
244
+ auto e = std::move (*this ).asKnownExpr ();
245
+ SGF.emitExprInto (e, dest);
246
+ return ;
247
+ }
248
+ case Kind::Tuple: {
249
+ auto loc = getKnownTupleLocation ();
250
+ auto rvalue = std::move (*this ).getKnownTupleAsRValue (SGF, SGFContext (dest));
251
+ if (!rvalue.isInContext ())
252
+ std::move (rvalue).forwardInto (SGF, loc, dest);
253
+ return ;
254
+ }
255
+ }
256
+ llvm_unreachable (" bad kind" );
156
257
}
157
258
158
259
ManagedValue ArgumentSource::materialize (SILGenFunction &SGF) && {
159
- assert (!isLValue ());
160
260
if (isRValue ()) {
161
261
auto loc = getKnownRValueLocation ();
162
262
return std::move (*this ).asKnownRValue ().materialize (SGF, loc);
163
263
}
164
264
165
- auto expr = std::move (* this ). asKnownExpr ();
166
- auto temp = SGF.emitTemporary (expr , SGF.getTypeLowering (expr-> getType ()));
167
- SGF. emitExprInto (expr , temp.get ());
265
+ auto loc = getLocation ();
266
+ auto temp = SGF.emitTemporary (loc , SGF.getTypeLowering (getSubstType ()));
267
+ std::move (* this ). forwardInto (SGF , temp.get ());
168
268
return temp->getManagedAddress ();
169
269
}
170
270
@@ -245,3 +345,38 @@ SILType ArgumentSource::getSILSubstType(SILGenFunction &SGF) const & {
245
345
AbstractionPattern origType (funcType->getGenericSignature (), substType);
246
346
return SGF.getLoweredType (origType, substType);
247
347
}
348
+
349
+ void ArgumentSource::dump () const {
350
+ dump (llvm::errs ());
351
+ }
352
+ void ArgumentSource::dump (raw_ostream &out, unsigned indent) const {
353
+ out.indent (indent) << " ArgumentSource::" ;
354
+ switch (StoredKind) {
355
+ case Kind::Invalid:
356
+ out << " Invalid\n " ;
357
+ return ;
358
+ case Kind::LValue:
359
+ out << " LValue\n " ;
360
+ Storage.get <LValueStorage>(StoredKind).Value .dump (out, indent + 2 );
361
+ return ;
362
+ case Kind::Tuple: {
363
+ out << " Tuple\n " ;
364
+ auto &storage = Storage.get <TupleStorage>(StoredKind);
365
+ storage.SubstType .dump (out, indent + 2 );
366
+ for (auto &elt : storage.Elements ) {
367
+ elt.dump (out, indent + 2 );
368
+ out << ' \n ' ;
369
+ }
370
+ return ;
371
+ }
372
+ case Kind::RValue:
373
+ out << " RValue\n " ;
374
+ Storage.get <RValueStorage>(StoredKind).Value .dump (out, indent + 2 );
375
+ return ;
376
+ case Kind::Expr:
377
+ out << " Expr\n " ;
378
+ Storage.get <Expr*>(StoredKind)->dump (out); // FIXME: indent
379
+ return ;
380
+ }
381
+ llvm_unreachable (" bad kind" );
382
+ }
0 commit comments