--- /dev/null
+package Analysis.MLP;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import Analysis.OwnershipAnalysis.HeapRegionNode;
+import IR.Flat.FlatMethod;
+import IR.Flat.FlatSESEEnterNode;
+import IR.Flat.TempDescriptor;
+
+public class ConflictGraph {
+
+ public Hashtable<String, ConflictNode> td2cn;
+
+ public ConflictGraph() {
+ td2cn = new Hashtable<String, ConflictNode>();
+ }
+
+ public String addStallNode(TempDescriptor td, FlatMethod fm,
+ StallSite stallSite) {
+
+ String stallNodeID = td + "_" + fm.getMethod().getSymbol();
+
+ if (!td2cn.containsKey(stallNodeID)) {
+ StallSiteNode newNode = new StallSiteNode(stallNodeID, td,
+ stallSite);
+ td2cn.put(stallNodeID, newNode);
+ // it add new new stall node to conflict graph
+ return stallNodeID;
+ }
+ // it doesn't add new stall node because stall node has already been
+ // added.
+ return null;
+ }
+
+ public StallSiteNode getStallNode(String stallNodeID) {
+ ConflictNode node = td2cn.get(stallNodeID);
+ if (node instanceof StallSiteNode) {
+ return (StallSiteNode) node;
+ } else {
+ return null;
+ }
+ }
+
+ public void addLiveInNode(TempDescriptor td, FlatSESEEnterNode fsen,
+ Set<SESEEffectsKey> readEffectsSet,
+ Set<SESEEffectsKey> writeEffectsSet) {
+
+ String liveinNodeID = td + "_" + fsen.getIdentifier();
+
+ LiveInNode newNode = new LiveInNode(liveinNodeID, td, readEffectsSet,
+ writeEffectsSet);
+ td2cn.put(liveinNodeID, newNode);
+
+ }
+
+ public void addWriteConflictEdge(StallSiteNode stallNode,
+ LiveInNode liveInNode) {
+ ConflictEdge newEdge = new ConflictEdge(stallNode, liveInNode,
+ ConflictEdge.WRITE_CONFLICT);
+ stallNode.addEdge(newEdge);
+ liveInNode.addEdge(newEdge);
+ }
+
+ public HashSet<LiveInNode> getLiveInNodeSet() {
+ HashSet<LiveInNode> resultSet = new HashSet<LiveInNode>();
+
+ Set<String> keySet = td2cn.keySet();
+ for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+ String key = (String) iterator.next();
+ ConflictNode node = td2cn.get(key);
+
+ if (node instanceof LiveInNode) {
+ resultSet.add((LiveInNode) node);
+ }
+ }
+
+ return resultSet;
+ }
+
+ public void writeGraph(String graphName) throws java.io.IOException {
+
+ graphName = graphName.replaceAll("[\\W]", "");
+
+ BufferedWriter bw = new BufferedWriter(new FileWriter(graphName
+ + ".dot"));
+ bw.write("graph " + graphName + " {\n");
+
+ HashSet<HeapRegionNode> visited = new HashSet<HeapRegionNode>();
+ // then visit every heap region node
+ Set<Entry<String, ConflictNode>> s = td2cn.entrySet();
+ Iterator<Entry<String, ConflictNode>> i = s.iterator();
+
+ HashSet<ConflictEdge> addedSet=new HashSet<ConflictEdge>();
+
+ while (i.hasNext()) {
+ Entry<String, ConflictNode> entry = i.next();
+ ConflictNode node = entry.getValue();
+ String attributes = "[";
+
+ attributes += "label=\"ID" + node.getID() + "\\n";
+
+ if (node instanceof StallSiteNode) {
+ attributes += "STALL SITE" + "\\n" + "\"]";
+ } else {
+ attributes += "LIVE-IN" + "\\n" + "\"]";
+ }
+ bw.write(entry.getKey() + attributes + ";\n");
+
+ HashSet<ConflictEdge> edgeSet = node.getEdgeSet();
+ for (Iterator iterator = edgeSet.iterator(); iterator.hasNext();) {
+ ConflictEdge conflictEdge = (ConflictEdge) iterator.next();
+
+ ConflictNode u = conflictEdge.getVertexU();
+ ConflictNode v = conflictEdge.getVertexV();
+
+ if (conflictEdge.getType() == ConflictEdge.WRITE_CONFLICT) {
+ if(!addedSet.contains(conflictEdge)){
+ bw.write(" " + u.getID() + "--" + v.getID()
+ + "[label=\""
+ + conflictEdge.toGraphEdgeString()
+ + "\",decorate];\n");
+ addedSet.add(conflictEdge);
+ }
+ }
+ }
+ }
+
+ bw.write(" graphTitle[label=\"" + graphName + "\",shape=box];\n");
+
+ bw.write("}\n");
+ bw.close();
+
+ }
+
+}
+
+class ConflictEdge {
+
+ private ConflictNode u;
+ private ConflictNode v;
+ private int type;
+
+ public static final int WRITE_CONFLICT = 0;
+ public static final int REACH_CONFLICT = 1;
+
+ public ConflictEdge(ConflictNode u, ConflictNode v, int type) {
+ this.u = u;
+ this.v = v;
+ this.type = type;
+ }
+
+ public String toGraphEdgeString() {
+ if (type == WRITE_CONFLICT) {
+ return "W_CONFLICT";
+ } else {
+ return "R_CONFLICT";
+ }
+ }
+
+ public ConflictNode getVertexU() {
+ return u;
+ }
+
+ public ConflictNode getVertexV() {
+ return v;
+ }
+
+ public int getType(){
+ return type;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package Analysis.MLP;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import Analysis.OwnershipAnalysis.HeapRegionNode;
+import IR.Flat.TempDescriptor;
+
+public class LiveInNode extends ConflictNode {
+
+ Set<SESEEffectsKey> readEffectsSet;
+ Set<SESEEffectsKey> writeEffectsSet;
+
+ public LiveInNode(String id, TempDescriptor td,
+ Set<SESEEffectsKey> readEffectsSet,
+ Set<SESEEffectsKey> writeEffectsSet) {
+ this.id = id;
+ this.td = td;
+ this.readEffectsSet = readEffectsSet;
+ this.writeEffectsSet = writeEffectsSet;
+ }
+
+ public boolean isWriteConflictWith(StallSiteNode stallNode) {
+
+ // if live-in var has write-effects on heap region node of stall site,
+ // it is write conflict
+
+ boolean result = false;
+ StallSite stallSite = stallNode.getStallSite();
+
+ if (writeEffectsSet != null) {
+ Iterator<SESEEffectsKey> writeIter = writeEffectsSet.iterator();
+ while (writeIter.hasNext()) {
+ SESEEffectsKey seseEffectsKey = (SESEEffectsKey) writeIter
+ .next();
+ String writeHeapRegionID = seseEffectsKey.getHRNUniqueId();
+ String writeFieldName = seseEffectsKey.getFieldDescriptor();
+
+ HashSet<HeapRegionNode> stallSiteHRNSet = stallNode.getHRNSet();
+ for (Iterator iterator = stallSiteHRNSet.iterator(); iterator
+ .hasNext();) {
+ HeapRegionNode stallHRN = (HeapRegionNode) iterator.next();
+ if (stallHRN.getGloballyUniqueIdentifier().equals(
+ writeHeapRegionID)) {
+
+ // check whether there are read or write effects of
+ // stall sites
+
+ HashSet<Effect> effectSet = stallSite.getEffectSet();
+ for (Iterator iterator2 = effectSet.iterator(); iterator2
+ .hasNext();) {
+ Effect effect = (Effect) iterator2.next();
+ String stallEffectfieldName = effect.getField();
+
+ if (stallEffectfieldName.equals(writeFieldName)) {
+ result = result | true;
+ }
+ }
+
+ }
+ }
+
+ }
+ }
+
+ if (readEffectsSet != null) {
+ Iterator<SESEEffectsKey> readIter = readEffectsSet.iterator();
+ while (readIter.hasNext()) {
+
+ SESEEffectsKey seseEffectsKey = (SESEEffectsKey) readIter
+ .next();
+ String readHeapRegionID = seseEffectsKey.getHRNUniqueId();
+ String readFieldName = seseEffectsKey.getFieldDescriptor();
+
+ HashSet<HeapRegionNode> stallSiteHRNSet = stallNode.getHRNSet();
+ for (Iterator iterator = stallSiteHRNSet.iterator(); iterator
+ .hasNext();) {
+ HeapRegionNode stallHRN = (HeapRegionNode) iterator.next();
+ if (stallHRN.getGloballyUniqueIdentifier().equals(
+ readHeapRegionID)) {
+
+ HashSet<Effect> effectSet = stallSite.getEffectSet();
+ for (Iterator iterator2 = effectSet.iterator(); iterator2
+ .hasNext();) {
+ Effect effect = (Effect) iterator2.next();
+ String stallEffectfieldName = effect.getField();
+
+ if (effect.getEffectType().equals(
+ StallSite.WRITE_EFFECT)) {
+ if (stallEffectfieldName.equals(readFieldName)) {
+ result = result | true;
+ }
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+ }
+
+ return result;
+ }
+
+}
package Analysis.MLP;
-import Analysis.CallGraph.*;
-import Analysis.Liveness;
-import Analysis.OwnershipAnalysis.*;
-import IR.*;
-import IR.Flat.*;
-import IR.Tree.*;
-import java.util.*;
-import java.io.*;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+import java.util.Map.Entry;
+
+import Analysis.CallGraph.CallGraph;
+import Analysis.CallGraph.JavaCallGraph;
+import Analysis.OwnershipAnalysis.AllocationSite;
+import Analysis.OwnershipAnalysis.EffectsKey;
+import Analysis.OwnershipAnalysis.HeapRegionNode;
+import Analysis.OwnershipAnalysis.LabelNode;
+import Analysis.OwnershipAnalysis.MethodContext;
+import Analysis.OwnershipAnalysis.MethodEffects;
+import Analysis.OwnershipAnalysis.OwnershipAnalysis;
+import Analysis.OwnershipAnalysis.OwnershipGraph;
+import Analysis.OwnershipAnalysis.OwnershipNode;
+import Analysis.OwnershipAnalysis.ParameterDecomposition;
+import Analysis.OwnershipAnalysis.ReachabilitySet;
+import Analysis.OwnershipAnalysis.ReferenceEdge;
+import Analysis.OwnershipAnalysis.TokenTupleSet;
+import IR.Descriptor;
+import IR.FieldDescriptor;
+import IR.MethodDescriptor;
+import IR.Operation;
+import IR.State;
+import IR.TypeUtil;
+import IR.Flat.FKind;
+import IR.Flat.FlatCall;
+import IR.Flat.FlatEdge;
+import IR.Flat.FlatFieldNode;
+import IR.Flat.FlatMethod;
+import IR.Flat.FlatNew;
+import IR.Flat.FlatNode;
+import IR.Flat.FlatOpNode;
+import IR.Flat.FlatReturnNode;
+import IR.Flat.FlatSESEEnterNode;
+import IR.Flat.FlatSESEExitNode;
+import IR.Flat.FlatSetFieldNode;
+import IR.Flat.FlatWriteDynamicVarNode;
+import IR.Flat.TempDescriptor;
public class MLPAnalysis {
private Hashtable < FlatNode, ParentChildConflictsMap > conflictsResults;
private Hashtable< FlatMethod, MethodSummary > methodSummaryResults;
private OwnershipAnalysis ownAnalysisForSESEConflicts;
+ private Hashtable <FlatMethod, ConflictGraph> conflictGraphResults;
// temporal data structures to track analysis progress.
private MethodSummary currentMethodSummary;
conflictsResults = new Hashtable < FlatNode, ParentChildConflictsMap >();
methodSummaryResults=new Hashtable<FlatMethod, MethodSummary>();
+ conflictGraphResults=new Hashtable<FlatMethod, ConflictGraph>();
FlatMethod fmMain = state.getMethodFlat( typeUtil.getMain() );
System.err.println(e);
}
- postSESEConflictsForward(javaCallGraph);
+ // postSESEConflictsForward(javaCallGraph);
+ // another pass for making graph
+ methItr = ownAnalysis.descriptorsToAnalyze.iterator();
+ while (methItr.hasNext()) {
+ Descriptor d = methItr.next();
+ FlatMethod fm = state.getMethodFlat(d);
+ makeConflictGraph(fm);
+ }
+ methItr = ownAnalysis.descriptorsToAnalyze.iterator();
+ while(methItr.hasNext()){
+ Descriptor d = methItr.next();
+ FlatMethod fm = state.getMethodFlat(d);
+ if (fm.toString().indexOf("SomeWork") > 0) {
+ ConflictGraph conflictGraph=conflictGraphResults.get(fm);
+ try {
+ conflictGraph.writeGraph("ConflictGraphForSomeWork");
+ } catch (IOException e) {
+ System.out.println("Error writing");
+ System.exit(0);
+ }
+ }
+ }
+ ////////////////
// 7th pass
methItr = ownAnalysis.descriptorsToAnalyze.iterator();
FlatFieldNode ffn = (FlatFieldNode) fn;
TempDescriptor src = ffn.getSrc();
FieldDescriptor field = ffn.getField();
-
+
LabelNode srcLN = og.td2ln.get(src);
if (srcLN != null) {
HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(srcLN);
FlatSetFieldNode fsen = (FlatSetFieldNode) fn;
TempDescriptor dst = fsen.getDst();
FieldDescriptor field = fsen.getField();
-
+
LabelNode dstLN = og.td2ln.get(dst);
if (dstLN != null) {
+
// check possible strong updates
boolean strongUpdate = false;
private void postSESEConflictsForward(JavaCallGraph javaCallGraph) {
- // store the reachability set in stall site data structure
+ // store the reachability set in stall site data structure
Set methodCallSet = javaCallGraph.getAllMethods(typeUtil.getMain());
+
LinkedList<MethodDescriptor> sortedMethodCalls = topologicalSort(
methodCallSet, javaCallGraph);
MethodDescriptor md = (MethodDescriptor) iterator.next();
FlatMethod fm = state.getMethodFlat(md);
+ // create conflict graph for each flat method
+ ConflictGraph conflictGraph = new ConflictGraph();
+
HashSet<MethodContext> mcSet = ownAnalysis
.getAllMethodContextSetByDescriptor(md);
Iterator<MethodContext> mcIter = mcSet.iterator();
ParentChildConflictsMap currentConflictsMap = conflictsResults
.get(fn);
- postConflicts_nodeAction(mc, fn,
- currentConflictsMap);
+ //
+ Hashtable<TempDescriptor, StallSite> stallMap = currentConflictsMap
+ .getStallMap();
+ Set<Entry<TempDescriptor, StallSite>> entrySet = stallMap
+ .entrySet();
+ for (Iterator iterator2 = entrySet.iterator(); iterator2
+ .hasNext();) {
+ Entry<TempDescriptor, StallSite> entry = (Entry<TempDescriptor, StallSite>) iterator2
+ .next();
+ TempDescriptor td = entry.getKey();
+ StallSite stallSite = entry.getValue();
+ conflictGraph.addStallNode(td, fm, stallSite);
+ }
+ //
+
+ postConflicts_nodeAction(mc, fn, currentConflictsMap);
+
+ Set<TempDescriptor> tdSet = currentConflictsMap
+ .getStallMap().keySet();
+
+ // if(tdSet.size()>0){
+ // System.out.println("# of stalls="+tdSet.size());
+ // }
// if we have a new result, schedule forward nodes for
// analysis
flatNodesToVisit.add(nn);
}
}
-
}
-
}
-
+
+ conflictGraphResults.put(fm, conflictGraph);
+
}
+
+ for (Iterator iterator = sortedMethodCalls.iterator(); iterator
+ .hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator.next();
+ FlatMethod fm = state.getMethodFlat(md);
+ if (fm.toString().indexOf("SomeWork") > 0) {
+ ConflictGraph conflictGraph=conflictGraphResults.get(fm);
+ try {
+ conflictGraph.writeGraph("ConflictGraphForSomeWork");
+ } catch (IOException e) {
+ System.out.println("Error writing");
+ System.exit(0);
+ }
+ }
+ }
+
}
private void postConflicts_nodeAction(MethodContext mc, FlatNode fn,
TempDescriptor key = (TempDescriptor) iterator.next();
StallSite stallSite=stallMap.get(key);
+// System.out.println("stallSite="+stallSite);
+
Set<HeapRegionNode> hrnSet=stallSite.getHRNSet();
for (Iterator iterator2 = hrnSet.iterator(); iterator2.hasNext();) {
HeapRegionNode hrn = (HeapRegionNode) iterator2
.next();
-
- HeapRegionNode hrnOG=og.id2hrn.get(hrn.getID());
+
+ String uniqueHRNID=hrn.getGloballyUniqueIdentifier();
+ HeapRegionNode hrnOG=og.getHRNbyUniqueID(uniqueHRNID);
+
+// HeapRegionNode hrnOG=og.id2hrn.get(hrn.getID());
if(hrnOG!=null){
ReachabilitySet rSet=hrnOG.getAlpha();
Iterator<TokenTupleSet> ttIterator=rSet.iterator();
for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
TempDescriptor key = (TempDescriptor) iterator.next();
StallSite stallSite=stallMap.get(key);
+ HashSet<TokenTupleSet> rs=stallSite.getReachabilitySet();
+ Iterator iter=rs.iterator();
+ while (iter.hasNext()) {
+ TokenTupleSet tts = (TokenTupleSet) iter.next();
+// System.out.println("TTS="+tts);
+ }
+ }
+
+ }
+
+ private void makeConflictGraph(FlatMethod fm) {
+
+ // create conflict graph for each flat method
+ ConflictGraph conflictGraph = new ConflictGraph();
+
+ Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
+ flatNodesToVisit.add(fm);
+
+ Set<FlatNode> visited = new HashSet<FlatNode>();
+
+ while (!flatNodesToVisit.isEmpty()) {
+ Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
+ FlatNode fn = fnItr.next();
+
+ flatNodesToVisit.remove(fn);
+ visited.add(fn);
+
+ // ///////////////////////////////////////////////////////////////////////
+ // Adding Stall Node of current program statement
+ ParentChildConflictsMap currentConflictsMap = conflictsResults
+ .get(fn);
+
+ Hashtable<TempDescriptor, StallSite> stallMap = currentConflictsMap
+ .getStallMap();
+ Set<Entry<TempDescriptor, StallSite>> entrySet = stallMap
+ .entrySet();
+
+ HashSet<String> newStallNodeSet = new HashSet<String>();
+
+ for (Iterator<Entry<TempDescriptor, StallSite>> iterator2 = entrySet
+ .iterator(); iterator2.hasNext();) {
+ Entry<TempDescriptor, StallSite> entry = iterator2.next();
+ TempDescriptor td = entry.getKey();
+ StallSite stallSite = entry.getValue();
+ String stallNodeID;
+ if ((stallNodeID = conflictGraph
+ .addStallNode(td, fm, stallSite)) != null) {
+ // it added new stall node
+ newStallNodeSet.add(stallNodeID);
+ }
+ }
+
+ // Analyzing write conflicts between stall site and live-in
+ // variables
+ for (Iterator iterator = newStallNodeSet.iterator(); iterator
+ .hasNext();) {
+ String stallNodeID = (String) iterator.next();
+
+ StallSiteNode stallNode = conflictGraph
+ .getStallNode(stallNodeID);
+
+ if (stallNode != null) {
+ // if prior sese blocks have write effects on this stall
+ // node, it should be connected between them.
+ HashSet<LiveInNode> liveInNodeSet = conflictGraph
+ .getLiveInNodeSet();
+ for (Iterator iterator2 = liveInNodeSet.iterator(); iterator2
+ .hasNext();) {
+ LiveInNode liveInNode = (LiveInNode) iterator2.next();
+ if (liveInNode.isWriteConflictWith(stallNode)) {
+ // create conflict edge
+ conflictGraph.addWriteConflictEdge(stallNode, liveInNode);
+ }
+ }
+ }
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+
+ conflictGraph_nodeAction(fm, fn, conflictGraph, currentConflictsMap);
+
+ for (int i = 0; i < fn.numNext(); i++) {
+ FlatNode nn = fn.getNext(i);
+ if (!visited.contains(nn)) {
+ flatNodesToVisit.add(nn);
+ }
+ }
+ }
+
+ conflictGraphResults.put(fm, conflictGraph);
+
+ }
+
+ private void conflictGraph_nodeAction(FlatMethod fm, FlatNode fn,
+ ConflictGraph graph, ParentChildConflictsMap currentConflictsMap) {
+
+ switch (fn.kind()) {
+
+ case FKind.FlatSESEEnterNode: {
+
+ FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn;
+
+ if (!fsen.getIsCallerSESEplaceholder()) {
+ Set<TempDescriptor> invar_set = fsen.getInVarSet();
+
+ String liveinStr = "";
+
+ for (Iterator iterator = invar_set.iterator(); iterator
+ .hasNext();) {
+ TempDescriptor tempDescriptor = (TempDescriptor) iterator
+ .next();
+
+ SESEEffectsSet seseEffectsSet = fsen.getSeseEffectsSet();
+ Set<SESEEffectsKey> readEffectsSet=seseEffectsSet.getReadingSet(tempDescriptor);
+ Set<SESEEffectsKey> writeEffectsSet=seseEffectsSet.getWritingSet(tempDescriptor);
+
+ graph.addLiveInNode(tempDescriptor,fsen,readEffectsSet,writeEffectsSet);
+ }
+
+ }
+
+ }
+
+ break;
+
}
}
}
}
+ }else{
+ System.out.println("src is accessible="+possibleSrc);
}
currentConflictsMap.addAccessibleVar(possibleSrc);
// contribute read effect on source's stall site
- currentConflictsMap.contributeEffect(possibleSrc, field.getType()
- .getSafeSymbol(), field.toString(),
+ currentConflictsMap.contributeEffect(possibleSrc, field
+ .getType().getSafeSymbol(), field.getSymbol(),
StallSite.READ_EFFECT);
}
- HashSet<TempDescriptor> dstTempSet = getTempDescSetReferenceToSameHRN(
+ HashSet<TempDescriptor> dstTempSet = getTempDescSetReferenceToSameHRN(
og, dst);
for (Iterator iterator = dstTempSet.iterator(); iterator
.hasNext();) {
currentConflictsMap.addAccessibleVar(possibleDst);
// contribute write effect on destination's stall site
currentConflictsMap.contributeEffect(possibleDst, field
- .getType().getSafeSymbol(), field.toString(),
+ .getType().getSafeSymbol(), field.getSymbol(),
StallSite.WRITE_EFFECT);
}
while (paramIter.hasNext()) {
Integer paramID = paramIter.next();
PreEffectsKey effectKey = new PreEffectsKey(paramID,
- field.toString(), field.getType()
+ field.getSymbol(), field.getType()
.getSafeSymbol(), effectType);
preeffectsSet.add(effectKey);
}
while (paramIter.hasNext()) {
Integer paramID = paramIter.next();
PreEffectsKey effectKey = new PreEffectsKey(paramID,
- field.toString(), field.getType()
+ field.getSymbol(), field.getType()
.getSafeSymbol(), effectType);
preeffectsSet.add(effectKey);
}