major revisions on FlowGraph to have more precise information
authoryeom <yeom>
Wed, 3 Oct 2012 02:18:21 +0000 (02:18 +0000)
committeryeom <yeom>
Wed, 3 Oct 2012 02:18:21 +0000 (02:18 +0000)
Robust/src/Analysis/SSJava/FlowGraph.java
Robust/src/Analysis/SSJava/FlowNode.java
Robust/src/Analysis/SSJava/Location.java
Robust/src/Analysis/SSJava/LocationInference.java

index c8914f1450eea8486f8e701e78777c3684b62d12..e81fe7d073b93b29fe094b4f6313b353ec9d724f 100644 (file)
@@ -95,13 +95,18 @@ public class FlowGraph {
     return mapParamDescToIdx;
   }
 
     return mapParamDescToIdx;
   }
 
-  public FlowNode createIntermediateNode() {
+  public FlowNode createIntermediateNode(MethodDescriptor md) {
+
     NTuple<Descriptor> tuple = new NTuple<Descriptor>();
     Descriptor interDesc = new InterDescriptor(LocationInference.INTERLOC + interseed);
     tuple.add(interDesc);
     interseed++;
 
     NTuple<Descriptor> tuple = new NTuple<Descriptor>();
     Descriptor interDesc = new InterDescriptor(LocationInference.INTERLOC + interseed);
     tuple.add(interDesc);
     interseed++;
 
-    FlowNode newNode = new FlowNode(tuple);
+    NTuple<Location> locTuple = new NTuple<Location>();
+    Location interLoc = new Location(md, interDesc);
+    locTuple.add(interLoc);
+
+    FlowNode newNode = new FlowNode(locTuple);
     newNode.setIntermediate(true);
 
     mapDescTupleToInferNode.put(tuple, newNode);
     newNode.setIntermediate(true);
 
     mapDescTupleToInferNode.put(tuple, newNode);
@@ -274,8 +279,10 @@ public class FlowGraph {
 
   public FlowNode createNewFlowNode(NTuple<Descriptor> tuple) {
 
 
   public FlowNode createNewFlowNode(NTuple<Descriptor> tuple) {
 
+    NTuple<Location> locTuple = translateToLocationTuple(tuple);
     if (!mapDescTupleToInferNode.containsKey(tuple)) {
     if (!mapDescTupleToInferNode.containsKey(tuple)) {
-      FlowNode node = new FlowNode(tuple);
+
+      FlowNode node = new FlowNode(locTuple);
       mapDescTupleToInferNode.put(tuple, node);
       // nodeSet.add(node);
 
       mapDescTupleToInferNode.put(tuple, node);
       // nodeSet.add(node);
 
@@ -380,7 +387,7 @@ public class FlowGraph {
     for (Iterator iterator = outEdgeSet.iterator(); iterator.hasNext();) {
       FlowEdge edge = (FlowEdge) iterator.next();
 
     for (Iterator iterator = outEdgeSet.iterator(); iterator.hasNext();) {
       FlowEdge edge = (FlowEdge) iterator.next();
 
-      if (fn.getDescTuple().equals(edge.getInitTuple())) {
+      if (fn.getLocTuple().equals(edge.getInitTuple())) {
         FlowNode dstNode = getFlowNode(edge.getEndTuple());
         NTuple<Location> dstTuple = getLocationTuple(dstNode);
 
         FlowNode dstNode = getFlowNode(edge.getEndTuple());
         NTuple<Location> dstTuple = getLocationTuple(dstNode);
 
@@ -398,6 +405,51 @@ public class FlowGraph {
     return getLocationTuple(getFlowNode(descTuple));
   }
 
     return getLocationTuple(getFlowNode(descTuple));
   }
 
+  public NTuple<Location> translateToLocationTuple(NTuple<Descriptor> descTuple) {
+
+    NTuple<Location> locTuple = new NTuple<Location>();
+    ClassDescriptor cd = null;
+
+    Descriptor localDesc = descTuple.get(0);
+
+    if (localDesc instanceof InterDescriptor) {
+      Location interLoc = new Location(md, localDesc);
+      locTuple.add(interLoc);
+    } else if (localDesc.getSymbol().equals(LocationInference.TOPLOC)) {
+      Location topLoc = new Location(md, Location.TOP);
+      topLoc.setLocDescriptor(LocationInference.TOPDESC);
+      locTuple.add(topLoc);
+    } else if (localDesc.getSymbol().equals(LocationInference.GLOBALLOC)) {
+      Location globalLoc = new Location(md, LocationInference.GLOBALLOC);
+      globalLoc.setLocDescriptor(LocationInference.GLOBALDESC);
+      locTuple.add(globalLoc);
+    } else {
+      // normal case
+      for (int i = 0; i < descTuple.size(); i++) {
+        Descriptor curDesc = descTuple.get(i);
+        Location loc;
+        if (i == 0) {
+          loc = new Location(md, curDesc.getSymbol());
+          loc.setLocDescriptor(curDesc);
+          cd = ((VarDescriptor) curDesc).getType().getClassDesc();
+        } else {
+          loc = new Location(cd, curDesc.getSymbol());
+          loc.setLocDescriptor(curDesc);
+
+          if (curDesc instanceof FieldDescriptor) {
+            cd = ((FieldDescriptor) curDesc).getType().getClassDesc();
+          } else {
+            cd = ((LocationDescriptor) curDesc).getEnclosingClassDesc();
+          }
+
+        }
+        locTuple.add(loc);
+      }
+    }
+
+    return locTuple;
+  }
+
   public NTuple<Location> getLocationTuple(FlowNode fn) {
 
     if (!mapFlowNodeToLocTuple.containsKey(fn)) {
   public NTuple<Location> getLocationTuple(FlowNode fn) {
 
     if (!mapFlowNodeToLocTuple.containsKey(fn)) {
@@ -571,8 +623,8 @@ public class FlowGraph {
       FlowNode u = flowEdge.getSrc();
       FlowNode v = flowEdge.getDst();
 
       FlowNode u = flowEdge.getSrc();
       FlowNode v = flowEdge.getDst();
 
-      if (u.getDescTuple().equals(flowEdge.getInitTuple())
-          && v.getDescTuple().equals(flowEdge.getEndTuple())) {
+      if (u.getLocTuple().equals(flowEdge.getInitTuple())
+          && v.getLocTuple().equals(flowEdge.getEndTuple())) {
         // only draw an edge of the actual value flow
 
         if (!addedEdgeSet.contains(flowEdge)) {
         // only draw an edge of the actual value flow
 
         if (!addedEdgeSet.contains(flowEdge)) {
@@ -623,7 +675,7 @@ public class FlowGraph {
     while (iter.hasNext()) {
       FlowNode node = iter.next();
 
     while (iter.hasNext()) {
       FlowNode node = iter.next();
 
-      if (node.getDescTuple().size() == 1) {
+      if (node.getLocTuple().size() == 1) {
         // here, we just care about the local variable
         if (node.getFieldNodeSet().size() > 0) {
           drawSubgraph(node, bw, addedEdgeSet);
         // here, we just care about the local variable
         if (node.getFieldNodeSet().size() > 0) {
           drawSubgraph(node, bw, addedEdgeSet);
index cdd9bd472a939e1d53b3da0a1e2546805b1deb44..45de718a042fc73c862620be6ee2be93256ea145 100644 (file)
@@ -11,7 +11,7 @@ import IR.VarDescriptor;
 public class FlowNode {
 
   // descriptor tuple is a unique identifier of the flow node
 public class FlowNode {
 
   // descriptor tuple is a unique identifier of the flow node
-  private NTuple<Descriptor> descTuple;
+  private NTuple<Location> locTuple;
 
   // if the infer node represents the base type of field access,
   // this set contains fields of the base type
 
   // if the infer node represents the base type of field access,
   // this set contains fields of the base type
@@ -40,26 +40,26 @@ public class FlowNode {
     return fieldNodeSet;
   }
 
     return fieldNodeSet;
   }
 
-  public FlowNode(NTuple<Descriptor> tuple) {
+  public FlowNode(NTuple<Location> tuple) {
 
     this.isSkeleton = false;
     this.isIntermediate = false;
 
 
     this.isSkeleton = false;
     this.isIntermediate = false;
 
-    NTuple<Descriptor> base = null;
-    Descriptor desc = null;
+    NTuple<Location> base = null;
+    Location loc = null;
     if (tuple.size() > 1) {
       base = tuple.subList(0, tuple.size() - 1);
     if (tuple.size() > 1) {
       base = tuple.subList(0, tuple.size() - 1);
-      desc = tuple.get(tuple.size() - 1);
+      loc = tuple.get(tuple.size() - 1);
     } else {
       base = tuple;
     }
     fieldNodeSet = new HashSet<FlowNode>();
     } else {
       base = tuple;
     }
     fieldNodeSet = new HashSet<FlowNode>();
-    descTuple = new NTuple<Descriptor>();
+    locTuple = new NTuple<Location>();
     if (base != null) {
     if (base != null) {
-      descTuple.addAll(base);
+      locTuple.addAll(base);
     }
     }
-    if (desc != null) {
-      descTuple.add(desc);
+    if (loc != null) {
+      locTuple.add(loc);
     }
 
   }
     }
 
   }
@@ -76,12 +76,8 @@ public class FlowNode {
     fieldNodeSet.add(node);
   }
 
     fieldNodeSet.add(node);
   }
 
-  public NTuple<Descriptor> getDescTuple() {
-    return descTuple;
-  }
-
-  public Descriptor getOwnDescriptor() {
-    return descTuple.get(descTuple.size() - 1);
+  public NTuple<Location> getLocTuple() {
+    return locTuple;
   }
 
   public boolean isReturn() {
   }
 
   public boolean isReturn() {
@@ -92,35 +88,24 @@ public class FlowNode {
     this.isReturn = isReturn;
   }
 
     this.isReturn = isReturn;
   }
 
-  public boolean isPrimitiveType() {
-    Descriptor desc = descTuple.get(descTuple.size() - 1);
-    if (desc instanceof VarDescriptor) {
-      return ((VarDescriptor) desc).getType().isPrimitive();
-    } else if (desc instanceof FieldDescriptor) {
-      return ((FieldDescriptor) desc).getType().isPrimitive();
-    }
-    return false;
-  }
-
   public String toString() {
     String rtr = "[FlowNode]:";
     if (isSkeleton()) {
       rtr += "SKELETON:";
     }
   public String toString() {
     String rtr = "[FlowNode]:";
     if (isSkeleton()) {
       rtr += "SKELETON:";
     }
-    rtr += ":" + descTuple;
+    rtr += ":" + locTuple;
     return rtr;
   }
 
     return rtr;
   }
 
-
   public int hashCode() {
   public int hashCode() {
-    return 7 + descTuple.hashCode();
+    return 7 + locTuple.hashCode();
   }
 
   public boolean equals(Object obj) {
 
     if (obj instanceof FlowNode) {
       FlowNode in = (FlowNode) obj;
   }
 
   public boolean equals(Object obj) {
 
     if (obj instanceof FlowNode) {
       FlowNode in = (FlowNode) obj;
-      if (descTuple.equals(in.getDescTuple())) {
+      if (locTuple.equals(in.getLocTuple())) {
         return true;
       }
     }
         return true;
       }
     }
@@ -131,8 +116,8 @@ public class FlowNode {
 
   public String getID() {
     String id = "";
 
   public String getID() {
     String id = "";
-    for (int i = 0; i < descTuple.size(); i++) {
-      id += descTuple.get(i).getSymbol();
+    for (int i = 0; i < locTuple.size(); i++) {
+      id += locTuple.get(i).getSymbol();
     }
     return id;
   }
     }
     return id;
   }
@@ -140,11 +125,11 @@ public class FlowNode {
   public String getPrettyID() {
     String id = "<";
     String property = "";
   public String getPrettyID() {
     String id = "<";
     String property = "";
-    for (int i = 0; i < descTuple.size(); i++) {
+    for (int i = 0; i < locTuple.size(); i++) {
       if (i != 0) {
         id += ",";
       }
       if (i != 0) {
         id += ",";
       }
-      id += descTuple.get(i).getSymbol();
+      id += locTuple.get(i).getSymbol();
     }
     id += ">";
 
     }
     id += ">";
 
@@ -175,10 +160,22 @@ public class FlowNode {
     return isDeclarationNode;
   }
 
     return isDeclarationNode;
   }
 
+  public NTuple<Location> getCurrentLocTuple() {
+    if (compLoc == null) {
+      return locTuple;
+    }
+    NTuple<Location> curLocTuple = new NTuple<Location>();
+    for (int i = 0; i < compLoc.getSize(); i++) {
+      Location locElement = compLoc.get(i);
+      curLocTuple.add(locElement);
+    }
+    return curLocTuple;
+  }
+
   public NTuple<Descriptor> getCurrentDescTuple() {
 
     if (compLoc == null) {
   public NTuple<Descriptor> getCurrentDescTuple() {
 
     if (compLoc == null) {
-      return descTuple;
+      return getDescTuple();
     }
 
     NTuple<Descriptor> curDescTuple = new NTuple<Descriptor>();
     }
 
     NTuple<Descriptor> curDescTuple = new NTuple<Descriptor>();
@@ -197,4 +194,12 @@ public class FlowNode {
     this.isSkeleton = isSkeleton;
   }
 
     this.isSkeleton = isSkeleton;
   }
 
+  public NTuple<Descriptor> getDescTuple() {
+    NTuple<Descriptor> descTuple = new NTuple<Descriptor>();
+    for (int i = 0; i < locTuple.size(); i++) {
+      descTuple.add(locTuple.get(i).getLocDescriptor());
+    }
+    return descTuple;
+  }
+
 }
 }
index 98a05497131af40d7898f5fd74b086067678750f..c91b472fe9297b0d22fde1625f6cc1b0c86d9343 100644 (file)
@@ -14,6 +14,12 @@ public class Location implements TypeExtension {
   String loc;
   Descriptor locDesc;
 
   String loc;
   Descriptor locDesc;
 
+  public Location(Descriptor enclosingDesc, Descriptor locDescriptor) {
+    this.d = enclosingDesc;
+    this.locDesc = locDescriptor;
+    this.loc = locDescriptor.getSymbol();
+  }
+
   public Location(Descriptor d, String loc) {
     this.d = d;
     this.loc = loc;
   public Location(Descriptor d, String loc) {
     this.d = d;
     this.loc = loc;
index dfa8e0e72735a6c1364a78a7fe004624d4950773..36645aa1c8ae24ee4cbf0b49f919dc1d3c6a94cb 100644 (file)
@@ -293,10 +293,157 @@ public class LocationInference {
       }
 
     }
       }
 
     }
+
+    // DEBUG: write a global flow graph
+    MethodDescriptor mdContainingSSJavaLoop = ssjava.getMethodContainingSSJavaLoop();
+    FlowGraph globalFlowGraph = getSubGlobalFlowGraph(mdContainingSSJavaLoop);
+    // System.out.println("GLOBAL NODE SET=" + globalFlowGraph.getNodeSet());
+    assignCompositeLocation(globalFlowGraph);
+    try {
+      globalFlowGraph.writeGraph("_GLOBAL");
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
     // _debug_printGraph();
 
   }
 
     // _debug_printGraph();
 
   }
 
+  private void assignCompositeLocation(FlowGraph globalFlowGraph) {
+    Set<FlowNode> nodeSet = globalFlowGraph.getNodeSet();
+
+    for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
+      FlowNode flowNode = (FlowNode) iterator.next();
+      Set<FlowNode> inNodeSet = globalFlowGraph.getIncomingFlowNodeSet(flowNode);
+      Set<FlowNode> reachableNodeSet = globalFlowGraph.getReachFlowNodeSetFrom(flowNode);
+
+      // System.out.println("flowNode=" + flowNode + "   incoming=" + inNodeSet);
+      // System.out.println("reachableNodeSet=" + reachableNodeSet);
+
+      Map<NTuple<Location>, Set<NTuple<Descriptor>>> mapPrefixToIncomingLocTupleSet =
+          new HashMap<NTuple<Location>, Set<NTuple<Descriptor>>>();
+
+      List<NTuple<Descriptor>> prefixList = new ArrayList<NTuple<Descriptor>>();
+
+      for (Iterator iterator2 = inNodeSet.iterator(); iterator2.hasNext();) {
+        FlowNode inNode = (FlowNode) iterator2.next();
+
+        NTuple<Descriptor> inNodeTuple = inNode.getCurrentDescTuple();
+
+        // CompositeLocation inNodeInferredLoc =
+        // generateInferredCompositeLocation(methodInfo, inNodeTuple);
+        // NTuple<Location> inNodeInferredLocTuple = inNodeInferredLoc.getTuple();
+
+        for (int i = 1; i < inNodeTuple.size(); i++) {
+          NTuple<Descriptor> prefix = inNodeTuple.subList(0, i);
+          if (!prefixList.contains(prefix)) {
+            prefixList.add(prefix);
+          }
+        }
+      }
+
+      Collections.sort(prefixList, new Comparator<NTuple<Descriptor>>() {
+        public int compare(NTuple<Descriptor> arg0, NTuple<Descriptor> arg1) {
+          int s0 = arg0.size();
+          int s1 = arg1.size();
+          if (s0 > s1) {
+            return -1;
+          } else if (s0 == s1) {
+            return 0;
+          } else {
+            return 1;
+          }
+        }
+      });
+
+      // find out reachable nodes that have the longest common prefix
+      for (int i = 0; i < prefixList.size(); i++) {
+        NTuple<Descriptor> curPrefix = prefixList.get(i);
+        Set<NTuple<Descriptor>> reachableCommonPrefixSet = new HashSet<NTuple<Descriptor>>();
+
+        for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
+          FlowNode reachableNode = (FlowNode) iterator2.next();
+          NTuple<Descriptor> reachLocTuple = reachableNode.getCurrentDescTuple();
+          if (reachLocTuple.startsWith(curPrefix)) {
+            reachableCommonPrefixSet.add(reachLocTuple);
+          }
+        }
+
+        if (!reachableCommonPrefixSet.isEmpty()) {
+          // found reachable nodes that start with the prefix curPrefix
+          // need to assign a composite location
+          // System.out.println("-prefixList=" + prefixList);
+          // System.out.println("-reachableCommonPrefixSet=" + reachableCommonPrefixSet);
+          // System.out.println("-curPrefix=" + curPrefix);
+
+          // first, check if there are more than one the set of locations that has
+          // the same length of the longest reachable prefix, no way to assign
+          // a composite location to the input local var
+          prefixSanityCheck(prefixList, i, globalFlowGraph, reachableNodeSet);
+
+          MethodDescriptor topMethodDesc = globalFlowGraph.getMethodDescriptor();
+          CompositeLocation newCompLoc = generateCompositeLocation(curPrefix, topMethodDesc);
+
+          System.out.println("SET COMPOSITE LOCATION=" + newCompLoc + " to " + flowNode);
+          flowNode.setCompositeLocation(newCompLoc);
+        }
+      }
+
+    }
+
+  }
+
+  private CompositeLocation generateCompositeLocation(NTuple<Descriptor> curPrefix,
+      MethodDescriptor md) {
+    CompositeLocation newCompLoc = new CompositeLocation();
+
+    Descriptor enclosingDesc = md;
+    for (int i = 0; i < curPrefix.size(); i++) {
+      Descriptor curDesc = curPrefix.get(i);
+      Location loc = new Location(enclosingDesc, curDesc.getSymbol());
+      newCompLoc.addLocation(loc);
+      if (i == 0) {
+        VarDescriptor varDesc = (VarDescriptor) curDesc;
+        enclosingDesc = varDesc.getType().getClassDesc();
+      } else {
+        FieldDescriptor fieldDesc = (FieldDescriptor) curDesc;
+        enclosingDesc = fieldDesc.getType().getClassDesc();
+      }
+    }
+
+    LocationDescriptor newLocDescriptor = generateNewLocationDescriptor();
+    newLocDescriptor.setEnclosingClassDesc((ClassDescriptor) enclosingDesc);
+
+    Location newLoc = new Location(enclosingDesc, newLocDescriptor.getSymbol());
+    newLoc.setLocDescriptor(newLocDescriptor);
+    newCompLoc.addLocation(newLoc);
+
+    return newCompLoc;
+  }
+
+  private void prefixSanityCheck(List<NTuple<Descriptor>> prefixList, int curIdx,
+      FlowGraph globalFlowGraph, Set<FlowNode> reachableNodeSet) {
+
+    NTuple<Descriptor> curPrefix = prefixList.get(curIdx);
+
+    for (int i = curIdx + 1; i < prefixList.size(); i++) {
+      NTuple<Descriptor> prefixTuple = prefixList.get(i);
+
+      if (curPrefix.startsWith(prefixTuple)) {
+        continue;
+      }
+
+      for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
+        FlowNode reachableNode = (FlowNode) iterator2.next();
+        NTuple<Descriptor> reachLocTuple = reachableNode.getCurrentDescTuple();
+        if (reachLocTuple.startsWith(prefixTuple)) {
+          throw new Error(
+              "Failed to generate a composite location because there is more than one prefix which is reach to the current node.");
+        }
+      }
+    }
+
+  }
+
   private void addValueFlowsFromCalleeSubGlobalFlowGraph(MethodDescriptor mdCaller,
       FlowGraph subGlobalFlowGraph) {
 
   private void addValueFlowsFromCalleeSubGlobalFlowGraph(MethodDescriptor mdCaller,
       FlowGraph subGlobalFlowGraph) {
 
@@ -420,22 +567,6 @@ public class LocationInference {
     return callerTuple;
   }
 
     return callerTuple;
   }
 
-  private NTuple<Descriptor> traslateToCalleeParamTupleToCallerArgTuple(
-      NTuple<Descriptor> calleeInitTuple, NTuple<Descriptor> callerSrcTuple) {
-
-    NTuple<Descriptor> callerInitTuple = new NTuple<Descriptor>();
-
-    for (int i = 0; i < callerSrcTuple.size(); i++) {
-      callerInitTuple.add(callerSrcTuple.get(i));
-    }
-
-    for (int i = 1; i < calleeInitTuple.size(); i++) {
-      callerInitTuple.add(calleeInitTuple.get(i));
-    }
-
-    return callerInitTuple;
-  }
-
   private NTuple<Descriptor> translateToCaller(NTuple<Descriptor> dstDescTuple,
       NTuple<Descriptor> baseTuple) {
     NTuple<Descriptor> callerDescTuple = new NTuple<Descriptor>();
   private NTuple<Descriptor> translateToCaller(NTuple<Descriptor> dstDescTuple,
       NTuple<Descriptor> baseTuple) {
     NTuple<Descriptor> callerDescTuple = new NTuple<Descriptor>();
@@ -475,16 +606,14 @@ public class LocationInference {
 
       for (int paramIdx = 0; paramIdx < flowGraph.getNumParameters(); paramIdx++) {
         FlowNode flowNode = flowGraph.getParamFlowNode(paramIdx);
 
       for (int paramIdx = 0; paramIdx < flowGraph.getNumParameters(); paramIdx++) {
         FlowNode flowNode = flowGraph.getParamFlowNode(paramIdx);
-        NTuple<Descriptor> descTuple = flowNode.getDescTuple();
+        NTuple<Location> locTuple = flowNode.getLocTuple();
 
         CompositeLocation assignedCompLoc = flowNode.getCompositeLocation();
         CompositeLocation inferredCompLoc;
         if (assignedCompLoc != null) {
           inferredCompLoc = translateCompositeLocation(assignedCompLoc);
         } else {
 
         CompositeLocation assignedCompLoc = flowNode.getCompositeLocation();
         CompositeLocation inferredCompLoc;
         if (assignedCompLoc != null) {
           inferredCompLoc = translateCompositeLocation(assignedCompLoc);
         } else {
-          Descriptor locDesc = descTuple.get(0);
-          Location loc = new Location(md, locDesc.getSymbol());
-          loc.setLocDescriptor(locDesc);
+          Location loc = locTuple.get(0);
           inferredCompLoc = new CompositeLocation(loc);
         }
         System.out.println("-paramIdx=" + paramIdx + "   infer=" + inferredCompLoc);
           inferredCompLoc = new CompositeLocation(loc);
         }
         System.out.println("-paramIdx=" + paramIdx + "   infer=" + inferredCompLoc);
@@ -1157,7 +1286,7 @@ public class LocationInference {
     Set<FlowNode> nodeSet = fg.getNodeSet();
     for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
       FlowNode flowNode = (FlowNode) iterator.next();
     Set<FlowNode> nodeSet = fg.getNodeSet();
     for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
       FlowNode flowNode = (FlowNode) iterator.next();
-      if (flowNode.getDescTuple().get(0).equals(md.getThis())) {
+      if (flowNode.getLocTuple().get(0).equals(md.getThis())) {
         return true;
       }
     }
         return true;
       }
     }
@@ -2736,7 +2865,7 @@ public class LocationInference {
     CompositeLocation inferSrcLoc;
     CompositeLocation inferDstLoc = methodInfo.getInferLocation(dstDesc);
 
     CompositeLocation inferSrcLoc;
     CompositeLocation inferDstLoc = methodInfo.getInferLocation(dstDesc);
 
-    if (srcNode.getDescTuple().size() > 1) {
+    if (srcNode.getLocTuple().size() > 1) {
       // field access
       inferSrcLoc = new CompositeLocation();
 
       // field access
       inferSrcLoc = new CompositeLocation();
 
@@ -2749,7 +2878,7 @@ public class LocationInference {
       inferSrcLoc = methodInfo.getInferLocation(srcDesc);
     }
 
       inferSrcLoc = methodInfo.getInferLocation(srcDesc);
     }
 
-    if (dstNode.getDescTuple().size() > 1) {
+    if (dstNode.getLocTuple().size() > 1) {
       // field access
       inferDstLoc = new CompositeLocation();
 
       // field access
       inferDstLoc = new CompositeLocation();
 
@@ -2850,7 +2979,7 @@ public class LocationInference {
         // first, check if there are more than one the set of locations that has
         // the same length of the longest reachable prefix, no way to assign
         // a composite location to the input local var
         // first, check if there are more than one the set of locations that has
         // the same length of the longest reachable prefix, no way to assign
         // a composite location to the input local var
-        prefixSanityCheck(prefixList, i, flowGraph, reachableNodeSet);
+        // prefixSanityCheck(prefixList, i, flowGraph, reachableNodeSet);
 
         Set<NTuple<Location>> incomingCommonPrefixSet =
             mapPrefixToIncomingLocTupleSet.get(curPrefix);
 
         Set<NTuple<Location>> incomingCommonPrefixSet =
             mapPrefixToIncomingLocTupleSet.get(curPrefix);
@@ -2889,7 +3018,7 @@ public class LocationInference {
             methodInfo.removeMaplocalVarToLocSet(srcLocalVar);
 
             // add the field/var descriptor to the set of the location symbol
             methodInfo.removeMaplocalVarToLocSet(srcLocalVar);
 
             // add the field/var descriptor to the set of the location symbol
-            int lastIdx = srcNode.getDescTuple().size() - 1;
+            int lastIdx = srcNode.getLocTuple().size() - 1;
             Descriptor lastFlowNodeDesc = srcNode.getDescTuple().get(lastIdx);
             NTuple<Location> srcNodelocTuple = flowGraph.getLocationTuple(srcNode);
             Descriptor enclosinglastLastFlowNodeDesc = srcNodelocTuple.get(lastIdx).getDescriptor();
             Descriptor lastFlowNodeDesc = srcNode.getDescTuple().get(lastIdx);
             NTuple<Location> srcNodelocTuple = flowGraph.getLocationTuple(srcNode);
             Descriptor enclosinglastLastFlowNodeDesc = srcNodelocTuple.get(lastIdx).getDescriptor();
@@ -2931,7 +3060,7 @@ public class LocationInference {
           methodInfo.removeMaplocalVarToLocSet(localVarDesc);
 
           // add the field/var descriptor to the set of the location symbol
           methodInfo.removeMaplocalVarToLocSet(localVarDesc);
 
           // add the field/var descriptor to the set of the location symbol
-          int lastIdx = flowNode.getDescTuple().size() - 1;
+          int lastIdx = flowNode.getLocTuple().size() - 1;
           Descriptor lastFlowNodeDesc = flowNode.getDescTuple().get(lastIdx);
           Descriptor enclosinglastLastFlowNodeDesc = flowNodelocTuple.get(lastIdx).getDescriptor();
 
           Descriptor lastFlowNodeDesc = flowNode.getDescTuple().get(lastIdx);
           Descriptor enclosinglastLastFlowNodeDesc = flowNodelocTuple.get(lastIdx).getDescriptor();
 
@@ -3129,29 +3258,6 @@ public class LocationInference {
 
   }
 
 
   }
 
-  private void prefixSanityCheck(List<NTuple<Location>> prefixList, int curIdx,
-      FlowGraph flowGraph, Set<FlowNode> reachableNodeSet) {
-
-    NTuple<Location> curPrefix = prefixList.get(curIdx);
-
-    for (int i = curIdx + 1; i < prefixList.size(); i++) {
-      NTuple<Location> prefixTuple = prefixList.get(i);
-
-      if (curPrefix.startsWith(prefixTuple)) {
-        continue;
-      }
-
-      for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
-        FlowNode reachableNode = (FlowNode) iterator2.next();
-        NTuple<Location> reachLocTuple = flowGraph.getLocationTuple(reachableNode);
-        if (reachLocTuple.startsWith(prefixTuple)) {
-          // TODO
-          throw new Error("Failed to generate a composite location");
-        }
-      }
-    }
-  }
-
   public boolean isPrimitiveLocalVariable(FlowNode node) {
     VarDescriptor varDesc = (VarDescriptor) node.getDescTuple().get(0);
     return varDesc.getType().isPrimitive();
   public boolean isPrimitiveLocalVariable(FlowNode node) {
     VarDescriptor varDesc = (VarDescriptor) node.getDescTuple().get(0);
     return varDesc.getType().isPrimitive();
@@ -3213,8 +3319,8 @@ public class LocationInference {
   private void extractRelationFromFieldFlows(ClassDescriptor cd, FlowNode srcNode,
       FlowNode dstNode, int idx) throws CyclicFlowException {
 
   private void extractRelationFromFieldFlows(ClassDescriptor cd, FlowNode srcNode,
       FlowNode dstNode, int idx) throws CyclicFlowException {
 
-    if (srcNode.getDescTuple().get(idx).equals(dstNode.getDescTuple().get(idx))
-        && srcNode.getDescTuple().size() > (idx + 1) && dstNode.getDescTuple().size() > (idx + 1)) {
+    if (srcNode.getLocTuple().get(idx).equals(dstNode.getLocTuple().get(idx))
+        && srcNode.getLocTuple().size() > (idx + 1) && dstNode.getLocTuple().size() > (idx + 1)) {
       // value flow between fields: we don't need to add a binary relation
       // for this case
 
       // value flow between fields: we don't need to add a binary relation
       // for this case
 
@@ -3582,7 +3688,7 @@ public class LocationInference {
 
     if (newImplicitTupleSet.size() > 1) {
       // need to create an intermediate node for the GLB of conditional locations & implicit flows
 
     if (newImplicitTupleSet.size() > 1) {
       // need to create an intermediate node for the GLB of conditional locations & implicit flows
-      NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+      NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode(md).getDescTuple();
       for (Iterator<NTuple<Descriptor>> idxIter = newImplicitTupleSet.iterator(); idxIter.hasNext();) {
         NTuple<Descriptor> tuple = idxIter.next();
         addFlowGraphEdge(md, tuple, interTuple);
       for (Iterator<NTuple<Descriptor>> idxIter = newImplicitTupleSet.iterator(); idxIter.hasNext();) {
         NTuple<Descriptor> tuple = idxIter.next();
         addFlowGraphEdge(md, tuple, interTuple);
@@ -3639,7 +3745,7 @@ public class LocationInference {
       currentFlowTupleSet.addTupleSet(implicitFlowTupleSet);
 
       if (currentFlowTupleSet.size() > 1) {
       currentFlowTupleSet.addTupleSet(implicitFlowTupleSet);
 
       if (currentFlowTupleSet.size() > 1) {
-        FlowNode meetNode = fg.createIntermediateNode();
+        FlowNode meetNode = fg.createIntermediateNode(md);
         for (Iterator iterator = currentFlowTupleSet.iterator(); iterator.hasNext();) {
           NTuple<Descriptor> currentFlowTuple = (NTuple<Descriptor>) iterator.next();
           fg.addValueFlowEdge(currentFlowTuple, meetNode.getDescTuple());
         for (Iterator iterator = currentFlowTupleSet.iterator(); iterator.hasNext();) {
           NTuple<Descriptor> currentFlowTuple = (NTuple<Descriptor>) iterator.next();
           fg.addValueFlowEdge(currentFlowTuple, meetNode.getDescTuple());
@@ -3670,7 +3776,7 @@ public class LocationInference {
 
       if (newImplicitTupleSet.size() > 1) {
         // need to create an intermediate node for the GLB of conditional locations & implicit flows
 
       if (newImplicitTupleSet.size() > 1) {
         // need to create an intermediate node for the GLB of conditional locations & implicit flows
-        NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+        NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode(md).getDescTuple();
         for (Iterator<NTuple<Descriptor>> idxIter = newImplicitTupleSet.iterator(); idxIter
             .hasNext();) {
           NTuple<Descriptor> tuple = idxIter.next();
         for (Iterator<NTuple<Descriptor>> idxIter = newImplicitTupleSet.iterator(); idxIter
             .hasNext();) {
           NTuple<Descriptor> tuple = idxIter.next();
@@ -3720,7 +3826,7 @@ public class LocationInference {
           implicitFlowTupleSet, false);
 
       // ///////////
           implicitFlowTupleSet, false);
 
       // ///////////
-      NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+      NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode(md).getDescTuple();
 
       for (Iterator<NTuple<Descriptor>> idxIter = condTupleNode.iterator(); idxIter.hasNext();) {
         NTuple<Descriptor> tuple = idxIter.next();
 
       for (Iterator<NTuple<Descriptor>> idxIter = condTupleNode.iterator(); idxIter.hasNext();) {
         NTuple<Descriptor> tuple = idxIter.next();
@@ -3771,7 +3877,7 @@ public class LocationInference {
     if (newImplicitTupleSet.size() > 1) {
 
       // need to create an intermediate node for the GLB of conditional locations & implicit flows
     if (newImplicitTupleSet.size() > 1) {
 
       // need to create an intermediate node for the GLB of conditional locations & implicit flows
-      NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+      NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode(md).getDescTuple();
       for (Iterator<NTuple<Descriptor>> idxIter = newImplicitTupleSet.iterator(); idxIter.hasNext();) {
         NTuple<Descriptor> tuple = idxIter.next();
         addFlowGraphEdge(md, tuple, interTuple);
       for (Iterator<NTuple<Descriptor>> idxIter = newImplicitTupleSet.iterator(); idxIter.hasNext();) {
         NTuple<Descriptor> tuple = idxIter.next();
         addFlowGraphEdge(md, tuple, interTuple);
@@ -3807,7 +3913,7 @@ public class LocationInference {
       // creates edges from RHS to LHS
       NTuple<Descriptor> interTuple = null;
       if (nodeSetRHS.size() > 1) {
       // creates edges from RHS to LHS
       NTuple<Descriptor> interTuple = null;
       if (nodeSetRHS.size() > 1) {
-        interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+        interTuple = getFlowGraph(md).createIntermediateNode(md).getDescTuple();
       }
 
       for (Iterator<NTuple<Descriptor>> iter = nodeSetRHS.iterator(); iter.hasNext();) {
       }
 
       for (Iterator<NTuple<Descriptor>> iter = nodeSetRHS.iterator(); iter.hasNext();) {
@@ -4053,7 +4159,7 @@ public class LocationInference {
           NTuple<Descriptor> argTuple = new NTuple<Descriptor>();
           if (argTupleSet.size() > 1) {
             NTuple<Descriptor> interTuple =
           NTuple<Descriptor> argTuple = new NTuple<Descriptor>();
           if (argTupleSet.size() > 1) {
             NTuple<Descriptor> interTuple =
-                getFlowGraph(md).createIntermediateNode().getDescTuple();
+                getFlowGraph(md).createIntermediateNode(md).getDescTuple();
             for (Iterator<NTuple<Descriptor>> idxIter = argTupleSet.iterator(); idxIter.hasNext();) {
               NTuple<Descriptor> tuple = idxIter.next();
               addFlowGraphEdge(md, tuple, interTuple);
             for (Iterator<NTuple<Descriptor>> idxIter = argTupleSet.iterator(); idxIter.hasNext();) {
               NTuple<Descriptor> tuple = idxIter.next();
               addFlowGraphEdge(md, tuple, interTuple);
@@ -4402,7 +4508,7 @@ public class LocationInference {
       // creates edges from RHS to LHS
       NTuple<Descriptor> interTuple = null;
       if (nodeSetRHS.size() > 1) {
       // creates edges from RHS to LHS
       NTuple<Descriptor> interTuple = null;
       if (nodeSetRHS.size() > 1) {
-        interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+        interTuple = getFlowGraph(md).createIntermediateNode(md).getDescTuple();
       }
 
       for (Iterator<NTuple<Descriptor>> iter = nodeSetRHS.iterator(); iter.hasNext();) {
       }
 
       for (Iterator<NTuple<Descriptor>> iter = nodeSetRHS.iterator(); iter.hasNext();) {