// 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(); }
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); } } } }
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); } } } }
// 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); }
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); } }
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); }