public PointsToAnalysisData MergeAnalysisDataForBackEdge(PointsToAnalysisData forwardEdgeAnalysisData, PointsToAnalysisData backEdgeAnalysisData, Func <PointsToAbstractValue, IEnumerable <AnalysisEntity> > getChildAnalysisEntities) { Debug.Assert(forwardEdgeAnalysisData != null); Debug.Assert(backEdgeAnalysisData != null); // Stop tracking points to values present in both branches if their is an assignment to a may-be null value from the back edge. // Clone the input forwardEdgeAnalysisData to ensure we don't overwrite the input dictionary. forwardEdgeAnalysisData = new Dictionary <AnalysisEntity, PointsToAbstractValue>(forwardEdgeAnalysisData); List <AnalysisEntity> keysInMap1 = forwardEdgeAnalysisData.Keys.ToList(); foreach (var key in keysInMap1) { var forwardEdgeValue = forwardEdgeAnalysisData[key]; if (backEdgeAnalysisData.TryGetValue(key, out var backEdgeValue) && backEdgeValue != forwardEdgeValue) { switch (backEdgeValue.NullState) { case NullAbstractValue.MaybeNull: StopTrackingAnalysisDataForKey(); break; case NullAbstractValue.NotNull: if (backEdgeValue.MakeMayBeNull() != forwardEdgeAnalysisData[key]) { StopTrackingAnalysisDataForKey(); } break; } void StopTrackingAnalysisDataForKey() { var childEntities = getChildAnalysisEntities(forwardEdgeValue) .Union(getChildAnalysisEntities(backEdgeValue)); foreach (var childEntity in childEntities) { forwardEdgeAnalysisData[childEntity] = PointsToAbstractValue.Unknown; } forwardEdgeAnalysisData[key] = PointsToAbstractValue.Unknown; } } } var resultMap = Merge(forwardEdgeAnalysisData, backEdgeAnalysisData); Debug.Assert(Compare(forwardEdgeAnalysisData, resultMap) <= 0); Debug.Assert(Compare(backEdgeAnalysisData, resultMap) <= 0); return(resultMap); }
public PointsToAnalysisData MergeAnalysisDataForBackEdge(PointsToAnalysisData map1, PointsToAnalysisData map2) { // Stop tracking points to values present in both branches. List <AnalysisEntity> keysInMap1 = map1.Keys.ToList(); foreach (var key in keysInMap1) { if (map2.TryGetValue(key, out var value2) && value2 != map1[key]) { map1[key] = PointsToAbstractValue.Unknown; } } return(Merge(map1, map2)); }