import IR.Descriptor;
import IR.FieldDescriptor;
+import IR.VarDescriptor;
public class HierarchyGraph {
Map<Descriptor, HNode> mapDescToHNode;
Map<HNode, Set<Descriptor>> mapHNodeToDescSet;
Map<HNode, HNode> mapHNodeToCurrentHNode; // tracking which node corresponds to the initial node
+ Map<String, HNode> mapHNodeNameToCurrentHNode; // tracking which node corresponds to the initial
+ // node
Map<HNode, Set<HNode>> mapMergeNodetoMergingSet;
// data structures for a combination node
Map<Set<HNode>, HNode> mapCombineNodeSetToCombinationNode;
Map<Set<HNode>, Set<HNode>> mapCombineNodeSetToOutgoingNodeSet;
- Map<HNode, String> mapHNodeToLocationName;
+ Map<HNode, Set<HNode>> mapNormalNodeToSCNodeReachToSet;
Set<HNode> nodeSet;
- public static int seed = 0;
-
// for the lattice generation
Map<HNode, Integer> mapHNodeToUniqueIndex;
Map<HNode, Set<Integer>> mapHNodeToBasis;
mapHNodeToUniqueIndex = new HashMap<HNode, Integer>();
mapHNodeToBasis = new HashMap<HNode, Set<Integer>>();
- mapHNodeToLocationName = new HashMap<HNode, String>();
mapMergeNodetoMergingSet = new HashMap<HNode, Set<HNode>>();
mapHNodeToCurrentHNode = new HashMap<HNode, HNode>();
+ mapHNodeNameToCurrentHNode = new HashMap<String, HNode>();
+
+ mapNormalNodeToSCNodeReachToSet = new HashMap<HNode, Set<HNode>>();
}
public Descriptor getDesc() {
this.desc = desc;
}
- public void addMapHNodeToLocationName(HNode node, String locName) {
- mapHNodeToLocationName.put(node, locName);
- }
-
- public String getLocationName(HNode node) {
- return mapHNodeToLocationName.get(node);
- }
-
public String getName() {
return name;
}
return mapHNodeToCurrentHNode;
}
+ public Map<String, HNode> getMapHNodeNameToCurrentHNode() {
+ return mapHNodeNameToCurrentHNode;
+ }
+
public void setMapHNodeToCurrentHNode(Map<HNode, HNode> mapHNodeToCurrentHNode) {
this.mapHNodeToCurrentHNode = mapHNodeToCurrentHNode;
}
+ public void setMapHNodeNameToCurrentHNode(Map<String, HNode> mapHNodeNameToCurrentHNode) {
+ this.mapHNodeNameToCurrentHNode = mapHNodeNameToCurrentHNode;
+ }
+
public Map<Descriptor, HNode> getMapDescToHNode() {
return mapDescToHNode;
}
HNode newMergeNode = mergeNodes(possibleCycleSet, false);
newMergeNode.setSharedNode(true);
System.out.println("### INTRODUCE A NEW MERGE NODE: " + newMergeNode);
- System.out.println("### CYCLIC VALUE FLOW: " + srcHNode + " -> " + dstHNode);
+ System.out.println("### CYCLIC VALUE FLOW: " + srcHNode + " -> " + dstHNode + "\n");
} else {
getIncomingNodeSet(dstHNode).add(srcHNode);
getOutgoingNodeSet(srcHNode).add(dstHNode);
- System.out.println("add an edge " + srcHNode + " -> " + dstHNode);
+ // System.out.println("add an edge " + srcHNode + " -> " + dstHNode);
}
}
}
public void addEdge(Descriptor src, Descriptor dst) {
- HNode srcHNode = getHNode(src);
- HNode dstHNode = getHNode(dst);
- addEdge(srcHNode, dstHNode);
+ if (src.equals(LocationInference.LITERALDESC)) {
+ // in this case, we do not need to add a source hnode
+ // just add a destination hnode
+ getHNode(dst);
+ } else {
+ HNode srcHNode = getHNode(src);
+ HNode dstHNode = getHNode(dst);
+ addEdge(srcHNode, dstHNode);
+ }
}
public HNode getHNode(Descriptor d) {
if (!mapDescToHNode.containsKey(d)) {
HNode newNode = new HNode(d);
+
if (d instanceof FieldDescriptor) {
newNode.setSkeleton(true);
}
+
+ String symbol = d.getSymbol();
+ if (symbol.startsWith(LocationInference.PCLOC) || symbol.startsWith(LocationInference.RLOC)) {
+ newNode.setSkeleton(true);
+ }
+
mappingDescriptorToHNode(d, newNode);
nodeSet.add(newNode);
}
continue;
}
+ if (!isEligibleForMerging(node1, node2)) {
+ continue;
+ }
+
if (!node1.equals(node2)) {
Set<HNode> incomingNodeSet2 = getIncomingNodeSet(node2);
return false;
}
+ private boolean isEligibleForMerging(HNode node1, HNode node2) {
+
+ if (node1.isSharedNode() || node2.isSharedNode()) {
+
+ // if either of nodes is a shared node,
+ // all descriptors of node1 & node2 should have a primitive type
+
+ Set<Descriptor> descSet = new HashSet<Descriptor>();
+ descSet.addAll(getDescSetOfNode(node1));
+ descSet.addAll(getDescSetOfNode(node2));
+
+ for (Iterator iterator = descSet.iterator(); iterator.hasNext();) {
+ Descriptor desc = (Descriptor) iterator.next();
+ if (!LocationInference.isPrimitive(desc)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
private void addEdgeWithNoCycleCheck(HNode srcHNode, HNode dstHNode) {
getIncomingNodeSet(dstHNode).add(srcHNode);
getOutgoingNodeSet(srcHNode).add(dstHNode);
String nodeName;
boolean isMergeNode = false;
if (onlyCombinationNodes) {
- nodeName = "Comb" + (seed++);
+ nodeName = "Comb" + (LocationInference.locSeed++);
} else {
- nodeName = "Node" + (seed++);
+ nodeName = "Node" + (LocationInference.locSeed++);
isMergeNode = true;
}
HNode newMergeNode = new HNode(nodeName);
}
}
System.out.println("--Set merging node=" + newMergeNode + " as a skeleton=" + set
- + " hasSkeleton=" + hasSkeleton);
+ + " hasSkeleton=" + hasSkeleton + " CUR DESC=" + desc);
newMergeNode.setSkeleton(hasSkeleton);
for (Iterator iterator = set.iterator(); iterator.hasNext();) {
mergedSkeletonNode.add(merged);
}
}
- mapMergeNodetoMergingSet.put(newMergeNode, mergedSkeletonNode);
- for (Iterator iterator = mergedSkeletonNode.iterator(); iterator.hasNext();) {
+
+ // mapMergeNodetoMergingSet.put(newMergeNode, mergedSkeletonNode);
+ // for (Iterator iterator = set.iterator(); iterator.hasNext();) {
+ mapMergeNodetoMergingSet.put(newMergeNode, set);
+ for (Iterator iterator = set.iterator(); iterator.hasNext();) {
HNode mergedNode = (HNode) iterator.next();
addMapHNodeToCurrentHNode(mergedNode, newMergeNode);
}
-
+ System.out.println("###mergedSkeletonNode=" + mergedSkeletonNode);
System.out.println("###MERGING NODE=" + set + " new node=" + newMergeNode);
+
+ for (Iterator iterator = set.iterator(); iterator.hasNext();) {
+ HNode hNode = (HNode) iterator.next();
+ System.out.println("old=" + hNode + "----->newNode=" + getCurrentHNode(hNode));
+ }
+
return newMergeNode;
}
private void addMapHNodeToCurrentHNode(HNode curNode, HNode newNode) {
if (curNode.isMergeNode()) {
Set<HNode> mergingSet = getMergingSet(curNode);
+ mergingSet.add(curNode);
+ System.out.println("addMapHNodeToCurrentHNode curNode=" + curNode + " meringSet="
+ + mergingSet);
for (Iterator iterator = mergingSet.iterator(); iterator.hasNext();) {
HNode mergingNode = (HNode) iterator.next();
mapHNodeToCurrentHNode.put(mergingNode, newNode);
+ mapHNodeNameToCurrentHNode.put(mergingNode.getName(), newNode);
}
} else {
mapHNodeToCurrentHNode.put(curNode, newNode);
+ mapHNodeNameToCurrentHNode.put(curNode.getName(), newNode);
}
}
return mapHNodeToCurrentHNode.get(node);
}
+ public HNode getCurrentHNode(String nodeName) {
+ return mapHNodeNameToCurrentHNode.get(nodeName);
+ }
+
private Set<HNode> getMergingSet(HNode mergeNode) {
Set<HNode> mergingSet = new HashSet<HNode>();
Set<HNode> mergedNode = mapMergeNodetoMergingSet.get(mergeNode);
for (Iterator iterator = mergedNode.iterator(); iterator.hasNext();) {
HNode node = (HNode) iterator.next();
if (node.isMergeNode()) {
+ mergingSet.add(node);
mergingSet.addAll(getMergingSet(node));
} else {
mergingSet.add(node);
}
+ public Set<HNode> getReachableSCNodeSet(HNode startNode) {
+ // returns the set of hnodes which is reachable from the startNode and is either SC node or a
+ // node which is directly connected to the SC nodes
+ Set<HNode> reachable = new HashSet<HNode>();
+ Set<HNode> visited = new HashSet<HNode>();
+ visited.add(startNode);
+ recurReachableNodeSet(startNode, visited, reachable);
+ return reachable;
+ }
+
+ public Set<HNode> getSCNodeReachToSet(HNode node) {
+ if (!mapNormalNodeToSCNodeReachToSet.containsKey(node)) {
+ mapNormalNodeToSCNodeReachToSet.put(node, new HashSet<HNode>());
+ }
+ return mapNormalNodeToSCNodeReachToSet.get(node);
+ }
+
+ private void recurReachableNodeSet(HNode node, Set<HNode> visited, Set<HNode> reachable) {
+
+ Set<HNode> outSet = getOutgoingNodeSet(node);
+ for (Iterator iterator = outSet.iterator(); iterator.hasNext();) {
+ HNode out = (HNode) iterator.next();
+
+ if (!visited.contains(out)) {
+ visited.add(out);
+ Set<HNode> reachableFromSCNodeSet = reachableFromSCNode(out);
+ mapNormalNodeToSCNodeReachToSet.put(out, reachableFromSCNodeSet);
+ if (out.isSkeleton() || out.isCombinationNode() || reachableFromSCNodeSet.size() > 0) {
+ reachable.add(out);
+ } else {
+ visited.add(out);
+ recurReachableNodeSet(out, visited, reachable);
+ }
+
+ }
+
+ }
+
+ }
+
+ private Set<HNode> reachableFromSCNode(HNode node) {
+ Set<HNode> visited = new HashSet<HNode>();
+ visited.add(node);
+ Set<HNode> reachable = new HashSet<HNode>();
+ recurReachableFromSCNode(node, reachable, visited);
+ return reachable;
+ }
+
+ private void recurReachableFromSCNode(HNode node, Set<HNode> reachable, Set<HNode> visited) {
+ Set<HNode> inNodeSet = getIncomingNodeSet(node);
+ for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) {
+ HNode inNode = (HNode) iterator.next();
+ if (inNode.isSkeleton() || inNode.isCombinationNode()) {
+ visited.add(inNode);
+ reachable.add(inNode);
+ } else if (!visited.contains(inNode)) {
+ visited.add(inNode);
+ recurReachableFromSCNode(inNode, reachable, visited);
+ }
+ }
+ }
+
public Set<HNode> getDirectlyReachableSkeletonCombinationNodeFrom(HNode node,
Set<HNode> combinationNodeSet) {
Set<HNode> reachable = new HashSet<HNode>();
public HNode getCombinationNode(Set<HNode> combineSet) {
if (!mapCombineNodeSetToCombinationNode.containsKey(combineSet)) {
- String name = "COMB" + (seed++);
+ String name = "COMB" + (LocationInference.locSeed++);
HNode node = new HNode(name);
node.setCombinationNode(true);
nodeSet.add(node);
HNode outNode = getCombinationNode(combineNode);
addEdgeWithNoCycleCheck(combinationNode, outNode);
} else if (curNode.isSkeleton()) {
- // HNode dstNode = getHNode(curNode.getDescriptor());
+ // HNode dstNode2 = getHNode(curNode.getDescriptor());
HNode dstNode = getCurrentHNode(curNode);
+ // System.out.println("-----curNode=" + curNode + "------->" + dstNode + " dstNode2="
+ // + dstNode2);
addEdgeWithNoCycleCheck(combinationNode, dstNode);
}
}
private void addCombinationNode(HNode curNode, Set<HNode> reachToSet, Set<HNode> reachableSet) {
if (!mapSkeletonNodeSetToCombinationNode.containsKey(reachToSet)) {
// need to create a new combination node
- String nodeName = "Comb" + (seed++);
+ String nodeName = "Comb" + (LocationInference.locSeed++);
HNode newCombinationNode = new HNode(nodeName);
newCombinationNode.setCombinationNode(true);
clone.setMapHNodeToDescSet(getMapHNodeToDescSet());
clone.setMapHNodetoMergeSet(getMapHNodetoMergeSet());
clone.setMapHNodeToCurrentHNode(getMapHNodeToCurrentHNode());
+ clone.setMapHNodeNameToCurrentHNode(getMapHNodeNameToCurrentHNode());
+
return clone;
}
public void assignUniqueIndexToNode() {
int idx = 1;
+ System.out.println("nodeSet=" + nodeSet);
for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
HNode node = (HNode) iterator.next();
mapHNodeToUniqueIndex.put(node, idx);
}
}
- public BasisSet computeBasisSet() {
+ public BasisSet computeBasisSet(Set<HNode> notGenerateSet) {
// assign a unique index to a node
assignUniqueIndexToNode();
for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
HNode node = (HNode) iterator.next();
+ if (notGenerateSet.contains(node)) {
+ System.out.println("%%%SKIP =" + node);
+ continue;
+ }
Set<Integer> basis = new HashSet<Integer>();
basis.addAll(BASISTOPELEMENT);
Set<HNode> reachableNodeSet = getReachableNodeSetFrom(node);
System.out.println("node=" + node + " reachableNodeSet=" + reachableNodeSet);
-
+ System.out.println("mapHNodeToUniqueIndex.get(node)=" + mapHNodeToUniqueIndex.get(node));
// if a node is reachable from the current node
// need to remove the index of the reachable node from the basis
for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
HNode reachableNode = (HNode) iterator2.next();
System.out.println("reachableNode=" + reachableNode);
+ System.out.println("getHNodeIndex(reachableNode))="
+ + mapHNodeToUniqueIndex.get(reachableNode));
int idx = getHNodeIndex(reachableNode);
basis.remove(idx);
}