protected override void RemoveEntryInPredicatedData(AnalysisEntity key, CoreCopyAnalysisData predicatedData) { Debug.Assert(HasPredicatedData); var hasEntry = predicatedData.TryGetValue(key, out var value); base.RemoveEntryInPredicatedData(key, predicatedData); // If we are removing an entity from predicated data, we need to adjust the copy values of its copy entities. if (hasEntry && value !.AnalysisEntities.Count > 1) { var newValueForOldCopyEntities = value.WithEntityRemoved(key); if (newValueForOldCopyEntities.AnalysisEntities.Count == 1) { predicatedData.Remove(newValueForOldCopyEntities.AnalysisEntities.Single()); } else { foreach (var copyEntity in newValueForOldCopyEntities.AnalysisEntities) { predicatedData[copyEntity] = newValueForOldCopyEntities; } } } }
public override CoreCopyAnalysisData Merge(CoreCopyAnalysisData map1, CoreCopyAnalysisData map2) { Debug.Assert(map1 != null); Debug.Assert(map2 != null); CopyAnalysisData.AssertValidCopyAnalysisData(map1); CopyAnalysisData.AssertValidCopyAnalysisData(map2); var result = new DictionaryAnalysisData <AnalysisEntity, CopyAbstractValue>(); foreach (var kvp in map1) { var key = kvp.Key; var value1 = kvp.Value; // If the key exists in both maps, use the merged value. // Otherwise, use the default value. CopyAbstractValue mergedValue; if (map2.TryGetValue(key, out var value2)) { mergedValue = ValueDomain.Merge(value1, value2); } else { mergedValue = _getDefaultCopyValue(key); } result.Add(key, mergedValue); } foreach (var kvp in map2) { if (!result.ContainsKey(kvp.Key)) { result.Add(kvp.Key, _getDefaultCopyValue(kvp.Key)); } } CopyAnalysisData.AssertValidCopyAnalysisData(result); return(result); }
#pragma warning disable CA1725 // Parameter names should match base declaration public override CoreCopyAnalysisData Merge(CoreCopyAnalysisData map1, CoreCopyAnalysisData map2) #pragma warning restore CA1725 // Parameter names should match base declaration { CopyAnalysisData.AssertValidCopyAnalysisData(map1); CopyAnalysisData.AssertValidCopyAnalysisData(map2); var result = new DictionaryAnalysisData <AnalysisEntity, CopyAbstractValue>(); foreach (var kvp in map1) { var key = kvp.Key; var value1 = kvp.Value; // If the key exists in both maps, use the merged value. // Otherwise, use the default value. CopyAbstractValue mergedValue; if (map2.TryGetValue(key, out var value2)) { mergedValue = ValueDomain.Merge(value1, value2); } else { mergedValue = _getDefaultCopyValue(key); } result.Add(key, mergedValue); } foreach (var kvp in map2) { if (!result.ContainsKey(kvp.Key)) { result.Add(kvp.Key, _getDefaultCopyValue(kvp.Key)); } } CopyAnalysisData.AssertValidCopyAnalysisData(result); return(result); }
protected override void ApplyPredicatedData(CoreCopyAnalysisData coreAnalysisData, CoreCopyAnalysisData predicatedData) { if (predicatedData.Count == 0) { return; } #if DEBUG var originalCoreAnalysisData = new Dictionary <AnalysisEntity, CopyAbstractValue>(coreAnalysisData); #endif AssertValidCopyAnalysisData(coreAnalysisData); AssertValidCopyAnalysisData(predicatedData); // Applying predicated copy data to current copy analysis data needs us to merge the copy sets of an entity from both the maps. foreach (var kvp in predicatedData) { var predicatedValue = kvp.Value; // Check if the entity has a copy value in both the predicated and current copy anaylysis data. if (coreAnalysisData.TryGetValue(kvp.Key, out var currentValue)) { var newCopyEntities = currentValue.AnalysisEntities; var newKind = currentValue.Kind; foreach (var predicatedCopyEntity in predicatedValue.AnalysisEntities) { // Predicate copy value has an entity which is not part of the current copy value. // Include this entity and it's copy entities in the new copy value. if (!newCopyEntities.Contains(predicatedCopyEntity)) { if (coreAnalysisData.TryGetValue(predicatedCopyEntity, out var predicatedCopyEntityValue)) { newCopyEntities = newCopyEntities.Union(predicatedCopyEntityValue.AnalysisEntities); newKind = newKind.MergeIfBothKnown(predicatedCopyEntityValue.Kind); } else { newCopyEntities = newCopyEntities.Add(predicatedCopyEntity); } } } // Check if we need to change the current copy value. if (newCopyEntities.Count != currentValue.AnalysisEntities.Count) { var newCopyValue = new CopyAbstractValue(newCopyEntities, newKind); foreach (var copyEntity in newCopyEntities) { coreAnalysisData[copyEntity] = newCopyValue; } } else { Debug.Assert(newCopyEntities.SetEquals(currentValue.AnalysisEntities)); } } else { // Predicated copy entity has no entry in the current copy analysis data, so just add the entry. coreAnalysisData[kvp.Key] = kvp.Value; } } // Ensure that applying predicated data to the current copy data can only increase the copy value entities in the current copy data. Debug.Assert(predicatedData.All(kvp => kvp.Value.AnalysisEntities.IsSubsetOf(coreAnalysisData[kvp.Key].AnalysisEntities))); AssertValidCopyAnalysisData(coreAnalysisData); }