// vers.size() == 0 means uninitialized variable, which is impossible private void CreateOrUpdatePhiNode(VarVersionPair phivar, FastSparseSetFactory <int> .FastSparseSet <int> vers, Statement stat) { FastSparseSetFactory <int> .FastSparseSet <int> versCopy = vers.GetCopy(); HashSet <int> phiVers = new HashSet <int>(); // take into account the corresponding mm/pp node if existing int ppvers = phantomppnodes.ContainsKey(phivar) ? phantomppnodes.GetOrNull(phivar ).version : -1; // ssu graph VarVersionNode phinode = ssuversions.nodes.GetWithKey(phivar); List <VarVersionEdge> lstPreds = new List <VarVersionEdge>(phinode.preds); if (lstPreds.Count == 1) { // not yet a phi node VarVersionEdge edge = lstPreds[0]; edge.source.RemoveSuccessor(edge); phinode.RemovePredecessor(edge); } else { foreach (VarVersionEdge edge in lstPreds) { int verssrc = new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version; if (!vers.Contains(verssrc) && verssrc != ppvers) { edge.source.RemoveSuccessor(edge); phinode.RemovePredecessor(edge); } else { versCopy.Remove(verssrc); phiVers.Add(verssrc); } } } List <VarVersionNode> colnodes = new List <VarVersionNode>(); List <VarVersionPair> colpaars = new List <VarVersionPair>(); foreach (int ver in versCopy) { VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(phivar.var , ver)); int tempver = GetNextFreeVersion(phivar.var, stat); VarVersionNode tempnode = new VarVersionNode(phivar.var, tempver); colnodes.Add(tempnode); colpaars.Add(new VarVersionPair(phivar.var, tempver)); VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, tempnode ); prenode.AddSuccessor(edge); tempnode.AddPredecessor(edge); edge = new VarVersionEdge(VarVersionEdge.Edge_General, tempnode, phinode); tempnode.AddSuccessor(edge); phinode.AddPredecessor(edge); phiVers.Add(tempver); } ssuversions.AddNodes(colnodes, colpaars); }
private SFormsFastMapDirect GetFilteredOutMap(string nodeid, string predid, DirectGraph dgraph, string destid) { SFormsFastMapDirect mapNew = new SFormsFastMapDirect(); bool isFinallyExit = dgraph.mapShortRangeFinallyPaths.ContainsKey(predid); if (nodeid.Equals(dgraph.mapNegIfBranch.GetOrNull(predid))) { if (outNegVarVersions.ContainsKey(predid)) { mapNew = outNegVarVersions.GetOrNull(predid).GetCopy(); } } else if (outVarVersions.ContainsKey(predid)) { mapNew = outVarVersions.GetOrNull(predid).GetCopy(); } if (isFinallyExit) { SFormsFastMapDirect mapNewTemp = mapNew.GetCopy(); SFormsFastMapDirect mapTrueSource = new SFormsFastMapDirect(); string exceptionDest = dgraph.mapFinallyMonitorExceptionPathExits.GetOrNull(predid ); bool isExceptionMonitorExit = (exceptionDest != null && !nodeid.Equals(exceptionDest )); HashSet <string> setLongPathWrapper = new HashSet <string>(); foreach (List <FlattenStatementsHelper.FinallyPathWrapper> lstwrapper in dgraph.mapLongRangeFinallyPaths .Values) { foreach (FlattenStatementsHelper.FinallyPathWrapper finwraplong in lstwrapper) { setLongPathWrapper.Add(finwraplong.destination + "##" + finwraplong.source); } } foreach (FlattenStatementsHelper.FinallyPathWrapper finwrap in dgraph.mapShortRangeFinallyPaths .GetOrNull(predid)) { SFormsFastMapDirect map; bool recFinally = dgraph.mapShortRangeFinallyPaths.ContainsKey(finwrap.source); if (recFinally) { // recursion map = GetFilteredOutMap(finwrap.entry, finwrap.source, dgraph, destid); } else if (finwrap.entry.Equals(dgraph.mapNegIfBranch.GetOrNull(finwrap.source))) { map = outNegVarVersions.GetOrNull(finwrap.source); } else { map = outVarVersions.GetOrNull(finwrap.source); } // false path? bool isFalsePath; if (recFinally) { isFalsePath = !finwrap.destination.Equals(nodeid); } else { isFalsePath = !setLongPathWrapper.Contains(destid + "##" + finwrap.source); } if (isFalsePath) { mapNewTemp.Complement(map); } else if (mapTrueSource.IsEmpty()) { if (map != null) { mapTrueSource = map.GetCopy(); } } else { MergeMaps(mapTrueSource, map); } } if (isExceptionMonitorExit) { mapNew = mapTrueSource; } else { mapNewTemp.Union(mapTrueSource); mapNew.Intersection(mapNewTemp); if (!mapTrueSource.IsEmpty() && !mapNew.IsEmpty()) { // FIXME: what for?? // replace phi versions with corresponding phantom ones Dictionary <VarVersionPair, VarVersionPair> mapPhantom = phantomexitnodes.GetOrNull (predid); if (mapPhantom == null) { mapPhantom = new Dictionary <VarVersionPair, VarVersionPair>(); } SFormsFastMapDirect mapExitVar = mapNew.GetCopy(); mapExitVar.Complement(mapTrueSource); foreach (KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > ent in mapExitVar .EntryList()) { foreach (int version in ent.Value) { int varindex = ent.Key; VarVersionPair exitvar = new VarVersionPair(varindex, version); FastSparseSetFactory <int> .FastSparseSet <int> newSet = mapNew.Get(varindex); // remove the actual exit version newSet.Remove(version); // get or create phantom version VarVersionPair phantomvar = mapPhantom.GetOrNull(exitvar); if (phantomvar == null) { int newversion = GetNextFreeVersion(exitvar.var, null); phantomvar = new VarVersionPair(exitvar.var, newversion); VarVersionNode exitnode = ssuversions.nodes.GetWithKey(exitvar); VarVersionNode phantomnode = ssuversions.CreateNode(phantomvar); phantomnode.flags |= VarVersionNode.Flag_Phantom_Finexit; VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_Phantom, exitnode, phantomnode ); exitnode.AddSuccessor(edge); phantomnode.AddPredecessor(edge); Sharpen.Collections.Put(mapPhantom, exitvar, phantomvar); } // add phantom version newSet.Add(phantomvar.version); } } if (!(mapPhantom.Count == 0)) { Sharpen.Collections.Put(phantomexitnodes, predid, mapPhantom); } } } } return(mapNew); }