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;
                    }
                }
            }
        }
Exemplo n.º 2
0
            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);
        }