1 package Analysis.Prefetch;
4 import Analysis.CallGraph.CallGraph;
5 import Analysis.Locality.LocalityAnalysis;
6 import Analysis.Prefetch.PrefetchPair;
7 import Analysis.Prefetch.PairMap;
8 import Analysis.Prefetch.IndexDescriptor;
12 import IR.MethodDescriptor;
15 import IR.ClassDescriptor;
17 public class PrefetchAnalysis {
23 Set<FlatNode> tovisit;
24 public Hashtable<FlatNode, Hashtable<PrefetchPair, Double>> prefetch_hash; //holds all flatnodes and corresponding prefetch set
25 public Hashtable<FlatNode, Hashtable<FlatNode, PairMap>> pmap_hash; //holds all flatnodes and mappings between child prefetch pair and parent prefetch pair
26 public static final double PROB_DIFF = 0.05; //threshold for difference in probabilities during first phase of analysis
27 public static final double ANALYSIS_THRESHOLD_PROB = 0.10; //threshold for prefetches to stop propagating during first phase of analysis
28 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 static int prefetchsiteid = 1; //initialized to one because there is a prefetch siteid 0 for starting remote thread
30 LocalityAnalysis locality;
32 public PrefetchAnalysis(State state, CallGraph callgraph, TypeUtil typeutil, LocalityAnalysis locality) {
33 this.typeutil=typeutil;
35 this.callgraph=callgraph;
36 this.locality=locality;
37 prefetch_hash = new Hashtable<FlatNode, Hashtable<PrefetchPair,Double>>();
38 pmap_hash = new Hashtable<FlatNode, Hashtable<FlatNode, PairMap>>();
39 this.loop=new LoopExit(state);
44 /** This function starts the prefetch analysis */
45 private void DoPrefetch() {
46 for (Iterator methodit=locality.getMethods().iterator(); methodit.hasNext();) {
47 MethodDescriptor md=(MethodDescriptor)methodit.next();
48 if (state.excprefetch.contains(md.getClassMethodName()))
49 continue; //Skip this method
50 Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
51 FlatMethod fm=state.getMethodFlat(md);
52 doFlatNodeAnalysis(fm);
53 doInsPrefetchAnalysis(fm, newprefetchset);
54 if(newprefetchset.size() > 0) {
55 addFlatPrefetchNode(newprefetchset);
57 newprefetchset = null;
61 /** This function calls analysis for every node in a method */
62 private void doFlatNodeAnalysis(FlatMethod fm) {
63 tovisit = fm.getNodeSet();
64 Hashtable<PrefetchPair, Double> nodehash = new Hashtable<PrefetchPair, Double>();
65 /* Create Empty Prefetch Sets for all flat nodes in the global hashtable */
66 while(!tovisit.isEmpty()) {
67 FlatNode fn = (FlatNode)tovisit.iterator().next();
68 prefetch_hash.put(fn, nodehash);
72 /* Visit and process nodes */
73 tovisit = fm.getNodeSet();
74 while(!tovisit.isEmpty()) {
75 FlatNode fn = (FlatNode)tovisit.iterator().next();
76 doChildNodeAnalysis(fm.getMethod(),fn);
82 * This function generates the prefetch sets for a given Flatnode considering the kind of node
83 * It calls severals functions based on the kind of the node and
84 * returns true: if the prefetch set has changed since last time the node was analysed
85 * returns false : otherwise
87 private void doChildNodeAnalysis(MethodDescriptor md, FlatNode curr) {
88 if (curr.kind()==FKind.FlatCondBranch) {
89 processFlatCondBranch((FlatCondBranch)curr, md);
91 Hashtable<PrefetchPair, Double> child_prefetch_set_copy = new Hashtable<PrefetchPair, Double>();
92 if(curr.numNext() != 0) {
93 FlatNode child_node = curr.getNext(0);
94 if(prefetch_hash.containsKey(child_node)) {
95 child_prefetch_set_copy = (Hashtable<PrefetchPair,Double>)prefetch_hash.get(child_node).clone();
101 processCall((FlatCall)curr,child_prefetch_set_copy);
104 case FKind.FlatBackEdge:
105 case FKind.FlatCheckNode:
106 case FKind.FlatReturnNode:
107 case FKind.FlatAtomicEnterNode:
108 case FKind.FlatAtomicExitNode:
109 case FKind.FlatFlagActionNode:
110 case FKind.FlatGlobalConvNode:
114 case FKind.FlatCastNode:
115 case FKind.FlatTagDeclaration:
116 case FKind.FlatInstanceOfNode:
117 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);
125 case FKind.FlatFieldNode:
126 processFlatFieldNode(curr, child_prefetch_set_copy);
129 case FKind.FlatElementNode:
130 processFlatElementNode(curr, child_prefetch_set_copy);
133 case FKind.FlatOpNode:
134 processFlatOpNode(curr, child_prefetch_set_copy);
137 case FKind.FlatLiteralNode:
138 processFlatLiteralNode(curr, child_prefetch_set_copy);
141 case FKind.FlatSetElementNode:
142 processFlatSetElementNode(curr, child_prefetch_set_copy);
145 case FKind.FlatSetFieldNode:
146 processFlatSetFieldNode(curr, child_prefetch_set_copy);
149 case FKind.FlatOffsetNode:
150 processDefaultCase(curr,child_prefetch_set_copy);
154 throw new Error("No such Flatnode kind");
159 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
160 * returns: true if something has changed in the new Prefetch set else
163 private boolean comparePrefetchSets(Hashtable<PrefetchPair, Double> oldPrefetchSet, Hashtable<PrefetchPair, Double> newPrefetchSet) {
164 if (oldPrefetchSet.size()!=newPrefetchSet.size())
167 for(Enumeration e = newPrefetchSet.keys(); e.hasMoreElements();) {
168 PrefetchPair pp = (PrefetchPair) e.nextElement();
169 double newprob = newPrefetchSet.get(pp).doubleValue();
170 if (!oldPrefetchSet.containsKey(pp))
172 double oldprob = oldPrefetchSet.get(pp).doubleValue();
174 if((newprob - oldprob) > PROB_DIFF) {
177 if (newprob >= PREFETCH_THRESHOLD_PROB && oldprob < PREFETCH_THRESHOLD_PROB) {
180 if (oldprob>newprob) {
181 System.out.println("ERROR:" + pp);
182 System.out.println(oldprob + " -> "+ newprob);
188 private void updatePairMap(FlatNode curr, PairMap pm, int index) {
189 if (index>=curr.numNext())
191 if (!pmap_hash.containsKey(curr.getNext(index))) {
192 pmap_hash.put(curr.getNext(index), new Hashtable<FlatNode, PairMap>());
194 pmap_hash.get(curr.getNext(index)).put(curr, pm);
197 private void updatePrefetchSet(FlatNode curr, Hashtable<PrefetchPair, Double> newset) {
198 Hashtable<PrefetchPair, Double>oldset=prefetch_hash.get(curr);
199 if (comparePrefetchSets(oldset, newset)) {
200 for(int i=0; i<curr.numPrev(); i++) {
201 tovisit.add(curr.getPrev(i));
203 prefetch_hash.put(curr, newset);
208 /** This function processes the prefetch set of FlatFieldNode
209 * It generates a new prefetch set after comparision with its children
210 * Then compares it with its old prefetch set
211 * If old prefetch set is not same as new prefetch set then enqueue the parents
212 * of the current FlatFieldNode
214 private void processFlatFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
215 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
216 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
217 FlatFieldNode currffn = (FlatFieldNode) curr;
218 PairMap pm = new PairMap();
220 /* Do Self analysis of the current node*/
221 FieldDescriptor currffn_field = currffn.getField();
222 TempDescriptor currffn_src = currffn.getSrc();
223 if (currffn_field.getType().isPtr()) {
224 PrefetchPair pp = new PrefetchPair(currffn_src, (Descriptor) currffn_field);
225 Double prob = new Double(1.0);
226 tocompare.put(pp, prob);
229 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
231 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
232 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
233 if (childpp.base == currffn.getDst() && (childpp.getDesc()!= null)) {
234 if (currffn.getField().getType().isPtr()) {
235 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
236 newdesc.add(currffn.getField());
237 newdesc.addAll(childpp.desc);
238 PrefetchPair newpp = new PrefetchPair(currffn.getSrc(), newdesc);
239 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
240 if (tocompare.containsKey(newpp)) {
241 Double oldprob=tocompare.get(newpp);
242 newprob=1.0-(1.0-oldprob)*(1.0-newprob);
244 tocompare.put(newpp, newprob);
245 pm.addPair(childpp, newpp);
248 } else if(childpp.base == currffn.getDst() && (childpp.getDesc() == null)) {
249 //covered by current prefetch
250 child_prefetch_set_copy.remove(childpp);
251 } else if(childpp.containsTemp(currffn.getDst())) {
252 child_prefetch_set_copy.remove(childpp);
254 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
255 if (tocompare.containsKey(childpp)) {
256 Double oldprob=tocompare.get(childpp);
257 newprob=1.0-(1.0-oldprob)*(1.0-newprob);
259 tocompare.put(childpp, newprob);
260 pm.addPair(childpp, childpp);
264 for(Iterator<PrefetchPair> it=tocompare.keySet().iterator(); it.hasNext();) {
265 PrefetchPair pp=it.next();
266 if (tocompare.get(pp)<ANALYSIS_THRESHOLD_PROB)
271 updatePairMap(curr, pm, 0);
272 updatePrefetchSet(curr, tocompare);
275 /** This function processes the prefetch set of a FlatElementNode
276 * It generates a new prefetch set after comparision with its children
277 * It compares the old prefetch set with this new prefetch set and enqueues the parents
278 * of the current node if change occurs and updates the global flatnode hash table
280 private void processFlatElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
282 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
283 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
284 FlatElementNode currfen = (FlatElementNode) curr;
285 PairMap pm = new PairMap();
288 /* Do Self analysis of the current node*/
289 TempDescriptor currfen_index = currfen.getIndex();
290 IndexDescriptor idesc = new IndexDescriptor(currfen_index, 0);
291 TempDescriptor currfen_src = currfen.getSrc();
292 if(currfen.getDst().getType().isPtr()) {
293 PrefetchPair pp = new PrefetchPair(currfen_src, (Descriptor) idesc);
294 Double prob = new Double(1.0);
295 currcopy.put(pp, prob);
298 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
299 PrefetchPair currpp = null;
300 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
301 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
302 if (childpp.base == currfen.getDst() && (childpp.getDesc()!= null)) {
303 if (currfen.getDst().getType().isPtr()) {
304 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
305 newdesc.add((Descriptor)idesc);
306 newdesc.addAll(childpp.desc);
307 PrefetchPair newpp = new PrefetchPair(currfen.getSrc(), newdesc);
308 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
309 tocompare.put(newpp, newprob);
310 pm.addPair(childpp, newpp);
311 child_prefetch_set_copy.remove(childpp);
312 /* Check for independence of prefetch pairs to compute new probability */
313 if(child_prefetch_set_copy.containsKey(newpp)) {
314 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
315 if(newprob < ANALYSIS_THRESHOLD_PROB) {
316 tocompare.remove(newpp);
318 tocompare.put(newpp, newprob);
319 pm.addPair(newpp, newpp);
321 child_prefetch_set_copy.remove(newpp);
324 } else if(childpp.base == currfen.getDst() && (childpp.getDesc() == null)) {
325 child_prefetch_set_copy.remove(childpp);
326 } else if(childpp.containsTemp(currfen.getDst())) {
327 child_prefetch_set_copy.remove(childpp);
332 /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
333 * if so calculate the new probability */
334 for(Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
335 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
336 for(Enumeration e = currcopy.keys(); e.hasMoreElements();) {
337 currpp = (PrefetchPair) e.nextElement();
338 if(currpp.equals(childpp)) {
339 pm.addPair(childpp, currpp);
340 child_prefetch_set_copy.remove(childpp);
346 /* Merge child prefetch pairs */
347 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
348 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
349 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
350 pm.addPair(childpp, childpp);
351 child_prefetch_set_copy.remove(childpp);
354 /* Merge curr prefetch pairs */
355 for (Enumeration e = currcopy.keys(); e.hasMoreElements();) {
356 currpp = (PrefetchPair) e.nextElement();
357 tocompare.put(currpp, currcopy.get(currpp).doubleValue());
358 currcopy.remove(currpp);
361 updatePairMap(curr, pm, 0);
362 updatePrefetchSet(curr, tocompare);
365 /** This function processes the prefetch set of a FlatSetFieldNode
366 * It generates a new prefetch set after comparision with its children
367 * It compares the old prefetch set with this new prefetch set and enqueues the parents
368 * of the current node if change occurs and then updates the global flatnode hash table
370 private void processFlatSetFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
371 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
372 FlatSetFieldNode currfsfn = (FlatSetFieldNode) curr;
373 PairMap pm = new PairMap();
375 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
376 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
377 if(childpp.base == currfsfn.getDst()) {
378 int size = childpp.desc.size();
379 if(size >=2) { /*e.g. x.f = g (with child prefetches x.f.g, x.f[0].j) */
380 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
381 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
382 for(int i = 0; i<(childpp.desc.size()-1); i++) {
383 newdesc.add(i,childpp.desc.get(i+1));
385 PrefetchPair newpp = new PrefetchPair(currfsfn.getSrc(), newdesc);
386 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
387 tocompare.put(newpp, newprob);
388 pm.addPair(childpp, newpp);
389 child_prefetch_set_copy.remove(childpp);
390 /* Check for independence of prefetch pairs in newly generated prefetch pair
391 * to compute new probability */
392 if(child_prefetch_set_copy.containsKey(newpp)) {
393 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
394 if(newprob < ANALYSIS_THRESHOLD_PROB) {
395 tocompare.remove(newpp);
397 tocompare.put(newpp, newprob);
398 pm.addPair(newpp, newpp);
400 child_prefetch_set_copy.remove(newpp);
403 } else if(size==1) { /* e.g x.f = g (with child prefetch x.f) */
404 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
405 child_prefetch_set_copy.remove(childpp);
413 /* Merge child prefetch pairs */
414 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
415 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
416 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
417 pm.addPair(childpp, childpp);
418 child_prefetch_set_copy.remove(childpp);
421 updatePairMap(curr, pm, 0);
422 updatePrefetchSet(curr, tocompare);
425 /** This function processes the prefetch set of a FlatSetElementNode
426 * It generates a new prefetch set after comparision with its children
427 * It compares the old prefetch set with this new prefetch set and enqueues the parents
428 * of the current node if change occurs and then updates the global flatnode hash table
430 private void processFlatSetElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
431 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
432 FlatSetElementNode currfsen = (FlatSetElementNode) curr;
433 PairMap pm = new PairMap();
435 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
436 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
437 if (childpp.base == currfsen.getDst()) {
438 int sizedesc = childpp.desc.size();
439 if((childpp.getDescAt(0) instanceof IndexDescriptor)) {
440 int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size();
441 if(sizetempdesc == 1) {
442 if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) {
443 /* For e.g. a[i] = g with child prefetch set a[i].r or a[i].r.f */
444 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
445 for(int i = 0; i<(childpp.desc.size()-1); i++) {
446 newdesc.add(i,childpp.desc.get(i+1));
448 PrefetchPair newpp = new PrefetchPair(currfsen.getSrc(), newdesc);
449 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
450 tocompare.put(newpp, newprob);
451 pm.addPair(childpp, newpp);
452 child_prefetch_set_copy.remove(childpp);
453 /* Check for independence of prefetch pairs to compute new probability */
454 if(child_prefetch_set_copy.containsKey(newpp)) {
455 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
456 if(newprob < ANALYSIS_THRESHOLD_PROB) {
457 tocompare.remove(newpp);
459 tocompare.put(newpp, newprob);
460 pm.addPair(newpp, newpp);
462 child_prefetch_set_copy.remove(newpp);
464 } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1))
465 /* For e.g. a[i] = g with child prefetch set a[i] */
466 child_prefetch_set_copy.remove(childpp);
473 /* Merge child prefetch pairs */
474 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
475 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
476 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
477 pm.addPair(childpp, childpp);
478 child_prefetch_set_copy.remove(childpp);
481 updatePairMap(curr, pm, 0);
482 updatePrefetchSet(curr, tocompare);
485 /** This function applies rules and does analysis for a FlatOpNode
486 * And updates the global prefetch hashtable
488 private void processFlatOpNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
490 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
491 FlatOpNode currfopn = (FlatOpNode) curr;
492 PairMap pm = new PairMap();
494 if(currfopn.getOp().getOp() == Operation.ASSIGN) {
495 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
496 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
497 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
499 /* For cases like x=y with child prefetch set x[i].z,x.g*/
500 if(childpp.base == currfopn.getDest()) {
501 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
502 newdesc.addAll(childpp.desc);
503 PrefetchPair newpp = new PrefetchPair(currfopn.getLeft(), newdesc);
504 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
505 tocompare.put(newpp, newprob);
506 pm.addPair(childpp, newpp);
507 child_prefetch_set_copy.remove(childpp);
508 /* Check for independence of prefetch pairs to compute new probability */
509 if(child_prefetch_set_copy.containsKey(newpp)) {
510 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
511 if(newprob < ANALYSIS_THRESHOLD_PROB) {
512 tocompare.remove(newpp);
514 tocompare.put(newpp, newprob);
515 pm.addPair(newpp, newpp);
517 child_prefetch_set_copy.remove(newpp);
519 /* For cases like x=y with child prefetch set r[x].p, r[p+x].q where x is a tempdescriptor*/
520 } else if(copyofchildpp.containsTemp(currfopn.getDest())) {
521 PrefetchPair newpp=copyofchildpp.replaceTemp(currfopn.getDest(), new TempDescriptor[] {currfopn.getLeft()});
522 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
523 tocompare.put(newpp, newprob);
524 pm.addPair(childpp, newpp);
525 child_prefetch_set_copy.remove(childpp);
526 /* Check for independence of prefetch pairs to compute new probability*/
527 if(child_prefetch_set_copy.containsKey(newpp)) {
528 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
529 if(newprob < ANALYSIS_THRESHOLD_PROB) {
530 tocompare.remove(newpp);
532 tocompare.put(newpp, newprob);
533 pm.addPair(newpp, newpp);
535 child_prefetch_set_copy.remove(newpp);
542 //case i = i+z with child prefetch set a[i].x
543 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) {
544 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
545 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
546 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
548 if(copyofchildpp.containsTemp(currfopn.getDest())) {
549 PrefetchPair newpp=copyofchildpp.replaceTemp(currfopn.getDest(), new TempDescriptor[] {currfopn.getLeft(), currfopn.getRight()});
550 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
551 tocompare.put(newpp, newprob);
552 pm.addPair(childpp, newpp);
553 child_prefetch_set_copy.remove(childpp);
554 /* Check for independence of prefetch pairs to compute new probability*/
555 if(child_prefetch_set_copy.containsKey(newpp)) {
556 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
557 if(newprob < ANALYSIS_THRESHOLD_PROB) {
558 tocompare.remove(newpp);
560 tocompare.put(newpp, newprob);
561 pm.addPair(newpp, newpp);
563 child_prefetch_set_copy.remove(newpp);
569 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.SUB)) {
570 for(Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
571 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
572 if(childpp.containsTemp(currfopn.getDest())) {
573 child_prefetch_set_copy.remove(childpp);
577 //FIXME Is not taken care of for cases like x = -y followed by a[x].i
580 /* Merge child prefetch pairs */
581 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
582 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
583 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
584 pm.addPair(childpp, childpp);
585 child_prefetch_set_copy.remove(childpp);
588 updatePairMap(curr, pm, 0);
589 updatePrefetchSet(curr, tocompare);
592 /** This function processes a FlatLiteralNode where cases such as
593 * for e.g. i = 0 with child prefetch sets a[i].r, a[j+i].r or a[j].b[i].r
595 private void processFlatLiteralNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
596 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
597 FlatLiteralNode currfln = (FlatLiteralNode) curr;
598 PairMap pm = new PairMap();
600 if(currfln.getType().isIntegerType()) {
601 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
602 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
603 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
604 if(copyofchildpp.containsTemp(currfln.getDst())) {
605 ArrayList<Descriptor> copychilddesc = (ArrayList<Descriptor>)copyofchildpp.getDesc();
606 int sizetempdesc = copychilddesc.size();
607 for(ListIterator it = copychilddesc.listIterator(); it.hasNext();) {
608 Object o = it.next();
609 if(o instanceof IndexDescriptor) {
610 ArrayList<TempDescriptor> td = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
611 int sizetddesc = td.size();
612 if(td.contains(currfln.getDst())) {
613 int index = td.indexOf(currfln.getDst());
615 ((IndexDescriptor)o).offset += (Integer)currfln.getValue();
619 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
620 newdesc.addAll(copychilddesc);
621 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
622 Double newprob = (child_prefetch_set_copy.get(childpp)).doubleValue();
623 tocompare.put(newpp, newprob);
624 pm.addPair(childpp, newpp);
625 child_prefetch_set_copy.remove(childpp);
626 /* Check for independence of prefetch pairs to compute new probability */
627 if(child_prefetch_set_copy.containsKey(newpp)) {
628 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
629 if(newprob < ANALYSIS_THRESHOLD_PROB) {
630 tocompare.remove(newpp);
632 tocompare.put(newpp, newprob);
633 pm.addPair(newpp, newpp);
635 child_prefetch_set_copy.remove(newpp);
641 /* Merge child prefetch pairs */
642 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
643 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
644 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
645 pm.addPair(childpp, childpp);
646 child_prefetch_set_copy.remove(childpp);
649 updatePairMap(curr, pm, 0);
650 updatePrefetchSet(curr, tocompare);
653 /** This function processes a FlatMethod where the method propagates
654 * the entire prefetch set of its child node */
655 private void processFlatMethod(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
656 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
657 FlatMethod currfm = (FlatMethod) curr;
658 PairMap pm = new PairMap();
660 /* Merge child prefetch pairs */
661 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
662 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
663 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
664 pm.addPair(childpp, childpp);
667 updatePairMap(curr, pm, 0);
668 updatePrefetchSet(curr, tocompare);
671 /** This function handles the processes the FlatNode of type FlatCondBranch
672 * It combines prefetches of both child elements and create a new hash table called
673 * branch_prefetch_set to contains the entries of both its children
675 private void processFlatCondBranch(FlatCondBranch fcb, MethodDescriptor md) {
676 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>(); //temporary hash table
677 PairMap truepm = new PairMap();
678 PairMap falsepm = new PairMap();
679 Hashtable<PrefetchPair, Double> truechild=prefetch_hash.get(fcb.getNext(0));
680 Hashtable<PrefetchPair, Double> falsechild=prefetch_hash.get(fcb.getNext(1));
682 HashSet<PrefetchPair> allpp=new HashSet<PrefetchPair>();
683 allpp.addAll(truechild.keySet());
684 allpp.addAll(falsechild.keySet());
686 for(Iterator<PrefetchPair> ppit=allpp.iterator(); ppit.hasNext();) {
687 PrefetchPair pp=ppit.next();
688 double trueprob=0,falseprob=0;
689 if (truechild.containsKey(pp))
690 trueprob=truechild.get(pp).doubleValue();
691 if (falsechild.containsKey(pp))
692 falseprob=falsechild.get(pp).doubleValue();
694 double newprob=trueprob*fcb.getTrueProb()+falseprob*fcb.getFalseProb();
695 if (loop.isLoopingBranch(md,fcb)&&
700 if(newprob < ANALYSIS_THRESHOLD_PROB) //Skip pp that are below threshold
703 tocompare.put(pp, newprob);
704 if (truechild.containsKey(pp))
705 truepm.addPair(pp, pp);
707 if (falsechild.containsKey(pp))
708 falsepm.addPair(pp, pp);
712 updatePairMap(fcb, truepm, 0);
713 updatePairMap(fcb, falsepm, 1);
714 updatePrefetchSet(fcb, tocompare);
717 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
718 * prefetches up the FlatNode*/
719 private void processDefaultCase(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
720 PairMap pm = new PairMap();
721 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
723 /* Propagate all child nodes */
725 for(Enumeration e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
726 PrefetchPair childpp = (PrefetchPair) e.nextElement();
727 TempDescriptor[] writearray=curr.writesTemps();
728 for(int i=0; i<writearray.length; i++) {
729 TempDescriptor wtd=writearray[i];
730 if(childpp.base == wtd||
731 childpp.containsTemp(wtd))
734 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
735 pm.addPair(childpp, childpp);
738 updatePairMap(curr, pm, 0);
739 updatePrefetchSet(curr, tocompare);
742 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
743 * prefetches up the FlatNode*/
744 private void processCall(FlatCall curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
745 PairMap pm = new PairMap();
746 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
748 /* Don't propagate prefetches across cache clear */
749 if (!(curr.getMethod().getClassMethodName().equals("System.clearPrefetchCache")||
750 curr.getMethod().getClassMethodName().equals("Barrier.enterBarrier"))) {
751 /* Propagate all child nodes */
753 for(Enumeration e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
754 PrefetchPair childpp = (PrefetchPair) e.nextElement();
755 TempDescriptor[] writearray=curr.writesTemps();
756 for(int i=0; i<writearray.length; i++) {
757 TempDescriptor wtd=writearray[i];
758 if(childpp.base == wtd||
759 childpp.containsTemp(wtd))
762 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
763 pm.addPair(childpp, childpp);
767 updatePairMap(curr, pm, 0);
768 updatePrefetchSet(curr, tocompare);
771 /** This function prints the Prefetch pairs of a given flatnode */
772 private void printPrefetchPairs(FlatNode fn) {
773 System.out.println(fn);
774 if(prefetch_hash.containsKey(fn)) {
775 System.out.print("Prefetch" + "(");
776 Hashtable<PrefetchPair, Double> currhash = (Hashtable) prefetch_hash.get(fn);
777 for(Enumeration pphash= currhash.keys(); pphash.hasMoreElements();) {
778 PrefetchPair pp = (PrefetchPair) pphash.nextElement();
779 System.out.print(pp.toString() + ", ");
781 System.out.println(")");
783 System.out.println("Flatnode is currently not present in the global hash: Prefetch Set is Empty");
787 private void doInsPrefetchAnalysis(FlatMethod fm, Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
788 Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
789 HashSet<PrefetchPair> pset1_init = new HashSet<PrefetchPair>();
790 LinkedList<FlatNode> newtovisit = new LinkedList<FlatNode>();
791 LinkedList<FlatNode> newvisited = new LinkedList<FlatNode>();
793 newtovisit.addLast((FlatNode)fm);
794 while(!newtovisit.isEmpty()) {
795 FlatNode fn = (FlatNode) newtovisit.iterator().next();
796 newtovisit.remove(0);
797 pset1_hash.put(fn, pset1_init); //Initialize pset1_hash
798 newvisited.addLast(fn);
799 for(int i=0; i<fn.numNext(); i++) {
800 FlatNode nn = fn.getNext(i);
801 if(!newtovisit.contains(nn) && !newvisited.contains(nn)) {
802 newtovisit.addLast(nn);
807 /* Start with a top down sorted order of nodes */
808 while(!newvisited.isEmpty()) {
809 applyPrefetchInsertRules((FlatNode) newvisited.getFirst(), newvisited, pset1_hash, newprefetchset);
810 newvisited.remove(0);
812 delSubsetPPairs(newprefetchset);
815 /** This function deletes the smaller prefetch pair subset from a list of prefetch pairs
816 * for e.g. if there are 2 prefetch pairs a.b.c.d and a.b.c for a given flatnode
817 * then this function drops a.b.c from the prefetch set of the flatnode */
818 private void delSubsetPPairs(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
819 for (Enumeration e = newprefetchset.keys(); e.hasMoreElements();) {
820 FlatNode fn = (FlatNode) e.nextElement();
821 Set<PrefetchPair> ppairs = newprefetchset.get(fn);
822 Set<PrefetchPair> toremove=new HashSet<PrefetchPair>();
824 for(Iterator<PrefetchPair> it1=ppairs.iterator(); it1.hasNext();) {
825 PrefetchPair pp1=it1.next();
826 if (toremove.contains(pp1))
828 int l1=pp1.desc.size()+1;
829 for(Iterator<PrefetchPair> it2=ppairs.iterator(); it2.hasNext();) {
830 PrefetchPair pp2=it2.next();
831 int l2=pp2.desc.size()+1;
833 if (l1<l2&&isSubSet(pp1,pp2))
836 if (l2>l1&&isSubSet(pp2,pp1))
841 ppairs.removeAll(toremove);
845 /** This function returns: true if the shorter prefetch pair is a subset of the longer prefetch
846 * pair else it returns: false */
847 private boolean isSubSet(PrefetchPair shrt, PrefetchPair lng) {
848 if (shrt.base != lng.base) {
851 for (int j = 0; j < shrt.desc.size(); j++) {
852 if(shrt.getDescAt(j) instanceof IndexDescriptor) {
853 IndexDescriptor shrtid = (IndexDescriptor) shrt.getDescAt(j);
854 if(lng.getDescAt(j) instanceof IndexDescriptor) {
855 IndexDescriptor lngid = (IndexDescriptor) lng.getDescAt(j);
856 if(shrtid.equals(lngid)) {
865 if ((Descriptor)shrt.getDescAt(j) != (Descriptor)lng.getDescAt(j)) {
873 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
874 * returns: true if something has changed in the new Prefetch set else
877 private boolean comparePSet1(HashSet<PrefetchPair> oldPSet, HashSet<PrefetchPair>newPSet) {
878 if(oldPSet.size() != newPSet.size()) {
881 for(Iterator it = newPSet.iterator(); it.hasNext();) {
882 if(!oldPSet.contains((PrefetchPair)it.next())) {
890 /** This function creates a set called pset1 that contains prefetch pairs that have already
891 * been prefetched. While traversing the graph of a flat representation in a top down fashion,
892 * this function creates pset1 such that it contains prefetch pairs that have been prefetched at
893 * the previous nodes */
895 private void applyPrefetchInsertRules(FlatNode fn, LinkedList<FlatNode> newvisited, Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash, Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
896 if(fn.kind() == FKind.FlatMethod) {
897 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
898 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
899 for(Enumeration e = prefetchset.keys(); e.hasMoreElements();) {
900 PrefetchPair pp = (PrefetchPair) e.nextElement();
901 /* Apply initial rule */
902 if(prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB) {
906 /* Enqueue child node if Pset1 has changed */
907 if (comparePSet1(pset1_hash.get(fn), pset1)) {
908 for(int j=0; j<fn.numNext(); j++) {
909 FlatNode nn = fn.getNext(j);
910 newvisited.addLast((FlatNode)nn);
912 pset1_hash.put(fn, pset1);
914 newprefetchset.put(fn, pset1);
915 } else { /* Nodes other than Flat Method Node */
916 HashSet<PrefetchPair> pset2 = new HashSet<PrefetchPair>();
917 HashSet<PrefetchPair> newpset = new HashSet<PrefetchPair>();
918 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
919 Hashtable<FlatNode, PairMap> ppairmaphash = pmap_hash.get(fn);
920 for(Enumeration epset = prefetchset.keys(); epset.hasMoreElements();) {
921 PrefetchPair pp = (PrefetchPair) epset.nextElement();
922 boolean pprobIsGreater = (prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB);
923 boolean mapprobIsLess=false;
924 boolean mapIsPresent=true;
925 for(int i=0; i<fn.numPrev(); i++) {
926 FlatNode parentnode=fn.getPrev(i);
927 PairMap pm = (PairMap) ppairmaphash.get(parentnode);
928 //Find if probability is less for previous node
929 if(pm!=null&&pm.getPair(pp) != null) {
930 PrefetchPair mappedpp = pm.getPair(pp);
931 if(prefetch_hash.get(parentnode).containsKey(mappedpp)) {
932 double prob = prefetch_hash.get(parentnode).get(mappedpp).doubleValue();
933 if(prob < PREFETCH_THRESHOLD_PROB)
934 mapprobIsLess = true;
936 mapprobIsLess = true;
938 mapprobIsLess = true;
942 HashSet pset = pset1_hash.get(parentnode);
943 if(pset.isEmpty()||!pset.contains((PrefetchPair) pm.getPair(pp)))
944 mapIsPresent = false;
952 if(pprobIsGreater && mapprobIsLess)
956 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
958 pset1.addAll(newpset);
959 /* Enqueue child node if Pset1 has changed */
960 if (comparePSet1(pset1_hash.get(fn), pset1)) {
961 for(int i=0; i<fn.numNext(); i++) {
962 FlatNode nn = fn.getNext(i);
963 newvisited.addLast((FlatNode)nn);
965 pset1_hash.put(fn, pset1);
968 /* To insert prefetch, apply rule: if the newpset minus pset2 is nonempty
969 * then insert a new prefetch node here*/
971 HashSet<PrefetchPair> s = new HashSet<PrefetchPair>();
974 newprefetchset.put(fn, s);
978 private void addFlatPrefetchNode(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
979 boolean isFNPresent = false; /* Detects presence of FlatNew node */
980 /* This modifies the Flat representation graph */
981 for(Enumeration e = newprefetchset.keys(); e.hasMoreElements();) {
982 FlatNode fn = (FlatNode) e.nextElement();
983 FlatPrefetchNode fpn = new FlatPrefetchNode();
984 if(newprefetchset.get(fn).size() > 0) {
985 fpn.insAllpp((HashSet)newprefetchset.get(fn));
986 if(fn.kind() == FKind.FlatMethod) {
987 FlatNode nn = fn.getNext(0);
990 fpn.siteid = prefetchsiteid++;
992 /* Check if previous node of this FlatNode is a NEW node
993 * If yes, delete this flatnode and its prefetch set from hash table
994 * This eliminates prefetches for NULL ptrs*/
995 for(int i = 0; i< fn.numPrev(); i++) {
996 FlatNode nn = fn.getPrev(i);
997 if(nn.kind() == FKind.FlatNew) {
1002 while(fn.numPrev() > 0) {
1003 FlatNode nn = fn.getPrev(0);
1004 for(int j = 0; j<nn.numNext(); j++) {
1005 if(nn.getNext(j) == fn) {
1011 fpn.siteid = prefetchsiteid++;