@@ -114,6 +114,10 @@ class ActorInstance {
114
114
}
115
115
};
116
116
117
+ // / The isolation info inferred for a specific SILValue. Use
118
+ // / SILIsolationInfo::get() to compute these. It is intended to be a
119
+ // / conservatively correct model that we expand over time with more pattern
120
+ // / matching.
117
121
class SILIsolationInfo {
118
122
public:
119
123
// / The lattice is:
@@ -128,6 +132,23 @@ class SILIsolationInfo {
128
132
Actor,
129
133
};
130
134
135
+ enum class Flag : uint8_t {
136
+ None,
137
+
138
+ // / If set, this means that the element that we derived this from was marked
139
+ // / with nonisolated(unsafe).
140
+ UnsafeNonIsolated = 0x1 ,
141
+
142
+ // / If set, this means that this actor isolation is from an isolated
143
+ // / parameter and should be allowed to merge into a self parameter.
144
+ UnappliedIsolatedAnyParameter = 0x2 ,
145
+
146
+ // / The maximum number of bits used by a Flag.
147
+ MaxNumBits = 2 ,
148
+ };
149
+
150
+ using Options = OptionSet<Flag>;
151
+
131
152
private:
132
153
// / The actor isolation if this value has one. The default unspecified case
133
154
// / otherwise.
@@ -142,13 +163,13 @@ class SILIsolationInfo {
142
163
ActorInstance actorInstance;
143
164
144
165
unsigned kind : 8 ;
145
- unsigned unsafeNonIsolated : 1 ;
166
+ unsigned options : 8 ;
146
167
147
168
SILIsolationInfo (SILValue isolatedValue, SILValue actorInstance,
148
- ActorIsolation actorIsolation, bool isUnsafeNonIsolated )
169
+ ActorIsolation actorIsolation, Options options = Options() )
149
170
: actorIsolation(actorIsolation), isolatedValue(isolatedValue),
150
171
actorInstance (ActorInstance::getForValue(actorInstance)), kind(Actor),
151
- unsafeNonIsolated(isUnsafeNonIsolated ) {
172
+ options(options.toRaw() ) {
152
173
assert ((!actorInstance ||
153
174
(actorIsolation.getKind () == ActorIsolation::ActorInstance &&
154
175
actorInstance->getType ()
@@ -159,24 +180,22 @@ class SILIsolationInfo {
159
180
}
160
181
161
182
SILIsolationInfo (SILValue isolatedValue, ActorInstance actorInstance,
162
- ActorIsolation actorIsolation, bool isUnsafeNonIsolated )
183
+ ActorIsolation actorIsolation, Options options = Options() )
163
184
: actorIsolation(actorIsolation), isolatedValue(isolatedValue),
164
- actorInstance(actorInstance), kind(Actor),
165
- unsafeNonIsolated(isUnsafeNonIsolated) {
185
+ actorInstance(actorInstance), kind(Actor), options(options.toRaw()) {
166
186
assert (actorInstance);
167
187
assert (actorIsolation.getKind () == ActorIsolation::ActorInstance);
168
188
}
169
189
170
190
SILIsolationInfo (Kind kind, SILValue isolatedValue)
171
- : actorIsolation(), isolatedValue(isolatedValue), kind(kind),
172
- unsafeNonIsolated( false ) { }
191
+ : actorIsolation(), isolatedValue(isolatedValue), kind(kind), options( 0 ) {
192
+ }
173
193
174
- SILIsolationInfo (Kind kind, bool isUnsafeNonIsolated )
175
- : actorIsolation(), kind(kind), unsafeNonIsolated(isUnsafeNonIsolated ) {}
194
+ SILIsolationInfo (Kind kind, Options options = Options() )
195
+ : actorIsolation(), kind(kind), options(options.toRaw() ) {}
176
196
177
197
public:
178
- SILIsolationInfo ()
179
- : actorIsolation(), kind(Kind::Unknown), unsafeNonIsolated(false ) {}
198
+ SILIsolationInfo () : actorIsolation(), kind(Kind::Unknown), options(0 ) {}
180
199
181
200
operator bool () const { return kind != Kind::Unknown; }
182
201
@@ -188,12 +207,43 @@ class SILIsolationInfo {
188
207
bool isActorIsolated () const { return kind == Kind::Actor; }
189
208
bool isTaskIsolated () const { return kind == Kind::Task; }
190
209
191
- bool isUnsafeNonIsolated () const { return unsafeNonIsolated; }
210
+ Options getOptions () const { return Options (options); }
211
+
212
+ void setOptions (Options newOptions) { options = newOptions.toRaw (); }
213
+
214
+ bool isUnsafeNonIsolated () const {
215
+ return getOptions ().contains (Flag::UnsafeNonIsolated);
216
+ }
192
217
193
218
SILIsolationInfo withUnsafeNonIsolated (bool newValue = true ) const {
194
219
assert (*this && " Cannot be unknown" );
195
220
auto self = *this ;
196
- self.unsafeNonIsolated = newValue;
221
+ if (newValue) {
222
+ self.options = (self.getOptions () | Flag::UnsafeNonIsolated).toRaw ();
223
+ } else {
224
+ self.options =
225
+ self.getOptions ().toRaw () & ~Options (Flag::UnsafeNonIsolated).toRaw ();
226
+ }
227
+ return self;
228
+ }
229
+
230
+ // / Returns true if this actor isolation is derived from an unapplied
231
+ // / isolation parameter. When merging, we allow for this to be merged with a
232
+ // / more specific isolation kind.
233
+ bool isUnappliedIsolatedAnyParameter () const {
234
+ return getOptions ().contains (Flag::UnappliedIsolatedAnyParameter);
235
+ }
236
+
237
+ SILIsolationInfo withUnappliedIsolatedParameter (bool newValue = true ) const {
238
+ assert (*this && " Cannot be unknown" );
239
+ auto self = *this ;
240
+ if (newValue) {
241
+ self.options =
242
+ (self.getOptions () | Flag::UnappliedIsolatedAnyParameter).toRaw ();
243
+ } else {
244
+ self.options = self.getOptions ().toRaw () &
245
+ ~Options (Flag::UnappliedIsolatedAnyParameter).toRaw ();
246
+ }
197
247
return self;
198
248
}
199
249
@@ -243,7 +293,8 @@ class SILIsolationInfo {
243
293
}
244
294
245
295
static SILIsolationInfo getDisconnected (bool isUnsafeNonIsolated) {
246
- return {Kind::Disconnected, isUnsafeNonIsolated};
296
+ return {Kind::Disconnected,
297
+ isUnsafeNonIsolated ? Flag::UnsafeNonIsolated : Flag::None};
247
298
}
248
299
249
300
// / Create an actor isolation for a value that we know is actor isolated to a
@@ -261,7 +312,7 @@ class SILIsolationInfo {
261
312
getFlowSensitiveActorIsolated (SILValue isolatedValue,
262
313
ActorIsolation actorIsolation) {
263
314
return {isolatedValue, SILValue (), actorIsolation,
264
- false /* nonisolated(unsafe) */ };
315
+ Flag::UnappliedIsolatedAnyParameter };
265
316
}
266
317
267
318
// / Only use this as a fallback if we cannot find better information.
@@ -270,8 +321,7 @@ class SILIsolationInfo {
270
321
if (crossing.getCalleeIsolation ().isActorIsolated ()) {
271
322
// SIL level, just let it through
272
323
return SILIsolationInfo (SILValue (), SILValue (),
273
- crossing.getCalleeIsolation (),
274
- false /* nonisolated(unsafe)*/ );
324
+ crossing.getCalleeIsolation ());
275
325
}
276
326
277
327
return {};
@@ -287,8 +337,7 @@ class SILIsolationInfo {
287
337
return {};
288
338
}
289
339
return {isolatedValue, actorInstance,
290
- ActorIsolation::forActorInstanceSelf (typeDecl),
291
- false /* nonisolated(unsafe)*/ };
340
+ ActorIsolation::forActorInstanceSelf (typeDecl)};
292
341
}
293
342
294
343
static SILIsolationInfo getActorInstanceIsolated (SILValue isolatedValue,
@@ -301,8 +350,7 @@ class SILIsolationInfo {
301
350
return {};
302
351
}
303
352
return {isolatedValue, actorInstance,
304
- ActorIsolation::forActorInstanceSelf (typeDecl),
305
- false /* nonisolated(unsafe)*/ };
353
+ ActorIsolation::forActorInstanceSelf (typeDecl)};
306
354
}
307
355
308
356
// / A special actor instance isolated for partial apply cases where we do not
@@ -318,14 +366,13 @@ class SILIsolationInfo {
318
366
}
319
367
return {isolatedValue, SILValue (),
320
368
ActorIsolation::forActorInstanceSelf (typeDecl),
321
- false /* nonisolated(unsafe) */ };
369
+ Flag::UnappliedIsolatedAnyParameter };
322
370
}
323
371
324
372
static SILIsolationInfo getGlobalActorIsolated (SILValue value,
325
373
Type globalActorType) {
326
374
return {value, SILValue () /* no actor instance*/ ,
327
- ActorIsolation::forGlobalActor (globalActorType),
328
- false /* nonisolated(unsafe)*/ };
375
+ ActorIsolation::forGlobalActor (globalActorType)};
329
376
}
330
377
331
378
static SILIsolationInfo getGlobalActorIsolated (SILValue value,
@@ -382,6 +429,9 @@ class SILIsolationInfo {
382
429
bool isEqual (const SILIsolationInfo &other) const ;
383
430
384
431
void Profile (llvm::FoldingSetNodeID &id) const ;
432
+
433
+ private:
434
+ void printOptions (llvm::raw_ostream &os) const ;
385
435
};
386
436
387
437
// / A SILIsolationInfo that has gone through merging and represents the dynamic
@@ -395,7 +445,7 @@ class SILDynamicMergedIsolationInfo {
395
445
396
446
public:
397
447
SILDynamicMergedIsolationInfo () : innerInfo() {}
398
- explicit SILDynamicMergedIsolationInfo (SILIsolationInfo innerInfo)
448
+ SILDynamicMergedIsolationInfo (SILIsolationInfo innerInfo)
399
449
: innerInfo(innerInfo) {}
400
450
401
451
// / Returns nullptr only if both this isolation info and \p other are actor
@@ -435,6 +485,10 @@ class SILDynamicMergedIsolationInfo {
435
485
SWIFT_DEBUG_DUMPER (dumpForDiagnostics()) {
436
486
innerInfo.dumpForDiagnostics ();
437
487
}
488
+
489
+ void printForOneLineLogging (llvm::raw_ostream &os) const {
490
+ innerInfo.printForOneLineLogging (os);
491
+ }
438
492
};
439
493
440
494
} // namespace swift
0 commit comments