Пример #1
0
        // node id, var, version
        //private HashMap<String, HashMap<Integer, FastSet<Integer>>> inVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>();
        // node id, var, version (direct branch)
        //private HashMap<String, HashMap<Integer, FastSet<Integer>>> outVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>();
        // node id, var, version (negative branch)
        //private HashMap<String, HashMap<Integer, FastSet<Integer>>> outNegVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>();
        // node id, var, version
        //private HashMap<String, HashMap<Integer, FastSet<Integer>>> extraVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>();
        // var, version
        // version, protected ranges (catch, finally)
        // version, version
        // ++ and --
        // node.id, version, version
        // finally exits
        // versions memory dependencies
        // field access vars (exprent id, var id)
        // field access counter
        // set factory
        public virtual void SplitVariables(RootStatement root, StructMethod mt)
        {
            FlattenStatementsHelper flatthelper = new FlattenStatementsHelper();
            DirectGraph             dgraph      = flatthelper.BuildDirectGraph(root);
            HashSet <int>           setInit     = new HashSet <int>();

            for (int i = 0; i < 64; i++)
            {
                setInit.Add(i);
            }
            factory = new FastSparseSetFactory <int>(setInit);
            Sharpen.Collections.Put(extraVarVersions, dgraph.first.id, CreateFirstMap(mt, root
                                                                                      ));
            SetCatchMaps(root, dgraph, flatthelper);
            //		try {
            //			DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr12_my.dot"));
            //		} catch(Exception ex) {ex.printStackTrace();}
            HashSet <string> updated = new HashSet <string>();

            do
            {
                //			System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava());
                SsaStatements(dgraph, updated, false);
            }while (!(updated.Count == 0));
            //			System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava());
            SsaStatements(dgraph, updated, true);
            ssuversions.InitDominators();
        }
Пример #2
0
        private void MergeInVarMaps(DirectNode node, DirectGraph dgraph)
        {
            SFormsFastMapDirect mapNew = new SFormsFastMapDirect();

            foreach (DirectNode pred in node.preds)
            {
                SFormsFastMapDirect mapOut = GetFilteredOutMap(node.id, pred.id, dgraph, node.id);
                if (mapNew.IsEmpty())
                {
                    mapNew = mapOut.GetCopy();
                }
                else
                {
                    MergeMaps(mapNew, mapOut);
                }
            }
            if (extraVarVersions.ContainsKey(node.id))
            {
                SFormsFastMapDirect mapExtra = extraVarVersions.GetOrNull(node.id);
                if (mapNew.IsEmpty())
                {
                    mapNew = mapExtra.GetCopy();
                }
                else
                {
                    MergeMaps(mapNew, mapExtra);
                }
            }
            Sharpen.Collections.Put(inVarVersions, node.id, mapNew);
        }
 // System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava());
 private void SsaStatements(DirectGraph dgraph, HashSet <string> updated)
 {
     // try {
     // DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr1_my.dot"));
     // } catch(Exception ex) {ex.printStackTrace();}
     foreach (DirectNode node in dgraph.nodes)
     {
         //			if (node.id.endsWith("_inc")) {
         //				System.out.println();
         //
         //				try {
         //					DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr1_my.dot"));
         //				} catch (Exception ex) {
         //					ex.printStackTrace();
         //				}
         //			}
         updated.Remove(node.id);
         MergeInVarMaps(node, dgraph);
         SFormsFastMapDirect varmap = inVarVersions.GetOrNull(node.id);
         varmap = new SFormsFastMapDirect(varmap);
         SFormsFastMapDirect[] varmaparr = new SFormsFastMapDirect[] { varmap, null };
         if (node.exprents != null)
         {
             foreach (Exprent expr in node.exprents)
             {
                 ProcessExprent(expr, varmaparr);
             }
         }
         if (varmaparr[1] == null)
         {
             varmaparr[1] = varmaparr[0];
         }
         bool this_updated = !MapsEqual(varmaparr[0], outVarVersions.GetOrNull(node.id)) ||
                             (outNegVarVersions.ContainsKey(node.id) && !MapsEqual(varmaparr[1], outNegVarVersions
                                                                                   .GetOrNull(node.id)));
         if (this_updated)
         {
             Sharpen.Collections.Put(outVarVersions, node.id, varmaparr[0]);
             if (dgraph.mapNegIfBranch.ContainsKey(node.id))
             {
                 Sharpen.Collections.Put(outNegVarVersions, node.id, varmaparr[1]);
             }
             foreach (DirectNode nd in node.succs)
             {
                 updated.Add(nd.id);
             }
         }
     }
 }
Пример #4
0
 private void SsaStatements(DirectGraph dgraph, HashSet <string> updated, bool calcLiveVars
                            )
 {
     foreach (DirectNode node in dgraph.nodes)
     {
         updated.Remove(node.id);
         MergeInVarMaps(node, dgraph);
         SFormsFastMapDirect varmap = new SFormsFastMapDirect(inVarVersions.GetOrNull(node
                                                                                      .id));
         SFormsFastMapDirect[] varmaparr = new SFormsFastMapDirect[] { varmap, null };
         if (node.exprents != null)
         {
             foreach (Exprent expr in node.exprents)
             {
                 ProcessExprent(expr, varmaparr, node.statement, calcLiveVars);
             }
         }
         if (varmaparr[1] == null)
         {
             varmaparr[1] = varmaparr[0];
         }
         // quick solution: 'dummy' field variables should not cross basic block borders (otherwise problems e.g. with finally loops - usage without assignment in a loop)
         // For the full solution consider adding a dummy assignment at the entry point of the method
         bool allow_field_propagation = (node.succs.Count == 0) || (node.succs.Count == 1 &&
                                                                    node.succs[0].preds.Count == 1);
         if (!allow_field_propagation && varmaparr[0] != null)
         {
             varmaparr[0].RemoveAllFields();
             varmaparr[1].RemoveAllFields();
         }
         bool this_updated = !MapsEqual(varmaparr[0], outVarVersions.GetOrNull(node.id)) ||
                             (outNegVarVersions.ContainsKey(node.id) && !MapsEqual(varmaparr[1], outNegVarVersions
                                                                                   .GetOrNull(node.id)));
         if (this_updated)
         {
             Sharpen.Collections.Put(outVarVersions, node.id, varmaparr[0]);
             if (dgraph.mapNegIfBranch.ContainsKey(node.id))
             {
                 Sharpen.Collections.Put(outNegVarVersions, node.id, varmaparr[1]);
             }
             foreach (DirectNode nd in node.succs)
             {
                 updated.Add(nd.id);
             }
         }
     }
 }
Пример #5
0
        // statement.id, node.id(direct), node.id(continue)
        // node.id(source), statement.id(destination), edge type
        // node.id(exit), [node.id(source), statement.id(destination)]
        // node.id(exit), [node.id(source), statement.id(destination)]
        // positive if branches
        public virtual DirectGraph BuildDirectGraph(RootStatement root)
        {
            this.root = root;
            graph     = new DirectGraph();
            FlattenStatement();
            // dummy exit node
            Statement  dummyexit = root.GetDummyExit();
            DirectNode node      = new DirectNode(DirectNode.Node_Direct, dummyexit, dummyexit.id.
                                                  ToString());

            node.exprents = new List <Exprent>();
            graph.nodes.AddWithKey(node, node.id);
            Sharpen.Collections.Put(mapDestinationNodes, dummyexit.id, new string[] { node.id
                                                                                      , null });
            SetEdges();
            graph.first = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(root.id)[0]);
            graph.SortReversePostOrder();
            return(graph);
        }
Пример #6
0
        private void SetCatchMaps(Statement stat, DirectGraph dgraph, FlattenStatementsHelper
                                  flatthelper)
        {
            SFormsFastMapDirect map;

            switch (stat.type)
            {
            case Statement.Type_Catchall:
            case Statement.Type_Trycatch:
            {
                List <VarExprent> lstVars;
                if (stat.type == Statement.Type_Catchall)
                {
                    lstVars = ((CatchAllStatement)stat).GetVars();
                }
                else
                {
                    lstVars = ((CatchStatement)stat).GetVars();
                }
                for (int i = 1; i < stat.GetStats().Count; i++)
                {
                    int varindex = lstVars[i - 1].GetIndex();
                    int version  = GetNextFreeVersion(varindex, stat);
                    // == 1
                    map = new SFormsFastMapDirect();
                    SetCurrentVar(map, varindex, version);
                    Sharpen.Collections.Put(extraVarVersions, dgraph.nodes.GetWithKey(flatthelper.GetMapDestinationNodes
                                                                                          ().GetOrNull(stat.GetStats()[i].id)[0]).id, map);
                    //ssuversions.createOrGetNode(new VarVersionPair(varindex, version));
                    ssuversions.CreateNode(new VarVersionPair(varindex, version));
                }
                break;
            }
            }
            foreach (Statement st in stat.GetStats())
            {
                SetCatchMaps(st, dgraph, flatthelper);
            }
        }
Пример #7
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);
        }
        private SFormsFastMapDirect GetFilteredOutMap(string nodeid, string predid, DirectGraph
                                                      dgraph, string destid)
        {
            SFormsFastMapDirect mapNew = new SFormsFastMapDirect();

            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();
            }
            bool isFinallyExit = dgraph.mapShortRangeFinallyPaths.ContainsKey(predid);

            if (isFinallyExit && !mapNew.IsEmpty())
            {
                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 (FlattenStatementsHelper.FinallyPathWrapper finwraplong in dgraph.mapLongRangeFinallyPaths
                         .GetOrNull(predid))
                {
                    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);
                    SFormsFastMapDirect oldInMap = inVarVersions.GetOrNull(nodeid);
                    if (oldInMap != null)
                    {
                        mapNewTemp.Union(oldInMap);
                    }
                    mapNew.Intersection(mapNewTemp);
                }
            }
            return(mapNew);
        }