adding a test case
[IRC.git] / Robust / src / Analysis / OwnershipAnalysis / ParameterDecomposition.java
1 package Analysis.OwnershipAnalysis;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6
7 // This class must be instantiated from objects out
8 // of a completed analysis.  Given a method's reachability
9 // graph and a call site, what heap regions might the
10 // parameter regions be decomposed into?
11 //
12 // Also you can build a call chain by constructing
13 // a new decomposition from another decomp and a
14 // flat call one step back in the chain.
15 public class ParameterDecomposition {
16
17
18   // the ownership analysis results to compute from
19   protected OwnershipAnalysis oa;
20
21   // info needed to use OwnershipGraph.resolveMethodCall()
22   // to do the parameter decomp mapping itself
23   protected FlatCall fcInCaller;
24   protected FlatMethod fmPossible;
25   protected MethodContext mcCallSite;
26   protected OwnershipGraph ogCallee;
27   protected OwnershipGraph ogCaller;
28
29   // computed information:
30   // a IDs are heap regions that map the primary parameter object region
31   // r IDs are regions that map to the gamma parameter region
32   // allocation sites are any that provide the regions a param could map to
33   // type descriptors are any types of any allocation site from above
34   protected Hashtable<Integer, Set<Integer>        > pi2a_id;
35   protected Hashtable<Integer, Set<Integer>        > pi2r_id;
36   protected Hashtable<Integer, Set<AllocationSite> > pi2a_as;
37   protected Hashtable<Integer, Set<AllocationSite> > pi2r_as;
38   protected Hashtable<Integer, Set<TypeDescriptor> > pi2a_td;
39   protected Hashtable<Integer, Set<TypeDescriptor> > pi2r_td;
40
41
42   public ParameterDecomposition(OwnershipAnalysis oa,
43                                 FlatCall fc,
44                                 FlatMethod fm,
45                                 MethodContext mc,
46                                 OwnershipGraph cee,
47                                 OwnershipGraph cer) {
48     oa.checkAnalysisComplete();
49     this.oa = oa;
50
51     MethodDescriptor md = (MethodDescriptor) mc.getDescriptor();
52     // the call site should be calling the method in question
53     assert fc.getMethod() == md;
54
55     this.fcInCaller = fc;
56     this.fmPossible = fm;
57     this.mcCallSite = mc;
58
59     // make copies of the graphs so that resolveMethodCall can
60     // destroy the graph while calculating the stuff we want
61     this.ogCallee = new OwnershipGraph();
62     this.ogCallee.merge(cee);
63
64     this.ogCaller = new OwnershipGraph();
65     this.ogCaller.merge(cer);
66
67     allocOutputStructs();
68
69     computeDecompositon();
70   }
71
72   /*
73      public ParameterDecomposition( ParameterDecomposition pd,
74                                  FlatCall fc ) {
75      this.oa = pd.oa;
76
77      // the call site should be calling the caller of
78      // the input parameter decomposition object
79      assert fc.getMethod() == pd.mdCaller;
80
81      mdCallee = pd.mdCaller;
82      mdCaller = getCaller( fc );
83      }
84    */
85
86   protected void allocOutputStructs() {
87     pi2a_id = new Hashtable<Integer, Set<Integer>        >();
88     pi2r_id = new Hashtable<Integer, Set<Integer>        >();
89     pi2a_as = new Hashtable<Integer, Set<AllocationSite> >();
90     pi2r_as = new Hashtable<Integer, Set<AllocationSite> >();
91     pi2a_td = new Hashtable<Integer, Set<TypeDescriptor> >();
92     pi2r_td = new Hashtable<Integer, Set<TypeDescriptor> >();
93   }
94
95   protected void computeDecompositon() {
96     MethodDescriptor mdCallee = (MethodDescriptor) mcCallSite.getDescriptor();
97
98     ogCaller.resolveMethodCall(fcInCaller,
99                                mdCallee.isStatic(),
100                                fmPossible,
101                                ogCallee,
102                                mcCallSite,
103                                this);
104   }
105
106   // called by resolveMethodCall in decomp mode
107   // to report mapping results
108   protected void mapRegionToParamObject(HeapRegionNode hrn, Integer paramIndex) {
109
110     // extract region's intergraph ID
111     Set<Integer> hrnIDs = pi2a_id.get(paramIndex);
112     if( hrnIDs == null ) {
113       hrnIDs = new HashSet<Integer>();
114     }
115     hrnIDs.add(hrn.getID() );
116     pi2a_id.put(paramIndex, hrnIDs);
117
118     // the regions allocation site (if any)
119     AllocationSite as = hrn.getAllocationSite();
120     if( as != null ) {
121       Set<AllocationSite> asSet = pi2a_as.get(paramIndex);
122       if( asSet == null ) {
123         asSet = new HashSet<AllocationSite>();
124       }
125       asSet.add(as);
126       pi2a_as.put(paramIndex, asSet);
127
128       // and if there is an allocation site, grab type
129       Set<TypeDescriptor> tdSet = pi2a_td.get(paramIndex);
130       if( tdSet == null ) {
131         tdSet = new HashSet<TypeDescriptor>();
132       }
133       tdSet.add(as.getType() );
134       pi2a_td.put(paramIndex, tdSet);
135     }
136   }
137
138   protected void mapRegionToParamReachable(HeapRegionNode hrn, Integer paramIndex) {
139
140     // extract region's intergraph ID
141     Set<Integer> hrnIDs = pi2r_id.get(paramIndex);
142     if( hrnIDs == null ) {
143       hrnIDs = new HashSet<Integer>();
144     }
145     hrnIDs.add(hrn.getID() );
146     pi2r_id.put(paramIndex, hrnIDs);
147
148     // the regions allocation site (if any)
149     AllocationSite as = hrn.getAllocationSite();
150     if( as != null ) {
151       Set<AllocationSite> asSet = pi2r_as.get(paramIndex);
152       if( asSet == null ) {
153         asSet = new HashSet<AllocationSite>();
154       }
155       asSet.add(as);
156       pi2r_as.put(paramIndex, asSet);
157
158       // and if there is an allocation site, grab type
159       Set<TypeDescriptor> tdSet = pi2r_td.get(paramIndex);
160       if( tdSet == null ) {
161         tdSet = new HashSet<TypeDescriptor>();
162       }
163       tdSet.add(as.getType() );
164       pi2r_td.put(paramIndex, tdSet);
165     }
166   }
167
168
169   // this family of "gets" returns, for some
170   // parameter index, all of the associated data
171   // that parameter might decompose into
172   public Set<Integer> getParamObject_hrnIDs(Integer paramIndex) {
173     Set<Integer> hrnIDs = pi2a_id.get(paramIndex);
174     if( hrnIDs == null ) {
175       hrnIDs = new HashSet<Integer>();
176     }
177     return hrnIDs;
178   }
179
180   public Set<AllocationSite> getParamObject_allocSites(Integer paramIndex) {
181     Set<AllocationSite> asSet = pi2a_as.get(paramIndex);
182     if( asSet == null ) {
183       asSet = new HashSet<AllocationSite>();
184     }
185     return asSet;
186   }
187
188   public Set<TypeDescriptor> getParamObject_TypeDescs(Integer paramIndex) {
189     Set<TypeDescriptor> tdSet = pi2a_td.get(paramIndex);
190     if( tdSet == null ) {
191       tdSet = new HashSet<TypeDescriptor>();
192     }
193     return tdSet;
194   }
195
196
197   public Set<Integer> getParamReachable_hrnIDs(Integer paramIndex) {
198     Set<Integer> hrnIDs = pi2r_id.get(paramIndex);
199     if( hrnIDs == null ) {
200       hrnIDs = new HashSet<Integer>();
201     }
202     return hrnIDs;
203   }
204
205   public Set<AllocationSite> getParamReachable_allocSites(Integer paramIndex) {
206     Set<AllocationSite> asSet = pi2r_as.get(paramIndex);
207     if( asSet == null ) {
208       asSet = new HashSet<AllocationSite>();
209     }
210     return asSet;
211   }
212
213   public Set<TypeDescriptor> getParamReachable_TypeDescs(Integer paramIndex) {
214     Set<TypeDescriptor> tdSet = pi2r_td.get(paramIndex);
215     if( tdSet == null ) {
216       tdSet = new HashSet<TypeDescriptor>();
217     }
218     return tdSet;
219   }
220 }