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);
148 throw new Error("No such Flatnode kind");
153 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
154 * returns: true if something has changed in the new Prefetch set else
157 private boolean comparePrefetchSets(Hashtable<PrefetchPair, Double> oldPrefetchSet, Hashtable<PrefetchPair, Double> newPrefetchSet) {
158 if (oldPrefetchSet.size()!=newPrefetchSet.size())
161 for(Enumeration e = newPrefetchSet.keys(); e.hasMoreElements();) {
162 PrefetchPair pp = (PrefetchPair) e.nextElement();
163 double newprob = newPrefetchSet.get(pp).doubleValue();
164 if (!oldPrefetchSet.containsKey(pp))
166 double oldprob = oldPrefetchSet.get(pp).doubleValue();
168 if((newprob - oldprob) > PROB_DIFF) {
171 if (newprob >= PREFETCH_THRESHOLD_PROB && oldprob < PREFETCH_THRESHOLD_PROB) {
174 if (oldprob>newprob) {
175 System.out.println("ERROR:" + pp);
176 System.out.println(oldprob + " -> "+ newprob);
182 private void updatePairMap(FlatNode curr, PairMap pm, int index) {
183 if (index>=curr.numNext())
185 if (!pmap_hash.containsKey(curr.getNext(index))) {
186 pmap_hash.put(curr.getNext(index), new Hashtable<FlatNode, PairMap>());
188 pmap_hash.get(curr.getNext(index)).put(curr, pm);
191 private void updatePrefetchSet(FlatNode curr, Hashtable<PrefetchPair, Double> newset) {
192 Hashtable<PrefetchPair, Double>oldset=prefetch_hash.get(curr);
193 if (comparePrefetchSets(oldset, newset)) {
194 for(int i=0; i<curr.numPrev(); i++) {
195 tovisit.add(curr.getPrev(i));
197 prefetch_hash.put(curr, newset);
202 /** This function processes the prefetch set of FlatFieldNode
203 * It generates a new prefetch set after comparision with its children
204 * Then compares it with its old prefetch set
205 * If old prefetch set is not same as new prefetch set then enqueue the parents
206 * of the current FlatFieldNode
208 private void processFlatFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
209 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
210 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
211 FlatFieldNode currffn = (FlatFieldNode) curr;
212 PairMap pm = new PairMap();
214 /* Do Self analysis of the current node*/
215 FieldDescriptor currffn_field = currffn.getField();
216 TempDescriptor currffn_src = currffn.getSrc();
217 if (currffn_field.getType().isPtr()) {
218 PrefetchPair pp = new PrefetchPair(currffn_src, (Descriptor) currffn_field);
219 Double prob = new Double(1.0);
220 tocompare.put(pp, prob);
223 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
225 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
226 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
227 if (childpp.base == currffn.getDst() && (childpp.getDesc()!= null)) {
228 if (currffn.getField().getType().isPtr()) {
229 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
230 newdesc.add(currffn.getField());
231 newdesc.addAll(childpp.desc);
232 PrefetchPair newpp = new PrefetchPair(currffn.getSrc(), newdesc);
233 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
234 if (tocompare.containsKey(newpp)) {
235 Double oldprob=tocompare.get(newpp);
236 newprob=1.0-(1.0-oldprob)*(1.0-newprob);
238 tocompare.put(newpp, newprob);
239 pm.addPair(childpp, newpp);
242 } else if(childpp.base == currffn.getDst() && (childpp.getDesc() == null)) {
243 //covered by current prefetch
244 child_prefetch_set_copy.remove(childpp);
245 } else if(childpp.containsTemp(currffn.getDst())) {
246 child_prefetch_set_copy.remove(childpp);
248 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
249 if (tocompare.containsKey(childpp)) {
250 Double oldprob=tocompare.get(childpp);
251 newprob=1.0-(1.0-oldprob)*(1.0-newprob);
253 tocompare.put(childpp, newprob);
254 pm.addPair(childpp, childpp);
258 for(Iterator<PrefetchPair> it=tocompare.keySet().iterator(); it.hasNext();) {
259 PrefetchPair pp=it.next();
260 if (tocompare.get(pp)<ANALYSIS_THRESHOLD_PROB)
265 updatePairMap(curr, pm, 0);
266 updatePrefetchSet(curr, tocompare);
269 /** This function processes the prefetch set of a FlatElementNode
270 * It generates a new prefetch set after comparision with its children
271 * It compares the old prefetch set with this new prefetch set and enqueues the parents
272 * of the current node if change occurs and updates the global flatnode hash table
274 private void processFlatElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
276 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
277 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
278 FlatElementNode currfen = (FlatElementNode) curr;
279 PairMap pm = new PairMap();
282 /* Do Self analysis of the current node*/
283 TempDescriptor currfen_index = currfen.getIndex();
284 IndexDescriptor idesc = new IndexDescriptor(currfen_index, 0);
285 TempDescriptor currfen_src = currfen.getSrc();
286 if(currfen.getDst().getType().isPtr()) {
287 PrefetchPair pp = new PrefetchPair(currfen_src, (Descriptor) idesc);
288 Double prob = new Double(1.0);
289 currcopy.put(pp, prob);
292 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
293 PrefetchPair currpp = null;
294 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
295 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
296 if (childpp.base == currfen.getDst() && (childpp.getDesc()!= null)) {
297 if (currfen.getDst().getType().isPtr()) {
298 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
299 newdesc.add((Descriptor)idesc);
300 newdesc.addAll(childpp.desc);
301 PrefetchPair newpp = new PrefetchPair(currfen.getSrc(), newdesc);
302 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
303 tocompare.put(newpp, newprob);
304 pm.addPair(childpp, newpp);
305 child_prefetch_set_copy.remove(childpp);
306 /* Check for independence of prefetch pairs to compute new probability */
307 if(child_prefetch_set_copy.containsKey(newpp)) {
308 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
309 if(newprob < ANALYSIS_THRESHOLD_PROB) {
310 tocompare.remove(newpp);
312 tocompare.put(newpp, newprob);
313 pm.addPair(newpp, newpp);
315 child_prefetch_set_copy.remove(newpp);
318 } else if(childpp.base == currfen.getDst() && (childpp.getDesc() == null)) {
319 child_prefetch_set_copy.remove(childpp);
320 } else if(childpp.containsTemp(currfen.getDst())) {
321 child_prefetch_set_copy.remove(childpp);
326 /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
327 * if so calculate the new probability */
328 for(Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
329 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
330 for(Enumeration e = currcopy.keys(); e.hasMoreElements();) {
331 currpp = (PrefetchPair) e.nextElement();
332 if(currpp.equals(childpp)) {
333 pm.addPair(childpp, currpp);
334 child_prefetch_set_copy.remove(childpp);
340 /* Merge child prefetch pairs */
341 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
342 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
343 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
344 pm.addPair(childpp, childpp);
345 child_prefetch_set_copy.remove(childpp);
348 /* Merge curr prefetch pairs */
349 for (Enumeration e = currcopy.keys(); e.hasMoreElements();) {
350 currpp = (PrefetchPair) e.nextElement();
351 tocompare.put(currpp, currcopy.get(currpp).doubleValue());
352 currcopy.remove(currpp);
355 updatePairMap(curr, pm, 0);
356 updatePrefetchSet(curr, tocompare);
359 /** This function processes the prefetch set of a FlatSetFieldNode
360 * It generates a new prefetch set after comparision with its children
361 * It compares the old prefetch set with this new prefetch set and enqueues the parents
362 * of the current node if change occurs and then updates the global flatnode hash table
364 private void processFlatSetFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
365 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
366 FlatSetFieldNode currfsfn = (FlatSetFieldNode) curr;
367 PairMap pm = new PairMap();
369 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
370 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
371 if(childpp.base == currfsfn.getDst()) {
372 int size = childpp.desc.size();
373 if(size >=2) { /*e.g. x.f = g (with child prefetches x.f.g, x.f[0].j) */
374 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
375 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
376 for(int i = 0; i<(childpp.desc.size()-1); i++) {
377 newdesc.add(i,childpp.desc.get(i+1));
379 PrefetchPair newpp = new PrefetchPair(currfsfn.getSrc(), newdesc);
380 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
381 tocompare.put(newpp, newprob);
382 pm.addPair(childpp, newpp);
383 child_prefetch_set_copy.remove(childpp);
384 /* Check for independence of prefetch pairs in newly generated prefetch pair
385 * to compute new probability */
386 if(child_prefetch_set_copy.containsKey(newpp)) {
387 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
388 if(newprob < ANALYSIS_THRESHOLD_PROB) {
389 tocompare.remove(newpp);
391 tocompare.put(newpp, newprob);
392 pm.addPair(newpp, newpp);
394 child_prefetch_set_copy.remove(newpp);
397 } else if(size==1) { /* e.g x.f = g (with child prefetch x.f) */
398 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
399 child_prefetch_set_copy.remove(childpp);
407 /* Merge child prefetch pairs */
408 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
409 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
410 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
411 pm.addPair(childpp, childpp);
412 child_prefetch_set_copy.remove(childpp);
415 updatePairMap(curr, pm, 0);
416 updatePrefetchSet(curr, tocompare);
419 /** This function processes the prefetch set of a FlatSetElementNode
420 * It generates a new prefetch set after comparision with its children
421 * It compares the old prefetch set with this new prefetch set and enqueues the parents
422 * of the current node if change occurs and then updates the global flatnode hash table
424 private void processFlatSetElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
425 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
426 FlatSetElementNode currfsen = (FlatSetElementNode) curr;
427 PairMap pm = new PairMap();
429 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
430 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
431 if (childpp.base == currfsen.getDst()) {
432 int sizedesc = childpp.desc.size();
433 if((childpp.getDescAt(0) instanceof IndexDescriptor)) {
434 int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size();
435 if(sizetempdesc == 1) {
436 if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) {
437 /* For e.g. a[i] = g with child prefetch set a[i].r or a[i].r.f */
438 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
439 for(int i = 0; i<(childpp.desc.size()-1); i++) {
440 newdesc.add(i,childpp.desc.get(i+1));
442 PrefetchPair newpp = new PrefetchPair(currfsen.getSrc(), newdesc);
443 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
444 tocompare.put(newpp, newprob);
445 pm.addPair(childpp, newpp);
446 child_prefetch_set_copy.remove(childpp);
447 /* Check for independence of prefetch pairs to compute new probability */
448 if(child_prefetch_set_copy.containsKey(newpp)) {
449 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
450 if(newprob < ANALYSIS_THRESHOLD_PROB) {
451 tocompare.remove(newpp);
453 tocompare.put(newpp, newprob);
454 pm.addPair(newpp, newpp);
456 child_prefetch_set_copy.remove(newpp);
458 } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1))
459 /* For e.g. a[i] = g with child prefetch set a[i] */
460 child_prefetch_set_copy.remove(childpp);
467 /* Merge child prefetch pairs */
468 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
469 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
470 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
471 pm.addPair(childpp, childpp);
472 child_prefetch_set_copy.remove(childpp);
475 updatePairMap(curr, pm, 0);
476 updatePrefetchSet(curr, tocompare);
479 /** This function applies rules and does analysis for a FlatOpNode
480 * And updates the global prefetch hashtable
482 private void processFlatOpNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
484 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
485 FlatOpNode currfopn = (FlatOpNode) curr;
486 PairMap pm = new PairMap();
488 if(currfopn.getOp().getOp() == Operation.ASSIGN) {
489 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
490 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
491 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
493 /* For cases like x=y with child prefetch set x[i].z,x.g*/
494 if(childpp.base == currfopn.getDest()) {
495 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
496 newdesc.addAll(childpp.desc);
497 PrefetchPair newpp = new PrefetchPair(currfopn.getLeft(), newdesc);
498 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
499 tocompare.put(newpp, newprob);
500 pm.addPair(childpp, newpp);
501 child_prefetch_set_copy.remove(childpp);
502 /* Check for independence of prefetch pairs to compute new probability */
503 if(child_prefetch_set_copy.containsKey(newpp)) {
504 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
505 if(newprob < ANALYSIS_THRESHOLD_PROB) {
506 tocompare.remove(newpp);
508 tocompare.put(newpp, newprob);
509 pm.addPair(newpp, newpp);
511 child_prefetch_set_copy.remove(newpp);
513 /* For cases like x=y with child prefetch set r[x].p, r[p+x].q where x is a tempdescriptor*/
514 } else if(copyofchildpp.containsTemp(currfopn.getDest())) {
515 PrefetchPair newpp=copyofchildpp.replaceTemp(currfopn.getDest(), new TempDescriptor[] {currfopn.getLeft()});
516 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
517 tocompare.put(newpp, newprob);
518 pm.addPair(childpp, newpp);
519 child_prefetch_set_copy.remove(childpp);
520 /* Check for independence of prefetch pairs to compute new probability*/
521 if(child_prefetch_set_copy.containsKey(newpp)) {
522 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
523 if(newprob < ANALYSIS_THRESHOLD_PROB) {
524 tocompare.remove(newpp);
526 tocompare.put(newpp, newprob);
527 pm.addPair(newpp, newpp);
529 child_prefetch_set_copy.remove(newpp);
536 //case i = i+z with child prefetch set a[i].x
537 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) {
538 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
539 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
540 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
542 if(copyofchildpp.containsTemp(currfopn.getDest())) {
543 PrefetchPair newpp=copyofchildpp.replaceTemp(currfopn.getDest(), new TempDescriptor[] {currfopn.getLeft(), currfopn.getRight()});
544 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
545 tocompare.put(newpp, newprob);
546 pm.addPair(childpp, newpp);
547 child_prefetch_set_copy.remove(childpp);
548 /* Check for independence of prefetch pairs to compute new probability*/
549 if(child_prefetch_set_copy.containsKey(newpp)) {
550 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
551 if(newprob < ANALYSIS_THRESHOLD_PROB) {
552 tocompare.remove(newpp);
554 tocompare.put(newpp, newprob);
555 pm.addPair(newpp, newpp);
557 child_prefetch_set_copy.remove(newpp);
563 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.SUB)) {
564 for(Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
565 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
566 if(childpp.containsTemp(currfopn.getDest())) {
567 child_prefetch_set_copy.remove(childpp);
571 //FIXME Is not taken care of for cases like x = -y followed by a[x].i
574 /* Merge child prefetch pairs */
575 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
576 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
577 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
578 pm.addPair(childpp, childpp);
579 child_prefetch_set_copy.remove(childpp);
582 updatePairMap(curr, pm, 0);
583 updatePrefetchSet(curr, tocompare);
586 /** This function processes a FlatLiteralNode where cases such as
587 * for e.g. i = 0 with child prefetch sets a[i].r, a[j+i].r or a[j].b[i].r
589 private void processFlatLiteralNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
590 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
591 FlatLiteralNode currfln = (FlatLiteralNode) curr;
592 PairMap pm = new PairMap();
594 if(currfln.getType().isIntegerType()) {
595 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
596 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
597 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
598 if(copyofchildpp.containsTemp(currfln.getDst())) {
599 ArrayList<Descriptor> copychilddesc = (ArrayList<Descriptor>)copyofchildpp.getDesc();
600 int sizetempdesc = copychilddesc.size();
601 for(ListIterator it = copychilddesc.listIterator(); it.hasNext();) {
602 Object o = it.next();
603 if(o instanceof IndexDescriptor) {
604 ArrayList<TempDescriptor> td = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
605 int sizetddesc = td.size();
606 if(td.contains(currfln.getDst())) {
607 int index = td.indexOf(currfln.getDst());
609 ((IndexDescriptor)o).offset += (Integer)currfln.getValue();
613 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
614 newdesc.addAll(copychilddesc);
615 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
616 Double newprob = (child_prefetch_set_copy.get(childpp)).doubleValue();
617 tocompare.put(newpp, newprob);
618 pm.addPair(childpp, newpp);
619 child_prefetch_set_copy.remove(childpp);
620 /* Check for independence of prefetch pairs to compute new probability */
621 if(child_prefetch_set_copy.containsKey(newpp)) {
622 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
623 if(newprob < ANALYSIS_THRESHOLD_PROB) {
624 tocompare.remove(newpp);
626 tocompare.put(newpp, newprob);
627 pm.addPair(newpp, newpp);
629 child_prefetch_set_copy.remove(newpp);
635 /* Merge child prefetch pairs */
636 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
637 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
638 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
639 pm.addPair(childpp, childpp);
640 child_prefetch_set_copy.remove(childpp);
643 updatePairMap(curr, pm, 0);
644 updatePrefetchSet(curr, tocompare);
647 /** This function processes a FlatMethod where the method propagates
648 * the entire prefetch set of its child node */
649 private void processFlatMethod(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
650 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
651 FlatMethod currfm = (FlatMethod) curr;
652 PairMap pm = new PairMap();
654 /* Merge child prefetch pairs */
655 for (Enumeration ecld = child_prefetch_set_copy.keys(); ecld.hasMoreElements();) {
656 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
657 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
658 pm.addPair(childpp, childpp);
661 updatePairMap(curr, pm, 0);
662 updatePrefetchSet(curr, tocompare);
665 /** This function handles the processes the FlatNode of type FlatCondBranch
666 * It combines prefetches of both child elements and create a new hash table called
667 * branch_prefetch_set to contains the entries of both its children
669 private void processFlatCondBranch(FlatCondBranch fcb, MethodDescriptor md) {
670 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>(); //temporary hash table
671 PairMap truepm = new PairMap();
672 PairMap falsepm = new PairMap();
673 Hashtable<PrefetchPair, Double> truechild=prefetch_hash.get(fcb.getNext(0));
674 Hashtable<PrefetchPair, Double> falsechild=prefetch_hash.get(fcb.getNext(1));
676 HashSet<PrefetchPair> allpp=new HashSet<PrefetchPair>();
677 allpp.addAll(truechild.keySet());
678 allpp.addAll(falsechild.keySet());
680 for(Iterator<PrefetchPair> ppit=allpp.iterator(); ppit.hasNext();) {
681 PrefetchPair pp=ppit.next();
682 double trueprob=0,falseprob=0;
683 if (truechild.containsKey(pp))
684 trueprob=truechild.get(pp).doubleValue();
685 if (falsechild.containsKey(pp))
686 falseprob=falsechild.get(pp).doubleValue();
688 double newprob=trueprob*fcb.getTrueProb()+falseprob*fcb.getFalseProb();
689 if (loop.isLoopingBranch(md,fcb)&&
694 if(newprob < ANALYSIS_THRESHOLD_PROB) //Skip pp that are below threshold
697 tocompare.put(pp, newprob);
698 if (truechild.containsKey(pp))
699 truepm.addPair(pp, pp);
701 if (falsechild.containsKey(pp))
702 falsepm.addPair(pp, pp);
706 updatePairMap(fcb, truepm, 0);
707 updatePairMap(fcb, falsepm, 1);
708 updatePrefetchSet(fcb, tocompare);
711 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
712 * prefetches up the FlatNode*/
713 private void processDefaultCase(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
714 PairMap pm = new PairMap();
715 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
717 /* Propagate all child nodes */
719 for(Enumeration e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
720 PrefetchPair childpp = (PrefetchPair) e.nextElement();
721 TempDescriptor[] writearray=curr.writesTemps();
722 for(int i=0; i<writearray.length; i++) {
723 TempDescriptor wtd=writearray[i];
724 if(childpp.base == wtd||
725 childpp.containsTemp(wtd))
728 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
729 pm.addPair(childpp, childpp);
732 updatePairMap(curr, pm, 0);
733 updatePrefetchSet(curr, tocompare);
736 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
737 * prefetches up the FlatNode*/
738 private void processCall(FlatCall curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy) {
739 PairMap pm = new PairMap();
740 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
742 /* Don't propagate prefetches across cache clear */
743 if (!(curr.getMethod().getClassMethodName().equals("System.clearPrefetchCache")||
744 curr.getMethod().getClassMethodName().equals("Barrier.enterBarrier"))) {
745 /* Propagate all child nodes */
747 for(Enumeration e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
748 PrefetchPair childpp = (PrefetchPair) e.nextElement();
749 TempDescriptor[] writearray=curr.writesTemps();
750 for(int i=0; i<writearray.length; i++) {
751 TempDescriptor wtd=writearray[i];
752 if(childpp.base == wtd||
753 childpp.containsTemp(wtd))
756 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
757 pm.addPair(childpp, childpp);
761 updatePairMap(curr, pm, 0);
762 updatePrefetchSet(curr, tocompare);
765 /** This function prints the Prefetch pairs of a given flatnode */
766 private void printPrefetchPairs(FlatNode fn) {
767 System.out.println(fn);
768 if(prefetch_hash.containsKey(fn)) {
769 System.out.print("Prefetch" + "(");
770 Hashtable<PrefetchPair, Double> currhash = (Hashtable) prefetch_hash.get(fn);
771 for(Enumeration pphash= currhash.keys(); pphash.hasMoreElements();) {
772 PrefetchPair pp = (PrefetchPair) pphash.nextElement();
773 System.out.print(pp.toString() + ", ");
775 System.out.println(")");
777 System.out.println("Flatnode is currently not present in the global hash: Prefetch Set is Empty");
781 private void doInsPrefetchAnalysis(FlatMethod fm, Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
782 Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
783 HashSet<PrefetchPair> pset1_init = new HashSet<PrefetchPair>();
784 LinkedList<FlatNode> newtovisit = new LinkedList<FlatNode>();
785 LinkedList<FlatNode> newvisited = new LinkedList<FlatNode>();
787 newtovisit.addLast((FlatNode)fm);
788 while(!newtovisit.isEmpty()) {
789 FlatNode fn = (FlatNode) newtovisit.iterator().next();
790 newtovisit.remove(0);
791 pset1_hash.put(fn, pset1_init); //Initialize pset1_hash
792 newvisited.addLast(fn);
793 for(int i=0; i<fn.numNext(); i++) {
794 FlatNode nn = fn.getNext(i);
795 if(!newtovisit.contains(nn) && !newvisited.contains(nn)) {
796 newtovisit.addLast(nn);
801 /* Start with a top down sorted order of nodes */
802 while(!newvisited.isEmpty()) {
803 applyPrefetchInsertRules((FlatNode) newvisited.getFirst(), newvisited, pset1_hash, newprefetchset);
804 newvisited.remove(0);
806 delSubsetPPairs(newprefetchset);
809 /** This function deletes the smaller prefetch pair subset from a list of prefetch pairs
810 * for e.g. if there are 2 prefetch pairs a.b.c.d and a.b.c for a given flatnode
811 * then this function drops a.b.c from the prefetch set of the flatnode */
812 private void delSubsetPPairs(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
813 for (Enumeration e = newprefetchset.keys(); e.hasMoreElements();) {
814 FlatNode fn = (FlatNode) e.nextElement();
815 Set<PrefetchPair> ppairs = newprefetchset.get(fn);
816 Set<PrefetchPair> toremove=new HashSet<PrefetchPair>();
818 for(Iterator<PrefetchPair> it1=ppairs.iterator(); it1.hasNext();) {
819 PrefetchPair pp1=it1.next();
820 if (toremove.contains(pp1))
822 int l1=pp1.desc.size()+1;
823 for(Iterator<PrefetchPair> it2=ppairs.iterator(); it2.hasNext();) {
824 PrefetchPair pp2=it2.next();
825 int l2=pp2.desc.size()+1;
827 if (l1<l2&&isSubSet(pp1,pp2))
830 if (l2>l1&&isSubSet(pp2,pp1))
835 ppairs.removeAll(toremove);
839 /** This function returns: true if the shorter prefetch pair is a subset of the longer prefetch
840 * pair else it returns: false */
841 private boolean isSubSet(PrefetchPair shrt, PrefetchPair lng) {
842 if (shrt.base != lng.base) {
845 for (int j = 0; j < shrt.desc.size(); j++) {
846 if(shrt.getDescAt(j) instanceof IndexDescriptor) {
847 IndexDescriptor shrtid = (IndexDescriptor) shrt.getDescAt(j);
848 if(lng.getDescAt(j) instanceof IndexDescriptor) {
849 IndexDescriptor lngid = (IndexDescriptor) lng.getDescAt(j);
850 if(shrtid.equals(lngid)) {
859 if ((Descriptor)shrt.getDescAt(j) != (Descriptor)lng.getDescAt(j)) {
867 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
868 * returns: true if something has changed in the new Prefetch set else
871 private boolean comparePSet1(HashSet<PrefetchPair> oldPSet, HashSet<PrefetchPair>newPSet) {
872 if(oldPSet.size() != newPSet.size()) {
875 for(Iterator it = newPSet.iterator(); it.hasNext();) {
876 if(!oldPSet.contains((PrefetchPair)it.next())) {
884 /** This function creates a set called pset1 that contains prefetch pairs that have already
885 * been prefetched. While traversing the graph of a flat representation in a top down fashion,
886 * this function creates pset1 such that it contains prefetch pairs that have been prefetched at
887 * the previous nodes */
889 private void applyPrefetchInsertRules(FlatNode fn, LinkedList<FlatNode> newvisited, Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash, Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
890 if(fn.kind() == FKind.FlatMethod) {
891 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
892 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
893 for(Enumeration e = prefetchset.keys(); e.hasMoreElements();) {
894 PrefetchPair pp = (PrefetchPair) e.nextElement();
895 /* Apply initial rule */
896 if(prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB) {
900 /* Enqueue child node if Pset1 has changed */
901 if (comparePSet1(pset1_hash.get(fn), pset1)) {
902 for(int j=0; j<fn.numNext(); j++) {
903 FlatNode nn = fn.getNext(j);
904 newvisited.addLast((FlatNode)nn);
906 pset1_hash.put(fn, pset1);
908 newprefetchset.put(fn, pset1);
909 } else { /* Nodes other than Flat Method Node */
910 HashSet<PrefetchPair> pset2 = new HashSet<PrefetchPair>();
911 HashSet<PrefetchPair> newpset = new HashSet<PrefetchPair>();
912 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
913 Hashtable<FlatNode, PairMap> ppairmaphash = pmap_hash.get(fn);
914 for(Enumeration epset = prefetchset.keys(); epset.hasMoreElements();) {
915 PrefetchPair pp = (PrefetchPair) epset.nextElement();
916 boolean pprobIsGreater = (prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB);
917 boolean mapprobIsLess=false;
918 boolean mapIsPresent=true;
919 for(int i=0; i<fn.numPrev(); i++) {
920 FlatNode parentnode=fn.getPrev(i);
921 PairMap pm = (PairMap) ppairmaphash.get(parentnode);
922 //Find if probability is less for previous node
923 if(pm!=null&&pm.getPair(pp) != null) {
924 PrefetchPair mappedpp = pm.getPair(pp);
925 if(prefetch_hash.get(parentnode).containsKey(mappedpp)) {
926 double prob = prefetch_hash.get(parentnode).get(mappedpp).doubleValue();
927 if(prob < PREFETCH_THRESHOLD_PROB)
928 mapprobIsLess = true;
930 mapprobIsLess = true;
932 mapprobIsLess = true;
936 HashSet pset = pset1_hash.get(parentnode);
937 if(pset.isEmpty()||!pset.contains((PrefetchPair) pm.getPair(pp)))
938 mapIsPresent = false;
946 if(pprobIsGreater && mapprobIsLess)
950 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
952 pset1.addAll(newpset);
953 /* Enqueue child node if Pset1 has changed */
954 if (comparePSet1(pset1_hash.get(fn), pset1)) {
955 for(int i=0; i<fn.numNext(); i++) {
956 FlatNode nn = fn.getNext(i);
957 newvisited.addLast((FlatNode)nn);
959 pset1_hash.put(fn, pset1);
962 /* To insert prefetch, apply rule: if the newpset minus pset2 is nonempty
963 * then insert a new prefetch node here*/
965 HashSet<PrefetchPair> s = new HashSet<PrefetchPair>();
968 newprefetchset.put(fn, s);
972 private void addFlatPrefetchNode(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
973 boolean isFNPresent = false; /* Detects presence of FlatNew node */
974 /* This modifies the Flat representation graph */
975 for(Enumeration e = newprefetchset.keys(); e.hasMoreElements();) {
976 FlatNode fn = (FlatNode) e.nextElement();
977 FlatPrefetchNode fpn = new FlatPrefetchNode();
978 if(newprefetchset.get(fn).size() > 0) {
979 fpn.insAllpp((HashSet)newprefetchset.get(fn));
980 if(fn.kind() == FKind.FlatMethod) {
981 FlatNode nn = fn.getNext(0);
984 fpn.siteid = prefetchsiteid++;
986 /* Check if previous node of this FlatNode is a NEW node
987 * If yes, delete this flatnode and its prefetch set from hash table
988 * This eliminates prefetches for NULL ptrs*/
989 for(int i = 0; i< fn.numPrev(); i++) {
990 FlatNode nn = fn.getPrev(i);
991 if(nn.kind() == FKind.FlatNew) {
996 while(fn.numPrev() > 0) {
997 FlatNode nn = fn.getPrev(0);
998 for(int j = 0; j<nn.numNext(); j++) {
999 if(nn.getNext(j) == fn) {
1005 fpn.siteid = prefetchsiteid++;