protected AnalysisEntityBasedPredicateAnalysisData( DictionaryAnalysisData <AnalysisEntity, TValue> mergedCoreAnalysisData, PredicatedAnalysisData <AnalysisEntity, TValue> predicatedData1, PredicatedAnalysisData <AnalysisEntity, TValue> predicatedData2, bool isReachableData, MapAbstractDomain <AnalysisEntity, TValue> coreDataAnalysisDomain) : base(predicatedData1, predicatedData2, mergedCoreAnalysisData, mergedCoreAnalysisData, isReachableData, coreDataAnalysisDomain) { CoreAnalysisData = mergedCoreAnalysisData; }
/// <summary> /// Helper method to reset analysis data for analysis locations. /// </summary> protected void ResetAnalysisData(DictionaryAnalysisData <AbstractLocation, TAbstractAnalysisValue> currentAnalysisData) { // Reset the current analysis data, while ensuring that we don't violate the monotonicity, i.e. we cannot remove any existing key from currentAnalysisData. // Just set the values for existing keys to ValueDomain.UnknownOrMayBeValue. var keys = currentAnalysisData.Keys.ToImmutableArray(); foreach (var key in keys) { SetAbstractValue(key, ValueDomain.UnknownOrMayBeValue); } }
private static DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData> MergeForPredicatedDataInBothBranches( DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData> predicatedData1, DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData> predicatedData2, DictionaryAnalysisData <TKey, TValue> coreAnalysisData1, DictionaryAnalysisData <TKey, TValue> coreAnalysisData2, MapAbstractDomain <TKey, TValue> coreDataAnalysisDomain, Action <DictionaryAnalysisData <TKey, TValue>, DictionaryAnalysisData <TKey, TValue> > applyPredicatedData) { Debug.Assert(predicatedData1 != null); Debug.Assert(predicatedData2 != null); Debug.Assert(coreAnalysisData1 != null); Debug.Assert(coreAnalysisData2 != null); var result = new DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData>(); foreach (var kvp in predicatedData1) { DictionaryAnalysisData <TKey, TValue> resultTruePredicatedData; DictionaryAnalysisData <TKey, TValue> resultFalsePredicatedData; if (!predicatedData2.TryGetValue(kvp.Key, out var value2)) { // Data predicated by the analysis entity present in only one branch. // We should merge with the core non-predicate data in other branch. resultTruePredicatedData = MergeForPredicatedDataInOneBranch(kvp.Value.TruePredicatedData, coreAnalysisData2, coreDataAnalysisDomain); resultFalsePredicatedData = MergeForPredicatedDataInOneBranch(kvp.Value.FalsePredicatedData, coreAnalysisData2, coreDataAnalysisDomain); } else { // Data predicated by the analysis entity present in both branches. resultTruePredicatedData = Merge(kvp.Value.TruePredicatedData, value2.TruePredicatedData, coreAnalysisData1, coreAnalysisData2, coreDataAnalysisDomain, applyPredicatedData); resultFalsePredicatedData = Merge(kvp.Value.FalsePredicatedData, value2.FalsePredicatedData, coreAnalysisData1, coreAnalysisData2, coreDataAnalysisDomain, applyPredicatedData); } var perEntityPredicatedData = new PerEntityPredicatedAnalysisData(resultTruePredicatedData, resultFalsePredicatedData); result.Add(kvp.Key, perEntityPredicatedData); } foreach (var kvp in predicatedData2) { if (!predicatedData1.TryGetValue(kvp.Key, out _)) { // Data predicated by the analysis entity present in only one branch. // We should merge with the core non-predicate data in other branch. var resultTruePredicatedData = MergeForPredicatedDataInOneBranch(kvp.Value.TruePredicatedData, coreAnalysisData1, coreDataAnalysisDomain); var resultFalsePredicatedData = MergeForPredicatedDataInOneBranch(kvp.Value.FalsePredicatedData, coreAnalysisData1, coreDataAnalysisDomain); var perEntityPredicatedData = new PerEntityPredicatedAnalysisData(resultTruePredicatedData, resultFalsePredicatedData); result.Add(kvp.Key, perEntityPredicatedData); } } return(result); }
private static DictionaryAnalysisData <TKey, TValue> MergeForPredicatedDataInOneBranch( DictionaryAnalysisData <TKey, TValue> predicatedData, DictionaryAnalysisData <TKey, TValue> coreAnalysisDataForOtherBranch, MapAbstractDomain <TKey, TValue> coreDataAnalysisDomain) { if (predicatedData == null) { return(null); } return(coreDataAnalysisDomain.Merge(predicatedData, coreAnalysisDataForOtherBranch)); }
protected void StartTrackingPredicatedData(AnalysisEntity predicatedEntity, DictionaryAnalysisData <TKey, TValue> truePredicatedData, DictionaryAnalysisData <TKey, TValue> falsePredicatedData) { Debug.Assert(predicatedEntity.IsCandidatePredicateEntity()); Debug.Assert(predicatedEntity.CaptureIdOpt != null, "Currently we only support predicated data tracking for flow captures"); AssertValidAnalysisData(); EnsurePredicatedData(); _lazyPredicateDataMap[predicatedEntity] = new PerEntityPredicatedAnalysisData(truePredicatedData, falsePredicatedData); AssertValidAnalysisData(); }
private static DictionaryAnalysisData <TKey, TValue> CloneAndApplyPredicatedData( DictionaryAnalysisData <TKey, TValue> coreAnalysisData, DictionaryAnalysisData <TKey, TValue> predicateTrueOrFalseData, Action <DictionaryAnalysisData <TKey, TValue>, DictionaryAnalysisData <TKey, TValue> > applyPredicatedData) { Debug.Assert(predicateTrueOrFalseData != null); Debug.Assert(coreAnalysisData != null); var result = new DictionaryAnalysisData <TKey, TValue>(coreAnalysisData); applyPredicatedData(result, predicateTrueOrFalseData); return(result); }
protected PredicatedAnalysisData( PredicatedAnalysisData <TKey, TValue> predicatedData1, PredicatedAnalysisData <TKey, TValue> predicatedData2, DictionaryAnalysisData <TKey, TValue> coreAnalysisData1, DictionaryAnalysisData <TKey, TValue> coreAnalysisData2, bool isReachableData, MapAbstractDomain <TKey, TValue> coreDataAnalysisDomain) { IsReachableBlockData = isReachableData; _lazyPredicateDataMap = Merge(predicatedData1._lazyPredicateDataMap, predicatedData2._lazyPredicateDataMap, coreAnalysisData1, coreAnalysisData2, coreDataAnalysisDomain, ApplyPredicatedData); AssertValidAnalysisData(); }
private int Compare(DictionaryAnalysisData <TKey, TValue> oldValue, DictionaryAnalysisData <TKey, TValue> newValue, bool assertMonotonicity) { Debug.Assert(oldValue != null); Debug.Assert(newValue != null); if (ReferenceEquals(oldValue, newValue)) { return(0); } if (newValue.Count < oldValue.Count) { FireNonMonotonicAssertIfNeeded(assertMonotonicity); return(1); } // Ensure that every key in oldValue exists in newValue and the value corresponding to that key // is not greater in oldValue as compared to the value in newValue bool newValueIsBigger = false; foreach (var kvp in oldValue) { var key = kvp.Key; var value = kvp.Value; if (!newValue.TryGetValue(key, out TValue otherValue)) { FireNonMonotonicAssertIfNeeded(assertMonotonicity); return(1); } var result = ValueDomain.Compare(value, otherValue, assertMonotonicity); if (result > 0) { FireNonMonotonicAssertIfNeeded(assertMonotonicity); return(1); } else if (result < 0) { newValueIsBigger = true; } } if (!newValueIsBigger) { newValueIsBigger = newValue.Count > oldValue.Count; } return(newValueIsBigger ? -1 : 0); }
protected static bool EqualsHelper(DictionaryAnalysisData <TKey, TValue> dict1, DictionaryAnalysisData <TKey, TValue> dict2) { if (dict1 == null) { return(dict2 == null); } else if (dict2 == null || dict1.Count != dict2.Count) { return(false); } return(dict1.Keys.All(key => dict2.TryGetValue(key, out TValue value2) && EqualityComparer <TValue> .Default.Equals(dict1[key], value2))); }
public PerEntityPredicatedAnalysisData(DictionaryAnalysisData <TKey, TValue>?truePredicatedData, DictionaryAnalysisData <TKey, TValue>?falsePredicatedData) { Debug.Assert(truePredicatedData != null || falsePredicatedData != null); if (truePredicatedData != null) { TruePredicatedData = new DictionaryAnalysisData <TKey, TValue>(truePredicatedData); } if (falsePredicatedData != null) { FalsePredicatedData = new DictionaryAnalysisData <TKey, TValue>(falsePredicatedData); } }
protected void StartTrackingPredicatedData(AnalysisEntity predicatedEntity, DictionaryAnalysisData <TKey, TValue> truePredicatedData, DictionaryAnalysisData <TKey, TValue> falsePredicatedData) { Debug.Assert(predicatedEntity.Type.SpecialType == SpecialType.System_Boolean || predicatedEntity.Type.IsNullableOfBoolean() || predicatedEntity.Type.Language == LanguageNames.VisualBasic && predicatedEntity.Type.SpecialType == SpecialType.System_Object); Debug.Assert(predicatedEntity.CaptureIdOpt != null, "Currently we only support predicated data tracking for flow captures"); AssertValidAnalysisData(); EnsurePredicatedData(); _lazyPredicateDataMap[predicatedEntity] = new PerEntityPredicatedAnalysisData(truePredicatedData, falsePredicatedData); AssertValidAnalysisData(); }
private static DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData> Clone(DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData> fromData) { if (fromData == null) { return(null); } var clonedMap = new DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData>(); foreach (var kvp in fromData) { clonedMap.Add(kvp.Key, new PerEntityPredicatedAnalysisData(kvp.Value)); } return(clonedMap); }
protected void ResetPredicatedData() { if (_lazyPredicateDataMap == null) { return; } if (!_lazyPredicateDataMap.IsDisposed) { _lazyPredicateDataMap.Values.Dispose(); _lazyPredicateDataMap.Dispose(); } Debug.Assert(_lazyPredicateDataMap.IsDisposed); _lazyPredicateDataMap = null; }
private static DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData> MergeForPredicatedDataInOneBranch( DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData> predicatedData, DictionaryAnalysisData <TKey, TValue> coreAnalysisDataForOtherBranch, MapAbstractDomain <TKey, TValue> coreDataAnalysisDomain) { Debug.Assert(predicatedData != null); Debug.Assert(coreAnalysisDataForOtherBranch != null); var result = new DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData>(); foreach (var kvp in predicatedData) { var resultTruePredicatedData = MergeForPredicatedDataInOneBranch(kvp.Value.TruePredicatedData, coreAnalysisDataForOtherBranch, coreDataAnalysisDomain); var resultFalsePredicatedData = MergeForPredicatedDataInOneBranch(kvp.Value.FalsePredicatedData, coreAnalysisDataForOtherBranch, coreDataAnalysisDomain); var perEntityPredicatedData = new PerEntityPredicatedAnalysisData(resultTruePredicatedData, resultFalsePredicatedData); result.Add(kvp.Key, perEntityPredicatedData); } return(result); }
internal static DictionaryAnalysisData <TKey, TValue> Intersect( DictionaryAnalysisData <TKey, TValue> map1, DictionaryAnalysisData <TKey, TValue> map2, Func <TValue, TValue, TValue> intersect) { var result = new DictionaryAnalysisData <TKey, TValue>(); if (map1.Count == 0 || map2.Count == 0) { return(result); } foreach (var kvp in map1) { if (map2.TryGetValue(kvp.Key, out var value2)) { result.Add(kvp.Key, intersect(kvp.Value, value2)); } } return(result); }
protected PredicateValueKind ApplyPredicatedDataForEntity(DictionaryAnalysisData <TKey, TValue> coreAnalysisData, AnalysisEntity predicatedEntity, bool trueData) { Debug.Assert(HasPredicatedDataForEntity(predicatedEntity)); AssertValidAnalysisData(); var perEntityPredicateData = _lazyPredicateDataMap[predicatedEntity]; var predicatedDataToApply = trueData ? perEntityPredicateData.TruePredicatedData : perEntityPredicateData.FalsePredicatedData; if (predicatedDataToApply == null) { // Infeasible branch. return(PredicateValueKind.AlwaysFalse); } ApplyPredicatedData(coreAnalysisData, predicatedDataToApply); // Predicate is always true if other branch predicate data is null. var otherBranchPredicatedData = trueData ? perEntityPredicateData.FalsePredicatedData : perEntityPredicateData.TruePredicatedData; return(otherBranchPredicatedData == null ? PredicateValueKind.AlwaysTrue : PredicateValueKind.Unknown); }
private static DictionaryAnalysisData <TKey, TValue> Merge( DictionaryAnalysisData <TKey, TValue> predicateTrueOrFalseData1, DictionaryAnalysisData <TKey, TValue> predicateTrueOrFalseData2, DictionaryAnalysisData <TKey, TValue> coreAnalysisData1, DictionaryAnalysisData <TKey, TValue> coreAnalysisData2, MapAbstractDomain <TKey, TValue> coreDataAnalysisDomain, Action <DictionaryAnalysisData <TKey, TValue>, DictionaryAnalysisData <TKey, TValue> > applyPredicatedData) { if (predicateTrueOrFalseData1 == null) { return(predicateTrueOrFalseData2 != null? CloneAndApplyPredicatedData(coreAnalysisData2, predicateTrueOrFalseData2, applyPredicatedData) : null); } else if (predicateTrueOrFalseData2 == null) { return(CloneAndApplyPredicatedData(coreAnalysisData1, predicateTrueOrFalseData1, applyPredicatedData)); } var appliedPredicatedData1 = CloneAndApplyPredicatedData(coreAnalysisData1, predicateTrueOrFalseData1, applyPredicatedData); var appliedPredicatedData2 = CloneAndApplyPredicatedData(coreAnalysisData2, predicateTrueOrFalseData2, applyPredicatedData); return(coreDataAnalysisDomain.Merge(appliedPredicatedData1, appliedPredicatedData2)); }
public override DictionaryAnalysisData <AnalysisEntity, TValue> Merge(DictionaryAnalysisData <AnalysisEntity, TValue> map1, DictionaryAnalysisData <AnalysisEntity, TValue> map2) { Debug.Assert(map1 != null); AssertValidAnalysisData(map1); Debug.Assert(map2 != null); AssertValidAnalysisData(map2); TValue GetMergedValueForEntityPresentInOneMap(AnalysisEntity key, TValue value) { if (key.HasConstantValue) { return(value); } var defaultValue = GetDefaultValue(key); return(ValueDomain.Merge(value, defaultValue)); } var resultMap = new DictionaryAnalysisData <AnalysisEntity, TValue>(); var newKeys = PooledHashSet <AnalysisEntity> .GetInstance(); var map2LookupIgnoringInstanceLocation = map2.Keys.Where(IsAnalysisEntityForFieldOrProperty) .ToLookup(entity => entity.EqualsIgnoringInstanceLocationId); foreach (var entry1 in map1) { AnalysisEntity key1 = entry1.Key; TValue value1 = entry1.Value; if (map2LookupIgnoringInstanceLocation.Count > 0 && IsAnalysisEntityForFieldOrProperty(key1)) { var equivalentKeys2 = map2LookupIgnoringInstanceLocation[key1.EqualsIgnoringInstanceLocationId]; if (!equivalentKeys2.Any()) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1); Debug.Assert(!map2.ContainsKey(key1)); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); AssertValidEntryForMergedMap(key1, mergedValue); resultMap.Add(key1, mergedValue); continue; } foreach (AnalysisEntity key2 in equivalentKeys2) { // Confirm that key2 and key1 are indeed EqualsIgnoringInstanceLocation // This ensures that we handle hash code clashes of EqualsIgnoringInstanceLocationId. if (!key1.EqualsIgnoringInstanceLocation(key2)) { continue; } TValue value2 = map2[key2]; TValue mergedValue = ValueDomain.Merge(value1, value2); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); if (key1.InstanceLocation.Equals(key2.InstanceLocation)) { AssertValidEntryForMergedMap(key1, mergedValue); resultMap[key1] = mergedValue; } else { if (key1.SymbolOpt == null || key1.SymbolOpt != key2.SymbolOpt) { // PERF: Do not add a new key-value pair to the resultMap for unrelated entities or non-symbol based entities. continue; } AnalysisEntity mergedKey = key1.WithMergedInstanceLocation(key2); TValue newMergedValue = mergedValue; var isExistingKeyInInput = false; var isExistingKeyInResult = false; if (resultMap.TryGetValue(mergedKey, out var existingValue)) { newMergedValue = ValueDomain.Merge(newMergedValue, existingValue); isExistingKeyInResult = true; } if (map1.TryGetValue(mergedKey, out existingValue)) { newMergedValue = ValueDomain.Merge(newMergedValue, existingValue); isExistingKeyInInput = true; } if (map2.TryGetValue(mergedKey, out existingValue)) { newMergedValue = ValueDomain.Merge(newMergedValue, existingValue); isExistingKeyInInput = true; } Debug.Assert(ValueDomain.Compare(value1, newMergedValue) <= 0); Debug.Assert(ValueDomain.Compare(value2, newMergedValue) <= 0); Debug.Assert(ValueDomain.Compare(mergedValue, newMergedValue) <= 0); mergedValue = newMergedValue; if (!isExistingKeyInInput && !isExistingKeyInResult && CanSkipNewEntry(mergedKey, mergedValue)) { // PERF: Do not add a new key-value pair to the resultMap if the value can be skipped. continue; } if (!isExistingKeyInInput) { newKeys.Add(mergedKey); } AssertValidEntryForMergedMap(mergedKey, mergedValue); resultMap[mergedKey] = mergedValue; } } } else if (map2.TryGetValue(key1, out var value2)) { TValue mergedValue = ValueDomain.Merge(value1, value2); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); resultMap.Add(key1, mergedValue); continue; } if (!resultMap.ContainsKey(key1)) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); AssertValidEntryForMergedMap(key1, mergedValue); resultMap.Add(key1, mergedValue); } } foreach (var kvp in map2) { var key2 = kvp.Key; var value2 = kvp.Value; if (!resultMap.ContainsKey(key2)) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key2, value2); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); AssertValidEntryForMergedMap(key2, mergedValue); resultMap.Add(key2, mergedValue); } } foreach (var newKey in newKeys) { Debug.Assert(!map1.ContainsKey(newKey)); Debug.Assert(!map2.ContainsKey(newKey)); if (ReferenceEquals(resultMap[newKey], GetDefaultValue(newKey))) { resultMap.Remove(newKey); } } newKeys.Free(); Debug.Assert(Compare(map1, resultMap) <= 0); Debug.Assert(Compare(map2, resultMap) <= 0); AssertValidAnalysisData(resultMap); return(resultMap); bool IsAnalysisEntityForFieldOrProperty(AnalysisEntity entity) => entity.SymbolOpt?.Kind == SymbolKind.Field || entity.SymbolOpt?.Kind == SymbolKind.Property; }
protected AnalysisEntityBasedPredicateAnalysisData() { CoreAnalysisData = new DictionaryAnalysisData <AnalysisEntity, TValue>(); }
protected AnalysisEntityBasedPredicateAnalysisData(AnalysisEntityBasedPredicateAnalysisData <TValue> fromData) : base(fromData) { CoreAnalysisData = new DictionaryAnalysisData <AnalysisEntity, TValue>(fromData.CoreAnalysisData); }
private void EnsurePredicatedData() { _lazyPredicateDataMap = _lazyPredicateDataMap ?? new DictionaryAnalysisData <AnalysisEntity, PerEntityPredicatedAnalysisData>(); }
public override DictionaryAnalysisData <AnalysisEntity, TValue> Merge(DictionaryAnalysisData <AnalysisEntity, TValue> map1, DictionaryAnalysisData <AnalysisEntity, TValue> map2) { AssertValidAnalysisData(map1); AssertValidAnalysisData(map2); var resultMap = new DictionaryAnalysisData <AnalysisEntity, TValue>(); using var newKeys = PooledHashSet <AnalysisEntity> .GetInstance(); using var valuesToMergeBuilder = ArrayBuilder <TValue> .GetInstance(5); var map2LookupIgnoringInstanceLocation = map2.Keys.Where(IsAnalysisEntityForFieldOrProperty) .ToLookup(entity => entity.EqualsIgnoringInstanceLocationId); foreach (var entry1 in map1) { AnalysisEntity key1 = entry1.Key; TValue value1 = entry1.Value; if (map2LookupIgnoringInstanceLocation.Count > 0 && IsAnalysisEntityForFieldOrProperty(key1)) { var equivalentKeys2 = map2LookupIgnoringInstanceLocation[key1.EqualsIgnoringInstanceLocationId]; if (!equivalentKeys2.Any()) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1); Debug.Assert(!map2.ContainsKey(key1)); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); AddNewEntryToResultMap(key1, mergedValue); continue; } foreach (AnalysisEntity key2 in equivalentKeys2) { // Confirm that key2 and key1 are indeed EqualsIgnoringInstanceLocation // This ensures that we handle hash code clashes of EqualsIgnoringInstanceLocationId. if (!key1.EqualsIgnoringInstanceLocation(key2)) { continue; } TValue value2 = map2[key2]; valuesToMergeBuilder.Clear(); valuesToMergeBuilder.Add(value1); valuesToMergeBuilder.Add(value2); if (key1.InstanceLocation.Equals(key2.InstanceLocation)) { var mergedValue = GetMergedValue(valuesToMergeBuilder); AddNewEntryToResultMap(key1, mergedValue); } else { if (key1.SymbolOpt == null || !Equals(key1.SymbolOpt, key2.SymbolOpt)) { // PERF: Do not add a new key-value pair to the resultMap for unrelated entities or non-symbol based entities. continue; } AnalysisEntity mergedKey = key1.WithMergedInstanceLocation(key2); var isExistingKeyInInput = false; var isExistingKeyInResult = false; if (resultMap.TryGetValue(mergedKey, out var existingValue)) { valuesToMergeBuilder.Add(existingValue); isExistingKeyInResult = true; } if (map1.TryGetValue(mergedKey, out existingValue)) { valuesToMergeBuilder.Add(existingValue); isExistingKeyInInput = true; } if (map2.TryGetValue(mergedKey, out existingValue)) { valuesToMergeBuilder.Add(existingValue); isExistingKeyInInput = true; } var isCandidateToBeSkipped = !isExistingKeyInInput && !isExistingKeyInResult; if (isCandidateToBeSkipped && CanSkipNewEntity(mergedKey)) { // PERF: Do not add a new key-value pair to the resultMap if the key is not reachable from tracked entities and PointsTo values. continue; } var mergedValue = GetMergedValue(valuesToMergeBuilder); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); if (isCandidateToBeSkipped && CanSkipNewEntry(mergedKey, mergedValue)) { // PERF: Do not add a new key-value pair to the resultMap if the value can be skipped. continue; } if (!isExistingKeyInInput) { newKeys.Add(mergedKey); } AddNewEntryToResultMap(mergedKey, mergedValue, isNewKey: !isExistingKeyInInput); } } } else if (map2.TryGetValue(key1, out var value2)) { TValue mergedValue = ValueDomain.Merge(value1, value2); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); AddNewEntryToResultMap(key1, mergedValue); continue; } if (!resultMap.ContainsKey(key1)) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1); Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0); AddNewEntryToResultMap(key1, mergedValue); } } foreach (var kvp in map2) { var key2 = kvp.Key; var value2 = kvp.Value; if (!resultMap.ContainsKey(key2)) { TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key2, value2); Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0); AddNewEntryToResultMap(key2, mergedValue); } } foreach (var newKey in newKeys) { Debug.Assert(!map1.ContainsKey(newKey)); Debug.Assert(!map2.ContainsKey(newKey)); var value = resultMap[newKey]; if (ReferenceEquals(value, GetDefaultValue(newKey))) { resultMap.Remove(newKey); } else { OnNewMergedValue(value); } } Debug.Assert(Compare(map1, resultMap) <= 0); Debug.Assert(Compare(map2, resultMap) <= 0); AssertValidAnalysisData(resultMap); return(resultMap);
#pragma warning restore CA1030 // Use events where appropriate public override DictionaryAnalysisData <TKey, TValue> Merge(DictionaryAnalysisData <TKey, TValue> value1, DictionaryAnalysisData <TKey, TValue> value2) { Debug.Assert(value1 != null); Debug.Assert(value2 != null); var result = new DictionaryAnalysisData <TKey, TValue>(value1); foreach (var entry in value2) { if (result.TryGetValue(entry.Key, out TValue value)) { value = ValueDomain.Merge(value, entry.Value); if (value != null) { result[entry.Key] = value; } else { result.Remove(entry.Key); } } else { result.Add(entry.Key, entry.Value); } } return(result); }
/// <summary> /// Compares if the abstract dataflow values in <paramref name="oldValue"/> against the values in <paramref name="newValue"/> to ensure /// dataflow function is a monotically increasing function. See https://en.wikipedia.org/wiki/Monotonic_function for understanding monotonic functions. /// </summary> /// <returns> /// 1) 0, if both the dictionaries are identical. /// 2) -1, if dictionaries are not identical and for every key in <paramref name="oldValue"/>, the corresponding key exists in <paramref name="newValue"/> and /// the value of each such key in <paramref name="oldValue"/> is lesser than or equals the value in <paramref name="newValue"/>. /// 3) 1, otherwise. /// </returns> public sealed override int Compare(DictionaryAnalysisData <TKey, TValue> oldValue, DictionaryAnalysisData <TKey, TValue> newValue) => Compare(oldValue, newValue, assertMonotonicity: true);
protected PredicatedAnalysisData(PredicatedAnalysisData <TKey, TValue> fromData) { IsReachableBlockData = fromData.IsReachableBlockData; _lazyPredicateDataMap = Clone(fromData._lazyPredicateDataMap); AssertValidAnalysisData(); }
public sealed override bool Equals(DictionaryAnalysisData <TKey, TValue> value1, DictionaryAnalysisData <TKey, TValue> value2) => Compare(value1, value2, assertMonotonicity: false) == 0;
protected void ApplyMissingCurrentAnalysisDataForUnhandledExceptionData( DictionaryAnalysisData <AbstractLocation, TAbstractAnalysisValue> coreDataAtException, DictionaryAnalysisData <AbstractLocation, TAbstractAnalysisValue> coreCurrentAnalysisData) { base.ApplyMissingCurrentAnalysisDataForUnhandledExceptionData(coreDataAtException, coreCurrentAnalysisData, predicateOpt: null); }
public override DictionaryAnalysisData <TKey, TValue> Clone(DictionaryAnalysisData <TKey, TValue> value) => new(value);
protected virtual void RemoveEntryInPredicatedData(TKey key, DictionaryAnalysisData <TKey, TValue> predicatedData) { predicatedData.Remove(key); }
protected virtual void ApplyPredicatedData(DictionaryAnalysisData <TKey, TValue> coreAnalysisData, DictionaryAnalysisData <TKey, TValue> predicatedData) { Debug.Assert(coreAnalysisData != null); Debug.Assert(predicatedData != null); foreach (var kvp in predicatedData) { coreAnalysisData[kvp.Key] = kvp.Value; } }