get compiler side of STM working
[IRC.git] / Robust / src / Analysis / Loops / GlobalFieldType.java
1 package Analysis.Loops;
2
3 import IR.Flat.*;
4 import IR.State;
5 import IR.TypeUtil;
6 import IR.MethodDescriptor;
7 import IR.FieldDescriptor;
8 import IR.TypeDescriptor;
9 import Analysis.CallGraph.*;
10 import java.util.Iterator;
11 import java.util.HashSet;
12 import java.util.Hashtable;
13 import java.util.Set;
14
15 public class GlobalFieldType {
16   CallGraph cg;
17   State st;
18   MethodDescriptor root;
19   Hashtable<MethodDescriptor, Set<FieldDescriptor>> fields;
20   Hashtable<MethodDescriptor, Set<TypeDescriptor>> arrays;
21   HashSet<MethodDescriptor> containsAtomic;
22   
23   public GlobalFieldType(CallGraph cg, State st, MethodDescriptor root) {
24     this.cg=cg;
25     this.st=st;
26     this.root=root;
27     this.fields=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
28     this.arrays=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
29     this.containsAtomic=new HashSet<MethodDescriptor>();
30     doAnalysis();
31   }
32   private void doAnalysis() {
33     HashSet toprocess=new HashSet();
34     toprocess.add(root);
35     HashSet discovered=new HashSet();
36     discovered.add(root);
37     while(!toprocess.isEmpty()) {
38       MethodDescriptor md=(MethodDescriptor)toprocess.iterator().next();
39       toprocess.remove(md);
40       analyzeMethod(md);
41       Set callees=cg.getCalleeSet(md);
42       for(Iterator it=callees.iterator();it.hasNext();) {
43         MethodDescriptor md2=(MethodDescriptor)it.next();
44         if (!discovered.contains(md2)) {
45           discovered.add(md2);
46           toprocess.add(md2);
47         }
48       }
49       if (md.getClassDesc().getSymbol().equals(TypeUtil.ThreadClass)&&
50           md.getSymbol().equals("start")&&!md.getModifiers().isStatic()&&
51           md.numParameters()==0) {
52         //start -> run link     
53         MethodDescriptor runmd=null;
54         for(Iterator methodit=md.getClassDesc().getMethodTable().getSet("run").iterator(); methodit.hasNext();) {
55           MethodDescriptor mdrun=(MethodDescriptor) methodit.next();
56           if (mdrun.numParameters()!=0||mdrun.getModifiers().isStatic())
57             continue;
58           runmd=mdrun;
59           break;
60         }
61         if (runmd!=null) {
62           Set runmethodset=cg.getMethods(runmd);
63           for(Iterator it=runmethodset.iterator();it.hasNext();) {
64             MethodDescriptor md2=(MethodDescriptor)it.next();
65             if (!discovered.contains(md2)) {
66               discovered.add(md2);
67               toprocess.add(md2);
68             }
69           }
70         } else throw new Error("Can't find run method");
71       }
72     }
73     boolean changed=true;
74     while(changed) {
75       changed=false;
76       for(Iterator it=discovered.iterator();it.hasNext();) {
77         MethodDescriptor md=(MethodDescriptor)it.next();
78         Set callees=cg.getCalleeSet(md);
79         for(Iterator cit=callees.iterator();cit.hasNext();) {
80           MethodDescriptor md2=(MethodDescriptor)cit.next();
81           if (fields.get(md).addAll(fields.get(md2)))
82             changed=true;
83           if (arrays.get(md).addAll(arrays.get(md2)))
84             changed=true;
85           if (containsAtomic.contains(md2)) {
86             if (containsAtomic.add(md))
87               changed=true;
88           }
89         }
90       }
91     }
92   }
93
94   public boolean containsAtomic(MethodDescriptor md) {
95     return containsAtomic.contains(md);
96   }
97
98   public Set<FieldDescriptor> getFields(MethodDescriptor md) {
99     return fields.get(md);
100   }
101
102   public Set<TypeDescriptor> getArrays(MethodDescriptor md) {
103     return arrays.get(md);
104   }
105
106   public void analyzeMethod(MethodDescriptor md) {
107     fields.put(md, new HashSet<FieldDescriptor>());
108     arrays.put(md, new HashSet<TypeDescriptor>());
109     
110     FlatMethod fm=st.getMethodFlat(md);
111     for(Iterator it=fm.getNodeSet().iterator();it.hasNext();) {
112       FlatNode fn=(FlatNode)it.next();
113       if (fn.kind()==FKind.FlatSetElementNode) {
114         FlatSetElementNode fsen=(FlatSetElementNode)fn;
115         arrays.get(md).add(fsen.getDst().getType());
116       } else if (fn.kind()==FKind.FlatSetFieldNode) {
117         FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
118         fields.get(md).add(fsfn.getField());
119       } else if (fn.kind()==FKind.FlatAtomicEnterNode) {
120         containsAtomic.add(md);
121       }
122     }
123   }
124 }