public void SetAnalysisDataFrom(BasicBlockAnalysisData other)
            {
                if (ReferenceEquals(this, other))
                {
                    return;
                }

                FreeAndClearValues();
                AddEntries(_reachingWrites, other);
            }
            public static BasicBlockAnalysisData Merge(
                BasicBlockAnalysisData data1,
                BasicBlockAnalysisData data2,
                Action <BasicBlockAnalysisData> trackAllocatedData)
            {
                // Ensure that we don't return 'null' data if other the other data is non-null,
                // even if latter is Empty.
                if (data1 == null)
                {
                    return(data2);
                }
                else if (data2 == null)
                {
                    return(data1);
                }
                else if (data1.IsEmpty)
                {
                    return(data2);
                }
                else if (data2.IsEmpty)
                {
                    return(data1);
                }
                else if (data1.Equals(data2))
                {
                    return(data1);
                }

                var mergedData = GetInstance();

                AddEntries(mergedData._reachingWrites, data1);
                AddEntries(mergedData._reachingWrites, data2);

                if (mergedData.Equals(data1))
                {
                    mergedData.Dispose();
                    return(data1);
                }
                else if (mergedData.Equals(data2))
                {
                    mergedData.Dispose();
                    return(data2);
                }

                trackAllocatedData(mergedData);
                return(mergedData);
            }
            public bool Equals(BasicBlockAnalysisData other)
            {
                // Check if both _reachingWrites maps have same key-value pair count.
                if (other == null ||
                    other._reachingWrites.Count != _reachingWrites.Count)
                {
                    return(false);
                }

                var uniqueSymbols = PooledHashSet <ISymbol> .GetInstance();

                try
                {
                    // Check if both _reachingWrites maps have same set of keys.
                    uniqueSymbols.AddRange(_reachingWrites.Keys);
                    uniqueSymbols.AddRange(other._reachingWrites.Keys);
                    if (uniqueSymbols.Count != _reachingWrites.Count)
                    {
                        return(false);
                    }

                    // Check if both _reachingWrites maps have same set of write
                    // operations for each tracked symbol.
                    foreach (var symbol in uniqueSymbols)
                    {
                        var writes1 = _reachingWrites[symbol];
                        var writes2 = other._reachingWrites[symbol];
                        if (!writes1.SetEquals(writes2))
                        {
                            return(false);
                        }
                    }

                    return(true);
                }
                finally
                {
                    uniqueSymbols.Free();
                }
            }
            public static BasicBlockAnalysisData Merge(
                BasicBlockAnalysisData data1,
                BasicBlockAnalysisData data2,
                Func <BasicBlockAnalysisData> createBasicBlockAnalysisData)
            {
                // Ensure that we don't return 'null' data if other the other data is non-null,
                // even if latter is Empty.
                if (data1 == null)
                {
                    return(data2);
                }
                else if (data2 == null)
                {
                    return(data1);
                }
                else if (data1.IsEmpty)
                {
                    return(data2);
                }
                else if (data2.IsEmpty)
                {
                    return(data1);
                }

                var mergedData = createBasicBlockAnalysisData();

                AddEntries(mergedData._reachingWrites, data1);
                AddEntries(mergedData._reachingWrites, data2);

                if (mergedData.Equals(data1))
                {
                    return(data1);
                }
                else if (mergedData.Equals(data2))
                {
                    return(data2);
                }

                return(mergedData);
            }
            private static void AddEntries(Dictionary <ISymbol, PooledHashSet <IOperation> > result, BasicBlockAnalysisData source)
            {
                if (source != null)
                {
                    foreach (var kvp in source._reachingWrites)
                    {
                        if (!result.TryGetValue(kvp.Key, out var values))
                        {
                            values = PooledHashSet <IOperation> .GetInstance();

                            result.Add(kvp.Key, values);
                        }

                        values.AddRange(kvp.Value);
                    }
                }
            }