예제 #1
0
        // 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);
        }
예제 #2
0
        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);
        }