1 package Analysis.Prefetch;
4 import Analysis.CallGraph.CallGraph;
5 import Analysis.Prefetch.PrefetchPair;
6 import Analysis.Prefetch.PairMap;
7 import Analysis.Prefetch.IndexDescriptor;
11 import IR.MethodDescriptor;
14 import IR.ClassDescriptor;
16 public class PrefetchAnalysis {
20 Set<FlatNode> tovisit;
21 public Hashtable<FlatNode, Hashtable<PrefetchPair, Double>> prefetch_hash;//holds all flatnodes and corresponding prefetch set
22 public Hashtable<FlatNode, Hashtable<FlatNode, PairMap>> pmap_hash;//holds all flatnodes and mappings between child prefetch pair and parent prefetch pair
23 public static final double PROB_DIFF = 0.05; //threshold for difference in probabilities during first phase of analysis
24 public static final double ANALYSIS_THRESHOLD_PROB = 0.10; //threshold for prefetches to stop propagating during first phase of analysis
25 public static final double PREFETCH_THRESHOLD_PROB = 0.30;//threshold for prefetches to stop propagating while applying prefetch rules during second phase of analysis
26 public static final double BRANCH_TRUE_EDGE_PROB = 0.5;
27 public static final double BRANCH_FALSE_EDGE_PROB = 0.5;
29 public PrefetchAnalysis(State state, CallGraph callgraph, TypeUtil typeutil) {
30 this.typeutil=typeutil;
32 this.callgraph=callgraph;
33 prefetch_hash = new Hashtable<FlatNode, Hashtable<PrefetchPair,Double>>();
34 pmap_hash = new Hashtable<FlatNode, Hashtable<FlatNode, PairMap>>();
40 /** This function returns true if a tempdescriptor object is found in the array of descriptors
41 * for a given prefetch pair else returns false*/
42 private boolean isTempDescFound(PrefetchPair pp, TempDescriptor td) {
43 ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
44 ListIterator it = desc.listIterator();
47 if(o instanceof IndexDescriptor) {
48 ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
49 if(tdarray.contains(td)) {
57 /** This function creates a new Arraylist of Descriptors by replacing old tempdescriptors with new
58 * tempdescriptors when there is a match */
59 private ArrayList<Descriptor> getNewDesc(PrefetchPair pp, TempDescriptor td, TempDescriptor newtd) {
60 ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
61 ListIterator it = desc.listIterator();
63 Object currdesc = it.next();
64 if(currdesc instanceof IndexDescriptor) {
65 ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)currdesc).tddesc;
66 if(tdarray.contains(td)) {
67 int index = tdarray.indexOf(td);
68 tdarray.set(index, newtd);
75 /** This function creates a new Arraylist of Descriptors by replacing old tempdescriptors with new
76 * tempdescriptors when there is a match for e.g FlatOpNodes if i= i+j then replace i with i+j */
77 private ArrayList<Descriptor> getNewDesc(PrefetchPair pp, TempDescriptor td, TempDescriptor left, TempDescriptor right) {
78 ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
79 ListIterator it = desc.listIterator();
81 Object currdesc = it.next();
82 if(currdesc instanceof IndexDescriptor) {
83 ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)currdesc).tddesc;
84 if(tdarray.contains(td)) {
85 int index = tdarray.indexOf(td);
86 tdarray.set(index, left);
94 /** This function starts the prefetch analysis */
95 private void DoPrefetch() {
96 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
97 while(classit.hasNext()) {
98 ClassDescriptor cn=(ClassDescriptor)classit.next();
103 /** This function calls analysis for every method in a class */
104 private void doMethodAnalysis(ClassDescriptor cn) {
105 for (Iterator methodit=cn.getMethods();methodit.hasNext();) {
106 MethodDescriptor md=(MethodDescriptor)methodit.next();
107 if (state.excprefetch.contains(md.getClassMethodName()))
108 continue; //Skip this method
109 Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
110 FlatMethod fm=state.getMethodFlat(md);
111 doFlatNodeAnalysis(fm);
112 doInsPrefetchAnalysis(fm, newprefetchset);
113 if(newprefetchset.size() > 0) {
114 addFlatPrefetchNode(newprefetchset);
116 newprefetchset = null;
120 /** This function calls analysis for every node in a method */
121 private void doFlatNodeAnalysis(FlatMethod fm) {
122 tovisit = fm.getNodeSet();
123 Hashtable<PrefetchPair, Double> nodehash = new Hashtable<PrefetchPair, Double>();
124 /* Create Empty Prefetch Sets for all flat nodes in the global hashtable */
125 while(!tovisit.isEmpty()) {
126 FlatNode fn = (FlatNode)tovisit.iterator().next();
127 prefetch_hash.put(fn, nodehash);
131 /* Visit and process nodes */
132 tovisit = fm.getNodeSet();
133 while(!tovisit.isEmpty()) {
134 FlatNode fn = (FlatNode)tovisit.iterator().next();
135 doChildNodeAnalysis(fn);
141 * This function generates the prefetch sets for a given Flatnode considering the kind of node
142 * It calls severals functions based on the kind of the node and
143 * returns true: if the prefetch set has changed since last time the node was analysed
144 * returns false : otherwise
146 private void doChildNodeAnalysis(FlatNode curr) {
147 Hashtable<PrefetchPair, Double> child_prefetch_set_copy = new Hashtable<PrefetchPair, Double>();
148 Hashtable<FlatNode, PairMap> parentpmap = new Hashtable<FlatNode, PairMap>();
149 FlatNode child_node = null;
150 if(curr.numNext() != 0) {
151 child_node = curr.getNext(0);
152 if(prefetch_hash.containsKey(child_node)) {
153 child_prefetch_set_copy = (Hashtable<PrefetchPair,Double>) prefetch_hash.get(child_node).clone();
157 switch(curr.kind()) {
158 case FKind.FlatBackEdge:
159 processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
162 //TODO change it to take care of FlatMethod, Flatcalls
163 processFlatCall(curr, child_prefetch_set_copy, parentpmap);
165 case FKind.FlatCheckNode:
166 processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
168 case FKind.FlatMethod:
169 //TODO change it to take care of FlatMethod, Flatcalls
170 processFlatMethod(curr, child_prefetch_set_copy, parentpmap);
173 processFlatNewNode(curr, child_prefetch_set_copy, parentpmap);
175 case FKind.FlatReturnNode:
176 //TODO change it to take care of FlatMethod, Flatcalls
177 processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
179 case FKind.FlatFieldNode:
180 processFlatFieldNode(curr, child_prefetch_set_copy, parentpmap);
182 case FKind.FlatElementNode:
183 processFlatElementNode(curr, child_prefetch_set_copy, parentpmap);
185 case FKind.FlatCondBranch:
186 Hashtable<PrefetchPair, Double> branch_prefetch_set = new Hashtable<PrefetchPair,Double>();
187 for (int i = 0; i < curr.numNext(); i++) {
188 Hashtable<FlatNode, PairMap> branchparentpmap = new Hashtable<FlatNode, PairMap>();
189 child_node = curr.getNext(i);
190 if (prefetch_hash.containsKey(child_node)) {
191 child_prefetch_set_copy = (Hashtable<PrefetchPair,Double>) prefetch_hash.get(child_node).clone();
193 processFlatCondBranch(curr, child_prefetch_set_copy, i, branch_prefetch_set, branchparentpmap);
196 case FKind.FlatOpNode:
197 processFlatOpNode(curr, child_prefetch_set_copy, parentpmap);
199 case FKind.FlatLiteralNode:
200 processFlatLiteralNode(curr, child_prefetch_set_copy, parentpmap);
202 case FKind.FlatSetElementNode:
203 processFlatSetElementNode(curr, child_prefetch_set_copy, parentpmap);
205 case FKind.FlatSetFieldNode:
206 processFlatSetFieldNode(curr, child_prefetch_set_copy, parentpmap);
208 case FKind.FlatAtomicEnterNode:
209 processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
211 case FKind.FlatAtomicExitNode:
212 processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
214 case FKind.FlatCastNode:
215 processFlatCastNode(curr, child_prefetch_set_copy, parentpmap);
217 case FKind.FlatFlagActionNode:
218 processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
220 case FKind.FlatGlobalConvNode:
221 processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
224 processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
226 case FKind.FlatTagDeclaration:
227 processFlatTagDeclaration(curr, child_prefetch_set_copy, parentpmap);
230 throw new Error("No such Flatnode kind");
234 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
235 * returns: true if something has changed in the new Prefetch set else
238 private boolean comparePrefetchSets(Hashtable<PrefetchPair, Double> oldPrefetchSet, Hashtable<PrefetchPair, Double>
240 boolean hasChanged = false;
241 PrefetchPair oldpp = null;
242 PrefetchPair newpp = null;
244 if(oldPrefetchSet.size() != newPrefetchSet.size()) {
245 if(newPrefetchSet.size() == 0) {
250 Enumeration e = newPrefetchSet.keys();
251 while(e.hasMoreElements()) {
252 newpp = (PrefetchPair) e.nextElement();
253 double newprob = newPrefetchSet.get(newpp).doubleValue();
254 for(Enumeration elem = oldPrefetchSet.keys(); elem.hasMoreElements();) {
255 oldpp = (PrefetchPair) elem.nextElement();
256 if(oldpp.equals(newpp)) {
257 /*Compare the difference in their probabilities */
258 double oldprob = oldPrefetchSet.get(oldpp).doubleValue();
259 if(((newprob - oldprob) > PROB_DIFF) || (newprob >= PREFETCH_THRESHOLD_PROB && oldprob < PREFETCH_THRESHOLD_PROB)) {
270 /** This function processes the prefetch set of FlatFieldNode
271 * It generates a new prefetch set after comparision with its children
272 * Then compares it with its old prefetch set
273 * If old prefetch set is not same as new prefetch set then enqueue the parents
274 * of the current FlatFieldNode
276 private void processFlatFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
277 Hashtable<FlatNode, PairMap> parentpmap) {
278 boolean pSetHasChanged = false;
279 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
280 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
281 FlatFieldNode currffn = (FlatFieldNode) curr;
282 PairMap pm = new PairMap();
284 /* Do Self analysis of the current node*/
285 FieldDescriptor currffn_field = currffn.getField();
286 TempDescriptor currffn_src = currffn.getSrc();
287 if (currffn_field.getType().isPtr()) {
288 PrefetchPair pp = new PrefetchPair(currffn_src, (Descriptor) currffn_field);
289 Double prob = new Double(1.0);
290 currcopy.put(pp, prob);
293 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
294 Enumeration ecld = child_prefetch_set_copy.keys();
295 PrefetchPair currpp = null;
296 PrefetchPair childpp = null;
297 while (ecld.hasMoreElements()) {
298 childpp = (PrefetchPair) ecld.nextElement();
299 if (childpp.base == currffn.getDst() && (childpp.getDesc()!= null)) {
300 if (currffn.getField().getType().isPtr()) {
301 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
302 newdesc.add(currffn.getField());
303 newdesc.addAll(childpp.desc);
304 PrefetchPair newpp = new PrefetchPair(currffn.getSrc(), newdesc);
305 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
306 tocompare.put(newpp, newprob);
307 pm.addPair(childpp, newpp);
308 child_prefetch_set_copy.remove(childpp);
309 /* Check for independence of prefetch pairs to compute new probability */
310 if(child_prefetch_set_copy.containsKey(newpp)) {
311 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
312 if(newprob < ANALYSIS_THRESHOLD_PROB) {
313 tocompare.remove(newpp);
315 tocompare.put(newpp, newprob);
316 pm.addPair(newpp, newpp);
318 child_prefetch_set_copy.remove(newpp);
321 } else if(childpp.base == currffn.getDst() && (childpp.getDesc() == null)) {
322 child_prefetch_set_copy.remove(childpp);
323 } else if(isTempDescFound(childpp, currffn.getDst())) {
324 child_prefetch_set_copy.remove(childpp);
329 /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
330 * if so, calculate the new probability */
331 ecld = child_prefetch_set_copy.keys();
332 Enumeration e = null;
333 while(ecld.hasMoreElements()) {
334 childpp = (PrefetchPair) ecld.nextElement();
335 for(e = currcopy.keys(); e.hasMoreElements();) {
336 currpp = (PrefetchPair) e.nextElement();
337 if(currpp.equals(childpp)) {
338 pm.addPair(childpp, currpp);
339 child_prefetch_set_copy.remove(childpp);
345 /* Merge child prefetch pairs */
346 ecld = child_prefetch_set_copy.keys();
347 while(ecld.hasMoreElements()) {
348 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 */
356 while(e.hasMoreElements()) {
357 currpp = (PrefetchPair) e.nextElement();
358 tocompare.put(currpp, currcopy.get(currpp).doubleValue());
359 currcopy.remove(currpp);
362 /* Create prefetch mappings for child nodes */
364 parentpmap.put(curr, pm);
367 if(!pmap_hash.isEmpty()) {
368 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
369 if(pairmapping != null) {
370 pairmapping.put(curr, pm);
371 pmap_hash.put(curr.getNext(0), pairmapping);
373 pmap_hash.put(curr.getNext(0), parentpmap);
376 pmap_hash.put(curr.getNext(0), parentpmap);
379 /* Compare with the orginal prefetch pairs */
380 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
381 /* Enqueue parent nodes */
383 for(int i=0; i<curr.numPrev(); i++) {
384 tovisit.add(curr.getPrev(i));
386 /* Overwrite the new prefetch set to the global hash table */
387 prefetch_hash.put(curr,tocompare);
391 /** This function processes the prefetch set of a FlatElementNode
392 * It generates a new prefetch set after comparision with its children
393 * It compares the old prefetch set with this new prefetch set and enqueues the parents
394 * of the current node if change occurs and updates the global flatnode hash table
396 private void processFlatElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
397 Hashtable<FlatNode, PairMap> parentpmap) {
399 boolean pSetHasChanged = false;
400 Hashtable<PrefetchPair, Double> currcopy = new Hashtable<PrefetchPair, Double>();
401 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
402 FlatElementNode currfen = (FlatElementNode) curr;
403 PairMap pm = new PairMap();
406 /* Do Self analysis of the current node*/
407 TempDescriptor currfen_index = currfen.getIndex();
408 IndexDescriptor idesc = new IndexDescriptor(currfen_index, 0);
409 TempDescriptor currfen_src = currfen.getSrc();
410 if(currfen.getDst().getType().isPtr()) {
411 PrefetchPair pp = new PrefetchPair(currfen_src, (Descriptor) idesc);
412 Double prob = new Double(1.0);
413 currcopy.put(pp, prob);
416 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
417 Enumeration ecld = child_prefetch_set_copy.keys();
418 PrefetchPair currpp = null;
419 while (ecld.hasMoreElements()) {
420 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
421 if (childpp.base == currfen.getDst() && (childpp.getDesc()!= null)) {
422 if (currfen.getDst().getType().isPtr()) {
423 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
424 newdesc.add((Descriptor)idesc);
425 newdesc.addAll(childpp.desc);
426 PrefetchPair newpp = new PrefetchPair(currfen.getSrc(), newdesc);
427 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
428 tocompare.put(newpp, newprob);
429 pm.addPair(childpp, newpp);
430 child_prefetch_set_copy.remove(childpp);
431 /* Check for independence of prefetch pairs to compute new probability */
432 if(child_prefetch_set_copy.containsKey(newpp)) {
433 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
434 if(newprob < ANALYSIS_THRESHOLD_PROB) {
435 tocompare.remove(newpp);
437 tocompare.put(newpp, newprob);
438 pm.addPair(newpp, newpp);
440 child_prefetch_set_copy.remove(newpp);
443 } else if(childpp.base == currfen.getDst() && (childpp.getDesc() == null)) {
444 child_prefetch_set_copy.remove(childpp);
445 } else if(isTempDescFound(childpp, currfen.getDst())) {
446 child_prefetch_set_copy.remove(childpp);
451 /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
452 * if so calculate the new probability */
453 ecld = child_prefetch_set_copy.keys();
454 Enumeration e = null;
455 while(ecld.hasMoreElements()) {
456 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
457 for(e = currcopy.keys(); e.hasMoreElements();) {
458 currpp = (PrefetchPair) e.nextElement();
459 if(currpp.equals(childpp)) {
460 pm.addPair(childpp, currpp);
461 child_prefetch_set_copy.remove(childpp);
467 /* Merge child prefetch pairs */
468 ecld = child_prefetch_set_copy.keys();
469 while(ecld.hasMoreElements()) {
470 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
471 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
472 pm.addPair(childpp, childpp);
473 child_prefetch_set_copy.remove(childpp);
476 /* Merge curr prefetch pairs */
478 while(e.hasMoreElements()) {
479 currpp = (PrefetchPair) e.nextElement();
480 tocompare.put(currpp, currcopy.get(currpp).doubleValue());
481 currcopy.remove(currpp);
484 /* Create prefetch mappings for child nodes */
486 parentpmap.put(curr, pm);
488 if(!pmap_hash.isEmpty()) {
489 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
490 if(pairmapping != null) {
491 pairmapping.put(curr, pm);
492 pmap_hash.put(curr.getNext(0), pairmapping);
494 pmap_hash.put(curr.getNext(0), parentpmap);
497 pmap_hash.put(curr.getNext(0), parentpmap);
500 /* Compare with the orginal prefetch pairs */
501 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
502 /* Enqueue parent nodes */
504 for(int i=0; i<curr.numPrev(); i++) {
505 tovisit.add(curr.getPrev(i));
507 /* Overwrite the new prefetch set to the global hash table */
508 prefetch_hash.put(curr,tocompare);
512 /** This function processes the prefetch set of a FlatSetFieldNode
513 * It generates a new prefetch set after comparision with its children
514 * It compares the old prefetch set with this new prefetch set and enqueues the parents
515 * of the current node if change occurs and then updates the global flatnode hash table
517 private void processFlatSetFieldNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
518 Hashtable<FlatNode, PairMap> parentpmap) {
519 boolean pSetHasChanged = false;
520 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
521 FlatSetFieldNode currfsfn = (FlatSetFieldNode) curr;
522 PairMap pm = new PairMap();
524 Enumeration ecld = child_prefetch_set_copy.keys();
525 while (ecld.hasMoreElements()) {
526 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
527 if(childpp.base == currfsfn.getDst()) {
528 int size = childpp.desc.size();
529 if(size >=2) { /*e.g. x.f = g (with child prefetches x.f.g, x.f[0].j) */
530 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
531 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
532 for(int i = 0;i<(childpp.desc.size()-1); i++) {
533 newdesc.add(i,childpp.desc.get(i+1));
535 PrefetchPair newpp = new PrefetchPair(currfsfn.getSrc(), newdesc);
536 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
537 tocompare.put(newpp, newprob);
538 pm.addPair(childpp, newpp);
539 child_prefetch_set_copy.remove(childpp);
540 /* Check for independence of prefetch pairs in newly generated prefetch pair
541 * to compute new probability */
542 if(child_prefetch_set_copy.containsKey(newpp)) {
543 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
544 if(newprob < ANALYSIS_THRESHOLD_PROB) {
545 tocompare.remove(newpp);
547 tocompare.put(newpp, newprob);
548 pm.addPair(newpp, newpp);
550 child_prefetch_set_copy.remove(newpp);
553 } else if(size==1) { /* e.g x.f = g (with child prefetch x.f) */
554 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
555 child_prefetch_set_copy.remove(childpp);
563 /* Merge child prefetch pairs */
564 ecld = child_prefetch_set_copy.keys();
565 while(ecld.hasMoreElements()) {
566 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
567 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
568 pm.addPair(childpp, childpp);
569 child_prefetch_set_copy.remove(childpp);
572 /* Create prefetch mappings for child nodes */
574 parentpmap.put(curr, pm);
576 if(!pmap_hash.isEmpty()) {
577 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
578 if(pairmapping != null) {
579 pairmapping.put(curr, pm);
580 pmap_hash.put(curr.getNext(0), pairmapping);
582 pmap_hash.put(curr.getNext(0), parentpmap);
585 pmap_hash.put(curr.getNext(0), parentpmap);
588 /* Compare with the orginal prefetch pairs */
589 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
590 /* Enqueue parent nodes */
592 for(int i=0; i<curr.numPrev(); i++) {
593 tovisit.add(curr.getPrev(i));
595 /* Overwrite the new prefetch set to the global hash table */
596 prefetch_hash.put(curr,tocompare);
600 /** This function processes the prefetch set of a FlatSetElementNode
601 * It generates a new prefetch set after comparision with its children
602 * It compares the old prefetch set with this new prefetch set and enqueues the parents
603 * of the current node if change occurs and then updates the global flatnode hash table
605 private void processFlatSetElementNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
606 Hashtable<FlatNode, PairMap> parentpmap) {
607 boolean pSetHasChanged = false;
608 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
609 FlatSetElementNode currfsen = (FlatSetElementNode) curr;
610 PairMap pm = new PairMap();
612 Enumeration ecld = child_prefetch_set_copy.keys();
613 while (ecld.hasMoreElements()) {
614 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
615 if (childpp.base == currfsen.getDst()){
616 int sizedesc = childpp.desc.size();
617 if((childpp.getDescAt(0) instanceof IndexDescriptor)) {
618 int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size();
619 if(sizetempdesc == 1) {
620 if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) {
621 /* For e.g. a[i] = g with child prefetch set a[i].r or a[i].r.f */
622 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
623 for(int i = 0;i<(childpp.desc.size()-1); i++) {
624 newdesc.add(i,childpp.desc.get(i+1));
626 PrefetchPair newpp = new PrefetchPair(currfsen.getSrc(), newdesc);
627 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
628 tocompare.put(newpp, newprob);
629 pm.addPair(childpp, newpp);
630 child_prefetch_set_copy.remove(childpp);
631 /* Check for independence of prefetch pairs to compute new probability */
632 if(child_prefetch_set_copy.containsKey(newpp)) {
633 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
634 if(newprob < ANALYSIS_THRESHOLD_PROB) {
635 tocompare.remove(newpp);
637 tocompare.put(newpp, newprob);
638 pm.addPair(newpp, newpp);
640 child_prefetch_set_copy.remove(newpp);
642 } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1))
643 /* For e.g. a[i] = g with child prefetch set a[i] */
644 child_prefetch_set_copy.remove(childpp);
651 /* Merge child prefetch pairs */
652 ecld = child_prefetch_set_copy.keys();
653 while(ecld.hasMoreElements()) {
654 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
655 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
656 pm.addPair(childpp, childpp);
657 child_prefetch_set_copy.remove(childpp);
660 /* Create prefetch mappings for child nodes */
662 parentpmap.put(curr, pm);
664 if(!pmap_hash.isEmpty()) {
665 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
666 if(pairmapping != null) {
667 pairmapping.put(curr, pm);
668 pmap_hash.put(curr.getNext(0), pairmapping);
670 pmap_hash.put(curr.getNext(0), parentpmap);
673 pmap_hash.put(curr.getNext(0), parentpmap);
676 /* Compare with the orginal prefetch pairs */
677 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
678 /* Enqueue parent nodes */
680 for(int i=0; i<curr.numPrev(); i++) {
681 tovisit.add(curr.getPrev(i));
683 /* Overwrite the new prefetch set to the global hash table */
684 prefetch_hash.put(curr,tocompare);
688 /** This function applies rules and does analysis for a FlatOpNode
689 * And updates the global prefetch hashtable
691 private void processFlatOpNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
692 Hashtable<FlatNode, PairMap> parentpmap) {
693 boolean pSetHasChanged = false;
695 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
696 FlatOpNode currfopn = (FlatOpNode) curr;
697 Enumeration ecld = null;
698 PairMap pm = new PairMap();
700 if(currfopn.getOp().getOp() == Operation.ASSIGN) {
701 ecld = child_prefetch_set_copy.keys();
702 while (ecld.hasMoreElements()) {
703 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
704 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
706 /* For cases like x=y with child prefetch set x[i].z,x.g*/
707 if(childpp.base == currfopn.getDest()) {
708 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
709 newdesc.addAll(childpp.desc);
710 PrefetchPair newpp = new PrefetchPair(currfopn.getLeft(), newdesc);
711 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
712 tocompare.put(newpp, newprob);
713 pm.addPair(childpp, newpp);
714 child_prefetch_set_copy.remove(childpp);
715 /* Check for independence of prefetch pairs to compute new probability */
716 if(child_prefetch_set_copy.containsKey(newpp)) {
717 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
718 if(newprob < ANALYSIS_THRESHOLD_PROB) {
719 tocompare.remove(newpp);
721 tocompare.put(newpp, newprob);
722 pm.addPair(newpp, newpp);
724 child_prefetch_set_copy.remove(newpp);
726 /* For cases like x=y with child prefetch set r[x].p, r[p+x].q where x is a tempdescriptor*/
727 } else if(isTempDescFound(copyofchildpp, currfopn.getDest())) {
728 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
729 newdesc.addAll((ArrayList<Descriptor>)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft()));
730 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
731 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
732 tocompare.put(newpp, newprob);
733 pm.addPair(childpp, newpp);
734 child_prefetch_set_copy.remove(childpp);
735 /* Check for independence of prefetch pairs to compute new probability*/
736 if(child_prefetch_set_copy.containsKey(newpp)) {
737 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
738 if(newprob < ANALYSIS_THRESHOLD_PROB) {
739 tocompare.remove(newpp);
741 tocompare.put(newpp, newprob);
742 pm.addPair(newpp, newpp);
744 child_prefetch_set_copy.remove(newpp);
752 //case i = i+z with child prefetch set a[i].x
753 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) {
754 ecld = child_prefetch_set_copy.keys();
755 while (ecld.hasMoreElements()) {
756 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
757 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
759 if(isTempDescFound(copyofchildpp, currfopn.getDest())) {
760 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
761 newdesc.addAll((ArrayList<Descriptor>)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft(), currfopn.getRight()));
762 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
763 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue();
764 tocompare.put(newpp, newprob);
765 pm.addPair(childpp, newpp);
766 child_prefetch_set_copy.remove(childpp);
767 /* Check for independence of prefetch pairs to compute new probability*/
768 if(child_prefetch_set_copy.containsKey(newpp)) {
769 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
770 if(newprob < ANALYSIS_THRESHOLD_PROB) {
771 tocompare.remove(newpp);
773 tocompare.put(newpp, newprob);
774 pm.addPair(newpp, newpp);
776 child_prefetch_set_copy.remove(newpp);
783 //FIXME Is not taken care of for cases like x = -y followed by a[x].i
786 /* Merge child prefetch pairs */
787 ecld = child_prefetch_set_copy.keys();
788 while(ecld.hasMoreElements()) {
789 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
790 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
791 pm.addPair(childpp, childpp);
792 child_prefetch_set_copy.remove(childpp);
795 /* Create prefetch mappings for child nodes */
797 parentpmap.put(curr, pm);
799 if(!pmap_hash.isEmpty()) {
800 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
801 if(pairmapping != null) {
802 pairmapping.put(curr, pm);
803 pmap_hash.put(curr.getNext(0), pairmapping);
805 pmap_hash.put(curr.getNext(0), parentpmap);
808 pmap_hash.put(curr.getNext(0), parentpmap);
811 /* Compare with the orginal prefetch pairs */
812 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
813 /* Enqueue parent nodes */
815 for(int i=0; i<curr.numPrev(); i++) {
816 tovisit.add(curr.getPrev(i));
818 /* Overwrite the new prefetch set to the global hash table */
819 prefetch_hash.put(curr,tocompare);
823 /** This function processes a FlatLiteralNode where cases such as
824 * for e.g. i = 0 with child prefetch sets a[i].r, a[j+i].r or a[j].b[i].r
826 private void processFlatLiteralNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
827 Hashtable<FlatNode, PairMap> parentpmap) {
828 boolean pSetHasChanged = false;
829 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
830 FlatLiteralNode currfln = (FlatLiteralNode) curr;
831 Enumeration ecld = null;
832 PairMap pm = new PairMap();
834 if(currfln.getType().isIntegerType()) {
835 ecld = child_prefetch_set_copy.keys();
836 while (ecld.hasMoreElements()) {
837 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
838 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
839 if(isTempDescFound(copyofchildpp,currfln.getDst())) {
840 ArrayList<Descriptor> copychilddesc = (ArrayList<Descriptor>) copyofchildpp.getDesc();
841 int sizetempdesc = copychilddesc.size();
842 for(ListIterator it = copychilddesc.listIterator();it.hasNext();) {
843 Object o = it.next();
844 if(o instanceof IndexDescriptor) {
845 ArrayList<TempDescriptor> td = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
846 int sizetddesc = td.size();
847 if(td.contains(currfln.getDst())) {
848 int index = td.indexOf(currfln.getDst());
850 ((IndexDescriptor)o).offset += (Integer)currfln.getValue();
854 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
855 newdesc.addAll(copychilddesc);
856 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
857 Double newprob = (child_prefetch_set_copy.get(childpp)).doubleValue();
858 tocompare.put(newpp, newprob);
859 pm.addPair(childpp, newpp);
860 child_prefetch_set_copy.remove(childpp);
861 /* Check for independence of prefetch pairs to compute new probability */
862 if(child_prefetch_set_copy.containsKey(newpp)) {
863 newprob = (1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).doubleValue()) * (1.0 - tocompare.get(newpp).doubleValue())));
864 if(newprob < ANALYSIS_THRESHOLD_PROB) {
865 tocompare.remove(newpp);
867 tocompare.put(newpp, newprob);
868 pm.addPair(newpp, newpp);
870 child_prefetch_set_copy.remove(newpp);
876 /* Merge child prefetch pairs */
877 ecld = child_prefetch_set_copy.keys();
878 while(ecld.hasMoreElements()) {
879 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
880 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
881 pm.addPair(childpp, childpp);
882 child_prefetch_set_copy.remove(childpp);
885 /* Create prefetch mappings for child nodes */
887 parentpmap.put(curr, pm);
889 if(!pmap_hash.isEmpty()) {
890 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
891 if(pairmapping != null) {
892 pairmapping.put(curr, pm);
893 pmap_hash.put(curr.getNext(0), pairmapping);
895 pmap_hash.put(curr.getNext(0), parentpmap);
898 pmap_hash.put(curr.getNext(0), parentpmap);
901 /* Compare with the orginal prefetch pairs */
902 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
903 /* Enqueue parent nodes */
905 for(int i=0; i<curr.numPrev(); i++) {
906 tovisit.add(curr.getPrev(i));
908 /* Overwrite the new prefetch set to the global hash table */
909 prefetch_hash.put(curr,tocompare);
913 /** This function processes a FlatMethod where the method propagates
914 * the entire prefetch set of its child node */
915 private void processFlatMethod(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
916 Hashtable<FlatNode, PairMap> parentpmap) {
917 boolean pSetHasChanged = false;
918 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
919 FlatMethod currfm = (FlatMethod) curr;
920 Enumeration ecld = null;
921 PairMap pm = new PairMap();
923 /* Merge child prefetch pairs */
924 ecld = child_prefetch_set_copy.keys();
925 while(ecld.hasMoreElements()) {
926 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
927 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
928 pm.addPair(childpp, childpp);
929 child_prefetch_set_copy.remove(childpp);
932 /* Create prefetch mappings for child nodes */
934 parentpmap.put(curr, pm);
936 if(!pmap_hash.isEmpty()) {
937 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
938 if(pairmapping != null) {
939 pairmapping.put(curr, pm);
940 pmap_hash.put(curr.getNext(0), pairmapping);
942 pmap_hash.put(curr.getNext(0), parentpmap);
945 pmap_hash.put(curr.getNext(0), parentpmap);
948 /* Compare with the orginal prefetch pairs */
949 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
950 /* Enqueue parent nodes */
952 /* Overwrite the new prefetch set to the global hash table */
953 prefetch_hash.put(curr,tocompare);
957 /** This Function processes the FlatCalls
958 * It currently drops the propagation of those prefetchpairs whose base is
959 * same as the destination of the FlatCall
961 private void processFlatCall(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
962 Hashtable<FlatNode, PairMap> parentpmap) {
963 boolean pSetHasChanged = false;
964 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
965 FlatCall currfcn = (FlatCall) curr;
966 PairMap pm = new PairMap();
967 Enumeration ecld = null;
969 ecld = child_prefetch_set_copy.keys();
970 while(ecld.hasMoreElements()) {
971 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
972 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
973 if(currfcn.getReturnTemp() != childpp.base) {
974 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
975 pm.addPair(childpp, childpp);
976 child_prefetch_set_copy.remove(childpp);
978 child_prefetch_set_copy.remove(childpp);
982 /* Create prefetch mappings for child nodes */
984 parentpmap.put(curr, pm);
986 if(!pmap_hash.isEmpty()) {
987 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
988 if(pairmapping != null) {
989 pairmapping.put(curr, pm);
990 pmap_hash.put(curr.getNext(0), pairmapping);
992 pmap_hash.put(curr.getNext(0), parentpmap);
995 pmap_hash.put(curr.getNext(0), parentpmap);
998 /* Compare with the orginal prefetch pairs */
999 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
1000 /* Enqueue parent nodes */
1001 if(pSetHasChanged) {
1002 for(int i=0; i<curr.numPrev(); i++) {
1003 tovisit.add(curr.getPrev(i));
1005 /* Overwrite the new prefetch set to the global hash table */
1006 prefetch_hash.put(curr,tocompare);
1010 /** This function handles the processes the FlatNode of type FlatCondBranch
1011 * It combines prefetches of both child elements and create a new hash table called
1012 * branch_prefetch_set to contains the entries of both its children
1014 private void processFlatCondBranch(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy, int index,
1015 Hashtable<PrefetchPair,Double> branch_prefetch_set, Hashtable<FlatNode, PairMap> parentpmap) {
1016 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();//temporary hash table
1017 FlatCondBranch currfcb = (FlatCondBranch) curr;
1018 PairMap pm = new PairMap();
1019 Enumeration ecld = null;
1021 ecld = child_prefetch_set_copy.keys();
1022 while (ecld.hasMoreElements()) {
1023 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
1026 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue() * currfcb.getTrueProb();
1027 tocompare.put(childpp, newprob);
1028 pm.addPair(childpp, childpp);
1029 child_prefetch_set_copy.remove(childpp);
1030 } else if(index == 1) { /* False Edge */
1031 Double newprob = child_prefetch_set_copy.get(childpp).doubleValue() * currfcb.getFalseProb();
1032 tocompare.put(childpp, newprob);
1033 pm.addPair(childpp, childpp);
1034 child_prefetch_set_copy.remove(childpp);
1036 throw new Error("processFlatCondBranch() has only two child edges");
1040 /* Create prefetch mappings for child nodes */
1042 parentpmap.put(curr, pm);
1044 if(!pmap_hash.isEmpty()) {
1045 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(index));
1046 if(pairmapping != null) {
1047 pairmapping.put(curr, pm);
1048 pmap_hash.put(curr.getNext(index), pairmapping);
1050 pmap_hash.put(curr.getNext(index), parentpmap);
1053 pmap_hash.put(curr.getNext(index), parentpmap);
1056 /* Update branch_prefetch_set (global hash table) to combine all prefetch pairs from childnodes of the
1057 * cond branch that is currently stored in the tocompare hash table */
1058 if(!tocompare.isEmpty()) {
1059 if(index == 0) { /* True Edge */
1060 branch_prefetch_set.putAll(tocompare);
1061 }else if(index == 1) { /* False Edge */
1062 if(branch_prefetch_set.isEmpty()) {
1063 branch_prefetch_set.putAll(tocompare);
1065 Enumeration e = tocompare.keys();
1066 while(e.hasMoreElements()) {
1067 PrefetchPair pp = (PrefetchPair) e.nextElement();
1068 if(branch_prefetch_set.containsKey(pp)) {
1069 Double newprob = (branch_prefetch_set.get(pp).doubleValue() + tocompare.get(pp).doubleValue());
1070 if(newprob < ANALYSIS_THRESHOLD_PROB) {
1071 branch_prefetch_set.remove(pp);
1073 branch_prefetch_set.put(pp, newprob);
1076 branch_prefetch_set.put(pp,tocompare.get(pp).doubleValue());
1078 tocompare.remove(pp);
1082 throw new Error("processFlatCondBranch() has only two child edges");
1086 /* Compare prefetch sets and enqueue parent nodes: Only possible after combining prefetch pairs of both child nodes
1087 * into branch_prefetch_set hashtable*/
1089 boolean pSetHasChanged = false;
1090 /* Delete the prefetch pairs below threshold */
1091 for(Iterator it = branch_prefetch_set.keySet().iterator(); it.hasNext();) {
1092 PrefetchPair pp = (PrefetchPair) it.next();
1093 if(branch_prefetch_set.get(pp).doubleValue() < ANALYSIS_THRESHOLD_PROB) {
1094 /* Delete pair mappings of PSChild-> PSParent for these prefetch pairs */
1095 for(int i = 0; i<curr.numNext(); i++) {
1096 FlatNode fn = (FlatNode) curr.getNext(i);
1097 Hashtable<FlatNode, PairMap> pairmap = pmap_hash.get(fn);
1098 PairMap childpm = pairmap.get(curr);
1099 if(childpm!=null && childpm.contains(pp)) {
1100 childpm.removePair(pp);
1103 branch_prefetch_set.remove(pp);
1104 it = branch_prefetch_set.keySet().iterator();
1108 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), branch_prefetch_set);
1109 if(pSetHasChanged) {
1110 for(int i=0; i<curr.numPrev(); i++) {
1111 tovisit.add(curr.getPrev(i));
1113 /* Overwrite the new prefetch set to the global hash table */
1114 prefetch_hash.put(curr,branch_prefetch_set);
1119 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
1120 * prefetches up the FlatNode*/
1121 private void processDefaultCase(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
1122 Hashtable<FlatNode, PairMap> parentpmap) {
1123 boolean pSetHasChanged = false;
1124 PairMap pm = new PairMap();
1125 Enumeration e = null;
1126 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
1128 /* Propagate all child nodes */
1129 for(e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
1130 PrefetchPair childpp = (PrefetchPair) e.nextElement();
1131 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
1132 pm.addPair(childpp, childpp);
1133 child_prefetch_set_copy.remove(childpp);
1136 /* Check case for nodes with no children (e.g return null) and create prefetch mappings for child nodes*/
1137 if(curr.numNext() != 0) {
1139 parentpmap.put(curr, pm);
1141 if(!pmap_hash.isEmpty()) {
1142 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
1143 if(pairmapping != null) {
1144 pairmapping.put(curr, pm);
1145 pmap_hash.put(curr.getNext(0), pairmapping);
1147 pmap_hash.put(curr.getNext(0), parentpmap);
1150 pmap_hash.put(curr.getNext(0), parentpmap);
1154 /* Compare with old Prefetch sets */
1155 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
1157 for(int i=0; i<curr.numPrev(); i++) {
1158 tovisit.add(curr.getPrev(i));
1160 /* Overwrite the new prefetch set to the global hash table */
1161 prefetch_hash.put(curr,tocompare);
1165 /** This functions processes for FlatNewNode
1166 * for e.g x = NEW(foo) followed by childnode with prefetch set x.f
1167 * then drop the prefetches beyond this FlatNewNode */
1168 private void processFlatNewNode(FlatNode curr, Hashtable<PrefetchPair, Double> child_prefetch_set_copy,
1169 Hashtable<FlatNode, PairMap> parentpmap) {
1170 boolean pSetHasChanged = false;
1171 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
1172 FlatNew currfnn = (FlatNew) curr;
1173 Double newprob = new Double(0.0);
1174 PairMap pm = new PairMap();
1175 Enumeration ecld = null;
1177 ecld = child_prefetch_set_copy.keys();
1178 while (ecld.hasMoreElements()) {
1179 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
1180 if(childpp.base == currfnn.getDst()){
1181 child_prefetch_set_copy.remove(childpp);
1182 } else if(isTempDescFound(childpp, currfnn.getDst())) {
1183 child_prefetch_set_copy.remove(childpp);
1185 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
1186 pm.addPair(childpp, childpp);
1187 child_prefetch_set_copy.remove(childpp);
1191 /* Create prefetch mappings for child nodes */
1193 parentpmap.put(curr, pm);
1195 if(!pmap_hash.isEmpty()) {
1196 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
1197 if(pairmapping != null) {
1198 pairmapping.put(curr, pm);
1199 pmap_hash.put(curr.getNext(0), pairmapping);
1201 pmap_hash.put(curr.getNext(0), parentpmap);
1204 pmap_hash.put(curr.getNext(0), parentpmap);
1207 /* Compare with the old prefetch set */
1208 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
1210 /* Enqueue parent nodes */
1211 if(pSetHasChanged) {
1212 for(int i=0; i<curr.numPrev(); i++) {
1213 tovisit.add(curr.getPrev(i));
1215 /* Overwrite the new prefetch set to the global hash table */
1216 prefetch_hash.put(curr,tocompare);
1220 /** This functions processes for FlatCastNode
1221 * for e.g x = (cast type) y followed by childnode with prefetch set x.f
1222 * then drop the prefetches beyond this FlatCastNode */
1223 private void processFlatCastNode(FlatNode curr, Hashtable<PrefetchPair, Double>child_prefetch_set_copy,
1224 Hashtable<FlatNode, PairMap> parentpmap) {
1225 boolean pSetHasChanged = false;
1226 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
1227 FlatCastNode currfcn = (FlatCastNode) curr;
1228 Double newprob = new Double(0.0);
1229 PairMap pm = new PairMap();
1230 Enumeration ecld = null;
1232 ecld = child_prefetch_set_copy.keys();
1233 while (ecld.hasMoreElements()) {
1234 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
1235 if(childpp.base == currfcn.getDst()){
1236 child_prefetch_set_copy.remove(childpp);
1237 } else if(isTempDescFound(childpp, currfcn.getDst())) {
1238 child_prefetch_set_copy.remove(childpp);
1240 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
1241 pm.addPair(childpp, childpp);
1242 child_prefetch_set_copy.remove(childpp);
1246 /* Create prefetch mappings for child nodes */
1248 parentpmap.put(curr, pm);
1250 if(!pmap_hash.isEmpty()) {
1251 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
1252 if(pairmapping != null) {
1253 pairmapping.put(curr, pm);
1254 pmap_hash.put(curr.getNext(0), pairmapping);
1256 pmap_hash.put(curr.getNext(0), parentpmap);
1259 pmap_hash.put(curr.getNext(0), parentpmap);
1262 /* Compare with the old prefetch set */
1263 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
1265 /* Enqueue parent nodes */
1266 if(pSetHasChanged) {
1267 for(int i=0; i<curr.numPrev(); i++) {
1268 tovisit.add(curr.getPrev(i));
1270 /* Overwrite the new prefetch set to the global hash table */
1271 prefetch_hash.put(curr,tocompare);
1275 /** This functions processes for FlatTagDeclaration
1276 * for e.g x = (cast type) y followed by childnode with prefetch set x.f
1277 * then drop the prefetches beyond this FlatTagDeclaration */
1278 private void processFlatTagDeclaration(FlatNode curr, Hashtable<PrefetchPair, Double>child_prefetch_set_copy,
1279 Hashtable<FlatNode, PairMap> parentpmap) {
1280 boolean pSetHasChanged = false;
1281 Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();
1282 FlatTagDeclaration currftd = (FlatTagDeclaration) curr;
1283 Double newprob = new Double(0.0);
1284 PairMap pm = new PairMap();
1285 Enumeration ecld = null;
1287 ecld = child_prefetch_set_copy.keys();
1288 while (ecld.hasMoreElements()) {
1289 PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
1290 if(childpp.base == currftd.getDst()){
1291 child_prefetch_set_copy.remove(childpp);
1292 } else if(isTempDescFound(childpp, currftd.getDst())) {
1293 child_prefetch_set_copy.remove(childpp);
1295 tocompare.put(childpp, child_prefetch_set_copy.get(childpp).doubleValue());
1296 pm.addPair(childpp, childpp);
1297 child_prefetch_set_copy.remove(childpp);
1301 /* Create prefetch mappings for child nodes */
1303 parentpmap.put(curr, pm);
1305 if(!pmap_hash.isEmpty()) {
1306 Hashtable<FlatNode, PairMap> pairmapping = pmap_hash.get(curr.getNext(0));
1307 if(pairmapping != null) {
1308 pairmapping.put(curr, pm);
1309 pmap_hash.put(curr.getNext(0), pairmapping);
1311 pmap_hash.put(curr.getNext(0), parentpmap);
1314 pmap_hash.put(curr.getNext(0), parentpmap);
1317 /* Compare with the old prefetch set */
1318 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
1320 /* Enqueue parent nodes */
1321 if(pSetHasChanged) {
1322 for(int i=0; i<curr.numPrev(); i++) {
1323 tovisit.add(curr.getPrev(i));
1325 /* Overwrite the new prefetch set to the global hash table */
1326 prefetch_hash.put(curr,tocompare);
1330 /** This function prints the Prefetch pairs of a given flatnode */
1331 private void printPrefetchPairs(FlatNode fn) {
1332 if(prefetch_hash.containsKey(fn)) {
1333 System.out.print("Prefetch" + "(");
1334 Hashtable<PrefetchPair, Double> currhash = (Hashtable) prefetch_hash.get(fn);
1335 for(Enumeration pphash= currhash.keys(); pphash.hasMoreElements();) {
1336 PrefetchPair pp = (PrefetchPair) pphash.nextElement();
1337 System.out.print(pp.toString() + ", ");
1339 System.out.println(")");
1341 System.out.println("Flatnode is currently not present in the global hash: Prefetch Set is Empty");
1345 private void doInsPrefetchAnalysis(FlatMethod fm, Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
1346 Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
1347 HashSet<PrefetchPair> pset1_init = new HashSet<PrefetchPair>();
1348 LinkedList<FlatNode> newtovisit = new LinkedList<FlatNode>();
1349 LinkedList<FlatNode> newvisited = new LinkedList<FlatNode>();
1351 newtovisit.addLast((FlatNode)fm);
1352 while(!newtovisit.isEmpty()) {
1353 FlatNode fn = (FlatNode) newtovisit.iterator().next();
1354 newtovisit.remove(0);
1355 pset1_hash.put(fn, pset1_init); //Initialize pset1_hash
1356 newvisited.addLast(fn);
1357 for(int i=0; i<fn.numNext(); i++) {
1358 FlatNode nn = fn.getNext(i);
1359 if(!newtovisit.contains(nn) && !newvisited.contains(nn)){
1360 newtovisit.addLast(nn);
1365 /* Delete redundant and subset prefetch pairs */
1368 /* Start with a top down sorted order of nodes */
1369 while(!newvisited.isEmpty()) {
1370 applyPrefetchInsertRules((FlatNode) newvisited.getFirst(), newvisited, pset1_hash, newprefetchset);
1371 newvisited.remove(0);
1375 /** This function deletes the smaller prefetch pair subset from a list of prefetch pairs
1376 * for e.g. if there are 2 prefetch pairs a.b.c.d and a.b.c for a given flatnode
1377 * then this function drops a.b.c from the prefetch set of the flatnode */
1378 private void delSubsetPPairs() {
1379 Enumeration e = prefetch_hash.keys();
1380 while(e.hasMoreElements()) {
1381 FlatNode fn = (FlatNode) e.nextElement();
1382 Hashtable ppairs = prefetch_hash.get(fn);
1383 Enumeration epp = ((Hashtable)(prefetch_hash.get(fn))).keys();
1384 Vector<PrefetchPair> pplist = new Vector<PrefetchPair>();
1385 Vector pplength = new Vector();
1386 Vector ppisMod = new Vector();
1387 while(epp.hasMoreElements()) {
1388 PrefetchPair pp = (PrefetchPair) epp.nextElement();
1390 int length = pp.desc.size()+ 1;
1391 pplength.add(length);
1394 int numpp = ((Hashtable)(prefetch_hash.get(fn))).size();
1395 for (int i = 0; i < numpp; i++) {
1396 for (int j = i+1; j < numpp; j++) {
1398 int x = ((Integer) (pplength.get(i))).intValue();
1399 if (((Integer) (pplength.get(i))).intValue() < ((Integer)( pplength.get(j))).intValue()) {
1400 ret = isSubSet(pplist.get(i), pplist.get(j));
1405 ret = isSubSet(pplist.get(j), pplist.get(i));
1412 for (int i = 0; i < numpp; i++) {
1413 if (((Integer)(ppisMod.get(i))).intValue() == 1) {
1414 PrefetchPair pp = (PrefetchPair) pplist.get(i);
1421 /** This function returns: true if the shorter prefetch pair is a subset of the longer prefetch
1422 * pair else it returns: false */
1423 private boolean isSubSet(PrefetchPair shrt, PrefetchPair lng) {
1424 if (shrt.base != lng.base) {
1427 for (int j = 0; j < shrt.desc.size(); j++) {
1428 if(shrt.getDescAt(j) instanceof IndexDescriptor) {
1429 IndexDescriptor shrtid = (IndexDescriptor) shrt.getDescAt(j);
1430 if(lng.getDescAt(j) instanceof IndexDescriptor){
1431 IndexDescriptor lngid = (IndexDescriptor) lng.getDescAt(j);
1432 if(shrtid.equals(lngid)) {
1441 if ((Descriptor)shrt.getDescAt(j) != (Descriptor)lng.getDescAt(j)){
1449 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
1450 * returns: true if something has changed in the new Prefetch set else
1453 private boolean comparePSet1(HashSet<PrefetchPair> oldPSet, HashSet<PrefetchPair>newPSet) {
1454 boolean hasChanged = false;
1456 if(oldPSet.size() != newPSet.size()) {
1459 for(Iterator it = newPSet.iterator();it.hasNext();) {
1460 if(!oldPSet.contains((PrefetchPair)it.next())) {
1468 /** This function creates a set called pset1 that contains prefetch pairs that have already
1469 * been prefetched. While traversing the graph of a flat representation in a top down fashion,
1470 * this function creates pset1 such that it contains prefetch pairs that have been prefetched at
1471 * the previous nodes */
1473 private void applyPrefetchInsertRules(FlatNode fn, LinkedList<FlatNode> newvisited, Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash,
1474 Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
1476 if(fn.kind() == FKind.FlatMethod) {
1477 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
1478 if(prefetch_hash.containsKey(fn)) {
1479 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
1480 for(Enumeration e = prefetchset.keys();e.hasMoreElements();) {
1481 PrefetchPair pp = (PrefetchPair) e.nextElement();
1482 /* Apply initial rule */
1483 if(prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB) {
1487 /* Enqueue child node if Pset1 has changed */
1488 if (comparePSet1(pset1_hash.get(fn), pset1)) {
1489 for(int j=0; j<fn.numNext(); j++) {
1490 FlatNode nn = fn.getNext(j);
1491 newvisited.addLast((FlatNode)nn);
1493 pset1_hash.put(fn, pset1);
1495 newprefetchset.put(fn, pset1);
1497 } else { /* Nodes other than Flat Method Node */
1498 HashSet<PrefetchPair> pset2 = new HashSet<PrefetchPair>();
1499 HashSet<PrefetchPair> newpset = new HashSet<PrefetchPair>();
1500 if(prefetch_hash.containsKey(fn)) {
1501 Hashtable<PrefetchPair, Double> prefetchset = prefetch_hash.get(fn);
1502 Hashtable<FlatNode, PairMap> ppairmaphash = pmap_hash.get(fn);
1503 for(Enumeration epset = prefetchset.keys(); epset.hasMoreElements();) {
1504 PrefetchPair pp = (PrefetchPair) epset.nextElement();
1505 boolean pprobIsGreater = (prefetchset.get(pp).doubleValue() >= PREFETCH_THRESHOLD_PROB);
1506 boolean mapprobIsLess=false;
1507 boolean mapIsPresent=true;
1508 for(int i=0;i<fn.numPrev();i++) {
1509 FlatNode parentnode=fn.getPrev(i);
1510 PairMap pm = (PairMap) ppairmaphash.get(parentnode);
1512 if(pm!=null&&pm.getPair(pp) != null) {
1513 PrefetchPair mappedpp = pm.getPair(pp);
1514 if(prefetch_hash.get(parentnode).containsKey(mappedpp)) {
1515 double prob = prefetch_hash.get(parentnode).get(mappedpp).doubleValue();
1516 if(prob < PREFETCH_THRESHOLD_PROB)
1517 mapprobIsLess = true;
1520 mapprobIsLess = true;
1523 if(pset1_hash.containsKey(parentnode)) {
1525 HashSet pset = pset1_hash.get(parentnode);
1526 if(pset.isEmpty()) {
1529 if(!pset.contains((PrefetchPair) pm.getPair(pp)))
1530 mapIsPresent = false;
1534 throw new Error("applyPrefetchInsertRules() Parent node not present in pset1_hash: Not Possible");
1541 if(pprobIsGreater && mapprobIsLess)
1545 throw new Error("applyPrefetchInsertRules() fn: " +fn+ "not found");
1548 HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
1549 pset1.addAll(pset2);
1550 pset1.addAll(newpset);
1551 /* Enqueue child node if Pset1 has changed */
1552 if (comparePSet1(pset1_hash.get(fn), pset1)) {
1553 for(int i=0; i<fn.numNext(); i++) {
1554 FlatNode nn = fn.getNext(i);
1555 newvisited.addLast((FlatNode)nn);
1557 pset1_hash.put(fn, pset1);
1560 /* To insert prefetch, apply rule: if the newpset minus pset2 is nonempty
1561 * then insert a new prefetch node here*/
1563 HashSet<PrefetchPair> s = new HashSet<PrefetchPair>();
1564 for(Iterator it = newpset.iterator(); it.hasNext();) {
1565 PrefetchPair pp = (PrefetchPair) it.next();
1566 if(!pset2.contains(pp)) {
1570 newprefetchset.put(fn, s);
1574 private void addFlatPrefetchNode(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
1575 Enumeration e = null;
1576 e = newprefetchset.keys();
1577 boolean isFNPresent = false; /* Detects presence of FlatNew node */
1578 /* This modifies the Flat representation graph */
1579 while(e.hasMoreElements()) {
1580 FlatNode fn = (FlatNode) e.nextElement();
1581 FlatPrefetchNode fpn = new FlatPrefetchNode();
1582 if(newprefetchset.get(fn).size() > 0) {
1583 fpn.insAllpp((HashSet)newprefetchset.get(fn));
1584 if(fn.kind() == FKind.FlatMethod) {
1585 FlatNode nn = fn.getNext(0);
1589 /* Check if previous node of this FlatNode is a NEW node
1590 * If yes, delete this flatnode and its prefetch set from hash table
1591 * This eliminates prefetches for NULL ptrs*/
1592 for(int i = 0; i< fn.numPrev(); i++) {
1593 FlatNode nn = fn.getPrev(i);
1594 if(nn.kind() == FKind.FlatNew) {
1599 while(fn.numPrev() > 0) {
1600 FlatNode nn = fn.getPrev(0);
1601 for(int j = 0; j<nn.numNext(); j++) {
1602 if(nn.getNext(j) == fn) {
1614 private void doAnalysis() {
1615 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
1616 while(classit.hasNext()) {
1617 ClassDescriptor cn=(ClassDescriptor)classit.next();
1618 Iterator methodit=cn.getMethods();
1619 while(methodit.hasNext()) {
1620 /* Classify parameters */
1621 MethodDescriptor md=(MethodDescriptor)methodit.next();
1622 FlatMethod fm=state.getMethodFlat(md);
1628 private void printMethod(FlatMethod fm) {
1629 System.out.println(fm.getMethod()+" {");
1630 HashSet tovisit=new HashSet();
1631 HashSet visited=new HashSet();
1633 Hashtable nodetolabel=new Hashtable();
1635 FlatNode current_node=null;
1637 //Node needs a label if it is
1638 while(!tovisit.isEmpty()) {
1639 FlatNode fn=(FlatNode)tovisit.iterator().next();
1643 for(int i=0;i<fn.numNext();i++) {
1644 FlatNode nn=fn.getNext(i);
1646 //1) Edge >1 of node
1647 nodetolabel.put(nn,new Integer(labelindex++));
1649 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1653 nodetolabel.put(nn,new Integer(labelindex++));
1657 //Do the actual printing
1658 tovisit=new HashSet();
1659 visited=new HashSet();
1661 while(current_node!=null||!tovisit.isEmpty()) {
1662 if (current_node==null) {
1663 current_node=(FlatNode)tovisit.iterator().next();
1664 tovisit.remove(current_node);
1666 visited.add(current_node);
1667 if (nodetolabel.containsKey(current_node))
1668 System.out.println("L"+nodetolabel.get(current_node)+":");
1669 if (current_node.numNext()==0) {
1670 System.out.println(" "+current_node.toString());
1672 } else if(current_node.numNext()==1) {
1673 System.out.println(" "+current_node.toString());
1674 FlatNode nextnode=current_node.getNext(0);
1675 if (visited.contains(nextnode)) {
1676 System.out.println("goto L"+nodetolabel.get(nextnode));
1679 current_node=nextnode;
1680 } else if (current_node.numNext()==2) {
1682 System.out.println(" "+((FlatCondBranch)current_node).toString("L"+nodetolabel.get(current_node.getNext(1))));
1683 if (!visited.contains(current_node.getNext(1)))
1684 tovisit.add(current_node.getNext(1));
1685 if (visited.contains(current_node.getNext(0))) {
1686 System.out.println("goto L"+nodetolabel.get(current_node.getNext(0)));
1689 current_node=current_node.getNext(0);
1690 } else throw new Error();
1692 System.out.println("}");