1 package Analysis.Prefetch;
4 import Analysis.CallGraph.CallGraph;
5 import Analysis.Prefetch.PrefetchPair;
6 import Analysis.Prefetch.PairMap;
7 import Analysis.Prefetch.IndexDescriptor;
11 import IR.MethodDescriptor;
14 import IR.ClassDescriptor;
16 public class PrefetchAnalysis {
22 Set<FlatNode> tovisit;
23 public Hashtable<FlatNode, Hashtable<PrefetchPair, Double>> prefetch_hash;//holds all flatnodes and corresponding prefetch set
24 public Hashtable<FlatNode, Hashtable<FlatNode, PairMap>> pmap_hash;//holds all flatnodes and mappings between child prefetch pair and parent prefetch pair
25 public static final double PROB_DIFF = 0.05; //threshold for difference in probabilities during first phase of analysis
26 public static final double ANALYSIS_THRESHOLD_PROB = 0.10; //threshold for prefetches to stop propagating during first phase of analysis
27 public static final double PREFETCH_THRESHOLD_PROB = 0.30;//threshold for prefetches to stop propagating while applying prefetch rules during second phase of analysis
29 public PrefetchAnalysis(State state, CallGraph callgraph, TypeUtil typeutil) {
30 this.typeutil=typeutil;
32 this.callgraph=callgraph;
33 prefetch_hash = new Hashtable<FlatNode, Hashtable<PrefetchPair,Double>>();
34 pmap_hash = new Hashtable<FlatNode, Hashtable<FlatNode, PairMap>>();
35 this.loop=new LoopExit(state);
40 /** This function starts the prefetch analysis */
41 private void DoPrefetch() {
42 for(Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();classit.hasNext();) {
43 ClassDescriptor cn=(ClassDescriptor)classit.next();
48 /** This function calls analysis for every method in a class */
49 private void doMethodAnalysis(ClassDescriptor cn) {
50 for (Iterator methodit=cn.getMethods();methodit.hasNext();) {
51 MethodDescriptor md=(MethodDescriptor)methodit.next();
52 if (state.excprefetch.contains(md.getClassMethodName()))
53 continue; //Skip this method
54 Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
55 FlatMethod fm=state.getMethodFlat(md);
56 doFlatNodeAnalysis(fm);
57 doInsPrefetchAnalysis(fm, newprefetchset);
58 if(newprefetchset.size() > 0) {
59 addFlatPrefetchNode(newprefetchset);
61 newprefetchset = null;
65 /** This function calls analysis for every node in a method */
66 private void doFlatNodeAnalysis(FlatMethod fm) {
67 tovisit = fm.getNodeSet();
68 Hashtable<PrefetchPair, Double> nodehash = new Hashtable<PrefetchPair, Double>();
69 /* Create Empty Prefetch Sets for all flat nodes in the global hashtable */
70 while(!tovisit.isEmpty()) {
71 FlatNode fn = (FlatNode)tovisit.iterator().next();
72 prefetch_hash.put(fn, nodehash);
76 /* Visit and process nodes */
77 tovisit = fm.getNodeSet();
78 while(!tovisit.isEmpty()) {
79 FlatNode fn = (FlatNode)tovisit.iterator().next();
80 doChildNodeAnalysis(fm.getMethod(),fn);
86 * This function generates the prefetch sets for a given Flatnode considering the kind of node
87 * It calls severals functions based on the kind of the node and
88 * returns true: if the prefetch set has changed since last time the node was analysed
89 * returns false : otherwise
91 private void doChildNodeAnalysis(MethodDescriptor md, FlatNode curr) {
92 if (curr.kind()==FKind.FlatCondBranch) {
93 processFlatCondBranch((FlatCondBranch)curr, md);
95 Hashtable<PrefetchPair, Double> child_prefetch_set_copy = new Hashtable<PrefetchPair, Double>();
96 if(curr.numNext() != 0) {
97 FlatNode child_node = curr.getNext(0);
98 if(prefetch_hash.containsKey(child_node)) {
99 child_prefetch_set_copy = (Hashtable<PrefetchPair,Double>) prefetch_hash.get(child_node).clone();
102 switch(curr.kind()) {
104 processCall((FlatCall)curr,child_prefetch_set_copy);
107 case FKind.FlatBackEdge:
108 case FKind.FlatCheckNode:
109 case FKind.FlatReturnNode:
110 case FKind.FlatAtomicEnterNode:
111 case FKind.FlatAtomicExitNode:
112 case FKind.FlatFlagActionNode:
113 case FKind.FlatGlobalConvNode:
116 case FKind.FlatCastNode:
117 case FKind.FlatTagDeclaration:
118 processDefaultCase(curr,child_prefetch_set_copy);
120 case FKind.FlatMethod:
121 //TODO change it to take care of FlatMethod, Flatcalls
122 processFlatMethod(curr, child_prefetch_set_copy);
124 case FKind.FlatFieldNode:
125 processFlatFieldNode(curr, child_prefetch_set_copy);
127 case FKind.FlatElementNode:
128 processFlatElementNode(curr, child_prefetch_set_copy);
130 case FKind.FlatOpNode:
131 processFlatOpNode(curr, child_prefetch_set_copy);
133 case FKind.FlatLiteralNode:
134 processFlatLiteralNode(curr, child_prefetch_set_copy);
136 case FKind.FlatSetElementNode:
137 processFlatSetElementNode(curr, child_prefetch_set_copy);
139 case FKind.FlatSetFieldNode:
140 processFlatSetFieldNode(curr, child_prefetch_set_copy);
143 throw new Error("No such Flatnode kind");
148 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
149 * returns: true if something has changed in the new Prefetch set else
152 private boolean comparePrefetchSets(Hashtable<PrefetchPair, Double> oldPrefetchSet, Hashtable<PrefetchPair, Double> newPrefetchSet) {
153 if (oldPrefetchSet.size()!=newPrefetchSet.size())
156 for(Enumeration e = newPrefetchSet.keys();e.hasMoreElements();) {
157 PrefetchPair pp = (PrefetchPair) e.nextElement();
158 double newprob = newPrefetchSet.get(pp).doubleValue();
159 if (!oldPrefetchSet.containsKey(pp))
161 double oldprob = oldPrefetchSet.get(pp).doubleValue();
163 if((newprob - oldprob) > PROB_DIFF) {
166 if (newprob >= PREFETCH_THRESHOLD_PROB && oldprob < PREFETCH_THRESHOLD_PROB) {
169 if (oldprob>newprob) {
170 System.out.println("ERROR:" + pp);
171 System.out.println(oldprob + " -> "+ newprob);
177 private void updatePairMap(FlatNode curr, PairMap pm, int index) {
178 if (index>=curr.numNext())
180 if (!pmap_hash.containsKey(curr.getNext(index))) {
181 pmap_hash.put(curr.getNext(index), new Hashtable<FlatNode, PairMap>());
183 pmap_hash.get(curr.getNext(index)).put(curr, pm);
186 private void updatePrefetchSet(FlatNode curr, Hashtable<PrefetchPair, Double> newset) {
187 Hashtable<PrefetchPair, Double>oldset=prefetch_hash.get(curr);
188 if (comparePrefetchSets(oldset, newset)) {
189 for(int i=0;i<curr.numPrev();i++) {
190 tovisit.add(curr.getPrev(i));
192 prefetch_hash.put(curr, newset);
197 /** This function processes the prefetch set of FlatFieldNode
198 * It generates a new prefetch set after comparision with its children
199 * Then compares it with its old prefetch set
200 * If old prefetch set is not same as new prefetch set then enqueue the parents
201 * of the current FlatFieldNode
203 private void processFlatFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
204 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
205 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
206 FlatFieldNode currffn = (FlatFieldNode) curr;
207 PairMap pm = new PairMap();
209 /* Do Self analysis of the current node*/
210 FieldDescriptor currffn_field = currffn.getField();
211 TempDescriptor currffn_src = currffn.getSrc();
212 if (currffn_field.getType().isPtr()) {
213 PrefetchPair pp = new PrefetchPair(currffn_src, (Descriptor) currffn_field);
214 Double prob = new Double(1.0);
215 currcopy.put(pp, prob);
218 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
220 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
221 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
222 if (childpp.base == currffn.getDst() && (childpp.getDesc()!= null)) {
223 if (currffn.getField().getType().isPtr()) {
224 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
225 newdesc.add(currffn.getField());
226 newdesc.addAll(childpp.desc);
227 PrefetchPair newpp = new PrefetchPair(currffn.getSrc(), newdesc);
228 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
229 tocompare.put(newpp, newprob);
230 pm.addPair(childpp, newpp);
231 child_prefetch_set_copy.remove(childpp);
232 /* Check for independence of prefetch pairs to compute new probability */
233 if(child_prefetch_set_copy.containsKey(newpp)) {
234 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
235 if(newprob < ANALYSIS_THRESHOLD_PROB) {
236 tocompare.remove(newpp);
238 tocompare.put(newpp, newprob);
239 pm.addPair(newpp, newpp);
241 child_prefetch_set_copy.remove(newpp);
244 } else if(childpp.base == currffn.getDst() && (childpp.getDesc() == null)) {
245 child_prefetch_set_copy.remove(childpp);
246 } else if(childpp.containsTemp(currffn.getDst())) {
247 child_prefetch_set_copy.remove(childpp);
252 /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
253 * if so, calculate the new probability */
254 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
255 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
256 for(Enumeration e = currcopy.keys(); e.hasMoreElements();) {
257 PrefetchPair currpp = (PrefetchPair) e.nextElement();
258 if(currpp.equals(childpp)) {
259 pm.addPair(childpp, currpp);
260 child_prefetch_set_copy.remove(childpp);
266 /* Merge child prefetch pairs */
267 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
268 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
269 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
270 pm.addPair(childpp, childpp);
271 child_prefetch_set_copy.remove(childpp);
274 /* Merge curr prefetch pairs */
275 for (Enumeration e = currcopy.keys();e.hasMoreElements();) {
276 PrefetchPair currpp = (PrefetchPair) e.nextElement();
277 tocompare.put(currpp, currcopy.get(currpp).doubleValue());
278 currcopy.remove(currpp);
281 updatePairMap(curr, pm, 0);
282 updatePrefetchSet(curr, tocompare);
285 /** This function processes the prefetch set of a FlatElementNode
286 * It generates a new prefetch set after comparision with its children
287 * It compares the old prefetch set with this new prefetch set and enqueues the parents
288 * of the current node if change occurs and updates the global flatnode hash table
290 private void processFlatElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
292 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
293 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
294 FlatElementNode currfen = (FlatElementNode) curr;
295 PairMap pm = new PairMap();
298 /* Do Self analysis of the current node*/
299 TempDescriptor currfen_index = currfen.getIndex();
300 IndexDescriptor idesc = new IndexDescriptor(currfen_index, 0);
301 TempDescriptor currfen_src = currfen.getSrc();
302 if(currfen.getDst().getType().isPtr()) {
303 PrefetchPair pp = new PrefetchPair(currfen_src, (Descriptor) idesc);
304 Double prob = new Double(1.0);
305 currcopy.put(pp, prob);
308 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
309 PrefetchPair currpp = null;
310 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
311 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
312 if (childpp.base == currfen.getDst() && (childpp.getDesc()!= null)) {
313 if (currfen.getDst().getType().isPtr()) {
314 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
315 newdesc.add((Descriptor)idesc);
316 newdesc.addAll(childpp.desc);
317 PrefetchPair newpp = new PrefetchPair(currfen.getSrc(), newdesc);
318 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
319 tocompare.put(newpp, newprob);
320 pm.addPair(childpp, newpp);
321 child_prefetch_set_copy.remove(childpp);
322 /* Check for independence of prefetch pairs to compute new probability */
323 if(child_prefetch_set_copy.containsKey(newpp)) {
324 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
325 if(newprob < ANALYSIS_THRESHOLD_PROB) {
326 tocompare.remove(newpp);
328 tocompare.put(newpp, newprob);
329 pm.addPair(newpp, newpp);
331 child_prefetch_set_copy.remove(newpp);
334 } else if(childpp.base == currfen.getDst() && (childpp.getDesc() == null)) {
335 child_prefetch_set_copy.remove(childpp);
336 } else if(childpp.containsTemp(currfen.getDst())) {
337 child_prefetch_set_copy.remove(childpp);
342 /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
343 * if so calculate the new probability */
344 for(Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
345 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
346 for(Enumeration e = currcopy.keys(); e.hasMoreElements();) {
347 currpp = (PrefetchPair) e.nextElement();
348 if(currpp.equals(childpp)) {
349 pm.addPair(childpp, currpp);
350 child_prefetch_set_copy.remove(childpp);
356 /* Merge child prefetch pairs */
357 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
358 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
359 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
360 pm.addPair(childpp, childpp);
361 child_prefetch_set_copy.remove(childpp);
364 /* Merge curr prefetch pairs */
365 for (Enumeration e = currcopy.keys();e.hasMoreElements();) {
366 currpp = (PrefetchPair) e.nextElement();
367 tocompare.put(currpp, currcopy.get(currpp).doubleValue());
368 currcopy.remove(currpp);
371 updatePairMap(curr, pm, 0);
372 updatePrefetchSet(curr, tocompare);
375 /** This function processes the prefetch set of a FlatSetFieldNode
376 * It generates a new prefetch set after comparision with its children
377 * It compares the old prefetch set with this new prefetch set and enqueues the parents
378 * of the current node if change occurs and then updates the global flatnode hash table
380 private void processFlatSetFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
381 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
382 FlatSetFieldNode currfsfn = (FlatSetFieldNode) curr;
383 PairMap pm = new PairMap();
385 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
386 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
387 if(childpp.base == currfsfn.getDst()) {
388 int size = childpp.desc.size();
389 if(size >=2) { /*e.g. x.f = g (with child prefetches x.f.g, x.f[0].j) */
390 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
391 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
392 for(int i = 0;i<(childpp.desc.size()-1); i++) {
393 newdesc.add(i,childpp.desc.get(i+1));
395 PrefetchPair newpp = new PrefetchPair(currfsfn.getSrc(), newdesc);
396 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
397 tocompare.put(newpp, newprob);
398 pm.addPair(childpp, newpp);
399 child_prefetch_set_copy.remove(childpp);
400 /* Check for independence of prefetch pairs in newly generated prefetch pair
401 * to compute new probability */
402 if(child_prefetch_set_copy.containsKey(newpp)) {
403 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
404 if(newprob < ANALYSIS_THRESHOLD_PROB) {
405 tocompare.remove(newpp);
407 tocompare.put(newpp, newprob);
408 pm.addPair(newpp, newpp);
410 child_prefetch_set_copy.remove(newpp);
413 } else if(size==1) { /* e.g x.f = g (with child prefetch x.f) */
414 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
415 child_prefetch_set_copy.remove(childpp);
423 /* Merge child prefetch pairs */
424 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
425 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
426 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
427 pm.addPair(childpp, childpp);
428 child_prefetch_set_copy.remove(childpp);
431 updatePairMap(curr, pm, 0);
432 updatePrefetchSet(curr, tocompare);
435 /** This function processes the prefetch set of a FlatSetElementNode
436 * It generates a new prefetch set after comparision with its children
437 * It compares the old prefetch set with this new prefetch set and enqueues the parents
438 * of the current node if change occurs and then updates the global flatnode hash table
440 private void processFlatSetElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
441 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
442 FlatSetElementNode currfsen = (FlatSetElementNode) curr;
443 PairMap pm = new PairMap();
445 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
446 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
447 if (childpp.base == currfsen.getDst()){
448 int sizedesc = childpp.desc.size();
449 if((childpp.getDescAt(0) instanceof IndexDescriptor)) {
450 int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size();
451 if(sizetempdesc == 1) {
452 if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) {
453 /* For e.g. a[i] = g with child prefetch set a[i].r or a[i].r.f */
454 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
455 for(int i = 0;i<(childpp.desc.size()-1); i++) {
456 newdesc.add(i,childpp.desc.get(i+1));
458 PrefetchPair newpp = new PrefetchPair(currfsen.getSrc(), newdesc);
459 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
460 tocompare.put(newpp, newprob);
461 pm.addPair(childpp, newpp);
462 child_prefetch_set_copy.remove(childpp);
463 /* Check for independence of prefetch pairs to compute new probability */
464 if(child_prefetch_set_copy.containsKey(newpp)) {
465 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
466 if(newprob < ANALYSIS_THRESHOLD_PROB) {
467 tocompare.remove(newpp);
469 tocompare.put(newpp, newprob);
470 pm.addPair(newpp, newpp);
472 child_prefetch_set_copy.remove(newpp);
474 } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1))
475 /* For e.g. a[i] = g with child prefetch set a[i] */
476 child_prefetch_set_copy.remove(childpp);
483 /* Merge child prefetch pairs */
484 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
485 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
486 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
487 pm.addPair(childpp, childpp);
488 child_prefetch_set_copy.remove(childpp);
491 updatePairMap(curr, pm, 0);
492 updatePrefetchSet(curr, tocompare);
495 /** This function applies rules and does analysis for a FlatOpNode
496 * And updates the global prefetch hashtable
498 private void processFlatOpNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
500 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
501 FlatOpNode currfopn = (FlatOpNode) curr;
502 PairMap pm = new PairMap();
504 if(currfopn.getOp().getOp() == Operation.ASSIGN) {
505 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
506 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
507 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
509 /* For cases like x=y with child prefetch set x[i].z,x.g*/
510 if(childpp.base == currfopn.getDest()) {
511 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
512 newdesc.addAll(childpp.desc);
513 PrefetchPair newpp = new PrefetchPair(currfopn.getLeft(), newdesc);
514 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
515 tocompare.put(newpp, newprob);
516 pm.addPair(childpp, newpp);
517 child_prefetch_set_copy.remove(childpp);
518 /* Check for independence of prefetch pairs to compute new probability */
519 if(child_prefetch_set_copy.containsKey(newpp)) {
520 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
521 if(newprob < ANALYSIS_THRESHOLD_PROB) {
522 tocompare.remove(newpp);
524 tocompare.put(newpp, newprob);
525 pm.addPair(newpp, newpp);
527 child_prefetch_set_copy.remove(newpp);
529 /* For cases like x=y with child prefetch set r[x].p, r[p+x].q where x is a tempdescriptor*/
530 } else if(copyofchildpp.containsTemp(currfopn.getDest())) {
531 PrefetchPair newpp=copyofchildpp.replaceTemp(currfopn.getDest(), new TempDescriptor[] {currfopn.getLeft()});
532 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
533 tocompare.put(newpp, newprob);
534 pm.addPair(childpp, newpp);
535 child_prefetch_set_copy.remove(childpp);
536 /* Check for independence of prefetch pairs to compute new probability*/
537 if(child_prefetch_set_copy.containsKey(newpp)) {
538 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
539 if(newprob < ANALYSIS_THRESHOLD_PROB) {
540 tocompare.remove(newpp);
542 tocompare.put(newpp, newprob);
543 pm.addPair(newpp, newpp);
545 child_prefetch_set_copy.remove(newpp);
552 //case i = i+z with child prefetch set a[i].x
553 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) {
554 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
555 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
556 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
558 if(copyofchildpp.containsTemp(currfopn.getDest())) {
559 PrefetchPair newpp=copyofchildpp.replaceTemp(currfopn.getDest(), new TempDescriptor[] {currfopn.getLeft(), currfopn.getRight()});
560 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
561 tocompare.put(newpp, newprob);
562 pm.addPair(childpp, newpp);
563 child_prefetch_set_copy.remove(childpp);
564 /* Check for independence of prefetch pairs to compute new probability*/
565 if(child_prefetch_set_copy.containsKey(newpp)) {
566 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
567 if(newprob < ANALYSIS_THRESHOLD_PROB) {
568 tocompare.remove(newpp);
570 tocompare.put(newpp, newprob);
571 pm.addPair(newpp, newpp);
573 child_prefetch_set_copy.remove(newpp);
579 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.SUB)) {
580 for(Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
581 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
582 if(childpp.containsTemp(currfopn.getDest())) {
583 child_prefetch_set_copy.remove(childpp);
587 //FIXME Is not taken care of for cases like x = -y followed by a[x].i
590 /* Merge child prefetch pairs */
591 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
592 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
593 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
594 pm.addPair(childpp, childpp);
595 child_prefetch_set_copy.remove(childpp);
598 updatePairMap(curr, pm, 0);
599 updatePrefetchSet(curr, tocompare);
602 /** This function processes a FlatLiteralNode where cases such as
603 * for e.g. i = 0 with child prefetch sets a[i].r, a[j+i].r or a[j].b[i].r
605 private void processFlatLiteralNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
606 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
607 FlatLiteralNode currfln = (FlatLiteralNode) curr;
608 PairMap pm = new PairMap();
610 if(currfln.getType().isIntegerType()) {
611 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
612 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
613 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
614 if(copyofchildpp.containsTemp(currfln.getDst())) {
615 ArrayList<Descriptor> copychilddesc = (ArrayList<Descriptor>) copyofchildpp.getDesc();
616 int sizetempdesc = copychilddesc.size();
617 for(ListIterator it = copychilddesc.listIterator();it.hasNext();) {
618 Object o = it.next();
619 if(o instanceof IndexDescriptor) {
620 ArrayList<TempDescriptor> td = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
621 int sizetddesc = td.size();
622 if(td.contains(currfln.getDst())) {
623 int index = td.indexOf(currfln.getDst());
625 ((IndexDescriptor)o).offset += (Integer)currfln.getValue();
629 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
630 newdesc.addAll(copychilddesc);
631 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
632 Double newprob = (child_prefetch_set_copy.get(childpp)).doubleValue();
633 tocompare.put(newpp, newprob);
634 pm.addPair(childpp, newpp);
635 child_prefetch_set_copy.remove(childpp);
636 /* Check for independence of prefetch pairs to compute new probability */
637 if(child_prefetch_set_copy.containsKey(newpp)) {
638 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
639 if(newprob < ANALYSIS_THRESHOLD_PROB) {
640 tocompare.remove(newpp);
642 tocompare.put(newpp, newprob);
643 pm.addPair(newpp, newpp);
645 child_prefetch_set_copy.remove(newpp);
651 /* Merge child prefetch pairs */
652 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
653 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
654 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
655 pm.addPair(childpp, childpp);
656 child_prefetch_set_copy.remove(childpp);
659 updatePairMap(curr, pm, 0);
660 updatePrefetchSet(curr, tocompare);
663 /** This function processes a FlatMethod where the method propagates
664 * the entire prefetch set of its child node */
665 private void processFlatMethod(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
666 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
667 FlatMethod currfm = (FlatMethod) curr;
668 PairMap pm = new PairMap();
670 /* Merge child prefetch pairs */
671 for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
672 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
673 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
674 pm.addPair(childpp, childpp);
677 updatePairMap(curr, pm, 0);
678 updatePrefetchSet(curr, tocompare);
681 /** This function handles the processes the FlatNode of type FlatCondBranch
682 * It combines prefetches of both child elements and create a new hash table called
683 * branch_prefetch_set to contains the entries of both its children
685 private void processFlatCondBranch(FlatCondBranch fcb, MethodDescriptor md) {
686 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();//temporary hash table
687 PairMap truepm = new PairMap();
688 PairMap falsepm = new PairMap();
689 Hashtable<PrefetchPair, Double> truechild=prefetch_hash.get(fcb.getNext(0));
690 Hashtable<PrefetchPair, Double> falsechild=prefetch_hash.get(fcb.getNext(1));
692 HashSet<PrefetchPair> allpp=new HashSet<PrefetchPair>();
693 allpp.addAll(truechild.keySet());
694 allpp.addAll(falsechild.keySet());
696 for(Iterator<PrefetchPair> ppit=allpp.iterator();ppit.hasNext();) {
697 PrefetchPair pp=ppit.next();
698 double trueprob=0,falseprob=0;
699 if (truechild.containsKey(pp))
700 trueprob=truechild.get(pp).doubleValue();
701 if (falsechild.containsKey(pp))
702 falseprob=falsechild.get(pp).doubleValue();
704 double newprob=trueprob*fcb.getTrueProb()+falseprob*fcb.getFalseProb();
705 if (loop.isLoopingBranch(md,fcb)&&
710 if(newprob < ANALYSIS_THRESHOLD_PROB) //Skip pp that are below threshold
713 tocompare.put(pp, newprob);
714 if (truechild.containsKey(pp))
715 truepm.addPair(pp, pp);
717 if (falsechild.containsKey(pp))
718 falsepm.addPair(pp, pp);
722 updatePairMap(fcb, truepm, 0);
723 updatePairMap(fcb, falsepm, 1);
724 updatePrefetchSet(fcb, tocompare);
727 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
728 * prefetches up the FlatNode*/
729 private void processDefaultCase(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
730 PairMap pm = new PairMap();
731 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
733 /* Propagate all child nodes */
735 for(Enumeration e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
736 PrefetchPair childpp = (PrefetchPair) e.nextElement();
737 TempDescriptor[] writearray=curr.writesTemps();
738 for(int i=0;i<writearray.length;i++) {
739 TempDescriptor wtd=writearray[i];
740 if(childpp.base == wtd||
741 childpp.containsTemp(wtd))
744 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
745 pm.addPair(childpp, childpp);
748 updatePairMap(curr, pm, 0);
749 updatePrefetchSet(curr, tocompare);
752 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
753 * prefetches up the FlatNode*/
754 private void processCall(FlatCall curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
755 PairMap pm = new PairMap();
756 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
758 /* Don't propagate prefetches across cache clear */
759 if (!curr.getMethod().getClassMethodName().equals("System.clearPrefetchCache")) {
760 /* Propagate all child nodes */
762 for(Enumeration e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
763 PrefetchPair childpp = (PrefetchPair) e.nextElement();
764 TempDescriptor[] writearray=curr.writesTemps();
765 for(int i=0;i<writearray.length;i++) {
766 TempDescriptor wtd=writearray[i];
767 if(childpp.base == wtd||
768 childpp.containsTemp(wtd))
771 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
772 pm.addPair(childpp, childpp);
776 updatePairMap(curr, pm, 0);
777 updatePrefetchSet(curr, tocompare);
780 /** This function prints the Prefetch pairs of a given flatnode */
781 private void printPrefetchPairs(FlatNode fn) {
782 if(prefetch_hash.containsKey(fn)) {
783 System.out.print("Prefetch" + "(");
784 Hashtable<PrefetchPair, Double> currhash = (Hashtable) prefetch_hash.get(fn);
785 for(Enumeration pphash= currhash.keys(); pphash.hasMoreElements();) {
786 PrefetchPair pp = (PrefetchPair) pphash.nextElement();
787 System.out.print(pp.toString() + ", ");
789 System.out.println(")");
791 System.out.println("Flatnode is currently not present in the global hash: Prefetch Set is Empty");
795 private void doInsPrefetchAnalysis(FlatMethod fm, Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
796 Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
797 HashSet<PrefetchPair> pset1_init = new HashSet<PrefetchPair>();
798 LinkedList<FlatNode> newtovisit = new LinkedList<FlatNode>();
799 LinkedList<FlatNode> newvisited = new LinkedList<FlatNode>();
801 newtovisit.addLast((FlatNode)fm);
802 while(!newtovisit.isEmpty()) {
803 FlatNode fn = (FlatNode) newtovisit.iterator().next();
804 newtovisit.remove(0);
805 pset1_hash.put(fn, pset1_init); //Initialize pset1_hash
806 newvisited.addLast(fn);
807 for(int i=0; i<fn.numNext(); i++) {
808 FlatNode nn = fn.getNext(i);
809 if(!newtovisit.contains(nn) && !newvisited.contains(nn)){
810 newtovisit.addLast(nn);
815 /* Delete redundant and subset prefetch pairs */
818 /* Start with a top down sorted order of nodes */
819 while(!newvisited.isEmpty()) {
820 applyPrefetchInsertRules((FlatNode) newvisited.getFirst(), newvisited, pset1_hash, newprefetchset);
821 newvisited.remove(0);
825 /** This function deletes the smaller prefetch pair subset from a list of prefetch pairs
826 * for e.g. if there are 2 prefetch pairs a.b.c.d and a.b.c for a given flatnode
827 * then this function drops a.b.c from the prefetch set of the flatnode */
828 private void delSubsetPPairs() {
829 for (Enumeration e = prefetch_hash.keys();e.hasMoreElements();) {
830 FlatNode fn = (FlatNode) e.nextElement();
831 Hashtable ppairs = prefetch_hash.get(fn);
832 Vector<PrefetchPair> pplist = new Vector<PrefetchPair>();
833 Vector pplength = new Vector();
834 Vector ppisMod = new Vector();
835 for(Enumeration epp = ((Hashtable)(prefetch_hash.get(fn))).keys();epp.hasMoreElements();) {
836 PrefetchPair pp = (PrefetchPair) epp.nextElement();
838 int length = pp.desc.size()+ 1;
839 pplength.add(length);
842 int numpp = ((Hashtable)(prefetch_hash.get(fn))).size();
843 for (int i = 0; i < numpp; i++) {
844 for (int j = i+1; j < numpp; j++) {
846 int x = ((Integer) (pplength.get(i))).intValue();
847 if (((Integer) (pplength.get(i))).intValue() < ((Integer)( pplength.get(j))).intValue()) {
848 ret = isSubSet(pplist.get(i), pplist.get(j));
853 ret = isSubSet(pplist.get(j), pplist.get(i));
860 for (int i = 0; i < numpp; i++) {
861 if (((Integer)(ppisMod.get(i))).intValue() == 1) {
862 PrefetchPair pp = (PrefetchPair) pplist.get(i);
869 /** This function returns: true if the shorter prefetch pair is a subset of the longer prefetch
870 * pair else it returns: false */
871 private boolean isSubSet(PrefetchPair shrt, PrefetchPair lng) {
872 if (shrt.base != lng.base) {
875 for (int j = 0; j < shrt.desc.size(); j++) {
876 if(shrt.getDescAt(j) instanceof IndexDescriptor) {
877 IndexDescriptor shrtid = (IndexDescriptor) shrt.getDescAt(j);
878 if(lng.getDescAt(j) instanceof IndexDescriptor){
879 IndexDescriptor lngid = (IndexDescriptor) lng.getDescAt(j);
880 if(shrtid.equals(lngid)) {
889 if ((Descriptor)shrt.getDescAt(j) != (Descriptor)lng.getDescAt(j)){
897 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
898 * returns: true if something has changed in the new Prefetch set else
901 private boolean comparePSet1(HashSet<PrefetchPair> oldPSet, HashSet<PrefetchPair>newPSet) {
902 if(oldPSet.size() != newPSet.size()) {
905 for(Iterator it = newPSet.iterator();it.hasNext();) {
906 if(!oldPSet.contains((PrefetchPair)it.next())) {
914 /** This function creates a set called pset1 that contains prefetch pairs that have already
915 * been prefetched. While traversing the graph of a flat representation in a top down fashion,
916 * this function creates pset1 such that it contains prefetch pairs that have been prefetched at
917 * the previous nodes */
919 private void applyPrefetchInsertRules(FlatNode fn, LinkedList<FlatNode> newvisited, Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash, Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
921 if(fn.kind() == FKind.FlatMethod) {
922 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
923 if(prefetch_hash.containsKey(fn)) {
924 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
925 for(Enumeration e = prefetchset.keys();e.hasMoreElements();) {
926 PrefetchPair pp = (PrefetchPair) e.nextElement();
927 /* Apply initial rule */
928 if(prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB) {
932 /* Enqueue child node if Pset1 has changed */
933 if (comparePSet1(pset1_hash.get(fn), pset1)) {
934 for(int j=0; j<fn.numNext(); j++) {
935 FlatNode nn = fn.getNext(j);
936 newvisited.addLast((FlatNode)nn);
938 pset1_hash.put(fn, pset1);
940 newprefetchset.put(fn, pset1);
942 } else { /* Nodes other than Flat Method Node */
943 HashSet<PrefetchPair> pset2 = new HashSet<PrefetchPair>();
944 HashSet<PrefetchPair> newpset = new HashSet<PrefetchPair>();
945 if(prefetch_hash.containsKey(fn)) {
946 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
947 Hashtable<FlatNode, PairMap> ppairmaphash = pmap_hash.get(fn);
948 for(Enumeration epset = prefetchset.keys(); epset.hasMoreElements();) {
949 PrefetchPair pp = (PrefetchPair) epset.nextElement();
950 boolean pprobIsGreater = (prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB);
951 boolean mapprobIsLess=false;
952 boolean mapIsPresent=true;
953 for(int i=0;i<fn.numPrev();i++) {
954 FlatNode parentnode=fn.getPrev(i);
955 PairMap pm = (PairMap) ppairmaphash.get(parentnode);
957 if(pm!=null&&pm.getPair(pp) != null) {
958 PrefetchPair mappedpp = pm.getPair(pp);
959 if(prefetch_hash.get(parentnode).containsKey(mappedpp)) {
960 double prob = prefetch_hash.get(parentnode).get(mappedpp).doubleValue();
961 if(prob < PREFETCH_THRESHOLD_PROB)
962 mapprobIsLess = true;
965 mapprobIsLess = true;
968 if(pset1_hash.containsKey(parentnode)) {
970 HashSet pset = pset1_hash.get(parentnode);
974 if(!pset.contains((PrefetchPair) pm.getPair(pp)))
975 mapIsPresent = false;
979 throw new Error("applyPrefetchInsertRules() Parent node not present in pset1_hash: Not Possible");
986 if(pprobIsGreater && mapprobIsLess)
990 throw new Error("applyPrefetchInsertRules() fn: " +fn+ "not found");
993 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
995 pset1.addAll(newpset);
996 /* Enqueue child node if Pset1 has changed */
997 if (comparePSet1(pset1_hash.get(fn), pset1)) {
998 for(int i=0; i<fn.numNext(); i++) {
999 FlatNode nn = fn.getNext(i);
1000 newvisited.addLast((FlatNode)nn);
1002 pset1_hash.put(fn, pset1);
1005 /* To insert prefetch, apply rule: if the newpset minus pset2 is nonempty
1006 * then insert a new prefetch node here*/
1008 HashSet<PrefetchPair> s = new HashSet<PrefetchPair>();
1009 for(Iterator it = newpset.iterator(); it.hasNext();) {
1010 PrefetchPair pp = (PrefetchPair) it.next();
1011 if(!pset2.contains(pp)) {
1015 newprefetchset.put(fn, s);
1019 private void addFlatPrefetchNode(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
1020 boolean isFNPresent = false; /* Detects presence of FlatNew node */
1021 /* This modifies the Flat representation graph */
1022 for(Enumeration e = newprefetchset.keys();e.hasMoreElements();) {
1023 FlatNode fn = (FlatNode) e.nextElement();
1024 FlatPrefetchNode fpn = new FlatPrefetchNode();
1025 if(newprefetchset.get(fn).size() > 0) {
1026 fpn.insAllpp((HashSet)newprefetchset.get(fn));
1027 if(fn.kind() == FKind.FlatMethod) {
1028 FlatNode nn = fn.getNext(0);
1032 /* Check if previous node of this FlatNode is a NEW node
1033 * If yes, delete this flatnode and its prefetch set from hash table
1034 * This eliminates prefetches for NULL ptrs*/
1035 for(int i = 0; i< fn.numPrev(); i++) {
1036 FlatNode nn = fn.getPrev(i);
1037 if(nn.kind() == FKind.FlatNew) {
1042 while(fn.numPrev() > 0) {
1043 FlatNode nn = fn.getPrev(0);
1044 for(int j = 0; j<nn.numNext(); j++) {
1045 if(nn.getNext(j) == fn) {