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:
113 case FKind.FlatCastNode:
114 case FKind.FlatTagDeclaration:
115 processDefaultCase(curr,child_prefetch_set_copy);
118 case FKind.FlatMethod:
119 //TODO change it to take care of FlatMethod, Flatcalls
120 processFlatMethod(curr, child_prefetch_set_copy);
123 case FKind.FlatFieldNode:
124 processFlatFieldNode(curr, child_prefetch_set_copy);
127 case FKind.FlatElementNode:
128 processFlatElementNode(curr, child_prefetch_set_copy);
131 case FKind.FlatOpNode:
132 processFlatOpNode(curr, child_prefetch_set_copy);
135 case FKind.FlatLiteralNode:
136 processFlatLiteralNode(curr, child_prefetch_set_copy);
139 case FKind.FlatSetElementNode:
140 processFlatSetElementNode(curr, child_prefetch_set_copy);
143 case FKind.FlatSetFieldNode:
144 processFlatSetFieldNode(curr, child_prefetch_set_copy);
147 case FKind.FlatOffsetNode:
148 processDefaultCase(curr,child_prefetch_set_copy);
152 throw new Error("No such Flatnode kind");
157 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
158 * returns: true if something has changed in the new Prefetch set else
161 private boolean comparePrefetchSets(Hashtable<PrefetchPair, Double> oldPrefetchSet, Hashtable<PrefetchPair, Double> newPrefetchSet) {
162 if (oldPrefetchSet.size()!=newPrefetchSet.size())
165 for(Enumeration e = newPrefetchSet.keys(); e.hasMoreElements();) {
166 PrefetchPair pp = (PrefetchPair) e.nextElement();
167 double newprob = newPrefetchSet.get(pp).doubleValue();
168 if (!oldPrefetchSet.containsKey(pp))
170 double oldprob = oldPrefetchSet.get(pp).doubleValue();
172 if((newprob - oldprob) > PROB_DIFF) {
175 if (newprob >= PREFETCH_THRESHOLD_PROB && oldprob < PREFETCH_THRESHOLD_PROB) {
178 if (oldprob>newprob) {
179 System.out.println("ERROR:" + pp);
180 System.out.println(oldprob + " -> "+ newprob);
186 private void updatePairMap(FlatNode curr, PairMap pm, int index) {
187 if (index>=curr.numNext())
189 if (!pmap_hash.containsKey(curr.getNext(index))) {
190 pmap_hash.put(curr.getNext(index), new Hashtable<FlatNode, PairMap>());
192 pmap_hash.get(curr.getNext(index)).put(curr, pm);
195 private void updatePrefetchSet(FlatNode curr, Hashtable<PrefetchPair, Double> newset) {
196 Hashtable<PrefetchPair, Double>oldset=prefetch_hash.get(curr);
197 if (comparePrefetchSets(oldset, newset)) {
198 for(int i=0; i<curr.numPrev(); i++) {
199 tovisit.add(curr.getPrev(i));
201 prefetch_hash.put(curr, newset);
206 /** This function processes the prefetch set of FlatFieldNode
207 * It generates a new prefetch set after comparision with its children
208 * Then compares it with its old prefetch set
209 * If old prefetch set is not same as new prefetch set then enqueue the parents
210 * of the current FlatFieldNode
212 private void processFlatFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
213 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
214 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
215 FlatFieldNode currffn = (FlatFieldNode) curr;
216 PairMap pm = new PairMap();
218 /* Do Self analysis of the current node*/
219 FieldDescriptor currffn_field = currffn.getField();
220 TempDescriptor currffn_src = currffn.getSrc();
221 if (currffn_field.getType().isPtr()) {
222 PrefetchPair pp = new PrefetchPair(currffn_src, (Descriptor) currffn_field);
223 Double prob = new Double(1.0);
224 tocompare.put(pp, prob);
227 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
229 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
230 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
231 if (childpp.base == currffn.getDst() && (childpp.getDesc()!= null)) {
232 if (currffn.getField().getType().isPtr()) {
233 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
234 newdesc.add(currffn.getField());
235 newdesc.addAll(childpp.desc);
236 PrefetchPair newpp = new PrefetchPair(currffn.getSrc(), newdesc);
237 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
238 if (tocompare.containsKey(newpp)) {
239 Double oldprob=tocompare.get(newpp);
240 newprob=1.0-(1.0-oldprob)*(1.0-newprob);
242 tocompare.put(newpp, newprob);
243 pm.addPair(childpp, newpp);
246 } else if(childpp.base == currffn.getDst() && (childpp.getDesc() == null)) {
247 //covered by current prefetch
248 child_prefetch_set_copy.remove(childpp);
249 } else if(childpp.containsTemp(currffn.getDst())) {
250 child_prefetch_set_copy.remove(childpp);
252 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
253 if (tocompare.containsKey(childpp)) {
254 Double oldprob=tocompare.get(childpp);
255 newprob=1.0-(1.0-oldprob)*(1.0-newprob);
257 tocompare.put(childpp, newprob);
258 pm.addPair(childpp, childpp);
262 for(Iterator<PrefetchPair> it=tocompare.keySet().iterator(); it.hasNext();) {
263 PrefetchPair pp=it.next();
264 if (tocompare.get(pp)<ANALYSIS_THRESHOLD_PROB)
269 updatePairMap(curr, pm, 0);
270 updatePrefetchSet(curr, tocompare);
273 /** This function processes the prefetch set of a FlatElementNode
274 * It generates a new prefetch set after comparision with its children
275 * It compares the old prefetch set with this new prefetch set and enqueues the parents
276 * of the current node if change occurs and updates the global flatnode hash table
278 private void processFlatElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
280 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
281 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
282 FlatElementNode currfen = (FlatElementNode) curr;
283 PairMap pm = new PairMap();
286 /* Do Self analysis of the current node*/
287 TempDescriptor currfen_index = currfen.getIndex();
288 IndexDescriptor idesc = new IndexDescriptor(currfen_index, 0);
289 TempDescriptor currfen_src = currfen.getSrc();
290 if(currfen.getDst().getType().isPtr()) {
291 PrefetchPair pp = new PrefetchPair(currfen_src, (Descriptor) idesc);
292 Double prob = new Double(1.0);
293 currcopy.put(pp, prob);
296 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
297 PrefetchPair currpp = null;
298 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
299 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
300 if (childpp.base == currfen.getDst() && (childpp.getDesc()!= null)) {
301 if (currfen.getDst().getType().isPtr()) {
302 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
303 newdesc.add((Descriptor)idesc);
304 newdesc.addAll(childpp.desc);
305 PrefetchPair newpp = new PrefetchPair(currfen.getSrc(), newdesc);
306 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
307 tocompare.put(newpp, newprob);
308 pm.addPair(childpp, newpp);
309 child_prefetch_set_copy.remove(childpp);
310 /* Check for independence of prefetch pairs to compute new probability */
311 if(child_prefetch_set_copy.containsKey(newpp)) {
312 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
313 if(newprob < ANALYSIS_THRESHOLD_PROB) {
314 tocompare.remove(newpp);
316 tocompare.put(newpp, newprob);
317 pm.addPair(newpp, newpp);
319 child_prefetch_set_copy.remove(newpp);
322 } else if(childpp.base == currfen.getDst() && (childpp.getDesc() == null)) {
323 child_prefetch_set_copy.remove(childpp);
324 } else if(childpp.containsTemp(currfen.getDst())) {
325 child_prefetch_set_copy.remove(childpp);
330 /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
331 * if so calculate the new probability */
332 for(Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
333 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
334 for(Enumeration e = currcopy.keys(); e.hasMoreElements();) {
335 currpp = (PrefetchPair) e.nextElement();
336 if(currpp.equals(childpp)) {
337 pm.addPair(childpp, currpp);
338 child_prefetch_set_copy.remove(childpp);
344 /* Merge child prefetch pairs */
345 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
346 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
347 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
348 pm.addPair(childpp, childpp);
349 child_prefetch_set_copy.remove(childpp);
352 /* Merge curr prefetch pairs */
353 for (Enumeration e = currcopy.keys(); e.hasMoreElements();) {
354 currpp = (PrefetchPair) e.nextElement();
355 tocompare.put(currpp, currcopy.get(currpp).doubleValue());
356 currcopy.remove(currpp);
359 updatePairMap(curr, pm, 0);
360 updatePrefetchSet(curr, tocompare);
363 /** This function processes the prefetch set of a FlatSetFieldNode
364 * It generates a new prefetch set after comparision with its children
365 * It compares the old prefetch set with this new prefetch set and enqueues the parents
366 * of the current node if change occurs and then updates the global flatnode hash table
368 private void processFlatSetFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
369 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
370 FlatSetFieldNode currfsfn = (FlatSetFieldNode) curr;
371 PairMap pm = new PairMap();
373 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
374 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
375 if(childpp.base == currfsfn.getDst()) {
376 int size = childpp.desc.size();
377 if(size >=2) { /*e.g. x.f = g (with child prefetches x.f.g, x.f[0].j) */
378 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
379 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
380 for(int i = 0; i<(childpp.desc.size()-1); i++) {
381 newdesc.add(i,childpp.desc.get(i+1));
383 PrefetchPair newpp = new PrefetchPair(currfsfn.getSrc(), newdesc);
384 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
385 tocompare.put(newpp, newprob);
386 pm.addPair(childpp, newpp);
387 child_prefetch_set_copy.remove(childpp);
388 /* Check for independence of prefetch pairs in newly generated prefetch pair
389 * to compute new probability */
390 if(child_prefetch_set_copy.containsKey(newpp)) {
391 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
392 if(newprob < ANALYSIS_THRESHOLD_PROB) {
393 tocompare.remove(newpp);
395 tocompare.put(newpp, newprob);
396 pm.addPair(newpp, newpp);
398 child_prefetch_set_copy.remove(newpp);
401 } else if(size==1) { /* e.g x.f = g (with child prefetch x.f) */
402 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
403 child_prefetch_set_copy.remove(childpp);
411 /* Merge child prefetch pairs */
412 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
413 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
414 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
415 pm.addPair(childpp, childpp);
416 child_prefetch_set_copy.remove(childpp);
419 updatePairMap(curr, pm, 0);
420 updatePrefetchSet(curr, tocompare);
423 /** This function processes the prefetch set of a FlatSetElementNode
424 * It generates a new prefetch set after comparision with its children
425 * It compares the old prefetch set with this new prefetch set and enqueues the parents
426 * of the current node if change occurs and then updates the global flatnode hash table
428 private void processFlatSetElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
429 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
430 FlatSetElementNode currfsen = (FlatSetElementNode) curr;
431 PairMap pm = new PairMap();
433 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
434 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
435 if (childpp.base == currfsen.getDst()) {
436 int sizedesc = childpp.desc.size();
437 if((childpp.getDescAt(0) instanceof IndexDescriptor)) {
438 int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size();
439 if(sizetempdesc == 1) {
440 if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) {
441 /* For e.g. a[i] = g with child prefetch set a[i].r or a[i].r.f */
442 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
443 for(int i = 0; i<(childpp.desc.size()-1); i++) {
444 newdesc.add(i,childpp.desc.get(i+1));
446 PrefetchPair newpp = new PrefetchPair(currfsen.getSrc(), newdesc);
447 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
448 tocompare.put(newpp, newprob);
449 pm.addPair(childpp, newpp);
450 child_prefetch_set_copy.remove(childpp);
451 /* Check for independence of prefetch pairs to compute new probability */
452 if(child_prefetch_set_copy.containsKey(newpp)) {
453 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
454 if(newprob < ANALYSIS_THRESHOLD_PROB) {
455 tocompare.remove(newpp);
457 tocompare.put(newpp, newprob);
458 pm.addPair(newpp, newpp);
460 child_prefetch_set_copy.remove(newpp);
462 } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1))
463 /* For e.g. a[i] = g with child prefetch set a[i] */
464 child_prefetch_set_copy.remove(childpp);
471 /* Merge child prefetch pairs */
472 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
473 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
474 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
475 pm.addPair(childpp, childpp);
476 child_prefetch_set_copy.remove(childpp);
479 updatePairMap(curr, pm, 0);
480 updatePrefetchSet(curr, tocompare);
483 /** This function applies rules and does analysis for a FlatOpNode
484 * And updates the global prefetch hashtable
486 private void processFlatOpNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
488 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
489 FlatOpNode currfopn = (FlatOpNode) curr;
490 PairMap pm = new PairMap();
492 if(currfopn.getOp().getOp() == Operation.ASSIGN) {
493 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
494 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
495 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
497 /* For cases like x=y with child prefetch set x[i].z,x.g*/
498 if(childpp.base == currfopn.getDest()) {
499 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
500 newdesc.addAll(childpp.desc);
501 PrefetchPair newpp = new PrefetchPair(currfopn.getLeft(), newdesc);
502 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
503 tocompare.put(newpp, newprob);
504 pm.addPair(childpp, newpp);
505 child_prefetch_set_copy.remove(childpp);
506 /* Check for independence of prefetch pairs to compute new probability */
507 if(child_prefetch_set_copy.containsKey(newpp)) {
508 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
509 if(newprob < ANALYSIS_THRESHOLD_PROB) {
510 tocompare.remove(newpp);
512 tocompare.put(newpp, newprob);
513 pm.addPair(newpp, newpp);
515 child_prefetch_set_copy.remove(newpp);
517 /* For cases like x=y with child prefetch set r[x].p, r[p+x].q where x is a tempdescriptor*/
518 } else if(copyofchildpp.containsTemp(currfopn.getDest())) {
519 PrefetchPair newpp=copyofchildpp.replaceTemp(currfopn.getDest(), new TempDescriptor[] {currfopn.getLeft()});
520 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
521 tocompare.put(newpp, newprob);
522 pm.addPair(childpp, newpp);
523 child_prefetch_set_copy.remove(childpp);
524 /* Check for independence of prefetch pairs to compute new probability*/
525 if(child_prefetch_set_copy.containsKey(newpp)) {
526 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
527 if(newprob < ANALYSIS_THRESHOLD_PROB) {
528 tocompare.remove(newpp);
530 tocompare.put(newpp, newprob);
531 pm.addPair(newpp, newpp);
533 child_prefetch_set_copy.remove(newpp);
540 //case i = i+z with child prefetch set a[i].x
541 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) {
542 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
543 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
544 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
546 if(copyofchildpp.containsTemp(currfopn.getDest())) {
547 PrefetchPair newpp=copyofchildpp.replaceTemp(currfopn.getDest(), new TempDescriptor[] {currfopn.getLeft(), currfopn.getRight()});
548 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
549 tocompare.put(newpp, newprob);
550 pm.addPair(childpp, newpp);
551 child_prefetch_set_copy.remove(childpp);
552 /* Check for independence of prefetch pairs to compute new probability*/
553 if(child_prefetch_set_copy.containsKey(newpp)) {
554 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
555 if(newprob < ANALYSIS_THRESHOLD_PROB) {
556 tocompare.remove(newpp);
558 tocompare.put(newpp, newprob);
559 pm.addPair(newpp, newpp);
561 child_prefetch_set_copy.remove(newpp);
567 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.SUB)) {
568 for(Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
569 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
570 if(childpp.containsTemp(currfopn.getDest())) {
571 child_prefetch_set_copy.remove(childpp);
575 //FIXME Is not taken care of for cases like x = -y followed by a[x].i
578 /* Merge child prefetch pairs */
579 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
580 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
581 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
582 pm.addPair(childpp, childpp);
583 child_prefetch_set_copy.remove(childpp);
586 updatePairMap(curr, pm, 0);
587 updatePrefetchSet(curr, tocompare);
590 /** This function processes a FlatLiteralNode where cases such as
591 * for e.g. i = 0 with child prefetch sets a[i].r, a[j+i].r or a[j].b[i].r
593 private void processFlatLiteralNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
594 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
595 FlatLiteralNode currfln = (FlatLiteralNode) curr;
596 PairMap pm = new PairMap();
598 if(currfln.getType().isIntegerType()) {
599 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
600 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
601 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
602 if(copyofchildpp.containsTemp(currfln.getDst())) {
603 ArrayList<Descriptor> copychilddesc = (ArrayList<Descriptor>)copyofchildpp.getDesc();
604 int sizetempdesc = copychilddesc.size();
605 for(ListIterator it = copychilddesc.listIterator(); it.hasNext();) {
606 Object o = it.next();
607 if(o instanceof IndexDescriptor) {
608 ArrayList<TempDescriptor> td = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
609 int sizetddesc = td.size();
610 if(td.contains(currfln.getDst())) {
611 int index = td.indexOf(currfln.getDst());
613 ((IndexDescriptor)o).offset += (Integer)currfln.getValue();
617 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
618 newdesc.addAll(copychilddesc);
619 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
620 Double newprob = (child_prefetch_set_copy.get(childpp)).doubleValue();
621 tocompare.put(newpp, newprob);
622 pm.addPair(childpp, newpp);
623 child_prefetch_set_copy.remove(childpp);
624 /* Check for independence of prefetch pairs to compute new probability */
625 if(child_prefetch_set_copy.containsKey(newpp)) {
626 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
627 if(newprob < ANALYSIS_THRESHOLD_PROB) {
628 tocompare.remove(newpp);
630 tocompare.put(newpp, newprob);
631 pm.addPair(newpp, newpp);
633 child_prefetch_set_copy.remove(newpp);
639 /* Merge child prefetch pairs */
640 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
641 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
642 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
643 pm.addPair(childpp, childpp);
644 child_prefetch_set_copy.remove(childpp);
647 updatePairMap(curr, pm, 0);
648 updatePrefetchSet(curr, tocompare);
651 /** This function processes a FlatMethod where the method propagates
652 * the entire prefetch set of its child node */
653 private void processFlatMethod(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
654 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
655 FlatMethod currfm = (FlatMethod) curr;
656 PairMap pm = new PairMap();
658 /* Merge child prefetch pairs */
659 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
660 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
661 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
662 pm.addPair(childpp, childpp);
665 updatePairMap(curr, pm, 0);
666 updatePrefetchSet(curr, tocompare);
669 /** This function handles the processes the FlatNode of type FlatCondBranch
670 * It combines prefetches of both child elements and create a new hash table called
671 * branch_prefetch_set to contains the entries of both its children
673 private void processFlatCondBranch(FlatCondBranch fcb, MethodDescriptor md) {
674 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>(); //temporary hash table
675 PairMap truepm = new PairMap();
676 PairMap falsepm = new PairMap();
677 Hashtable<PrefetchPair, Double> truechild=prefetch_hash.get(fcb.getNext(0));
678 Hashtable<PrefetchPair, Double> falsechild=prefetch_hash.get(fcb.getNext(1));
680 HashSet<PrefetchPair> allpp=new HashSet<PrefetchPair>();
681 allpp.addAll(truechild.keySet());
682 allpp.addAll(falsechild.keySet());
684 for(Iterator<PrefetchPair> ppit=allpp.iterator(); ppit.hasNext();) {
685 PrefetchPair pp=ppit.next();
686 double trueprob=0,falseprob=0;
687 if (truechild.containsKey(pp))
688 trueprob=truechild.get(pp).doubleValue();
689 if (falsechild.containsKey(pp))
690 falseprob=falsechild.get(pp).doubleValue();
692 double newprob=trueprob*fcb.getTrueProb()+falseprob*fcb.getFalseProb();
693 if (loop.isLoopingBranch(md,fcb)&&
698 if(newprob < ANALYSIS_THRESHOLD_PROB) //Skip pp that are below threshold
701 tocompare.put(pp, newprob);
702 if (truechild.containsKey(pp))
703 truepm.addPair(pp, pp);
705 if (falsechild.containsKey(pp))
706 falsepm.addPair(pp, pp);
710 updatePairMap(fcb, truepm, 0);
711 updatePairMap(fcb, falsepm, 1);
712 updatePrefetchSet(fcb, tocompare);
715 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
716 * prefetches up the FlatNode*/
717 private void processDefaultCase(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
718 PairMap pm = new PairMap();
719 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
721 /* Propagate all child nodes */
723 for(Enumeration e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
724 PrefetchPair childpp = (PrefetchPair) e.nextElement();
725 TempDescriptor[] writearray=curr.writesTemps();
726 for(int i=0; i<writearray.length; i++) {
727 TempDescriptor wtd=writearray[i];
728 if(childpp.base == wtd||
729 childpp.containsTemp(wtd))
732 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
733 pm.addPair(childpp, childpp);
736 updatePairMap(curr, pm, 0);
737 updatePrefetchSet(curr, tocompare);
740 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
741 * prefetches up the FlatNode*/
742 private void processCall(FlatCall curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
743 PairMap pm = new PairMap();
744 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
746 /* Don't propagate prefetches across cache clear */
747 if (!(curr.getMethod().getClassMethodName().equals("System.clearPrefetchCache")||
748 curr.getMethod().getClassMethodName().equals("Barrier.enterBarrier"))) {
749 /* Propagate all child nodes */
751 for(Enumeration e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
752 PrefetchPair childpp = (PrefetchPair) e.nextElement();
753 TempDescriptor[] writearray=curr.writesTemps();
754 for(int i=0; i<writearray.length; i++) {
755 TempDescriptor wtd=writearray[i];
756 if(childpp.base == wtd||
757 childpp.containsTemp(wtd))
760 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
761 pm.addPair(childpp, childpp);
765 updatePairMap(curr, pm, 0);
766 updatePrefetchSet(curr, tocompare);
769 /** This function prints the Prefetch pairs of a given flatnode */
770 private void printPrefetchPairs(FlatNode fn) {
771 System.out.println(fn);
772 if(prefetch_hash.containsKey(fn)) {
773 System.out.print("Prefetch" + "(");
774 Hashtable<PrefetchPair, Double> currhash = (Hashtable) prefetch_hash.get(fn);
775 for(Enumeration pphash= currhash.keys(); pphash.hasMoreElements();) {
776 PrefetchPair pp = (PrefetchPair) pphash.nextElement();
777 System.out.print(pp.toString() + ", ");
779 System.out.println(")");
781 System.out.println("Flatnode is currently not present in the global hash: Prefetch Set is Empty");
785 private void doInsPrefetchAnalysis(FlatMethod fm, Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
786 Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
787 HashSet<PrefetchPair> pset1_init = new HashSet<PrefetchPair>();
788 LinkedList<FlatNode> newtovisit = new LinkedList<FlatNode>();
789 LinkedList<FlatNode> newvisited = new LinkedList<FlatNode>();
791 newtovisit.addLast((FlatNode)fm);
792 while(!newtovisit.isEmpty()) {
793 FlatNode fn = (FlatNode) newtovisit.iterator().next();
794 newtovisit.remove(0);
795 pset1_hash.put(fn, pset1_init); //Initialize pset1_hash
796 newvisited.addLast(fn);
797 for(int i=0; i<fn.numNext(); i++) {
798 FlatNode nn = fn.getNext(i);
799 if(!newtovisit.contains(nn) && !newvisited.contains(nn)) {
800 newtovisit.addLast(nn);
805 /* Start with a top down sorted order of nodes */
806 while(!newvisited.isEmpty()) {
807 applyPrefetchInsertRules((FlatNode) newvisited.getFirst(), newvisited, pset1_hash, newprefetchset);
808 newvisited.remove(0);
810 delSubsetPPairs(newprefetchset);
813 /** This function deletes the smaller prefetch pair subset from a list of prefetch pairs
814 * for e.g. if there are 2 prefetch pairs a.b.c.d and a.b.c for a given flatnode
815 * then this function drops a.b.c from the prefetch set of the flatnode */
816 private void delSubsetPPairs(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
817 for (Enumeration e = newprefetchset.keys(); e.hasMoreElements();) {
818 FlatNode fn = (FlatNode) e.nextElement();
819 Set<PrefetchPair> ppairs = newprefetchset.get(fn);
820 Set<PrefetchPair> toremove=new HashSet<PrefetchPair>();
822 for(Iterator<PrefetchPair> it1=ppairs.iterator(); it1.hasNext();) {
823 PrefetchPair pp1=it1.next();
824 if (toremove.contains(pp1))
826 int l1=pp1.desc.size()+1;
827 for(Iterator<PrefetchPair> it2=ppairs.iterator(); it2.hasNext();) {
828 PrefetchPair pp2=it2.next();
829 int l2=pp2.desc.size()+1;
831 if (l1<l2&&isSubSet(pp1,pp2))
834 if (l2>l1&&isSubSet(pp2,pp1))
839 ppairs.removeAll(toremove);
843 /** This function returns: true if the shorter prefetch pair is a subset of the longer prefetch
844 * pair else it returns: false */
845 private boolean isSubSet(PrefetchPair shrt, PrefetchPair lng) {
846 if (shrt.base != lng.base) {
849 for (int j = 0; j < shrt.desc.size(); j++) {
850 if(shrt.getDescAt(j) instanceof IndexDescriptor) {
851 IndexDescriptor shrtid = (IndexDescriptor) shrt.getDescAt(j);
852 if(lng.getDescAt(j) instanceof IndexDescriptor) {
853 IndexDescriptor lngid = (IndexDescriptor) lng.getDescAt(j);
854 if(shrtid.equals(lngid)) {
863 if ((Descriptor)shrt.getDescAt(j) != (Descriptor)lng.getDescAt(j)) {
871 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
872 * returns: true if something has changed in the new Prefetch set else
875 private boolean comparePSet1(HashSet<PrefetchPair> oldPSet, HashSet<PrefetchPair>newPSet) {
876 if(oldPSet.size() != newPSet.size()) {
879 for(Iterator it = newPSet.iterator(); it.hasNext();) {
880 if(!oldPSet.contains((PrefetchPair)it.next())) {
888 /** This function creates a set called pset1 that contains prefetch pairs that have already
889 * been prefetched. While traversing the graph of a flat representation in a top down fashion,
890 * this function creates pset1 such that it contains prefetch pairs that have been prefetched at
891 * the previous nodes */
893 private void applyPrefetchInsertRules(FlatNode fn, LinkedList<FlatNode> newvisited, Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash, Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
894 if(fn.kind() == FKind.FlatMethod) {
895 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
896 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
897 for(Enumeration e = prefetchset.keys(); e.hasMoreElements();) {
898 PrefetchPair pp = (PrefetchPair) e.nextElement();
899 /* Apply initial rule */
900 if(prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB) {
904 /* Enqueue child node if Pset1 has changed */
905 if (comparePSet1(pset1_hash.get(fn), pset1)) {
906 for(int j=0; j<fn.numNext(); j++) {
907 FlatNode nn = fn.getNext(j);
908 newvisited.addLast((FlatNode)nn);
910 pset1_hash.put(fn, pset1);
912 newprefetchset.put(fn, pset1);
913 } else { /* Nodes other than Flat Method Node */
914 HashSet<PrefetchPair> pset2 = new HashSet<PrefetchPair>();
915 HashSet<PrefetchPair> newpset = new HashSet<PrefetchPair>();
916 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
917 Hashtable<FlatNode, PairMap> ppairmaphash = pmap_hash.get(fn);
918 for(Enumeration epset = prefetchset.keys(); epset.hasMoreElements();) {
919 PrefetchPair pp = (PrefetchPair) epset.nextElement();
920 boolean pprobIsGreater = (prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB);
921 boolean mapprobIsLess=false;
922 boolean mapIsPresent=true;
923 for(int i=0; i<fn.numPrev(); i++) {
924 FlatNode parentnode=fn.getPrev(i);
925 PairMap pm = (PairMap) ppairmaphash.get(parentnode);
926 //Find if probability is less for previous node
927 if(pm!=null&&pm.getPair(pp) != null) {
928 PrefetchPair mappedpp = pm.getPair(pp);
929 if(prefetch_hash.get(parentnode).containsKey(mappedpp)) {
930 double prob = prefetch_hash.get(parentnode).get(mappedpp).doubleValue();
931 if(prob < PREFETCH_THRESHOLD_PROB)
932 mapprobIsLess = true;
934 mapprobIsLess = true;
936 mapprobIsLess = true;
940 HashSet pset = pset1_hash.get(parentnode);
941 if(pset.isEmpty()||!pset.contains((PrefetchPair) pm.getPair(pp)))
942 mapIsPresent = false;
950 if(pprobIsGreater && mapprobIsLess)
954 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
956 pset1.addAll(newpset);
957 /* Enqueue child node if Pset1 has changed */
958 if (comparePSet1(pset1_hash.get(fn), pset1)) {
959 for(int i=0; i<fn.numNext(); i++) {
960 FlatNode nn = fn.getNext(i);
961 newvisited.addLast((FlatNode)nn);
963 pset1_hash.put(fn, pset1);
966 /* To insert prefetch, apply rule: if the newpset minus pset2 is nonempty
967 * then insert a new prefetch node here*/
969 HashSet<PrefetchPair> s = new HashSet<PrefetchPair>();
972 newprefetchset.put(fn, s);
976 private void addFlatPrefetchNode(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
977 boolean isFNPresent = false; /* Detects presence of FlatNew node */
978 /* This modifies the Flat representation graph */
979 for(Enumeration e = newprefetchset.keys(); e.hasMoreElements();) {
980 FlatNode fn = (FlatNode) e.nextElement();
981 FlatPrefetchNode fpn = new FlatPrefetchNode();
982 if(newprefetchset.get(fn).size() > 0) {
983 fpn.insAllpp((HashSet)newprefetchset.get(fn));
984 if(fn.kind() == FKind.FlatMethod) {
985 FlatNode nn = fn.getNext(0);
988 fpn.siteid = prefetchsiteid++;
990 /* Check if previous node of this FlatNode is a NEW node
991 * If yes, delete this flatnode and its prefetch set from hash table
992 * This eliminates prefetches for NULL ptrs*/
993 for(int i = 0; i< fn.numPrev(); i++) {
994 FlatNode nn = fn.getPrev(i);
995 if(nn.kind() == FKind.FlatNew) {
1000 while(fn.numPrev() > 0) {
1001 FlatNode nn = fn.getPrev(0);
1002 for(int j = 0; j<nn.numNext(); j++) {
1003 if(nn.getNext(j) == fn) {
1009 fpn.siteid = prefetchsiteid++;