@@ -295,13 +295,52 @@ class RegionAnalysisValueMap {
295295 // / into this map
296296 llvm::DenseMap<RepresentativeValue, TrackableValueState>
297297 equivalenceClassValuesToState;
298+
299+ // / The inverse map of equivalenceClassValuesToState.
298300 llvm::DenseMap<unsigned , RepresentativeValue> stateIndexToEquivalenceClass;
299301
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+
300333 SILFunction *fn;
301334
302335public:
303336 RegionAnalysisValueMap (SILFunction *fn) : fn(fn) { }
304337
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+
305344 // / Returns the value for this instruction if it isn't a fake "represenative
306345 // / value" to inject actor isolatedness. Asserts in such a case.
307346 SILValue getRepresentative (Element trackableValueID) const ;
@@ -354,6 +393,30 @@ class RegionAnalysisValueMap {
354393 // / {TrackableValue(), false}.
355394 std::pair<TrackableValue, bool >
356395 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+ }
357420};
358421
359422class RegionAnalysisFunctionInfo {
@@ -485,7 +548,9 @@ class RegionAnalysisFunctionInfo {
485548
486549 bool isClosureCaptured (SILValue value, Operand *op);
487550
488- static SILValue getUnderlyingTrackedValue (SILValue value);
551+ SILValue getUnderlyingTrackedValue (SILValue value) {
552+ return getValueMap ().getRepresentative (value);
553+ }
489554
490555private:
491556 void runDataflow ();
0 commit comments