@@ -295,13 +295,52 @@ class RegionAnalysisValueMap {
295
295
// / into this map
296
296
llvm::DenseMap<RepresentativeValue, TrackableValueState>
297
297
equivalenceClassValuesToState;
298
+
299
+ // / The inverse map of equivalenceClassValuesToState.
298
300
llvm::DenseMap<unsigned , RepresentativeValue> stateIndexToEquivalenceClass;
299
301
302
+ // / State that the value -> representative computation yields to us.
303
+ struct UnderlyingTrackedValueInfo {
304
+ SILValue value;
305
+
306
+ // / Only used for addresses.
307
+ std::optional<ActorIsolation> actorIsolation;
308
+
309
+ explicit UnderlyingTrackedValueInfo (SILValue value) : value(value) {}
310
+
311
+ UnderlyingTrackedValueInfo () : value(), actorIsolation() {}
312
+
313
+ UnderlyingTrackedValueInfo (const UnderlyingTrackedValueInfo &newVal)
314
+ : value(newVal.value), actorIsolation(newVal.actorIsolation) {}
315
+
316
+ UnderlyingTrackedValueInfo &
317
+ operator =(const UnderlyingTrackedValueInfo &newVal) {
318
+ value = newVal.value ;
319
+ actorIsolation = newVal.actorIsolation ;
320
+ return *this ;
321
+ }
322
+
323
+ UnderlyingTrackedValueInfo (SILValue value,
324
+ std::optional<ActorIsolation> actorIsolation)
325
+ : value(value), actorIsolation(actorIsolation) {}
326
+
327
+ operator bool () const { return value; }
328
+ };
329
+
330
+ // / A map from a SILValue to its equivalence class representative.
331
+ llvm::DenseMap<SILValue, UnderlyingTrackedValueInfo> valueToEquivalenceClass;
332
+
300
333
SILFunction *fn;
301
334
302
335
public:
303
336
RegionAnalysisValueMap (SILFunction *fn) : fn(fn) { }
304
337
338
+ // / Maps a value to its representative value if one exists. Return an empty
339
+ // / representative value if we do not find one.
340
+ SILValue getRepresentative (SILValue value) const {
341
+ return getUnderlyingTrackedValue (value).value ;
342
+ }
343
+
305
344
// / Returns the value for this instruction if it isn't a fake "represenative
306
345
// / value" to inject actor isolatedness. Asserts in such a case.
307
346
SILValue getRepresentative (Element trackableValueID) const ;
@@ -354,6 +393,30 @@ class RegionAnalysisValueMap {
354
393
// / {TrackableValue(), false}.
355
394
std::pair<TrackableValue, bool >
356
395
initializeTrackableValue (SILValue value, SILIsolationInfo info) const ;
396
+
397
+ // / A helper function that performs the actual getUnderlyingTrackedValue
398
+ // / computation that is cached in getUnderlyingTrackedValue(). Please never
399
+ // / call this directly! Only call it from getUnderlyingTrackedValue.
400
+ UnderlyingTrackedValueInfo
401
+ getUnderlyingTrackedValueHelper (SILValue value) const ;
402
+
403
+ UnderlyingTrackedValueInfo getUnderlyingTrackedValue (SILValue value) const {
404
+ // Use try_emplace so we only construct underlying tracked value info on
405
+ // success and only lookup once in the hash table.
406
+ auto *self = const_cast <RegionAnalysisValueMap *>(this );
407
+ auto iter = self->valueToEquivalenceClass .try_emplace (
408
+ value, UnderlyingTrackedValueInfo ());
409
+
410
+ // Didn't insert... we have a value!
411
+ if (!iter.second )
412
+ return iter.first ->getSecond ();
413
+
414
+ // Otherwise, update with the actual tracked value info.
415
+ iter.first ->getSecond () = getUnderlyingTrackedValueHelper (value);
416
+
417
+ // And return the value.
418
+ return iter.first ->getSecond ();
419
+ }
357
420
};
358
421
359
422
class RegionAnalysisFunctionInfo {
@@ -485,7 +548,9 @@ class RegionAnalysisFunctionInfo {
485
548
486
549
bool isClosureCaptured (SILValue value, Operand *op);
487
550
488
- static SILValue getUnderlyingTrackedValue (SILValue value);
551
+ SILValue getUnderlyingTrackedValue (SILValue value) {
552
+ return getValueMap ().getRepresentative (value);
553
+ }
489
554
490
555
private:
491
556
void runDataflow ();
0 commit comments