1 package Analysis.Prefetch;
4 import Analysis.CallGraph.CallGraph;
5 import Analysis.Prefetch.PrefetchPair;
6 import Analysis.Prefetch.IndexDescriptor;
10 import IR.MethodDescriptor;
13 import IR.ClassDescriptor;
15 public class PrefetchAnalysis {
19 Set<FlatNode> tovisit;
20 Hashtable<FlatNode, Hashtable<PrefetchPair, Float>> prefetch_hash;
21 Hashtable<PrefetchPair, Float> branch_prefetch_set;
22 public static final int ROUNDED_MODE = 30;
23 public static final float THRESHOLD_PROB = (float)0.2;
24 public static final float BRANCH_TRUE_EDGE_PROB = (float)0.5;
25 public static final float BRANCH_FALSE_EDGE_PROB = (float)0.5;
27 /** This function finds if a tempdescriptor object is found in a given prefetch pair
28 * It returns true if found else returns false*/
29 private boolean isTempDescFound(PrefetchPair pp, TempDescriptor td) {
30 ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
31 ListIterator it = desc.listIterator();
34 if(o instanceof IndexDescriptor) {
35 ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
36 if(tdarray.contains(td)) {
44 /** This function creates a new Arraylist of Descriptors by replacing old tempdescriptors with new
45 * tempdescriptors when there is a match for FlatOpNodes or FlatLiteralNodes */
46 private ArrayList<Descriptor> getNewDesc(PrefetchPair pp, TempDescriptor td, TempDescriptor newtd) {
47 ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
48 ListIterator it = desc.listIterator();
50 Object currdesc = it.next();
51 if(currdesc instanceof IndexDescriptor) {
52 ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)currdesc).tddesc;
53 if(tdarray.contains(td)) {
54 int index = tdarray.indexOf(td);
55 tdarray.set(index, newtd);
62 /** This function creates a new Arraylist of Descriptors by replacing old tempdescriptors with new
63 * tempdescriptors when there is a match for FlatOpNodes i= i+j then replace i with i+j */
64 private ArrayList<Descriptor> getNewDesc(PrefetchPair pp, TempDescriptor td, TempDescriptor left, TempDescriptor right) {
65 ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
66 ListIterator it = desc.listIterator();
68 Object currdesc = it.next();
69 if(currdesc instanceof IndexDescriptor) {
70 ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)currdesc).tddesc;
71 if(tdarray.contains(td)) {
72 int index = tdarray.indexOf(td);
73 tdarray.set(index, left);
81 public PrefetchAnalysis(State state, CallGraph callgraph, TypeUtil typeutil) {
82 this.typeutil=typeutil;
84 this.callgraph=callgraph;
85 prefetch_hash = new Hashtable<FlatNode, Hashtable<PrefetchPair,Float>>();
89 /** This function starts the prefetch analysis */
90 private void DoPrefetch() {
91 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
92 while(classit.hasNext()) {
93 ClassDescriptor cn=(ClassDescriptor)classit.next();
98 /** This function calls analysis for every method in a class */
99 private void doMethodAnalysis(ClassDescriptor cn) {
100 Iterator methodit=cn.getMethods();
101 while(methodit.hasNext()) {
102 /* Classify parameters */
103 MethodDescriptor md=(MethodDescriptor)methodit.next();
104 FlatMethod fm=state.getMethodFlat(md);
105 doFlatNodeAnalysis(fm);
109 /** This function calls analysis for every node in a method */
110 private void doFlatNodeAnalysis(FlatMethod fm) {
111 tovisit = fm.getNodeSet();
112 Hashtable<PrefetchPair, Float> nodehash = new Hashtable<PrefetchPair, Float>();
113 /* Create Empty Prefetch Sets for all flat nodes in the global hashtable */
114 while(!tovisit.isEmpty()) {
115 FlatNode fn = (FlatNode)tovisit.iterator().next();
116 prefetch_hash.put(fn, nodehash);
119 /* Visit and process nodes */
120 tovisit = fm.getNodeSet();
121 while(!tovisit.isEmpty()) {
122 FlatNode fn = (FlatNode)tovisit.iterator().next();
123 /* Generate prefetch pairs after the child node analysis */
124 doChildNodeAnalysis(fn);
130 * This function generates the prefetch sets for a given Flatnode considering the kind of node
131 * It calls severals functions based on the kind of the node and
132 * returns true: if the prefetch set has changed since last time the node was analysed
133 * returns false : otherwise
135 private void doChildNodeAnalysis(FlatNode curr) {
136 Hashtable<PrefetchPair, Float> child_prefetch_set_copy = new Hashtable<PrefetchPair, Float>();
137 FlatNode child_node = null;
138 if(curr.numNext() != 0) {
139 child_node = curr.getNext(0);
140 if(prefetch_hash.containsKey(child_node)) {
141 child_prefetch_set_copy = (Hashtable<PrefetchPair,Float>) prefetch_hash.get(child_node).clone();
144 switch(curr.kind()) {
145 case FKind.FlatBackEdge:
146 processDefaultCase(curr,child_prefetch_set_copy);
149 //TODO change it to take care of FlatMethod, Flatcalls
150 //processDefaultCase(curr,child_prefetch_set_copy);
151 processFlatCall(curr, child_prefetch_set_copy);
153 case FKind.FlatCheckNode:
154 processDefaultCase(curr,child_prefetch_set_copy);
156 case FKind.FlatMethod:
157 //TODO change it to take care of FlatMethod, Flatcalls
158 processFlatMethod(curr, child_prefetch_set_copy);
161 processFlatNewNode(curr, child_prefetch_set_copy);
163 case FKind.FlatReturnNode:
164 //TODO change it to take care of FlatMethod, Flatcalls
165 processDefaultCase(curr,child_prefetch_set_copy);
167 case FKind.FlatFieldNode:
168 processFlatFieldNode(curr, child_prefetch_set_copy);
170 case FKind.FlatElementNode:
171 processFlatElementNode(curr, child_prefetch_set_copy);
173 case FKind.FlatCondBranch:
174 branch_prefetch_set = new Hashtable<PrefetchPair,Float>();
175 for (int i = 0; i < curr.numNext(); i++) {
176 child_node = curr.getNext(i);
177 if (prefetch_hash.containsKey(child_node)) {
178 child_prefetch_set_copy = (Hashtable<PrefetchPair,Float>) prefetch_hash.get(child_node).clone();
180 processFlatCondBranch(curr, child_prefetch_set_copy, i, branch_prefetch_set);
183 case FKind.FlatOpNode:
184 processFlatOpNode(curr, child_prefetch_set_copy);
186 case FKind.FlatLiteralNode:
187 processFlatLiteralNode(curr, child_prefetch_set_copy);
189 case FKind.FlatSetElementNode:
190 processFlatSetElementNode(curr, child_prefetch_set_copy);
192 case FKind.FlatSetFieldNode:
193 processFlatSetFieldNode(curr, child_prefetch_set_copy);
195 case FKind.FlatAtomicEnterNode:
196 processDefaultCase(curr,child_prefetch_set_copy);
198 case FKind.FlatAtomicExitNode:
199 processDefaultCase(curr,child_prefetch_set_copy);
201 case FKind.FlatCastNode:
202 processDefaultCase(curr,child_prefetch_set_copy);
204 case FKind.FlatFlagActionNode:
205 processDefaultCase(curr,child_prefetch_set_copy);
207 case FKind.FlatGlobalConvNode:
208 processDefaultCase(curr,child_prefetch_set_copy);
211 processDefaultCase(curr,child_prefetch_set_copy);
213 case FKind.FlatTagDeclaration:
214 processDefaultCase(curr,child_prefetch_set_copy);
217 System.out.println("NO SUCH FLATNODE");
222 /**This function compares all the prefetch pairs in a Prefetch set hashtable and
223 * returns: true if something has changed in the new Prefetch set else
226 private boolean comparePrefetchSets(Hashtable<PrefetchPair, Float> oldPrefetchSet, Hashtable<PrefetchPair, Float>
228 boolean hasChanged = false;
229 PrefetchPair oldpp = null;
230 PrefetchPair newpp = null;
232 if(oldPrefetchSet.size() != newPrefetchSet.size()) {
233 if(newPrefetchSet.size() == 0) {
238 Enumeration e = newPrefetchSet.keys();
239 while(e.hasMoreElements()) {
240 newpp = (PrefetchPair) e.nextElement();
241 float newprob = newPrefetchSet.get(newpp);
242 for(Enumeration elem = oldPrefetchSet.keys(); elem.hasMoreElements();) {
243 oldpp = (PrefetchPair) elem.nextElement();
244 if(oldpp.equals(newpp)) {
245 /*Compare the difference in their probabilities */
246 float oldprob = oldPrefetchSet.get(oldpp);
247 int diff = (int) ((newprob - oldprob)/oldprob)*100;
248 if(diff >= ROUNDED_MODE) {
259 /** This function processes the prefetch set of FlatFieldNode
260 * It generates a new prefetch set after comparision with its children
261 * Then compares it with its old prefetch set
262 * If old prefetch set is not same as new prefetch set then enqueue the parents
263 * of the current FlatFieldNode
265 private void processFlatFieldNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
266 boolean pSetHasChanged = false;
267 Hashtable<PrefetchPair, Float> currcopy = new Hashtable<PrefetchPair, Float>();
268 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
269 FlatFieldNode currffn = (FlatFieldNode) curr;
271 /* Do Self analysis of the current node*/
272 FieldDescriptor currffn_field = currffn.getField();
273 TempDescriptor currffn_src = currffn.getSrc();
274 if (currffn_field.getType().isPtr()) {
275 PrefetchPair pp = new PrefetchPair(currffn_src, (Descriptor) currffn_field);
276 Float prob = new Float((float)1.0);
277 currcopy.put(pp, prob);
280 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
281 Enumeration ecld = child_prefetch_set_copy.keys();
282 PrefetchPair currpp = null;
283 PrefetchPair childpp = null;
284 while (ecld.hasMoreElements()) {
285 childpp = (PrefetchPair) ecld.nextElement();
286 if (childpp.base == currffn.getDst() && (childpp.getDesc()!= null)) {
287 if (currffn.getField().getType().isPtr()) {
288 /* Create a new Prefetch set*/
289 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
290 newdesc.add(currffn.getField());
291 newdesc.addAll(childpp.desc);
292 PrefetchPair newpp = new PrefetchPair(currffn.getSrc(), newdesc);
293 Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
294 tocompare.put(newpp, newprob);
295 child_prefetch_set_copy.remove(childpp);
296 /* Check for independence of prefetch pairs if any in the child prefetch set
297 * to compute new probability */
298 if(child_prefetch_set_copy.containsKey(newpp)) {
299 newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
300 if(newprob < THRESHOLD_PROB) {
301 tocompare.remove(newpp);
303 tocompare.put(newpp, newprob);
305 child_prefetch_set_copy.remove(newpp);
308 } else if(childpp.base == currffn.getDst() && (childpp.getDesc() == null)) {
309 child_prefetch_set_copy.remove(childpp);
314 /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
315 * if so calculate the new probability and then remove the common one from the child prefetch set */
316 ecld = child_prefetch_set_copy.keys();
317 Enumeration e = null;
318 while(ecld.hasMoreElements()) {
319 childpp = (PrefetchPair) ecld.nextElement();
320 for(e = currcopy.keys(); e.hasMoreElements();) {
321 currpp = (PrefetchPair) e.nextElement();
322 if(currpp.equals(childpp)) {
323 /* Probability of the incoming edge for a FlatFieldNode is always 100% */
324 Float prob = currcopy.get(currpp).floatValue();
325 currcopy.put(currpp, prob);
326 child_prefetch_set_copy.remove(childpp);
332 /* Merge child prefetch pairs */
333 ecld = child_prefetch_set_copy.keys();
334 while(ecld.hasMoreElements()) {
335 childpp = (PrefetchPair) ecld.nextElement();
336 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
337 child_prefetch_set_copy.remove(childpp);
340 /* Merge curr prefetch pairs */
342 while(e.hasMoreElements()) {
343 currpp = (PrefetchPair) e.nextElement();
344 tocompare.put(currpp, currcopy.get(currpp));
345 currcopy.remove(currpp);
348 /* Compare with the orginal prefetch pairs */
349 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
350 /* Enqueue parent nodes */
352 for(int i=0; i<curr.numPrev(); i++) {
353 tovisit.add(curr.getPrev(i));
355 /* Overwrite the new prefetch set to the global hash table */
356 prefetch_hash.put(curr,tocompare);
360 /** This function processes the prefetch set of a FlatElementNode
361 * It generates a new prefetch set after comparision with its children
362 * It compares the old prefetch set with this new prefetch set and enqueues the parents
363 * of the current node if change occurs and updates the global flatnode hash table
365 private void processFlatElementNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
367 boolean pSetHasChanged = false;
368 Hashtable<PrefetchPair, Float> currcopy = new Hashtable<PrefetchPair, Float>();
369 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
370 FlatElementNode currfen = (FlatElementNode) curr;
372 /* Do Self analysis of the current node*/
373 TempDescriptor currfen_index = currfen.getIndex();
374 IndexDescriptor idesc = new IndexDescriptor(currfen_index, 0);
375 TempDescriptor currfen_src = currfen.getSrc();
376 if(currfen.getDst().getType().isPtr()) {
377 PrefetchPair pp = new PrefetchPair(currfen_src, (Descriptor) idesc);
378 Float prob = new Float((float)1.0);
379 currcopy.put(pp, prob);
382 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
383 Enumeration ecld = child_prefetch_set_copy.keys();
384 PrefetchPair currpp = null;
385 PrefetchPair childpp = null;
386 while (ecld.hasMoreElements()) {
387 childpp = (PrefetchPair) ecld.nextElement();
388 if (childpp.base == currfen.getDst() && (childpp.getDesc()!= null)) {
389 if (currfen.getDst().getType().isPtr()) {
390 //if match exists then create a new Prefetch set with the new prefetch pair in a new hash table
391 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
392 newdesc.add((Descriptor)idesc);
393 newdesc.addAll(childpp.desc);
394 PrefetchPair newpp = new PrefetchPair(currfen.getSrc(), newdesc);
395 Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
396 tocompare.put(newpp, newprob);
397 child_prefetch_set_copy.remove(childpp);
398 /* Check for independence of prefetch pairs if any in the child prefetch set
399 * to compute new probability */
400 if(child_prefetch_set_copy.containsKey(newpp)) {
401 newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
402 if(newprob < THRESHOLD_PROB) {
403 tocompare.remove(newpp);
405 tocompare.put(newpp, newprob);
407 child_prefetch_set_copy.remove(newpp);
410 } else if(childpp.base == currfen.getDst() && (childpp.getDesc() == null)) {
411 child_prefetch_set_copy.remove(childpp);
414 /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
415 * if so calculate the new probability and then remove the common one from the child prefetch set */
416 ecld = child_prefetch_set_copy.keys();
417 Enumeration e = null;
418 while(ecld.hasMoreElements()) {
419 childpp = (PrefetchPair) ecld.nextElement();
420 for(e = currcopy.keys(); e.hasMoreElements();) {
421 currpp = (PrefetchPair) e.nextElement();
422 if(currpp.equals(childpp)) {
423 /* Probability of the incoming edge for a FlatElementNode is always 100% */
424 Float prob = currcopy.get(currpp).floatValue();
425 currcopy.put(currpp, prob);
426 child_prefetch_set_copy.remove(childpp);
432 /* Merge child prefetch pairs */
433 ecld = child_prefetch_set_copy.keys();
434 while(ecld.hasMoreElements()) {
435 childpp = (PrefetchPair) ecld.nextElement();
436 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
437 child_prefetch_set_copy.remove(childpp);
440 /* Merge curr prefetch pairs */
442 while(e.hasMoreElements()) {
443 currpp = (PrefetchPair) e.nextElement();
444 tocompare.put(currpp, currcopy.get(currpp));
445 currcopy.remove(currpp);
448 /* Compare with the orginal prefetch pairs */
449 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
450 /* Enqueue parent nodes */
452 for(int i=0; i<curr.numPrev(); i++) {
453 tovisit.add(curr.getPrev(i));
455 /* Overwrite the new prefetch set to the global hash table */
456 prefetch_hash.put(curr,tocompare);
460 /** This function processes the prefetch set of a FlatSetFieldNode
461 * It generates a new prefetch set after comparision with its children
462 * It compares the old prefetch set with this new prefetch set and enqueues the parents
463 * of the current node if change occurs and then updates the global flatnode hash table
465 private void processFlatSetFieldNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
466 boolean pSetHasChanged = false;
467 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
468 FlatSetFieldNode currfsfn = (FlatSetFieldNode) curr;
469 PrefetchPair childpp = null;
471 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
472 Enumeration ecld = child_prefetch_set_copy.keys();
473 while (ecld.hasMoreElements()) {
474 childpp = (PrefetchPair) ecld.nextElement();
475 if(childpp.base == currfsfn.getDst()) {
476 int size = childpp.desc.size();
478 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
479 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
480 for(int i = 0;i<(childpp.desc.size()-1); i++) {
481 newdesc.add(i,childpp.desc.get(i+1));
483 PrefetchPair newpp = new PrefetchPair(currfsfn.getSrc(), newdesc);
484 Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
485 tocompare.put(newpp, newprob);
486 child_prefetch_set_copy.remove(childpp);
487 /* Check for independence of prefetch pairs in newly generated and child_prefetch_set_copy prefetch pairs
488 * to compute new probability */
489 if(child_prefetch_set_copy.containsKey(newpp)) {
490 newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
491 if(newprob < THRESHOLD_PROB) {
492 tocompare.remove(newpp);
494 tocompare.put(newpp, newprob);
496 child_prefetch_set_copy.remove(newpp);
500 if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
501 child_prefetch_set_copy.remove(childpp);
509 /* Merge child prefetch pairs */
510 ecld = child_prefetch_set_copy.keys();
511 while(ecld.hasMoreElements()) {
512 childpp = (PrefetchPair) ecld.nextElement();
513 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
514 child_prefetch_set_copy.remove(childpp);
517 /* Compare with the orginal prefetch pairs */
518 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
519 /* Enqueue parent nodes */
521 for(int i=0; i<curr.numPrev(); i++) {
522 tovisit.add(curr.getPrev(i));
524 /* Overwrite the new prefetch set to the global hash table */
525 prefetch_hash.put(curr,tocompare);
529 /** This function processes the prefetch set of a FlatSeElementNode
530 * It generates a new prefetch set after comparision with its children
531 * It compares the old prefetch set with this new prefetch set and enqueues the parents
532 * of the current node if change occurs and then updates the global flatnode hash table
534 private void processFlatSetElementNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
535 boolean pSetHasChanged = false;
536 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
537 PrefetchPair childpp = null;
538 FlatSetElementNode currfsen = (FlatSetElementNode) curr;
540 /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
541 Enumeration ecld = child_prefetch_set_copy.keys();
542 while (ecld.hasMoreElements()) {
543 childpp = (PrefetchPair) ecld.nextElement();
544 if (childpp.base == currfsen.getDst()){
545 int sizedesc = childpp.desc.size();
546 if((childpp.getDescAt(0) instanceof IndexDescriptor)) {
547 int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size();
548 if(sizetempdesc == 1) {
549 if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) {
550 //if match exists then create a new Prefetch set with the new prefetch pair in a new hash table
551 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
552 for(int i = 0;i<(childpp.desc.size()-1); i++) {
553 newdesc.add(i,childpp.desc.get(i+1));
555 PrefetchPair newpp = new PrefetchPair(currfsen.getSrc(), newdesc);
556 Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
557 tocompare.put(newpp, newprob);
558 child_prefetch_set_copy.remove(childpp);
559 /* Check for independence of prefetch pairs if any in the child prefetch set
560 * to compute new probability */
561 if(child_prefetch_set_copy.containsKey(newpp)) {
562 newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
563 if(newprob < THRESHOLD_PROB) {
564 tocompare.remove(newpp);
566 tocompare.put(newpp, newprob);
568 child_prefetch_set_copy.remove(newpp);
570 } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1))
571 child_prefetch_set_copy.remove(childpp);
578 /* Merge child prefetch pairs */
579 ecld = child_prefetch_set_copy.keys();
580 while(ecld.hasMoreElements()) {
581 childpp = (PrefetchPair) ecld.nextElement();
582 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
583 child_prefetch_set_copy.remove(childpp);
585 /* Compare with the orginal prefetch pairs */
586 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
587 /* Enqueue parent nodes */
589 for(int i=0; i<curr.numPrev(); i++) {
590 tovisit.add(curr.getPrev(i));
592 /* Overwrite the new prefetch set to the global hash table */
593 prefetch_hash.put(curr,tocompare);
597 /** This function applies rules and does analysis for a FlatOpNode
598 * And updates the global prefetch hashtable
600 private void processFlatOpNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
601 boolean pSetHasChanged = false;
603 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
604 FlatOpNode currfopn = (FlatOpNode) curr;
605 Enumeration ecld = null;
606 PrefetchPair childpp = null;
608 /* Check the Operation type of flatOpNode */
609 if(currfopn.getOp().getOp()== Operation.ASSIGN) {
610 ecld = child_prefetch_set_copy.keys();
611 while (ecld.hasMoreElements()) {
612 childpp = (PrefetchPair) ecld.nextElement();
613 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
615 /* Base of child prefetch pair same as destination of the current FlatOpNode
616 * For cases like x=y followed by childnode t=x[i].z or t=x.g*/
617 if(childpp.base == currfopn.getDest()) {
618 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
619 newdesc.addAll(childpp.desc);
620 PrefetchPair newpp = new PrefetchPair(currfopn.getLeft(), newdesc);
621 Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
622 tocompare.put(newpp, newprob);
623 child_prefetch_set_copy.remove(childpp);
624 /* Check for independence of prefetch pairs if any in the child prefetch set
625 * to compute new probability */
626 if(child_prefetch_set_copy.containsKey(newpp)) {
627 newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
628 if(newprob < THRESHOLD_PROB) {
629 tocompare.remove(newpp);
631 tocompare.put(newpp, newprob);
633 child_prefetch_set_copy.remove(newpp);
635 /* Any member of the desc of child prefetch pair is same as destination of the current FlatOpNode
636 * For cases like x=y followed by t = r[i].x or t =r[x].p or t = r[p+x].q*/
637 } else if(isTempDescFound(copyofchildpp, currfopn.getDest())) {
638 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
639 newdesc.addAll((ArrayList<Descriptor>)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft()));
640 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
641 Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
642 tocompare.put(newpp, newprob);
643 child_prefetch_set_copy.remove(childpp);
644 /* Check for independence of prefetch pairs if any in the child prefetch set
645 * to compute new probability*/
646 if(child_prefetch_set_copy.containsKey(newpp)) {
647 newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
648 if(newprob < THRESHOLD_PROB) {
649 tocompare.remove(newpp);
651 tocompare.put(newpp, newprob);
653 child_prefetch_set_copy.remove(newpp);
659 } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) {
660 //case i = i+z followed by a[i].x
661 ecld = child_prefetch_set_copy.keys();
662 while (ecld.hasMoreElements()) {
663 childpp = (PrefetchPair) ecld.nextElement();
664 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
666 if(isTempDescFound(copyofchildpp, currfopn.getDest())) {
667 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
668 newdesc.addAll((ArrayList<Descriptor>)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft(), currfopn.getRight()));
669 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
670 Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
671 tocompare.put(newpp, newprob);
672 child_prefetch_set_copy.remove(childpp);
673 /* Check for independence of prefetch pairs if any in the child prefetch set
674 * to compute new probability*/
675 if(child_prefetch_set_copy.containsKey(newpp)) {
676 newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
677 if(newprob < THRESHOLD_PROB) {
678 tocompare.remove(newpp);
680 tocompare.put(newpp, newprob);
682 child_prefetch_set_copy.remove(newpp);
689 //FIXME Is not taken care of for cases like x = -y followed by a[x].i
692 /* Merge child prefetch pairs */
693 ecld = child_prefetch_set_copy.keys();
694 while(ecld.hasMoreElements()) {
695 childpp = (PrefetchPair) ecld.nextElement();
696 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
697 child_prefetch_set_copy.remove(childpp);
700 /* Compare with the orginal prefetch pairs */
701 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
702 /* Enqueue parent nodes */
704 for(int i=0; i<curr.numPrev(); i++) {
705 tovisit.add(curr.getPrev(i));
707 /* Overwrite the new prefetch set to the global hash table */
708 prefetch_hash.put(curr,tocompare);
712 /** This function processes a FlatLiteralNode where cases such as
713 * for cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r
715 private void processFlatLiteralNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
716 boolean pSetHasChanged = false;
717 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
718 FlatLiteralNode currfln = (FlatLiteralNode) curr;
719 Enumeration ecld = null;
720 PrefetchPair childpp = null;
722 if(currfln.getType().isIntegerType()) {
723 ecld = child_prefetch_set_copy.keys();
724 while (ecld.hasMoreElements()) {
725 childpp = (PrefetchPair) ecld.nextElement();
726 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
727 /* Check for same index in child prefetch pairs
728 * for cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r*/
729 if(isTempDescFound(copyofchildpp,currfln.getDst())) {
730 ArrayList<Descriptor> copychilddesc = (ArrayList<Descriptor>) copyofchildpp.getDesc();
731 int sizetempdesc = copychilddesc.size();
732 ListIterator it = copychilddesc.listIterator();
733 for(;it.hasNext();) {
734 Object o = it.next();
735 if(o instanceof IndexDescriptor) {
736 ArrayList<TempDescriptor> td = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
737 int sizetddesc = td.size();
738 if(td.contains(currfln.getDst())) {
739 int index = td.indexOf(currfln.getDst());
741 if((Integer)(currfln.getValue()) != 0) {
742 ((IndexDescriptor)o).offset = (Integer)currfln.getValue();
747 ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
748 newdesc.addAll(copychilddesc);
749 PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
750 Float newprob = (child_prefetch_set_copy.get(childpp)).floatValue();
751 tocompare.put(newpp, newprob);
752 child_prefetch_set_copy.remove(childpp);
753 /* Check for independence of prefetch pairs if any in the child prefetch set
754 * to compute new probability */
755 if(child_prefetch_set_copy.containsKey(newpp)) {
756 newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
757 if(newprob < THRESHOLD_PROB) {
758 tocompare.remove(newpp);
760 tocompare.put(newpp, newprob);
762 child_prefetch_set_copy.remove(newpp);
768 /* Merge child prefetch pairs */
769 ecld = child_prefetch_set_copy.keys();
770 while(ecld.hasMoreElements()) {
771 childpp = (PrefetchPair) ecld.nextElement();
772 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
773 child_prefetch_set_copy.remove(childpp);
776 /* Compare with the orginal prefetch pairs */
777 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
778 /* Enqueue parent nodes */
780 for(int i=0; i<curr.numPrev(); i++) {
781 tovisit.add(curr.getPrev(i));
783 /* Overwrite the new prefetch set to the global hash table */
784 prefetch_hash.put(curr,tocompare);
789 /** This function processes a FlatMethod where the method propagates
790 * the entire prefetch set of its child node */
791 private void processFlatMethod(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
792 boolean pSetHasChanged = false;
793 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
794 FlatMethod currfm = (FlatMethod) curr;
795 Enumeration ecld = null;
796 PrefetchPair childpp = null;
798 /* Merge child prefetch pairs */
799 ecld = child_prefetch_set_copy.keys();
800 while(ecld.hasMoreElements()) {
801 childpp = (PrefetchPair) ecld.nextElement();
802 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
803 child_prefetch_set_copy.remove(childpp);
806 /* Compare with the orginal prefetch pairs */
807 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
808 /* Enqueue parent nodes */
810 /* Overwrite the new prefetch set to the global hash table */
811 prefetch_hash.put(curr,tocompare);
815 /** This Function processes the FlatCalls
816 * It currently drops the propagation of those prefetchpairs that are passed as
817 * arguments in the FlatCall
819 private void processFlatCall(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
820 boolean pSetHasChanged = false;
821 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
822 FlatCall currfcn = (FlatCall) curr;
823 Enumeration ecld = null;
824 PrefetchPair childpp = null;
825 boolean isSameArg = false;
827 ecld = child_prefetch_set_copy.keys();
828 while(ecld.hasMoreElements()) {
829 childpp = (PrefetchPair) ecld.nextElement();
830 PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
831 if(currfcn.getReturnTemp() != childpp.base) {
832 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
833 child_prefetch_set_copy.remove(childpp);
835 child_prefetch_set_copy.remove(childpp);
839 /* Compare with the orginal prefetch pairs */
840 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
841 /* Enqueue parent nodes */
843 for(int i=0; i<curr.numPrev(); i++) {
844 tovisit.add(curr.getPrev(i));
846 /* Overwrite the new prefetch set to the global hash table */
847 prefetch_hash.put(curr,tocompare);
851 /** This function handles the processes the FlatNode of type FlatCondBranch
852 * It combines prefetches of both child elements and create a new hash table called
853 * branch_prefetch_set to contains the entries of both its children
855 private void processFlatCondBranch(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy, int index,
856 Hashtable<PrefetchPair,Float> branch_prefetch_set) {
857 boolean pSetHasChanged = false;
858 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();//temporary hash table
859 FlatCondBranch currfcb = (FlatCondBranch) curr;
860 Float newprob = new Float((float)0.0);
861 PrefetchPair childpp = null;
862 PrefetchPair pp = null;
863 Enumeration ecld = null;
865 ecld = child_prefetch_set_copy.keys();
866 while (ecld.hasMoreElements()) {
867 childpp = (PrefetchPair) ecld.nextElement();
870 newprob = child_prefetch_set_copy.get(childpp).floatValue() * BRANCH_TRUE_EDGE_PROB;
871 if(newprob >= THRESHOLD_PROB) {
872 tocompare.put(childpp, newprob);
874 child_prefetch_set_copy.remove(childpp);
875 } else if(index == 1) { /* False Edge */
876 newprob = child_prefetch_set_copy.get(childpp).floatValue() * BRANCH_FALSE_EDGE_PROB;
877 if(newprob >= THRESHOLD_PROB) {
878 tocompare.put(childpp, newprob);
880 child_prefetch_set_copy.remove(childpp);
882 System.out.println("DEBUG-> No more children of the FlatCondBranchNode present");
886 /* Update branch_prefetch_set (global hash table) to combine all prefetch pairs from childnodes of the
887 * cond branch that is currently stored in the tocompare hash table */
888 if(!tocompare.isEmpty()) {
890 branch_prefetch_set.putAll(tocompare);
891 }else if(index == 1) {
892 if(branch_prefetch_set.isEmpty()) {
893 branch_prefetch_set.putAll(tocompare);
895 Enumeration e = tocompare.keys();
896 while(e.hasMoreElements()) {
897 pp = (PrefetchPair) e.nextElement();
898 if(branch_prefetch_set.containsKey(pp)) {
899 newprob = (float)(branch_prefetch_set.get(pp).floatValue() + tocompare.get(pp).floatValue());
900 if(newprob < THRESHOLD_PROB) {
901 branch_prefetch_set.remove(pp);
903 branch_prefetch_set.put(pp, newprob);
905 tocompare.remove(pp);
908 e = tocompare.keys();
909 while(e.hasMoreElements()) {
910 pp = (PrefetchPair) e.nextElement();
911 branch_prefetch_set.put(pp,tocompare.get(pp));
912 tocompare.remove(pp);
916 System.out.println("DEBUG-> No more children of the FlatCondBranchNode present");
920 /* Enqueue parent nodes only after the prefetch sets of both child node have been evaluated
921 * and the branch_prefetch_set (hashtable) has been built containing the prefetch pairs for the
922 * incoming edge of the current node */
924 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), branch_prefetch_set);
926 for(int i=0; i<curr.numPrev(); i++) {
927 tovisit.add(curr.getPrev(i));
929 /* Overwrite the new prefetch set to the global hash table */
930 prefetch_hash.put(curr,branch_prefetch_set);
935 /** If FlatNode is not concerned with the prefetch set of its Child then propagate
936 * prefetches up the FlatNode*/
937 private void processDefaultCase(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
938 boolean pSetHasChanged = false;
939 Enumeration e = null;
940 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
942 for(e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
943 PrefetchPair newpp = (PrefetchPair) e.nextElement();
944 tocompare.put(newpp, child_prefetch_set_copy.get(newpp));
947 /* Compare with old Prefetch sets */
948 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
950 for(int i=0; i<curr.numPrev(); i++) {
951 tovisit.add(curr.getPrev(i));
953 /* Overwrite the new prefetch set to the global hash table */
954 prefetch_hash.put(curr,tocompare);
958 /** This function processes for FlatNewNode
959 * for e.g x = NEW(foo) followed by childnode with prefetch set x.f
960 * then drop the prefetches beyond this FlatNewNode */
961 private void processFlatNewNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy) {
962 boolean pSetHasChanged = false;
963 Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
964 FlatNew currfnn = (FlatNew) curr;
965 Float newprob = new Float((float)0.0);
966 PrefetchPair childpp = null;
967 Enumeration ecld = null;
969 ecld = child_prefetch_set_copy.keys();
970 while (ecld.hasMoreElements()) {
971 childpp = (PrefetchPair) ecld.nextElement();
972 if(childpp.base == currfnn.getDst()){
973 child_prefetch_set_copy.remove(childpp);
975 tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
976 child_prefetch_set_copy.remove(childpp);
980 /* Compare with the orginal prefetch pairs */
981 pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
982 /* Enqueue parent nodes */
984 for(int i=0; i<curr.numPrev(); i++) {
985 tovisit.add(curr.getPrev(i));
987 /* Overwrite the new prefetch set to the global hash table */
988 prefetch_hash.put(curr,tocompare);
992 /** This function prints the Prefetch pairs of a given flatnode */
993 private void printPrefetchPairs(FlatNode fn) {
994 if(prefetch_hash.containsKey(fn)) {
995 System.out.print("Prefetch" + "(");
996 Hashtable<PrefetchPair, Float> currhash = (Hashtable) prefetch_hash.get(fn);
997 for(Enumeration pphash= currhash.keys(); pphash.hasMoreElements();) {
998 PrefetchPair pp = (PrefetchPair) pphash.nextElement();
999 System.out.print(pp.toString() + ", ");
1001 System.out.println(")");
1003 System.out.println("Flatnode is currently not present in the global hash: Prefetch Set is Empty");
1007 private void doAnalysis() {
1008 Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
1009 while(classit.hasNext()) {
1010 ClassDescriptor cn=(ClassDescriptor)classit.next();
1011 Iterator methodit=cn.getMethods();
1012 while(methodit.hasNext()) {
1013 /* Classify parameters */
1014 MethodDescriptor md=(MethodDescriptor)methodit.next();
1015 FlatMethod fm=state.getMethodFlat(md);
1021 private void printMethod(FlatMethod fm) {
1022 System.out.println(fm.getMethod()+" {");
1023 HashSet tovisit=new HashSet();
1024 HashSet visited=new HashSet();
1026 Hashtable nodetolabel=new Hashtable();
1028 FlatNode current_node=null;
1030 //Node needs a label if it is
1031 while(!tovisit.isEmpty()) {
1032 FlatNode fn=(FlatNode)tovisit.iterator().next();
1036 for(int i=0;i<fn.numNext();i++) {
1037 FlatNode nn=fn.getNext(i);
1039 //1) Edge >1 of node
1040 nodetolabel.put(nn,new Integer(labelindex++));
1042 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1046 nodetolabel.put(nn,new Integer(labelindex++));
1050 //Do the actual printing
1051 tovisit=new HashSet();
1052 visited=new HashSet();
1054 while(current_node!=null||!tovisit.isEmpty()) {
1055 if (current_node==null) {
1056 current_node=(FlatNode)tovisit.iterator().next();
1057 tovisit.remove(current_node);
1059 visited.add(current_node);
1060 if (nodetolabel.containsKey(current_node))
1061 System.out.println("L"+nodetolabel.get(current_node)+":");
1062 if (current_node.numNext()==0) {
1063 System.out.println(" "+current_node.toString());
1065 } else if(current_node.numNext()==1) {
1066 System.out.println(" "+current_node.toString());
1067 FlatNode nextnode=current_node.getNext(0);
1068 if (visited.contains(nextnode)) {
1069 System.out.println("goto L"+nodetolabel.get(nextnode));
1072 current_node=nextnode;
1073 } else if (current_node.numNext()==2) {
1075 System.out.println(" "+((FlatCondBranch)current_node).toString("L"+nodetolabel.get(current_node.getNext(1))));
1076 if (!visited.contains(current_node.getNext(1)))
1077 tovisit.add(current_node.getNext(1));
1078 if (visited.contains(current_node.getNext(0))) {
1079 System.out.println("goto L"+nodetolabel.get(current_node.getNext(0)));
1082 current_node=current_node.getNext(0);
1083 } else throw new Error();
1085 System.out.println("}");