changes on the SJava inference
[IRC.git] / Robust / src / Analysis / Disjoint / PointerMethod.java
1 package Analysis.Disjoint;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6
7
8 public class PointerMethod {
9   public PointerMethod() {
10     nextmap=new Hashtable<FlatNode, Vector<FlatNode>>();
11     prevmap=new Hashtable<FlatNode, Vector<FlatNode>>();
12   }
13
14   Hashtable<FlatNode, Vector<FlatNode>> nextmap;
15   Hashtable<FlatNode, Vector<FlatNode>> prevmap;
16
17   public void analyzeMethod(FlatMethod fm) {
18     if (nextmap.containsKey(fm))
19       return;
20     Hashtable<FlatNode, HashSet<FlatNode>> map=new Hashtable<FlatNode, HashSet<FlatNode>>();
21     HashSet<FlatNode> toprocess=new HashSet<FlatNode>();
22     toprocess.add(fm);
23     while(!toprocess.isEmpty()) {
24       FlatNode fn=toprocess.iterator().next();
25       toprocess.remove(fn);
26       HashSet<FlatNode> myset=new HashSet<FlatNode>();
27       if (!analysisCares(fn)) {
28         for(int i=0; i<fn.numPrev(); i++) {
29           if (map.containsKey(fn.getPrev(i)))
30             myset.addAll(map.get(fn.getPrev(i)));
31         }
32       } else {
33         myset.add(fn);
34       }
35       if (!map.containsKey(fn)||!map.get(fn).equals(myset)) {
36         map.put(fn, myset);
37         for(int i=0; i<fn.numNext(); i++) {
38           toprocess.add(fn.getNext(i));
39         }
40       }
41     }
42     for(Iterator<FlatNode> it=map.keySet().iterator(); it.hasNext(); ) {
43       FlatNode fn=it.next();
44       if (analysisCares(fn)) {
45         HashSet<FlatNode> myset=new HashSet<FlatNode>();
46         for(int i=0; i<fn.numPrev(); i++) {
47           if (map.containsKey(fn.getPrev(i)))
48             myset.addAll(map.get(fn.getPrev(i)));
49         }
50         if (!prevmap.containsKey(fn))
51           prevmap.put(fn, new Vector());
52         for(Iterator<FlatNode> it2=myset.iterator(); it2.hasNext(); ) {
53           FlatNode fnprev=it2.next();
54           if (!nextmap.containsKey(fnprev))
55             nextmap.put(fnprev, new Vector());
56           nextmap.get(fnprev).add(fn);
57           prevmap.get(fn).add(fnprev);
58         }
59       }
60     }
61   }
62
63   public int numNext(FlatNode fn) {
64     Vector<FlatNode> vfn=nextmap.get(fn);
65     if (vfn==null)
66       return 0;
67     else
68       return vfn.size();
69   }
70
71   public FlatNode getNext(FlatNode fn, int i) {
72     return nextmap.get(fn).get(i);
73   }
74
75   public int numPrev(FlatNode fn) {
76     return prevmap.get(fn).size();
77   }
78
79   public FlatNode getPrev(FlatNode fn, int i) {
80     return prevmap.get(fn).get(i);
81   }
82
83   public boolean isBackEdge(FlatNode fn) {
84     return fn.kind() == FKind.FlatBackEdge;
85   }
86
87   public boolean analysisCares(FlatNode fn) {
88     switch(fn.kind()) {
89     case FKind.FlatMethod:
90     case FKind.FlatFieldNode:
91     case FKind.FlatSetFieldNode:
92     case FKind.FlatElementNode:
93     case FKind.FlatSetElementNode:
94     case FKind.FlatNew:
95     case FKind.FlatLiteralNode:
96     case FKind.FlatCall:
97     case FKind.FlatReturnNode:
98     case FKind.FlatBackEdge:
99     case FKind.FlatSESEEnterNode:
100     case FKind.FlatSESEExitNode:
101     case FKind.FlatGenReachNode:
102     case FKind.FlatGenDefReachNode:
103     case FKind.FlatExit:
104       return true;
105
106     case FKind.FlatCastNode:
107       FlatCastNode fcn=(FlatCastNode)fn;
108       TypeDescriptor td=fcn.getType();
109       return td.isPtr();
110
111     case FKind.FlatOpNode:
112       FlatOpNode fon = (FlatOpNode) fn;
113       return fon.getOp().getOp()==Operation.ASSIGN&&fon.getLeft().getType().isPtr();
114
115     default:
116       return false;
117     }
118   }
119 }