a whole bunch of optimizations...should be useful for transactions
[IRC.git] / Robust / src / Analysis / Loops / GlobalFieldType.java
1 package Analysis.Loops;
2
3 import IR.Flat.*;
4 import IR.State;
5 import IR.MethodDescriptor;
6 import IR.FieldDescriptor;
7 import IR.TypeDescriptor;
8 import Analysis.CallGraph.*;
9 import java.util.Iterator;
10 import java.util.HashSet;
11 import java.util.Hashtable;
12 import java.util.Set;
13
14 public class GlobalFieldType {
15   CallGraph cg;
16   State st;
17   MethodDescriptor root;
18   Hashtable<MethodDescriptor, Set<FieldDescriptor>> fields;
19   Hashtable<MethodDescriptor, Set<TypeDescriptor>> arrays;
20   
21   public GlobalFieldType(CallGraph cg, State st, MethodDescriptor root) {
22     this.cg=cg;
23     this.st=st;
24     this.root=root;
25     this.fields=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
26     this.arrays=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
27     doAnalysis();
28   }
29   private void doAnalysis() {
30     HashSet toprocess=new HashSet();
31     toprocess.add(root);
32     HashSet discovered=new HashSet();
33     discovered.add(root);
34     while(!toprocess.isEmpty()) {
35       MethodDescriptor md=(MethodDescriptor)toprocess.iterator().next();
36       toprocess.remove(md);
37       analyzeMethod(md);
38       Set callees=cg.getCalleeSet(md);
39       for(Iterator it=callees.iterator();it.hasNext();) {
40         MethodDescriptor md2=(MethodDescriptor)it.next();
41         if (!discovered.contains(md2)) {
42           discovered.add(md2);
43           toprocess.add(md2);
44         }
45       }
46     }
47     boolean changed=true;
48     while(changed) {
49       changed=false;
50       for(Iterator it=discovered.iterator();it.hasNext();) {
51         MethodDescriptor md=(MethodDescriptor)it.next();
52         Set callees=cg.getCalleeSet(md);
53         for(Iterator cit=callees.iterator();cit.hasNext();) {
54           MethodDescriptor md2=(MethodDescriptor)cit.next();
55           if (fields.get(md).addAll(fields.get(md2)))
56             changed=true;
57           if (arrays.get(md).addAll(arrays.get(md2)))
58             changed=true;
59         }
60       }
61     }
62   }
63
64   public Set<FieldDescriptor> getFields(MethodDescriptor md) {
65     return fields.get(md);
66   }
67
68   public Set<TypeDescriptor> getArrays(MethodDescriptor md) {
69     return arrays.get(md);
70   }
71
72   public void analyzeMethod(MethodDescriptor md) {
73     fields.put(md, new HashSet<FieldDescriptor>());
74     arrays.put(md, new HashSet<TypeDescriptor>());
75     
76     FlatMethod fm=st.getMethodFlat(md);
77     for(Iterator it=fm.getNodeSet().iterator();it.hasNext();) {
78       FlatNode fn=(FlatNode)it.next();
79       if (fn.kind()==FKind.FlatSetElementNode) {
80         FlatSetElementNode fsen=(FlatSetElementNode)fn;
81         arrays.get(md).add(fsen.getDst().getType());
82       } else if (fn.kind()==FKind.FlatSetFieldNode) {
83         FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
84         fields.get(md).add(fsfn.getField());
85       }
86     }
87   }
88 }