Beispiel #1
0
 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;
 }
Beispiel #2
0
        /// <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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
        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();
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
 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();
 }
Beispiel #8
0
        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);
        }
Beispiel #9
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)));
        }
Beispiel #10
0
            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);
                }
            }
Beispiel #11
0
        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();
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        protected void ResetPredicatedData()
        {
            if (_lazyPredicateDataMap == null)
            {
                return;
            }

            if (!_lazyPredicateDataMap.IsDisposed)
            {
                _lazyPredicateDataMap.Values.Dispose();
                _lazyPredicateDataMap.Dispose();
            }

            Debug.Assert(_lazyPredicateDataMap.IsDisposed);
            _lazyPredicateDataMap = null;
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        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));
        }
Beispiel #18
0
        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;
        }
Beispiel #19
0
 protected AnalysisEntityBasedPredicateAnalysisData()
 {
     CoreAnalysisData = new DictionaryAnalysisData <AnalysisEntity, TValue>();
 }
Beispiel #20
0
 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);
Beispiel #23
0
#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);
        }
Beispiel #24
0
 /// <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);
Beispiel #25
0
 protected PredicatedAnalysisData(PredicatedAnalysisData <TKey, TValue> fromData)
 {
     IsReachableBlockData  = fromData.IsReachableBlockData;
     _lazyPredicateDataMap = Clone(fromData._lazyPredicateDataMap);
     AssertValidAnalysisData();
 }
Beispiel #26
0
 public sealed override bool Equals(DictionaryAnalysisData <TKey, TValue> value1, DictionaryAnalysisData <TKey, TValue> value2)
 => Compare(value1, value2, assertMonotonicity: false) == 0;
Beispiel #27
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);
Beispiel #29
0
 protected virtual void RemoveEntryInPredicatedData(TKey key, DictionaryAnalysisData <TKey, TValue> predicatedData)
 {
     predicatedData.Remove(key);
 }
Beispiel #30
0
        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;
            }
        }