bug fix for barriers...should be able to use joptimize with barriers now
[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   HashSet<MethodDescriptor> containsBarrier;
23   
24   public GlobalFieldType(CallGraph cg, State st, MethodDescriptor root) {
25     this.cg=cg;
26     this.st=st;
27     this.root=root;
28     this.fields=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
29     this.arrays=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
30     this.containsAtomic=new HashSet<MethodDescriptor>();
31     this.containsBarrier=new HashSet<MethodDescriptor>();
32     doAnalysis();
33   }
34   private void doAnalysis() {
35     HashSet toprocess=new HashSet();
36     toprocess.add(root);
37     HashSet discovered=new HashSet();
38     discovered.add(root);
39     while(!toprocess.isEmpty()) {
40       MethodDescriptor md=(MethodDescriptor)toprocess.iterator().next();
41       toprocess.remove(md);
42       analyzeMethod(md);
43       Set callees=cg.getCalleeSet(md);
44       for(Iterator it=callees.iterator();it.hasNext();) {
45         MethodDescriptor md2=(MethodDescriptor)it.next();
46         if (!discovered.contains(md2)) {
47           discovered.add(md2);
48           toprocess.add(md2);
49         }
50       }
51       if (md.getClassDesc().getSymbol().equals(TypeUtil.ThreadClass)&&
52           md.getSymbol().equals("start")&&!md.getModifiers().isStatic()&&
53           md.numParameters()==0) {
54         //start -> run link     
55         MethodDescriptor runmd=null;
56         for(Iterator methodit=md.getClassDesc().getMethodTable().getSet("run").iterator(); methodit.hasNext();) {
57           MethodDescriptor mdrun=(MethodDescriptor) methodit.next();
58           if (mdrun.numParameters()!=0||mdrun.getModifiers().isStatic())
59             continue;
60           runmd=mdrun;
61           break;
62         }
63         if (runmd!=null) {
64           Set runmethodset=cg.getMethods(runmd);
65           for(Iterator it=runmethodset.iterator();it.hasNext();) {
66             MethodDescriptor md2=(MethodDescriptor)it.next();
67             if (!discovered.contains(md2)) {
68               discovered.add(md2);
69               toprocess.add(md2);
70             }
71           }
72         } else throw new Error("Can't find run method");
73       }
74     }
75     boolean changed=true;
76     while(changed) {
77       changed=false;
78       for(Iterator it=discovered.iterator();it.hasNext();) {
79         MethodDescriptor md=(MethodDescriptor)it.next();
80         Set callees=cg.getCalleeSet(md);
81         for(Iterator cit=callees.iterator();cit.hasNext();) {
82           MethodDescriptor md2=(MethodDescriptor)cit.next();
83           if (fields.get(md).addAll(fields.get(md2)))
84             changed=true;
85           if (arrays.get(md).addAll(arrays.get(md2)))
86             changed=true;
87           if (containsAtomic.contains(md2)) {
88             if (containsAtomic.add(md))
89               changed=true;
90           }
91           if (containsBarrier.contains(md2)) {
92             if (containsBarrier.add(md))
93               changed=true;
94           }
95         }
96       }
97     }
98   }
99
100   public boolean containsAtomic(MethodDescriptor md) {
101     return containsAtomic.contains(md);
102   }
103
104   public boolean containsBarrier(MethodDescriptor md) {
105     return containsBarrier.contains(md);
106   }
107
108   public Set<FieldDescriptor> getFields(MethodDescriptor md) {
109     return fields.get(md);
110   }
111
112   public Set<TypeDescriptor> getArrays(MethodDescriptor md) {
113     return arrays.get(md);
114   }
115
116   public void analyzeMethod(MethodDescriptor md) {
117     fields.put(md, new HashSet<FieldDescriptor>());
118     arrays.put(md, new HashSet<TypeDescriptor>());
119     
120     FlatMethod fm=st.getMethodFlat(md);
121     for(Iterator it=fm.getNodeSet().iterator();it.hasNext();) {
122       FlatNode fn=(FlatNode)it.next();
123       if (fn.kind()==FKind.FlatSetElementNode) {
124         FlatSetElementNode fsen=(FlatSetElementNode)fn;
125         arrays.get(md).add(fsen.getDst().getType());
126       } else if (fn.kind()==FKind.FlatSetFieldNode) {
127         FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
128         fields.get(md).add(fsfn.getField());
129       } else if (fn.kind()==FKind.FlatAtomicEnterNode) {
130         containsAtomic.add(md);
131       } else if (fn.kind()==FKind.FlatCall) {
132         MethodDescriptor mdcall=((FlatCall)fn).getMethod();
133         if (mdcall.getSymbol().equals("enterBarrier")&&
134             mdcall.getClassDesc().getSymbol().equals("Barrier"))
135           containsBarrier.add(md);
136       }
137     }
138   }
139 }