beginning of points-to analysis
authorbdemsky <bdemsky>
Sat, 22 Jan 2011 06:27:41 +0000 (06:27 +0000)
committerbdemsky <bdemsky>
Sat, 22 Jan 2011 06:27:41 +0000 (06:27 +0000)
Robust/src/Analysis/Pointer/AllocFactory.java [new file with mode: 0644]
Robust/src/Analysis/Pointer/BasicBlock.java [new file with mode: 0644]
Robust/src/Analysis/Pointer/Delta.java [new file with mode: 0644]
Robust/src/Analysis/Pointer/Edge.java [new file with mode: 0644]
Robust/src/Analysis/Pointer/Graph.java [new file with mode: 0644]
Robust/src/Analysis/Pointer/Pointer.java [new file with mode: 0644]

diff --git a/Robust/src/Analysis/Pointer/AllocFactory.java b/Robust/src/Analysis/Pointer/AllocFactory.java
new file mode 100644 (file)
index 0000000..74a4f20
--- /dev/null
@@ -0,0 +1,48 @@
+package Analysis.Pointer;
+
+import java.util.*;
+import IR.*;
+import IR.Flat.*;
+
+public class AllocFactory {
+  public static class AllocNode {
+    int allocsite;
+    boolean summary;
+    TypeDescriptor type;
+    
+    public AllocNode(int allocsite, TypeDescriptor type, boolean summary) {
+      this.allocsite=allocsite;
+      this.summary=summary;
+      this.type=type;
+    }
+    
+    public int hashCode() {
+      return allocsite<<1^(summary?0:1);
+    }
+    
+    public boolean equals(Object o) {
+      if (o instanceof AllocNode) {
+       AllocNode an=(AllocNode)o;
+       return (allocsite==an.allocsite)&&(summary==an.summary);
+      }
+      return false;
+    }
+  }
+
+  public AllocFactory(State state, TypeUtil typeUtil) {
+    allocMap=new HashMap<FlatNode, Integer>();
+    this.typeUtil=typeUtil;
+    ClassDescriptor stringcd=typeUtil.getClass(TypeUtil.StringClass);
+    TypeDescriptor stringtd=new TypeDescriptor(stringcd);
+    TypeDescriptor stringarraytd=stringtd.makeArray(state);
+    StringArray=new AllocNode(0, stringarraytd, false);
+    Strings=new AllocNode(1, stringtd, true);
+  }
+  
+  HashMap<FlatNode, Integer> allocMap;
+  TypeUtil typeUtil;
+  int siteCounter=2;
+
+  public AllocNode StringArray;
+  public AllocNode Strings;
+}
\ No newline at end of file
diff --git a/Robust/src/Analysis/Pointer/BasicBlock.java b/Robust/src/Analysis/Pointer/BasicBlock.java
new file mode 100644 (file)
index 0000000..deb9346
--- /dev/null
@@ -0,0 +1,96 @@
+package Analysis.Pointer;
+import Analysis.Disjoint.PointerMethod;
+import java.util.*;
+import IR.Flat.*;
+
+public class BasicBlock {
+  public BBlock start;
+  public BBlock exit;
+
+  public BasicBlock(BBlock start, BBlock exit) {
+    this.start=start;
+    this.exit=exit;
+  }
+
+  public BBlock getStart() {
+    return start;
+  }
+
+  public BBlock getExit() {
+    return exit;
+  }
+
+  public static class BBlock {
+    Vector<FlatNode> nodes;
+    Vector<BBlock> prevb;
+    Vector<BBlock> nextb;
+
+    public BBlock() {
+      nodes=new Vector<FlatNode>();
+      prevb=new Vector<BBlock>();
+      nextb=new Vector<BBlock>();
+    }
+
+    public Vector<FlatNode> nodes() {
+      return nodes;
+    }
+    public Vector<BBlock> next() {
+      return nextb;
+    }
+    public Vector<BBlock> prev() {
+      return prevb;
+    }
+  }
+
+  public static BasicBlock getBBlock(FlatMethod fm) {
+    BBlock exit=null;
+    Stack<FlatNode> toprocess=new Stack<FlatNode>();
+    HashMap<FlatNode, BBlock> map=new HashMap<FlatNode, BBlock>();
+    PointerMethod pm=new PointerMethod();
+    pm.analyzeMethod(fm);
+    toprocess.add(fm);
+    map.put(fm, new BBlock());
+
+    while(!toprocess.isEmpty()) {
+      FlatNode fn=toprocess.pop();
+      BBlock block=map.get(fn);
+      block.nodes.add(fn);
+      if (fn.kind()==FKind.FlatExit)
+       exit=block;
+      do {
+       if (pm.numNext(fn)!=1) {
+         for(int i=0;i<pm.numNext(fn);i++) {
+           FlatNode fnext=pm.getNext(fn,i);
+           if (!map.containsKey(fnext)) {
+             map.put(fn, new BBlock());
+             toprocess.add(fn);
+           }
+           //link block in
+           if (!block.nextb.contains(map.get(fn))) {
+             block.nextb.add(map.get(fn));
+             map.get(fn).prevb.add(block);
+           }
+         }
+         break;
+       }
+       fn=pm.getNext(fn,0);
+       if (fn.numPrev()>1) {
+         //new basic block
+         if (!map.containsKey(fn)) {
+           map.put(fn, new BBlock());
+           toprocess.add(fn);
+         }
+         //link block in
+         if (!block.nextb.contains(map.get(fn))) {
+           block.nextb.add(map.get(fn));
+           map.get(fn).prevb.add(block);
+         }
+         break;
+       }
+       block.nodes.add(fn);
+      } while(true);
+    }
+
+    return new BasicBlock(map.get(fm), exit);
+  }
+}
diff --git a/Robust/src/Analysis/Pointer/Delta.java b/Robust/src/Analysis/Pointer/Delta.java
new file mode 100644 (file)
index 0000000..67b9414
--- /dev/null
@@ -0,0 +1,48 @@
+package Analysis.Pointer;
+import java.util.*;
+import Analysis.Pointer.AllocFactory.AllocNode;
+import Analysis.Pointer.BasicBlock.BBlock;
+import IR.Flat.*;
+
+public class Delta {
+  HashMap<AllocNode, Vector<Edge>> heapedgeremove;
+  HashMap<TempDescriptor, Vector<Edge>> varedgeremove;
+  HashMap<AllocNode, Vector<Edge>> heapedgeadd;
+  HashMap<TempDescriptor, Vector<Edge>> varedgeadd;
+
+  boolean init;
+  BBlock block;
+
+  public Delta(BBlock block, boolean init) {
+    this.heapedgeadd=new HashMap<AllocNode, Vector<Edge>>();
+    this.varedgeadd=new HashMap<TempDescriptor, Vector<Edge>>();
+    this.heapedgeremove=new HashMap<AllocNode, Vector<Edge>>();
+    this.varedgeremove=new HashMap<TempDescriptor, Vector<Edge>>();
+    this.init=init;
+    this.block=block;
+  }
+
+  public void addHeapEdge(AllocNode node, Edge e) {
+    if (!heapedgeadd.containsKey(node))
+      heapedgeadd.put(node, new Vector<Edge>());
+    heapedgeadd.get(node).add(e);
+  }
+
+  public void addVarEdge(TempDescriptor tmp, Edge e) {
+    if (!varedgeadd.containsKey(tmp))
+      varedgeadd.put(tmp, new Vector<Edge>());
+    varedgeadd.get(tmp).add(e);
+  }
+
+  public void setBlock(BBlock block) {
+    this.block=block;
+  }
+
+  public BBlock getBlock() {
+    return block;
+  }
+
+  public boolean getInit() {
+    return init;
+  }
+}
\ No newline at end of file
diff --git a/Robust/src/Analysis/Pointer/Edge.java b/Robust/src/Analysis/Pointer/Edge.java
new file mode 100644 (file)
index 0000000..5048f83
--- /dev/null
@@ -0,0 +1,23 @@
+package Analysis.Pointer;
+import IR.Flat.*;
+import IR.*;
+import Analysis.Pointer.AllocFactory.AllocNode;
+
+public class Edge {
+  FieldDescriptor fd;
+  AllocNode src;
+  TempDescriptor srcvar;
+  AllocNode dst;
+
+  public Edge(AllocNode src, FieldDescriptor fd, AllocNode dst) {
+    this.src=src;
+    this.fd=fd;
+    this.dst=dst;
+  }
+  
+  public Edge(TempDescriptor tmp, AllocNode dst) {
+    this.srcvar=tmp;
+    this.dst=dst;
+  }
+  
+}
\ No newline at end of file
diff --git a/Robust/src/Analysis/Pointer/Graph.java b/Robust/src/Analysis/Pointer/Graph.java
new file mode 100644 (file)
index 0000000..d4969e9
--- /dev/null
@@ -0,0 +1,29 @@
+package Analysis.Pointer;
+import java.util.*;
+import Analysis.Disjoint.PointerMethod;
+import Analysis.Pointer.AllocFactory.AllocNode;
+import IR.Flat.*;
+
+public class Graph {
+
+  /* This is field is set is this Graph is just a delta on the parent
+   * graph. */
+
+  Graph parent;
+  HashSet<TempDescriptor> tempset;
+  HashSet<AllocNode> allocset;
+
+  HashMap<AllocNode, Vector<Edge>> nodeMap;
+  HashMap<TempDescriptor, Vector<Edge>> tmpMap;
+
+  public Graph(Graph parent) {
+    nodeMap=new HashMap<AllocNode, Vector<Edge>>();
+    tmpMap=new HashMap<TempDescriptor, Vector<Edge>>();
+    tempset=new HashSet<TempDescriptor>();
+    allocset=new HashSet<AllocNode>();
+    
+    this.parent=parent;
+  }
+
+  
+}
\ No newline at end of file
diff --git a/Robust/src/Analysis/Pointer/Pointer.java b/Robust/src/Analysis/Pointer/Pointer.java
new file mode 100644 (file)
index 0000000..4987ac8
--- /dev/null
@@ -0,0 +1,81 @@
+package Analysis.Pointer;
+import java.util.*;
+import IR.Flat.*;
+import IR.*;
+import Analysis.Pointer.BasicBlock.BBlock;
+import Analysis.Pointer.AllocFactory.AllocNode;
+
+public class Pointer {
+  HashMap<FlatMethod, BasicBlock> blockMap;
+  HashMap<FlatNode, Graph> graphMap;
+  State state;
+  TypeUtil typeUtil;
+  AllocFactory allocFactory;
+  LinkedList<Delta> toprocess;
+
+  public Pointer(State state, TypeUtil typeUtil) {
+    this.state=state;
+    this.blockMap=new HashMap<FlatMethod, BasicBlock>();
+    this.graphMap=new HashMap<FlatNode, Graph>();
+    this.typeUtil=typeUtil;
+    this.allocFactory=new AllocFactory(state, typeUtil);
+    this.toprocess=new LinkedList<Delta>();
+  }
+
+  public BasicBlock getBBlock(FlatMethod fm) {
+    if (!blockMap.containsKey(fm))
+      blockMap.put(fm, BasicBlock.getBBlock(fm));
+    return blockMap.get(fm);
+  }
+  
+  Delta buildInitialContext() {
+    MethodDescriptor md=typeUtil.getMain();
+    FlatMethod fm=state.getMethodFlat(md);
+    BasicBlock bb=getBBlock(fm);
+    BBlock start=bb.getStart();
+    Delta delta=new Delta(start, true);
+    delta.addHeapEdge(allocFactory.StringArray, new Edge(allocFactory.StringArray, null, allocFactory.Strings));
+    delta.addVarEdge(fm.getParameter(0), new Edge(fm.getParameter(0), allocFactory.StringArray));
+    return delta;
+  }
+
+  void doAnalysis() {
+    toprocess.add(buildInitialContext());
+
+    while(!toprocess.isEmpty()) {
+      Delta delta=toprocess.remove();
+      BBlock bblock=delta.getBlock();
+      Vector<FlatNode> nodes=bblock.nodes();
+      FlatNode firstNode=nodes.get(0);
+
+      //Get graph for first node
+      if (!graphMap.containsKey(firstNode)) {
+       graphMap.put(firstNode, new Graph(null));
+      }
+      Graph graph=graphMap.get(firstNode);
+
+      //First entrance is special...
+      if (delta.getInit()) {
+       applyInit(delta, graph);
+      } else {
+       applyDelta(delta, graph);
+      }
+      
+      Graph nodeGraph=null;
+      for(int i=1; i<nodes.size();i++) {
+       FlatNode currNode=nodes.get(i);
+       if (!graphMap.containsKey(currNode)) {
+         graphMap.put(currNode, new Graph(graph, nodeGraph));
+       }
+       nodeGraph=graphMap.get(currNode);
+
+       if (delta.getInit()) {
+         applyInitDiff(delta, nodeGraph);
+       } else {
+         applyDeltaDiff(delta, nodeGraph);       
+       }
+      }
+    }
+    
+  }
+}
\ No newline at end of file