import IR.ClassDescriptor;
public class PrefetchAnalysis {
- State state;
- CallGraph callgraph;
- TypeUtil typeutil;
- Set<FlatNode> tovisit;
- public Hashtable<FlatNode, Hashtable<PrefetchPair, Float>> prefetch_hash;
- public Hashtable<FlatNode, Hashtable<FlatNode, PairMap>> pmap_hash;
- Hashtable<PrefetchPair, Float> branch_prefetch_set;
- public static final int PROB_DIFF = 10;
- public static final float ANALYSIS_THRESHOLD_PROB = (float)0.10;
- public static final float PREFETCH_THRESHOLD_PROB = (float)0.30;
- public static final float BRANCH_TRUE_EDGE_PROB = (float)0.5;
- public static final float BRANCH_FALSE_EDGE_PROB = (float)0.5;
-
- public PrefetchAnalysis(State state, CallGraph callgraph, TypeUtil typeutil) {
- this.typeutil=typeutil;
- this.state=state;
- this.callgraph=callgraph;
- prefetch_hash = new Hashtable<FlatNode, Hashtable<PrefetchPair,Float>>();
- pmap_hash = new Hashtable<FlatNode, Hashtable<FlatNode, PairMap>>();
- DoPrefetch();
- }
-
- /** This function returns true if a tempdescriptor object is found in the array of descriptors
- * for a given prefetch pair else returns false*/
- private boolean isTempDescFound(PrefetchPair pp, TempDescriptor td) {
- ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
- ListIterator it = desc.listIterator();
- for(;it.hasNext();) {
- Object o = it.next();
- if(o instanceof IndexDescriptor) {
- ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
- if(tdarray.contains(td)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /** This function creates a new Arraylist of Descriptors by replacing old tempdescriptors with new
- * tempdescriptors when there is a match */
- private ArrayList<Descriptor> getNewDesc(PrefetchPair pp, TempDescriptor td, TempDescriptor newtd) {
- ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
- ListIterator it = desc.listIterator();
- for(;it.hasNext();) {
- Object currdesc = it.next();
- if(currdesc instanceof IndexDescriptor) {
- ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)currdesc).tddesc;
- if(tdarray.contains(td)) {
- int index = tdarray.indexOf(td);
- tdarray.set(index, newtd);
- }
- }
- }
- return desc;
- }
-
- /** This function creates a new Arraylist of Descriptors by replacing old tempdescriptors with new
- * tempdescriptors when there is a match for e.g FlatOpNodes if i= i+j then replace i with i+j */
- private ArrayList<Descriptor> getNewDesc(PrefetchPair pp, TempDescriptor td, TempDescriptor left, TempDescriptor right) {
- ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
- ListIterator it = desc.listIterator();
- for(;it.hasNext();) {
- Object currdesc = it.next();
- if(currdesc instanceof IndexDescriptor) {
- ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)currdesc).tddesc;
- if(tdarray.contains(td)) {
- int index = tdarray.indexOf(td);
- tdarray.set(index, left);
- tdarray.add(right);
- }
- }
- }
- return desc;
- }
-
- /** This function starts the prefetch analysis */
- private void DoPrefetch() {
- Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
- while(classit.hasNext()) {
- ClassDescriptor cn=(ClassDescriptor)classit.next();
- doMethodAnalysis(cn);
- }
- }
-
- /** This function calls analysis for every method in a class */
- private void doMethodAnalysis(ClassDescriptor cn) {
- Iterator methodit=cn.getMethods();
- while(methodit.hasNext()) {
- LinkedList<FlatNode> newtovisit = new LinkedList<FlatNode>();
- LinkedList<FlatNode> newvisited = new LinkedList<FlatNode>();
- MethodDescriptor md=(MethodDescriptor)methodit.next();
- FlatMethod fm=state.getMethodFlat(md);
- newtovisit.addLast((FlatNode)fm);
- doFlatNodeAnalysis(fm);
- /* Sort flatnodes in top down fashion */
- while(!newtovisit.isEmpty()) {
- FlatNode fn = (FlatNode) newtovisit.iterator().next();
- newtovisit.remove(0);
- newvisited.addLast(fn);
- for(int i=0; i<fn.numNext(); i++) {
- FlatNode nn = fn.getNext(i);
- if(!newvisited.contains(nn) && !newtovisit.contains(nn)) {
- newtovisit.addLast(nn);
- }
- }
- }
-
- /* Insert prefetches along edges */
- applyPrefetchInsertRules(newvisited);
- }
- }
-
- /** This function calls analysis for every node in a method */
- private void doFlatNodeAnalysis(FlatMethod fm) {
- tovisit = fm.getNodeSet();
- Hashtable<PrefetchPair, Float> nodehash = new Hashtable<PrefetchPair, Float>();
- /* Create Empty Prefetch Sets for all flat nodes in the global hashtable */
- while(!tovisit.isEmpty()) {
- FlatNode fn = (FlatNode)tovisit.iterator().next();
- prefetch_hash.put(fn, nodehash);
- tovisit.remove(fn);
- }
- /* Visit and process nodes */
- tovisit = fm.getNodeSet();
- while(!tovisit.isEmpty()) {
- FlatNode fn = (FlatNode)tovisit.iterator().next();
- doChildNodeAnalysis(fn);
- tovisit.remove(fn);
- }
- }
-
- /**
- * This function generates the prefetch sets for a given Flatnode considering the kind of node
- * It calls severals functions based on the kind of the node and
- * returns true: if the prefetch set has changed since last time the node was analysed
- * returns false : otherwise
- */
- private void doChildNodeAnalysis(FlatNode curr) {
- Hashtable<PrefetchPair, Float> child_prefetch_set_copy = new Hashtable<PrefetchPair, Float>();
- Hashtable<FlatNode, PairMap> parentpmap = new Hashtable<FlatNode, PairMap>();
- FlatNode child_node = null;
- if(curr.numNext() != 0) {
- child_node = curr.getNext(0);
- if(prefetch_hash.containsKey(child_node)) {
- child_prefetch_set_copy = (Hashtable<PrefetchPair,Float>) prefetch_hash.get(child_node).clone();
- }
- }
-
- switch(curr.kind()) {
- case FKind.FlatBackEdge:
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatCall:
- //TODO change it to take care of FlatMethod, Flatcalls
- processFlatCall(curr, child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatCheckNode:
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatMethod:
- //TODO change it to take care of FlatMethod, Flatcalls
- processFlatMethod(curr, child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatNew:
- processFlatNewNode(curr, child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatReturnNode:
- //TODO change it to take care of FlatMethod, Flatcalls
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatFieldNode:
- processFlatFieldNode(curr, child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatElementNode:
- processFlatElementNode(curr, child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatCondBranch:
- branch_prefetch_set = new Hashtable<PrefetchPair,Float>();
- for (int i = 0; i < curr.numNext(); i++) {
- parentpmap = new Hashtable<FlatNode, PairMap>();
- child_node = curr.getNext(i);
- if (prefetch_hash.containsKey(child_node)) {
- child_prefetch_set_copy = (Hashtable<PrefetchPair,Float>) prefetch_hash.get(child_node).clone();
- }
- processFlatCondBranch(curr, child_prefetch_set_copy, i, branch_prefetch_set, parentpmap);
- }
- break;
- case FKind.FlatOpNode:
- processFlatOpNode(curr, child_prefetch_set_copy,parentpmap);
- break;
- case FKind.FlatLiteralNode:
- processFlatLiteralNode(curr, child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatSetElementNode:
- processFlatSetElementNode(curr, child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatSetFieldNode:
- processFlatSetFieldNode(curr, child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatAtomicEnterNode:
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatAtomicExitNode:
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatCastNode:
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatFlagActionNode:
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatGlobalConvNode:
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatNop:
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- case FKind.FlatTagDeclaration:
- processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
- break;
- default:
- System.out.println("NO SUCH FLATNODE");
- break;
- }
- }
-
- /**This function compares all the prefetch pairs in a Prefetch set hashtable and
- * returns: true if something has changed in the new Prefetch set else
- * returns: false
- */
- private boolean comparePrefetchSets(Hashtable<PrefetchPair, Float> oldPrefetchSet, Hashtable<PrefetchPair, Float>
- newPrefetchSet) {
- boolean hasChanged = false;
- PrefetchPair oldpp = null;
- PrefetchPair newpp = null;
-
- if(oldPrefetchSet.size() != newPrefetchSet.size()) {
- if(newPrefetchSet.size() == 0) {
- return false;
- }
- return true;
- } else {
- Enumeration e = newPrefetchSet.keys();
- while(e.hasMoreElements()) {
- newpp = (PrefetchPair) e.nextElement();
- float newprob = newPrefetchSet.get(newpp);
- for(Enumeration elem = oldPrefetchSet.keys(); elem.hasMoreElements();) {
- oldpp = (PrefetchPair) elem.nextElement();
- if(oldpp.equals(newpp)) {
- /*Compare the difference in their probabilities */
- float oldprob = oldPrefetchSet.get(oldpp);
- int diff = (int) ((newprob - oldprob)/oldprob)*100;
- if(diff >= PROB_DIFF) {
- return true;
- }
- break;
- }
- }
- }
- }
- return hasChanged;
- }
-
- /** This function processes the prefetch set of FlatFieldNode
- * It generates a new prefetch set after comparision with its children
- * Then compares it with its old prefetch set
- * If old prefetch set is not same as new prefetch set then enqueue the parents
- * of the current FlatFieldNode
- * */
- private void processFlatFieldNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- Hashtable<PrefetchPair, Float> currcopy = new Hashtable<PrefetchPair, Float>();
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
- FlatFieldNode currffn = (FlatFieldNode) curr;
- PairMap pm = new PairMap();
-
- /* Do Self analysis of the current node*/
- FieldDescriptor currffn_field = currffn.getField();
- TempDescriptor currffn_src = currffn.getSrc();
- if (currffn_field.getType().isPtr()) {
- PrefetchPair pp = new PrefetchPair(currffn_src, (Descriptor) currffn_field);
- Float prob = new Float((float)1.0);
- currcopy.put(pp, prob);
- }
-
- /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
- Enumeration ecld = child_prefetch_set_copy.keys();
- PrefetchPair currpp = null;
- PrefetchPair childpp = null;
- while (ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- if (childpp.base == currffn.getDst() && (childpp.getDesc()!= null)) {
- if (currffn.getField().getType().isPtr()) {
- ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
- newdesc.add(currffn.getField());
- newdesc.addAll(childpp.desc);
- PrefetchPair newpp = new PrefetchPair(currffn.getSrc(), newdesc);
- Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
- tocompare.put(newpp, newprob);
- pm.addPair(childpp, newpp);
- child_prefetch_set_copy.remove(childpp);
- /* Check for independence of prefetch pairs to compute new probability */
- if(child_prefetch_set_copy.containsKey(newpp)) {
- newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- tocompare.remove(newpp);
- } else {
- tocompare.put(newpp, newprob);
- pm.addPair(newpp, newpp);
- }
- child_prefetch_set_copy.remove(newpp);
- }
- }
- } else if(childpp.base == currffn.getDst() && (childpp.getDesc() == null)) {
- child_prefetch_set_copy.remove(childpp);
- } else {
- continue;
- }
- }
- /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
- * if so, calculate the new probability */
- ecld = child_prefetch_set_copy.keys();
- Enumeration e = null;
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- for(e = currcopy.keys(); e.hasMoreElements();) {
- currpp = (PrefetchPair) e.nextElement();
- if(currpp.equals(childpp)) {
- Float prob = currcopy.get(currpp).floatValue();
- currcopy.put(currpp, prob);
- pm.addPair(childpp, currpp);
- child_prefetch_set_copy.remove(childpp);
- break;
- }
- }
- }
-
- /* Merge child prefetch pairs */
- ecld = child_prefetch_set_copy.keys();
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- }
-
- /* Merge curr prefetch pairs */
- e = currcopy.keys();
- while(e.hasMoreElements()) {
- currpp = (PrefetchPair) e.nextElement();
- tocompare.put(currpp, currcopy.get(currpp));
- currcopy.remove(currpp);
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
-
- /* Compare with the orginal prefetch pairs */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
- /* Enqueue parent nodes */
- if(pSetHasChanged) {
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This function processes the prefetch set of a FlatElementNode
- * It generates a new prefetch set after comparision with its children
- * It compares the old prefetch set with this new prefetch set and enqueues the parents
- * of the current node if change occurs and updates the global flatnode hash table
- * */
- private void processFlatElementNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
-
- boolean pSetHasChanged = false;
- Hashtable<PrefetchPair, Float> currcopy = new Hashtable<PrefetchPair, Float>();
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
- FlatElementNode currfen = (FlatElementNode) curr;
- PairMap pm = new PairMap();
-
-
- /* Do Self analysis of the current node*/
- TempDescriptor currfen_index = currfen.getIndex();
- IndexDescriptor idesc = new IndexDescriptor(currfen_index, 0);
- TempDescriptor currfen_src = currfen.getSrc();
- if(currfen.getDst().getType().isPtr()) {
- PrefetchPair pp = new PrefetchPair(currfen_src, (Descriptor) idesc);
- Float prob = new Float((float)1.0);
- currcopy.put(pp, prob);
- }
-
- /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
- Enumeration ecld = child_prefetch_set_copy.keys();
- PrefetchPair currpp = null;
- PrefetchPair childpp = null;
- while (ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- if (childpp.base == currfen.getDst() && (childpp.getDesc()!= null)) {
- if (currfen.getDst().getType().isPtr()) {
- ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
- newdesc.add((Descriptor)idesc);
- newdesc.addAll(childpp.desc);
- PrefetchPair newpp = new PrefetchPair(currfen.getSrc(), newdesc);
- Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
- tocompare.put(newpp, newprob);
- pm.addPair(childpp, newpp);
- child_prefetch_set_copy.remove(childpp);
- /* Check for independence of prefetch pairs to compute new probability */
- if(child_prefetch_set_copy.containsKey(newpp)) {
- newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- tocompare.remove(newpp);
- } else {
- tocompare.put(newpp, newprob);
- pm.addPair(newpp, newpp);
- }
- child_prefetch_set_copy.remove(newpp);
- }
- }
- } else if(childpp.base == currfen.getDst() && (childpp.getDesc() == null)) {
- child_prefetch_set_copy.remove(childpp);
- }
- }
- /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
- * if so calculate the new probability */
- ecld = child_prefetch_set_copy.keys();
- Enumeration e = null;
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- for(e = currcopy.keys(); e.hasMoreElements();) {
- currpp = (PrefetchPair) e.nextElement();
- if(currpp.equals(childpp)) {
- Float prob = currcopy.get(currpp).floatValue();
- currcopy.put(currpp, prob);
- pm.addPair(childpp, currpp);
- child_prefetch_set_copy.remove(childpp);
- break;
- }
- }
- }
-
- /* Merge child prefetch pairs */
- ecld = child_prefetch_set_copy.keys();
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- }
-
- /* Merge curr prefetch pairs */
- e = currcopy.keys();
- while(e.hasMoreElements()) {
- currpp = (PrefetchPair) e.nextElement();
- tocompare.put(currpp, currcopy.get(currpp));
- currcopy.remove(currpp);
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
-
- /* Compare with the orginal prefetch pairs */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
- /* Enqueue parent nodes */
- if(pSetHasChanged) {
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This function processes the prefetch set of a FlatSetFieldNode
- * It generates a new prefetch set after comparision with its children
- * It compares the old prefetch set with this new prefetch set and enqueues the parents
- * of the current node if change occurs and then updates the global flatnode hash table
- * */
- private void processFlatSetFieldNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
- FlatSetFieldNode currfsfn = (FlatSetFieldNode) curr;
- PrefetchPair childpp = null;
- PairMap pm = new PairMap();
-
- Enumeration ecld = child_prefetch_set_copy.keys();
- while (ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- if(childpp.base == currfsfn.getDst()) {
- int size = childpp.desc.size();
- if(size >=2) {
- if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
- ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
- for(int i = 0;i<(childpp.desc.size()-1); i++) {
- newdesc.add(i,childpp.desc.get(i+1));
- }
- PrefetchPair newpp = new PrefetchPair(currfsfn.getSrc(), newdesc);
- Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
- tocompare.put(newpp, newprob);
- pm.addPair(childpp, newpp);
- child_prefetch_set_copy.remove(childpp);
- /* Check for independence of prefetch pairs in newly generated prefetch pair
- * to compute new probability */
- if(child_prefetch_set_copy.containsKey(newpp)) {
- newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- tocompare.remove(newpp);
- } else {
- tocompare.put(newpp, newprob);
- pm.addPair(newpp, newpp);
- }
- child_prefetch_set_copy.remove(newpp);
- }
- }
- } else if(size==1) {
- if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
- child_prefetch_set_copy.remove(childpp);
- }
- } else {
- continue;
- }
- }
- }
-
- /* Merge child prefetch pairs */
- ecld = child_prefetch_set_copy.keys();
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
-
- /* Compare with the orginal prefetch pairs */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
- /* Enqueue parent nodes */
- if(pSetHasChanged) {
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This function processes the prefetch set of a FlatSeElementNode
- * It generates a new prefetch set after comparision with its children
- * It compares the old prefetch set with this new prefetch set and enqueues the parents
- * of the current node if change occurs and then updates the global flatnode hash table
- * */
- private void processFlatSetElementNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
- PrefetchPair childpp = null;
- FlatSetElementNode currfsen = (FlatSetElementNode) curr;
- PairMap pm = new PairMap();
-
- Enumeration ecld = child_prefetch_set_copy.keys();
- while (ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- if (childpp.base == currfsen.getDst()){
- int sizedesc = childpp.desc.size();
- if((childpp.getDescAt(0) instanceof IndexDescriptor)) {
- int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size();
- if(sizetempdesc == 1) {
- if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) {
- ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
- for(int i = 0;i<(childpp.desc.size()-1); i++) {
- newdesc.add(i,childpp.desc.get(i+1));
- }
- PrefetchPair newpp = new PrefetchPair(currfsen.getSrc(), newdesc);
- Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
- tocompare.put(newpp, newprob);
- pm.addPair(childpp, newpp);
- child_prefetch_set_copy.remove(childpp);
- /* Check for independence of prefetch pairs to compute new probability */
- if(child_prefetch_set_copy.containsKey(newpp)) {
- newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- tocompare.remove(newpp);
- } else {
- tocompare.put(newpp, newprob);
- pm.addPair(newpp, newpp);
- }
- child_prefetch_set_copy.remove(newpp);
- }
- } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1))
- child_prefetch_set_copy.remove(childpp);
- } else {
- continue;
- }
- }
- }
- }
- /* Merge child prefetch pairs */
- ecld = child_prefetch_set_copy.keys();
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
-
- /* Compare with the orginal prefetch pairs */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
- /* Enqueue parent nodes */
- if(pSetHasChanged) {
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This function applies rules and does analysis for a FlatOpNode
- * And updates the global prefetch hashtable
- * */
- private void processFlatOpNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- int index;
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
- FlatOpNode currfopn = (FlatOpNode) curr;
- Enumeration ecld = null;
- PrefetchPair childpp = null;
- PairMap pm = new PairMap();
-
- if(currfopn.getOp().getOp()== Operation.ASSIGN) {
- ecld = child_prefetch_set_copy.keys();
- while (ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
-
- /* For cases like x=y followed by childnode t=x[i].z or t=x.g*/
- if(childpp.base == currfopn.getDest()) {
- ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
- newdesc.addAll(childpp.desc);
- PrefetchPair newpp = new PrefetchPair(currfopn.getLeft(), newdesc);
- Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
- tocompare.put(newpp, newprob);
- pm.addPair(childpp, newpp);
- child_prefetch_set_copy.remove(childpp);
- /* Check for independence of prefetch pairs to compute new probability */
- if(child_prefetch_set_copy.containsKey(newpp)) {
- newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- tocompare.remove(newpp);
- } else {
- tocompare.put(newpp, newprob);
- pm.addPair(newpp, newpp);
- }
- child_prefetch_set_copy.remove(newpp);
- }
- /* For cases like x=y followed by t = r[i].x or t =r[x].p or t = r[p+x].q*/
- } else if(isTempDescFound(copyofchildpp, currfopn.getDest())) {
- ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
- newdesc.addAll((ArrayList<Descriptor>)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft()));
- PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
- Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
- tocompare.put(newpp, newprob);
- pm.addPair(childpp, newpp);
- child_prefetch_set_copy.remove(childpp);
- /* Check for independence of prefetch pairs to compute new probability*/
- if(child_prefetch_set_copy.containsKey(newpp)) {
- newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- tocompare.remove(newpp);
- } else {
- tocompare.put(newpp, newprob);
- pm.addPair(newpp, newpp);
- }
- child_prefetch_set_copy.remove(newpp);
- }
- }else {
- continue;
- }
- }
- //case i = i+z followed by a[i].x
- } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) {
- ecld = child_prefetch_set_copy.keys();
- while (ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
-
- if(isTempDescFound(copyofchildpp, currfopn.getDest())) {
- ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
- newdesc.addAll((ArrayList<Descriptor>)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft(), currfopn.getRight()));
- PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
- Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
- tocompare.put(newpp, newprob);
- pm.addPair(childpp, newpp);
- child_prefetch_set_copy.remove(childpp);
- /* Check for independence of prefetch pairs to compute new probability*/
- if(child_prefetch_set_copy.containsKey(newpp)) {
- newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- tocompare.remove(newpp);
- } else {
- tocompare.put(newpp, newprob);
- pm.addPair(newpp, newpp);
- }
- child_prefetch_set_copy.remove(newpp);
- }
- }else {
- continue;
- }
- }
- } else {
- //FIXME Is not taken care of for cases like x = -y followed by a[x].i
- }
-
- /* Merge child prefetch pairs */
- ecld = child_prefetch_set_copy.keys();
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
-
- /* Compare with the orginal prefetch pairs */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
- /* Enqueue parent nodes */
- if(pSetHasChanged) {
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This function processes a FlatLiteralNode where cases such as
- * for cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r
- * are handled */
- private void processFlatLiteralNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
- FlatLiteralNode currfln = (FlatLiteralNode) curr;
- Enumeration ecld = null;
- PrefetchPair childpp = null;
- PairMap pm = new PairMap();
-
- if(currfln.getType().isIntegerType()) {
- ecld = child_prefetch_set_copy.keys();
- while (ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
- /* For cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r*/
- if(isTempDescFound(copyofchildpp,currfln.getDst())) {
- ArrayList<Descriptor> copychilddesc = (ArrayList<Descriptor>) copyofchildpp.getDesc();
- int sizetempdesc = copychilddesc.size();
- ListIterator it = copychilddesc.listIterator();
- for(;it.hasNext();) {
- Object o = it.next();
- if(o instanceof IndexDescriptor) {
- ArrayList<TempDescriptor> td = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
- int sizetddesc = td.size();
- if(td.contains(currfln.getDst())) {
- int index = td.indexOf(currfln.getDst());
- td.remove(index);
- ((IndexDescriptor)o).offset += (Integer)currfln.getValue();
- }
- }
- }
- ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
- newdesc.addAll(copychilddesc);
- PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
- Float newprob = (child_prefetch_set_copy.get(childpp)).floatValue();
- tocompare.put(newpp, newprob);
- pm.addPair(childpp, newpp);
- child_prefetch_set_copy.remove(childpp);
- /* Check for independence of prefetch pairs to compute new probability */
- if(child_prefetch_set_copy.containsKey(newpp)) {
- newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- tocompare.remove(newpp);
- } else {
- tocompare.put(newpp, newprob);
- pm.addPair(newpp, newpp);
- }
- child_prefetch_set_copy.remove(newpp);
- }
- }
- }
- }
-
- /* Merge child prefetch pairs */
- ecld = child_prefetch_set_copy.keys();
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
-
- /* Compare with the orginal prefetch pairs */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
- /* Enqueue parent nodes */
- if(pSetHasChanged) {
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This function processes a FlatMethod where the method propagates
- * the entire prefetch set of its child node */
- private void processFlatMethod(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
- FlatMethod currfm = (FlatMethod) curr;
- Enumeration ecld = null;
- PrefetchPair childpp = null;
- PairMap pm = new PairMap();
-
- /* Merge child prefetch pairs */
- ecld = child_prefetch_set_copy.keys();
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
-
- /* Compare with the orginal prefetch pairs */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
- /* Enqueue parent nodes */
- if(pSetHasChanged) {
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This Function processes the FlatCalls
- * It currently drops the propagation of those prefetchpairs that are passed as
- * arguments in the FlatCall
- */
- private void processFlatCall(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
- FlatCall currfcn = (FlatCall) curr;
- PairMap pm = new PairMap();
- Enumeration ecld = null;
- PrefetchPair childpp = null;
-
-
- ecld = child_prefetch_set_copy.keys();
- while(ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
- if(currfcn.getReturnTemp() != childpp.base) {
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- } else {
- child_prefetch_set_copy.remove(childpp);
- }
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
-
- /* Compare with the orginal prefetch pairs */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
- /* Enqueue parent nodes */
- if(pSetHasChanged) {
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This function handles the processes the FlatNode of type FlatCondBranch
- * It combines prefetches of both child elements and create a new hash table called
- * branch_prefetch_set to contains the entries of both its children
- */
- private void processFlatCondBranch(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy, int index,
- Hashtable<PrefetchPair,Float> branch_prefetch_set, Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();//temporary hash table
- FlatCondBranch currfcb = (FlatCondBranch) curr;
- Float newprob = new Float((float)0.0);
- PairMap pm = new PairMap();
- PrefetchPair childpp = null;
- PrefetchPair pp = null;
- Enumeration ecld = null;
-
- ecld = child_prefetch_set_copy.keys();
- while (ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- /* True Edge */
- if(index == 0) {
- newprob = child_prefetch_set_copy.get(childpp).floatValue() * BRANCH_TRUE_EDGE_PROB;
- if(newprob >= ANALYSIS_THRESHOLD_PROB) {
- tocompare.put(childpp, newprob);
- pm.addPair(childpp, childpp);
- }
- child_prefetch_set_copy.remove(childpp);
- } else if(index == 1) { /* False Edge */
- newprob = child_prefetch_set_copy.get(childpp).floatValue() * BRANCH_FALSE_EDGE_PROB;
- if(newprob >= ANALYSIS_THRESHOLD_PROB) {
- tocompare.put(childpp, newprob);
- pm.addPair(childpp, childpp);
- }
- child_prefetch_set_copy.remove(childpp);
- } else {
- System.out.println("DEBUG-> No more children of the FlatCondBranchNode present");
- }
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(index), parentpmap);
-
- /* Update branch_prefetch_set (global hash table) to combine all prefetch pairs from childnodes of the
- * cond branch that is currently stored in the tocompare hash table */
- if(!tocompare.isEmpty()) {
- if(index == 0) {
- branch_prefetch_set.putAll(tocompare);
- }else if(index == 1) {
- if(branch_prefetch_set.isEmpty()) {
- branch_prefetch_set.putAll(tocompare);
- } else {
- Enumeration e = tocompare.keys();
- while(e.hasMoreElements()) {
- pp = (PrefetchPair) e.nextElement();
- if(branch_prefetch_set.containsKey(pp)) {
- newprob = (float)(branch_prefetch_set.get(pp).floatValue() + tocompare.get(pp).floatValue());
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- branch_prefetch_set.remove(pp);
- } else {
- branch_prefetch_set.put(pp, newprob);
- }
- tocompare.remove(pp);
- }
- }
- e = tocompare.keys();
- while(e.hasMoreElements()) {
- pp = (PrefetchPair) e.nextElement();
- branch_prefetch_set.put(pp,tocompare.get(pp));
- tocompare.remove(pp);
- }
- }
- } else {
- System.out.println("DEBUG-> No more children of the FlatCondBranchNode present");
- }
- }
-
- /* Compare prefetch sets and enqueue parent nodes: Only possible after combining prefetch pairs of both child nodes
- * into branch_prefetch_set hashtable*/
- if(index == 1) {
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), branch_prefetch_set);
- if(pSetHasChanged) {
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,branch_prefetch_set);
- }
- }
- }
-
- /** If FlatNode is not concerned with the prefetch set of its Child then propagate
- * prefetches up the FlatNode*/
- private void processDefaultCase(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- PairMap pm = new PairMap();
- Enumeration e = null;
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
-
- /* Propagate all child nodes */
- for(e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
- PrefetchPair childpp = (PrefetchPair) e.nextElement();
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- }
-
- /* Check case for nodes with no children (e.g return null) and create prefetch mappings for child nodes*/
- if(curr.numNext() != 0) {
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
- }
-
- /* Compare with old Prefetch sets */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
- if(pSetHasChanged){
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This functions processes for FlatNewNode
- * for e.g x = NEW(foo) followed by childnode with prefetch set x.f
- * then drop the prefetches beyond this FlatNewNode */
- private void processFlatNewNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
- Hashtable<FlatNode, PairMap> parentpmap) {
- boolean pSetHasChanged = false;
- Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
- FlatNew currfnn = (FlatNew) curr;
- Float newprob = new Float((float)0.0);
- PairMap pm = new PairMap();
- PrefetchPair childpp = null;
- Enumeration ecld = null;
-
- ecld = child_prefetch_set_copy.keys();
- while (ecld.hasMoreElements()) {
- childpp = (PrefetchPair) ecld.nextElement();
- if(childpp.base == currfnn.getDst()){
- child_prefetch_set_copy.remove(childpp);
- } else {
- tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
- pm.addPair(childpp, childpp);
- child_prefetch_set_copy.remove(childpp);
- }
- }
-
- /* Create prefetch mappings for child nodes */
- if(!pm.isEmpty()) {
- parentpmap.put(curr, pm);
- }
- pmap_hash.put(curr.getNext(0), parentpmap);
-
- /* Compare with the old prefetch set */
- pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
-
- /* Enqueue parent nodes */
- if(pSetHasChanged) {
- for(int i=0; i<curr.numPrev(); i++) {
- tovisit.add(curr.getPrev(i));
- }
- /* Overwrite the new prefetch set to the global hash table */
- prefetch_hash.put(curr,tocompare);
- }
- }
-
- /** This function prints the Prefetch pairs of a given flatnode */
- private void printPrefetchPairs(FlatNode fn) {
- if(prefetch_hash.containsKey(fn)) {
- System.out.print("Prefetch" + "(");
- Hashtable<PrefetchPair, Float> currhash = (Hashtable) prefetch_hash.get(fn);
- for(Enumeration pphash= currhash.keys(); pphash.hasMoreElements();) {
- PrefetchPair pp = (PrefetchPair) pphash.nextElement();
- System.out.print(pp.toString() + ", ");
- }
- System.out.println(")");
- } else {
- System.out.println("Flatnode is currently not present in the global hash: Prefetch Set is Empty");
- }
- }
-
- private void applyPrefetchInsertRules(LinkedList<FlatNode> visited) {
- Hashtable<FlatNode, Set> pset1_hash = new Hashtable<FlatNode, Set>();
- Hashtable<FlatNode, Set> pset2_hash = new Hashtable<FlatNode, Set>();
- Hashtable<FlatNode, Set> newpset_hash = new Hashtable<FlatNode, Set>();
- Hashtable<FlatNode, Set> newprefetchset = new Hashtable<FlatNode, Set>();
- boolean ppairIsPresent = false;
- boolean mapIsPresent = true;
- boolean pprobIsGreater = false;
- boolean mapprobIsLess = false;
- boolean probIsLess = false;
-
- /* Create pset1_hash */
- for(int i = 0; i<visited.size(); i++) {
- Enumeration e = null;
- HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
- HashSet<PrefetchPair> pset2 = new HashSet<PrefetchPair>();
- HashSet<PrefetchPair> newpset = new HashSet<PrefetchPair>();
- Hashtable<PrefetchPair, Float> prefetchset = new Hashtable<PrefetchPair, Float>();
- FlatNode fn = visited.get(i);
- if(fn.kind() == FKind.FlatMethod) {
- if(prefetch_hash.containsKey(fn)) {
- prefetchset = prefetch_hash.get(fn);
- e = prefetchset.keys();
- /* Insert Prefetch */
- if(e.hasMoreElements()) {
- //FIXME Insert PrefetchNode here
- }
- while(e.hasMoreElements()) {
- PrefetchPair pp = (PrefetchPair) e.nextElement();
- /* Apply initial rule */
- if(((float)prefetchset.get(pp).floatValue()) > PREFETCH_THRESHOLD_PROB) {
- pset1.add(pp);
- }
- }
- pset1_hash.put(fn, pset1);
- }
- } else {
- if(prefetch_hash.containsKey(fn)) {
- prefetchset = prefetch_hash.get(fn);
- for(Enumeration epset = prefetchset.keys(); epset.hasMoreElements();) {
- PrefetchPair pp = (PrefetchPair) epset.nextElement();
- /* Create pset2_hash */
- Hashtable<FlatNode, PairMap> ppairmaphash = new Hashtable<FlatNode, PairMap>();
- ppairmaphash = pmap_hash.get(fn);
- if(!ppairmaphash.isEmpty()) {
- e = ppairmaphash.keys();
- while(e.hasMoreElements()) {
- FlatNode parentnode = (FlatNode) e.nextElement();
- PairMap pm = (PairMap) ppairmaphash.get(parentnode);
- if(pset1_hash.containsKey(parentnode)) {
- Set pset = pset1_hash.get(parentnode);
- if(!pset.isEmpty()) {
- if(ppairIsPresent = (pset.contains((PrefetchPair) pm.getPair(pp)))) {
- mapIsPresent = ppairIsPresent && mapIsPresent;
- }
- } else {
- mapIsPresent = false;
- }
- }
- }
- if(mapIsPresent) {
- pset2.add(pp);
- }
- }
-
- /* Create newprefetchset */
- if(pprobIsGreater = (prefetchset.get(pp).floatValue() > PREFETCH_THRESHOLD_PROB)) {
- ppairmaphash = pmap_hash.get(fn);
- if(!ppairmaphash.isEmpty()) {
- e = ppairmaphash.keys();
- while(e.hasMoreElements()) {
- FlatNode parentnode = (FlatNode) e.nextElement();
- PairMap pm = (PairMap) ppairmaphash.get(parentnode);
- PrefetchPair mappedpp = pm.getPair(pp);
- if(mappedpp != null) {
- if(prefetch_hash.get(parentnode).containsKey(mappedpp)) {
- float prob = (float)prefetch_hash.get(parentnode).get(mappedpp).floatValue();
- if(probIsLess = (prob < PREFETCH_THRESHOLD_PROB))
- mapprobIsLess = mapprobIsLess || probIsLess;
- }
- } else {
- mapprobIsLess = false;
- }
- }
- } else {
- mapprobIsLess = true;
- }
- }
- if(pprobIsGreater && mapprobIsLess) {
- newpset.add(pp);
- }
- }
- }
- if(!pset2.isEmpty())
- pset1.addAll(pset2);
- if(!newpset.isEmpty())
- pset1.addAll(newpset);
- pset1_hash.put(fn, pset1);
- }
-
- /* To insert prefetch apply rule */
- HashSet s = null;
- if(!newpset.isEmpty() && !pset2.isEmpty()) {
- for(Iterator it = newpset.iterator(); it.hasNext();) {
- PrefetchPair pp = (PrefetchPair) it.next();
- if(!pset2.contains(pp)) {
- s.add(pp);
- }
- }
- }
- if(s != null) {
- newprefetchset.put(fn, s);
- //FIXME Insert PrefetchNode here
- }
- }
- }
-
- private void doAnalysis() {
- Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
- while(classit.hasNext()) {
- ClassDescriptor cn=(ClassDescriptor)classit.next();
- Iterator methodit=cn.getMethods();
- while(methodit.hasNext()) {
- /* Classify parameters */
- MethodDescriptor md=(MethodDescriptor)methodit.next();
- FlatMethod fm=state.getMethodFlat(md);
- printMethod(fm);
- }
- }
- }
-
- private void printMethod(FlatMethod fm) {
- System.out.println(fm.getMethod()+" {");
- HashSet tovisit=new HashSet();
- HashSet visited=new HashSet();
- int labelindex=0;
- Hashtable nodetolabel=new Hashtable();
- tovisit.add(fm);
- FlatNode current_node=null;
- //Assign labels 1st
- //Node needs a label if it is
- while(!tovisit.isEmpty()) {
- FlatNode fn=(FlatNode)tovisit.iterator().next();
- tovisit.remove(fn);
- visited.add(fn);
-
- for(int i=0;i<fn.numNext();i++) {
- FlatNode nn=fn.getNext(i);
- if(i>0) {
- //1) Edge >1 of node
- nodetolabel.put(nn,new Integer(labelindex++));
- }
- if (!visited.contains(nn)&&!tovisit.contains(nn)) {
- tovisit.add(nn);
- } else {
- //2) Join point
- nodetolabel.put(nn,new Integer(labelindex++));
- }
- }
- }
- //Do the actual printing
- tovisit=new HashSet();
- visited=new HashSet();
- tovisit.add(fm);
- while(current_node!=null||!tovisit.isEmpty()) {
- if (current_node==null) {
- current_node=(FlatNode)tovisit.iterator().next();
- tovisit.remove(current_node);
- }
- visited.add(current_node);
- if (nodetolabel.containsKey(current_node))
- System.out.println("L"+nodetolabel.get(current_node)+":");
- if (current_node.numNext()==0) {
- System.out.println(" "+current_node.toString());
- current_node=null;
- } else if(current_node.numNext()==1) {
- System.out.println(" "+current_node.toString());
- FlatNode nextnode=current_node.getNext(0);
- if (visited.contains(nextnode)) {
- System.out.println("goto L"+nodetolabel.get(nextnode));
- current_node=null;
- } else
- current_node=nextnode;
- } else if (current_node.numNext()==2) {
- /* Branch */
- System.out.println(" "+((FlatCondBranch)current_node).toString("L"+nodetolabel.get(current_node.getNext(1))));
- if (!visited.contains(current_node.getNext(1)))
- tovisit.add(current_node.getNext(1));
- if (visited.contains(current_node.getNext(0))) {
- System.out.println("goto L"+nodetolabel.get(current_node.getNext(0)));
- current_node=null;
- } else
- current_node=current_node.getNext(0);
- } else throw new Error();
- }
- System.out.println("}");
- }
-
+ State state;
+ CallGraph callgraph;
+ TypeUtil typeutil;
+ Set<FlatNode> tovisit;
+ public Hashtable<FlatNode, Hashtable<PrefetchPair, Float>> prefetch_hash;
+ public Hashtable<FlatNode, Hashtable<FlatNode, PairMap>> pmap_hash;
+ Hashtable<PrefetchPair, Float> branch_prefetch_set;
+ LinkedList<FlatNode> newvisited;
+ Hashtable<FlatNode, HashSet<PrefetchPair>> pset1_hash;
+ Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset;
+ public static final int PROB_DIFF = 10;
+ public static final float ANALYSIS_THRESHOLD_PROB = (float)0.10;
+ public static final float PREFETCH_THRESHOLD_PROB = (float)0.30;
+ public static final float BRANCH_TRUE_EDGE_PROB = (float)0.5;
+ public static final float BRANCH_FALSE_EDGE_PROB = (float)0.5;
+
+ public PrefetchAnalysis(State state, CallGraph callgraph, TypeUtil typeutil) {
+ this.typeutil=typeutil;
+ this.state=state;
+ this.callgraph=callgraph;
+ prefetch_hash = new Hashtable<FlatNode, Hashtable<PrefetchPair,Float>>();
+ pmap_hash = new Hashtable<FlatNode, Hashtable<FlatNode, PairMap>>();
+ DoPrefetch();
+ }
+
+ /** This function returns true if a tempdescriptor object is found in the array of descriptors
+ * for a given prefetch pair else returns false*/
+ private boolean isTempDescFound(PrefetchPair pp, TempDescriptor td) {
+ ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
+ ListIterator it = desc.listIterator();
+ for(;it.hasNext();) {
+ Object o = it.next();
+ if(o instanceof IndexDescriptor) {
+ ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
+ if(tdarray.contains(td)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /** This function creates a new Arraylist of Descriptors by replacing old tempdescriptors with new
+ * tempdescriptors when there is a match */
+ private ArrayList<Descriptor> getNewDesc(PrefetchPair pp, TempDescriptor td, TempDescriptor newtd) {
+ ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
+ ListIterator it = desc.listIterator();
+ for(;it.hasNext();) {
+ Object currdesc = it.next();
+ if(currdesc instanceof IndexDescriptor) {
+ ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)currdesc).tddesc;
+ if(tdarray.contains(td)) {
+ int index = tdarray.indexOf(td);
+ tdarray.set(index, newtd);
+ }
+ }
+ }
+ return desc;
+ }
+
+ /** This function creates a new Arraylist of Descriptors by replacing old tempdescriptors with new
+ * tempdescriptors when there is a match for e.g FlatOpNodes if i= i+j then replace i with i+j */
+ private ArrayList<Descriptor> getNewDesc(PrefetchPair pp, TempDescriptor td, TempDescriptor left, TempDescriptor right) {
+ ArrayList<Descriptor> desc = (ArrayList<Descriptor>) pp.getDesc();
+ ListIterator it = desc.listIterator();
+ for(;it.hasNext();) {
+ Object currdesc = it.next();
+ if(currdesc instanceof IndexDescriptor) {
+ ArrayList<TempDescriptor> tdarray = (ArrayList<TempDescriptor>)((IndexDescriptor)currdesc).tddesc;
+ if(tdarray.contains(td)) {
+ int index = tdarray.indexOf(td);
+ tdarray.set(index, left);
+ tdarray.add(right);
+ }
+ }
+ }
+ return desc;
+ }
+
+ /** This function starts the prefetch analysis */
+ private void DoPrefetch() {
+ Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
+ while(classit.hasNext()) {
+ ClassDescriptor cn=(ClassDescriptor)classit.next();
+ doMethodAnalysis(cn);
+ }
+ }
+
+ /** This function calls analysis for every method in a class */
+ private void doMethodAnalysis(ClassDescriptor cn) {
+ Iterator methodit=cn.getMethods();
+ while(methodit.hasNext()) {
+ newprefetchset = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
+ pset1_hash = new Hashtable<FlatNode, HashSet<PrefetchPair>>();
+ MethodDescriptor md=(MethodDescriptor)methodit.next();
+ FlatMethod fm=state.getMethodFlat(md);
+ doFlatNodeAnalysis(fm);
+ doInsPrefetchAnalysis(fm);
+ if(newprefetchset.size() > 0) {
+ addFlatPrefetchNode(newprefetchset);
+ printMethod(fm);
+ }
+ }
+ }
+
+ /** This function calls analysis for every node in a method */
+ private void doFlatNodeAnalysis(FlatMethod fm) {
+ tovisit = fm.getNodeSet();
+ Hashtable<PrefetchPair, Float> nodehash = new Hashtable<PrefetchPair, Float>();
+ /* Create Empty Prefetch Sets for all flat nodes in the global hashtable */
+ while(!tovisit.isEmpty()) {
+ FlatNode fn = (FlatNode)tovisit.iterator().next();
+ prefetch_hash.put(fn, nodehash);
+ tovisit.remove(fn);
+ }
+ /* Visit and process nodes */
+ tovisit = fm.getNodeSet();
+ while(!tovisit.isEmpty()) {
+ FlatNode fn = (FlatNode)tovisit.iterator().next();
+ doChildNodeAnalysis(fn);
+ tovisit.remove(fn);
+ }
+ }
+
+ /**
+ * This function generates the prefetch sets for a given Flatnode considering the kind of node
+ * It calls severals functions based on the kind of the node and
+ * returns true: if the prefetch set has changed since last time the node was analysed
+ * returns false : otherwise
+ */
+ private void doChildNodeAnalysis(FlatNode curr) {
+ Hashtable<PrefetchPair, Float> child_prefetch_set_copy = new Hashtable<PrefetchPair, Float>();
+ Hashtable<FlatNode, PairMap> parentpmap = new Hashtable<FlatNode, PairMap>();
+ FlatNode child_node = null;
+ if(curr.numNext() != 0) {
+ child_node = curr.getNext(0);
+ if(prefetch_hash.containsKey(child_node)) {
+ child_prefetch_set_copy = (Hashtable<PrefetchPair,Float>) prefetch_hash.get(child_node).clone();
+ }
+ }
+
+ switch(curr.kind()) {
+ case FKind.FlatBackEdge:
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatCall:
+ //TODO change it to take care of FlatMethod, Flatcalls
+ processFlatCall(curr, child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatCheckNode:
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatMethod:
+ //TODO change it to take care of FlatMethod, Flatcalls
+ processFlatMethod(curr, child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatNew:
+ processFlatNewNode(curr, child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatReturnNode:
+ //TODO change it to take care of FlatMethod, Flatcalls
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatFieldNode:
+ processFlatFieldNode(curr, child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatElementNode:
+ processFlatElementNode(curr, child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatCondBranch:
+ branch_prefetch_set = new Hashtable<PrefetchPair,Float>();
+ for (int i = 0; i < curr.numNext(); i++) {
+ parentpmap = new Hashtable<FlatNode, PairMap>();
+ child_node = curr.getNext(i);
+ if (prefetch_hash.containsKey(child_node)) {
+ child_prefetch_set_copy = (Hashtable<PrefetchPair,Float>) prefetch_hash.get(child_node).clone();
+ }
+ processFlatCondBranch(curr, child_prefetch_set_copy, i, branch_prefetch_set, parentpmap);
+ }
+ break;
+ case FKind.FlatOpNode:
+ processFlatOpNode(curr, child_prefetch_set_copy,parentpmap);
+ break;
+ case FKind.FlatLiteralNode:
+ processFlatLiteralNode(curr, child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatSetElementNode:
+ processFlatSetElementNode(curr, child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatSetFieldNode:
+ processFlatSetFieldNode(curr, child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatAtomicEnterNode:
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatAtomicExitNode:
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatCastNode:
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatFlagActionNode:
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatGlobalConvNode:
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatNop:
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ case FKind.FlatTagDeclaration:
+ processDefaultCase(curr,child_prefetch_set_copy, parentpmap);
+ break;
+ default:
+ System.out.println("NO SUCH FLATNODE");
+ break;
+ }
+ }
+
+ /**This function compares all the prefetch pairs in a Prefetch set hashtable and
+ * returns: true if something has changed in the new Prefetch set else
+ * returns: false
+ */
+ private boolean comparePrefetchSets(Hashtable<PrefetchPair, Float> oldPrefetchSet, Hashtable<PrefetchPair, Float>
+ newPrefetchSet) {
+ boolean hasChanged = false;
+ PrefetchPair oldpp = null;
+ PrefetchPair newpp = null;
+
+ if(oldPrefetchSet.size() != newPrefetchSet.size()) {
+ if(newPrefetchSet.size() == 0) {
+ return false;
+ }
+ return true;
+ } else {
+ Enumeration e = newPrefetchSet.keys();
+ while(e.hasMoreElements()) {
+ newpp = (PrefetchPair) e.nextElement();
+ float newprob = newPrefetchSet.get(newpp);
+ for(Enumeration elem = oldPrefetchSet.keys(); elem.hasMoreElements();) {
+ oldpp = (PrefetchPair) elem.nextElement();
+ if(oldpp.equals(newpp)) {
+ /*Compare the difference in their probabilities */
+ float oldprob = oldPrefetchSet.get(oldpp);
+ int diff = (int) ((newprob - oldprob)/oldprob)*100;
+ if(diff >= PROB_DIFF) {
+ return true;
+ }
+ break;
+ }
+ }
+ }
+ }
+ return hasChanged;
+ }
+
+ /** This function processes the prefetch set of FlatFieldNode
+ * It generates a new prefetch set after comparision with its children
+ * Then compares it with its old prefetch set
+ * If old prefetch set is not same as new prefetch set then enqueue the parents
+ * of the current FlatFieldNode
+ * */
+ private void processFlatFieldNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ Hashtable<PrefetchPair, Float> currcopy = new Hashtable<PrefetchPair, Float>();
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+ FlatFieldNode currffn = (FlatFieldNode) curr;
+ PairMap pm = new PairMap();
+
+ /* Do Self analysis of the current node*/
+ FieldDescriptor currffn_field = currffn.getField();
+ TempDescriptor currffn_src = currffn.getSrc();
+ if (currffn_field.getType().isPtr()) {
+ PrefetchPair pp = new PrefetchPair(currffn_src, (Descriptor) currffn_field);
+ Float prob = new Float((float)1.0);
+ currcopy.put(pp, prob);
+ }
+
+ /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
+ Enumeration ecld = child_prefetch_set_copy.keys();
+ PrefetchPair currpp = null;
+ PrefetchPair childpp = null;
+ while (ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ if (childpp.base == currffn.getDst() && (childpp.getDesc()!= null)) {
+ if (currffn.getField().getType().isPtr()) {
+ ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
+ newdesc.add(currffn.getField());
+ newdesc.addAll(childpp.desc);
+ PrefetchPair newpp = new PrefetchPair(currffn.getSrc(), newdesc);
+ Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
+ tocompare.put(newpp, newprob);
+ pm.addPair(childpp, newpp);
+ child_prefetch_set_copy.remove(childpp);
+ /* Check for independence of prefetch pairs to compute new probability */
+ if(child_prefetch_set_copy.containsKey(newpp)) {
+ newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
+ if(newprob < ANALYSIS_THRESHOLD_PROB) {
+ tocompare.remove(newpp);
+ } else {
+ tocompare.put(newpp, newprob);
+ pm.addPair(newpp, newpp);
+ }
+ child_prefetch_set_copy.remove(newpp);
+ }
+ }
+ } else if(childpp.base == currffn.getDst() && (childpp.getDesc() == null)) {
+ child_prefetch_set_copy.remove(childpp);
+ } else {
+ continue;
+ }
+ }
+ /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
+ * if so, calculate the new probability */
+ ecld = child_prefetch_set_copy.keys();
+ Enumeration e = null;
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ for(e = currcopy.keys(); e.hasMoreElements();) {
+ currpp = (PrefetchPair) e.nextElement();
+ if(currpp.equals(childpp)) {
+ Float prob = currcopy.get(currpp).floatValue();
+ currcopy.put(currpp, prob);
+ pm.addPair(childpp, currpp);
+ child_prefetch_set_copy.remove(childpp);
+ break;
+ }
+ }
+ }
+
+ /* Merge child prefetch pairs */
+ ecld = child_prefetch_set_copy.keys();
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ }
+
+ /* Merge curr prefetch pairs */
+ e = currcopy.keys();
+ while(e.hasMoreElements()) {
+ currpp = (PrefetchPair) e.nextElement();
+ tocompare.put(currpp, currcopy.get(currpp));
+ currcopy.remove(currpp);
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+
+ /* Compare with the orginal prefetch pairs */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+ /* Enqueue parent nodes */
+ if(pSetHasChanged) {
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This function processes the prefetch set of a FlatElementNode
+ * It generates a new prefetch set after comparision with its children
+ * It compares the old prefetch set with this new prefetch set and enqueues the parents
+ * of the current node if change occurs and updates the global flatnode hash table
+ * */
+ private void processFlatElementNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+
+ boolean pSetHasChanged = false;
+ Hashtable<PrefetchPair, Float> currcopy = new Hashtable<PrefetchPair, Float>();
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+ FlatElementNode currfen = (FlatElementNode) curr;
+ PairMap pm = new PairMap();
+
+
+ /* Do Self analysis of the current node*/
+ TempDescriptor currfen_index = currfen.getIndex();
+ IndexDescriptor idesc = new IndexDescriptor(currfen_index, 0);
+ TempDescriptor currfen_src = currfen.getSrc();
+ if(currfen.getDst().getType().isPtr()) {
+ PrefetchPair pp = new PrefetchPair(currfen_src, (Descriptor) idesc);
+ Float prob = new Float((float)1.0);
+ currcopy.put(pp, prob);
+ }
+
+ /* Get each prefetch pair of the child and match it with the destination temp descriptor of curr FlatFieldNode */
+ Enumeration ecld = child_prefetch_set_copy.keys();
+ PrefetchPair currpp = null;
+ PrefetchPair childpp = null;
+ while (ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ if (childpp.base == currfen.getDst() && (childpp.getDesc()!= null)) {
+ if (currfen.getDst().getType().isPtr()) {
+ ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
+ newdesc.add((Descriptor)idesc);
+ newdesc.addAll(childpp.desc);
+ PrefetchPair newpp = new PrefetchPair(currfen.getSrc(), newdesc);
+ Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
+ tocompare.put(newpp, newprob);
+ pm.addPair(childpp, newpp);
+ child_prefetch_set_copy.remove(childpp);
+ /* Check for independence of prefetch pairs to compute new probability */
+ if(child_prefetch_set_copy.containsKey(newpp)) {
+ newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
+ if(newprob < ANALYSIS_THRESHOLD_PROB) {
+ tocompare.remove(newpp);
+ } else {
+ tocompare.put(newpp, newprob);
+ pm.addPair(newpp, newpp);
+ }
+ child_prefetch_set_copy.remove(newpp);
+ }
+ }
+ } else if(childpp.base == currfen.getDst() && (childpp.getDesc() == null)) {
+ child_prefetch_set_copy.remove(childpp);
+ }
+ }
+ /* Check if curr prefetch set and the child prefetch set have same prefetch pairs
+ * if so calculate the new probability */
+ ecld = child_prefetch_set_copy.keys();
+ Enumeration e = null;
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ for(e = currcopy.keys(); e.hasMoreElements();) {
+ currpp = (PrefetchPair) e.nextElement();
+ if(currpp.equals(childpp)) {
+ Float prob = currcopy.get(currpp).floatValue();
+ currcopy.put(currpp, prob);
+ pm.addPair(childpp, currpp);
+ child_prefetch_set_copy.remove(childpp);
+ break;
+ }
+ }
+ }
+
+ /* Merge child prefetch pairs */
+ ecld = child_prefetch_set_copy.keys();
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ }
+
+ /* Merge curr prefetch pairs */
+ e = currcopy.keys();
+ while(e.hasMoreElements()) {
+ currpp = (PrefetchPair) e.nextElement();
+ tocompare.put(currpp, currcopy.get(currpp));
+ currcopy.remove(currpp);
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+
+ /* Compare with the orginal prefetch pairs */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+ /* Enqueue parent nodes */
+ if(pSetHasChanged) {
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This function processes the prefetch set of a FlatSetFieldNode
+ * It generates a new prefetch set after comparision with its children
+ * It compares the old prefetch set with this new prefetch set and enqueues the parents
+ * of the current node if change occurs and then updates the global flatnode hash table
+ * */
+ private void processFlatSetFieldNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+ FlatSetFieldNode currfsfn = (FlatSetFieldNode) curr;
+ PrefetchPair childpp = null;
+ PairMap pm = new PairMap();
+
+ Enumeration ecld = child_prefetch_set_copy.keys();
+ while (ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ if(childpp.base == currfsfn.getDst()) {
+ int size = childpp.desc.size();
+ if(size >=2) {
+ if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
+ ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
+ for(int i = 0;i<(childpp.desc.size()-1); i++) {
+ newdesc.add(i,childpp.desc.get(i+1));
+ }
+ PrefetchPair newpp = new PrefetchPair(currfsfn.getSrc(), newdesc);
+ Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
+ tocompare.put(newpp, newprob);
+ pm.addPair(childpp, newpp);
+ child_prefetch_set_copy.remove(childpp);
+ /* Check for independence of prefetch pairs in newly generated prefetch pair
+ * to compute new probability */
+ if(child_prefetch_set_copy.containsKey(newpp)) {
+ newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
+ if(newprob < ANALYSIS_THRESHOLD_PROB) {
+ tocompare.remove(newpp);
+ } else {
+ tocompare.put(newpp, newprob);
+ pm.addPair(newpp, newpp);
+ }
+ child_prefetch_set_copy.remove(newpp);
+ }
+ }
+ } else if(size==1) {
+ if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
+ child_prefetch_set_copy.remove(childpp);
+ }
+ } else {
+ continue;
+ }
+ }
+ }
+
+ /* Merge child prefetch pairs */
+ ecld = child_prefetch_set_copy.keys();
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+
+ /* Compare with the orginal prefetch pairs */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+ /* Enqueue parent nodes */
+ if(pSetHasChanged) {
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This function processes the prefetch set of a FlatSeElementNode
+ * It generates a new prefetch set after comparision with its children
+ * It compares the old prefetch set with this new prefetch set and enqueues the parents
+ * of the current node if change occurs and then updates the global flatnode hash table
+ * */
+ private void processFlatSetElementNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+ PrefetchPair childpp = null;
+ FlatSetElementNode currfsen = (FlatSetElementNode) curr;
+ PairMap pm = new PairMap();
+
+ Enumeration ecld = child_prefetch_set_copy.keys();
+ while (ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ if (childpp.base == currfsen.getDst()){
+ int sizedesc = childpp.desc.size();
+ if((childpp.getDescAt(0) instanceof IndexDescriptor)) {
+ int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size();
+ if(sizetempdesc == 1) {
+ if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) {
+ ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
+ for(int i = 0;i<(childpp.desc.size()-1); i++) {
+ newdesc.add(i,childpp.desc.get(i+1));
+ }
+ PrefetchPair newpp = new PrefetchPair(currfsen.getSrc(), newdesc);
+ Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
+ tocompare.put(newpp, newprob);
+ pm.addPair(childpp, newpp);
+ child_prefetch_set_copy.remove(childpp);
+ /* Check for independence of prefetch pairs to compute new probability */
+ if(child_prefetch_set_copy.containsKey(newpp)) {
+ newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
+ if(newprob < ANALYSIS_THRESHOLD_PROB) {
+ tocompare.remove(newpp);
+ } else {
+ tocompare.put(newpp, newprob);
+ pm.addPair(newpp, newpp);
+ }
+ child_prefetch_set_copy.remove(newpp);
+ }
+ } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1))
+ child_prefetch_set_copy.remove(childpp);
+ } else {
+ continue;
+ }
+ }
+ }
+ }
+ /* Merge child prefetch pairs */
+ ecld = child_prefetch_set_copy.keys();
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+
+ /* Compare with the orginal prefetch pairs */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+ /* Enqueue parent nodes */
+ if(pSetHasChanged) {
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This function applies rules and does analysis for a FlatOpNode
+ * And updates the global prefetch hashtable
+ * */
+ private void processFlatOpNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ int index;
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+ FlatOpNode currfopn = (FlatOpNode) curr;
+ Enumeration ecld = null;
+ PrefetchPair childpp = null;
+ PairMap pm = new PairMap();
+
+ if(currfopn.getOp().getOp()== Operation.ASSIGN) {
+ ecld = child_prefetch_set_copy.keys();
+ while (ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
+
+ /* For cases like x=y followed by childnode t=x[i].z or t=x.g*/
+ if(childpp.base == currfopn.getDest()) {
+ ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
+ newdesc.addAll(childpp.desc);
+ PrefetchPair newpp = new PrefetchPair(currfopn.getLeft(), newdesc);
+ Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
+ tocompare.put(newpp, newprob);
+ pm.addPair(childpp, newpp);
+ child_prefetch_set_copy.remove(childpp);
+ /* Check for independence of prefetch pairs to compute new probability */
+ if(child_prefetch_set_copy.containsKey(newpp)) {
+ newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
+ if(newprob < ANALYSIS_THRESHOLD_PROB) {
+ tocompare.remove(newpp);
+ } else {
+ tocompare.put(newpp, newprob);
+ pm.addPair(newpp, newpp);
+ }
+ child_prefetch_set_copy.remove(newpp);
+ }
+ /* For cases like x=y followed by t = r[i].x or t =r[x].p or t = r[p+x].q*/
+ } else if(isTempDescFound(copyofchildpp, currfopn.getDest())) {
+ ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
+ newdesc.addAll((ArrayList<Descriptor>)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft()));
+ PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
+ Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
+ tocompare.put(newpp, newprob);
+ pm.addPair(childpp, newpp);
+ child_prefetch_set_copy.remove(childpp);
+ /* Check for independence of prefetch pairs to compute new probability*/
+ if(child_prefetch_set_copy.containsKey(newpp)) {
+ newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
+ if(newprob < ANALYSIS_THRESHOLD_PROB) {
+ tocompare.remove(newpp);
+ } else {
+ tocompare.put(newpp, newprob);
+ pm.addPair(newpp, newpp);
+ }
+ child_prefetch_set_copy.remove(newpp);
+ }
+ }else {
+ continue;
+ }
+ }
+ //case i = i+z followed by a[i].x
+ } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) {
+ ecld = child_prefetch_set_copy.keys();
+ while (ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
+
+ if(isTempDescFound(copyofchildpp, currfopn.getDest())) {
+ ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
+ newdesc.addAll((ArrayList<Descriptor>)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft(), currfopn.getRight()));
+ PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
+ Float newprob = child_prefetch_set_copy.get(childpp).floatValue();
+ tocompare.put(newpp, newprob);
+ pm.addPair(childpp, newpp);
+ child_prefetch_set_copy.remove(childpp);
+ /* Check for independence of prefetch pairs to compute new probability*/
+ if(child_prefetch_set_copy.containsKey(newpp)) {
+ newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
+ if(newprob < ANALYSIS_THRESHOLD_PROB) {
+ tocompare.remove(newpp);
+ } else {
+ tocompare.put(newpp, newprob);
+ pm.addPair(newpp, newpp);
+ }
+ child_prefetch_set_copy.remove(newpp);
+ }
+ }else {
+ continue;
+ }
+ }
+ } else {
+ //FIXME Is not taken care of for cases like x = -y followed by a[x].i
+ }
+
+ /* Merge child prefetch pairs */
+ ecld = child_prefetch_set_copy.keys();
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+
+ /* Compare with the orginal prefetch pairs */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+ /* Enqueue parent nodes */
+ if(pSetHasChanged) {
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This function processes a FlatLiteralNode where cases such as
+ * for cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r
+ * are handled */
+ private void processFlatLiteralNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+ FlatLiteralNode currfln = (FlatLiteralNode) curr;
+ Enumeration ecld = null;
+ PrefetchPair childpp = null;
+ PairMap pm = new PairMap();
+
+ if(currfln.getType().isIntegerType()) {
+ ecld = child_prefetch_set_copy.keys();
+ while (ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
+ /* For cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r*/
+ if(isTempDescFound(copyofchildpp,currfln.getDst())) {
+ ArrayList<Descriptor> copychilddesc = (ArrayList<Descriptor>) copyofchildpp.getDesc();
+ int sizetempdesc = copychilddesc.size();
+ ListIterator it = copychilddesc.listIterator();
+ for(;it.hasNext();) {
+ Object o = it.next();
+ if(o instanceof IndexDescriptor) {
+ ArrayList<TempDescriptor> td = (ArrayList<TempDescriptor>)((IndexDescriptor)o).tddesc;
+ int sizetddesc = td.size();
+ if(td.contains(currfln.getDst())) {
+ int index = td.indexOf(currfln.getDst());
+ td.remove(index);
+ ((IndexDescriptor)o).offset += (Integer)currfln.getValue();
+ }
+ }
+ }
+ ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
+ newdesc.addAll(copychilddesc);
+ PrefetchPair newpp = new PrefetchPair(childpp.base, newdesc);
+ Float newprob = (child_prefetch_set_copy.get(childpp)).floatValue();
+ tocompare.put(newpp, newprob);
+ pm.addPair(childpp, newpp);
+ child_prefetch_set_copy.remove(childpp);
+ /* Check for independence of prefetch pairs to compute new probability */
+ if(child_prefetch_set_copy.containsKey(newpp)) {
+ newprob = (float)(1.0 - ((1.0 - child_prefetch_set_copy.get(newpp).floatValue()) * (1.0 - tocompare.get(newpp).floatValue())));
+ if(newprob < ANALYSIS_THRESHOLD_PROB) {
+ tocompare.remove(newpp);
+ } else {
+ tocompare.put(newpp, newprob);
+ pm.addPair(newpp, newpp);
+ }
+ child_prefetch_set_copy.remove(newpp);
+ }
+ }
+ }
+ }
+
+ /* Merge child prefetch pairs */
+ ecld = child_prefetch_set_copy.keys();
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+
+ /* Compare with the orginal prefetch pairs */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+ /* Enqueue parent nodes */
+ if(pSetHasChanged) {
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This function processes a FlatMethod where the method propagates
+ * the entire prefetch set of its child node */
+ private void processFlatMethod(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+ FlatMethod currfm = (FlatMethod) curr;
+ Enumeration ecld = null;
+ PrefetchPair childpp = null;
+ PairMap pm = new PairMap();
+
+ /* Merge child prefetch pairs */
+ ecld = child_prefetch_set_copy.keys();
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+
+ /* Compare with the orginal prefetch pairs */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+ /* Enqueue parent nodes */
+ if(pSetHasChanged) {
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This Function processes the FlatCalls
+ * It currently drops the propagation of those prefetchpairs that are passed as
+ * arguments in the FlatCall
+ */
+ private void processFlatCall(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+ FlatCall currfcn = (FlatCall) curr;
+ PairMap pm = new PairMap();
+ Enumeration ecld = null;
+ PrefetchPair childpp = null;
+
+ ecld = child_prefetch_set_copy.keys();
+ while(ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
+ if(currfcn.getReturnTemp() != childpp.base) {
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ } else {
+ child_prefetch_set_copy.remove(childpp);
+ }
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+
+ /* Compare with the orginal prefetch pairs */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+ /* Enqueue parent nodes */
+ if(pSetHasChanged) {
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This function handles the processes the FlatNode of type FlatCondBranch
+ * It combines prefetches of both child elements and create a new hash table called
+ * branch_prefetch_set to contains the entries of both its children
+ */
+ private void processFlatCondBranch(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy, int index,
+ Hashtable<PrefetchPair,Float> branch_prefetch_set, Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();//temporary hash table
+ FlatCondBranch currfcb = (FlatCondBranch) curr;
+ Float newprob = new Float((float)0.0);
+ PairMap pm = new PairMap();
+ PrefetchPair childpp = null;
+ PrefetchPair pp = null;
+ Enumeration ecld = null;
+
+ ecld = child_prefetch_set_copy.keys();
+ while (ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ /* True Edge */
+ if(index == 0) {
+ newprob = child_prefetch_set_copy.get(childpp).floatValue() * BRANCH_TRUE_EDGE_PROB;
+ if(newprob >= ANALYSIS_THRESHOLD_PROB) {
+ tocompare.put(childpp, newprob);
+ pm.addPair(childpp, childpp);
+ }
+ child_prefetch_set_copy.remove(childpp);
+ } else if(index == 1) { /* False Edge */
+ newprob = child_prefetch_set_copy.get(childpp).floatValue() * BRANCH_FALSE_EDGE_PROB;
+ if(newprob >= ANALYSIS_THRESHOLD_PROB) {
+ tocompare.put(childpp, newprob);
+ pm.addPair(childpp, childpp);
+ }
+ child_prefetch_set_copy.remove(childpp);
+ } else {
+ System.out.println("DEBUG-> No more children of the FlatCondBranchNode present");
+ }
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(index), parentpmap);
+
+ /* Update branch_prefetch_set (global hash table) to combine all prefetch pairs from childnodes of the
+ * cond branch that is currently stored in the tocompare hash table */
+ if(!tocompare.isEmpty()) {
+ if(index == 0) {
+ branch_prefetch_set.putAll(tocompare);
+ }else if(index == 1) {
+ if(branch_prefetch_set.isEmpty()) {
+ branch_prefetch_set.putAll(tocompare);
+ } else {
+ Enumeration e = tocompare.keys();
+ while(e.hasMoreElements()) {
+ pp = (PrefetchPair) e.nextElement();
+ if(branch_prefetch_set.containsKey(pp)) {
+ newprob = (float)(branch_prefetch_set.get(pp).floatValue() + tocompare.get(pp).floatValue());
+ if(newprob < ANALYSIS_THRESHOLD_PROB) {
+ branch_prefetch_set.remove(pp);
+ } else {
+ branch_prefetch_set.put(pp, newprob);
+ }
+ tocompare.remove(pp);
+ }
+ }
+ e = tocompare.keys();
+ while(e.hasMoreElements()) {
+ pp = (PrefetchPair) e.nextElement();
+ branch_prefetch_set.put(pp,tocompare.get(pp));
+ tocompare.remove(pp);
+ }
+ }
+ } else {
+ System.out.println("DEBUG-> No more children of the FlatCondBranchNode present");
+ }
+ }
+
+ /* Compare prefetch sets and enqueue parent nodes: Only possible after combining prefetch pairs of both child nodes
+ * into branch_prefetch_set hashtable*/
+ if(index == 1) {
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), branch_prefetch_set);
+ if(pSetHasChanged) {
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,branch_prefetch_set);
+ }
+ }
+ }
+
+ /** If FlatNode is not concerned with the prefetch set of its Child then propagate
+ * prefetches up the FlatNode*/
+ private void processDefaultCase(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ PairMap pm = new PairMap();
+ Enumeration e = null;
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+
+ /* Propagate all child nodes */
+ for(e = child_prefetch_set_copy.keys(); e.hasMoreElements();) {
+ PrefetchPair childpp = (PrefetchPair) e.nextElement();
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ }
+
+ /* Check case for nodes with no children (e.g return null) and create prefetch mappings for child nodes*/
+ if(curr.numNext() != 0) {
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+ }
+
+ /* Compare with old Prefetch sets */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+ if(pSetHasChanged){
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This functions processes for FlatNewNode
+ * for e.g x = NEW(foo) followed by childnode with prefetch set x.f
+ * then drop the prefetches beyond this FlatNewNode */
+ private void processFlatNewNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
+ Hashtable<FlatNode, PairMap> parentpmap) {
+ boolean pSetHasChanged = false;
+ Hashtable<PrefetchPair, Float> tocompare = new Hashtable<PrefetchPair, Float>();
+ FlatNew currfnn = (FlatNew) curr;
+ Float newprob = new Float((float)0.0);
+ PairMap pm = new PairMap();
+ PrefetchPair childpp = null;
+ Enumeration ecld = null;
+
+ ecld = child_prefetch_set_copy.keys();
+ while (ecld.hasMoreElements()) {
+ childpp = (PrefetchPair) ecld.nextElement();
+ if(childpp.base == currfnn.getDst()){
+ child_prefetch_set_copy.remove(childpp);
+ } else {
+ tocompare.put(childpp, child_prefetch_set_copy.get(childpp));
+ pm.addPair(childpp, childpp);
+ child_prefetch_set_copy.remove(childpp);
+ }
+ }
+
+ /* Create prefetch mappings for child nodes */
+ if(!pm.isEmpty()) {
+ parentpmap.put(curr, pm);
+ }
+ pmap_hash.put(curr.getNext(0), parentpmap);
+
+ /* Compare with the old prefetch set */
+ pSetHasChanged = comparePrefetchSets(prefetch_hash.get(curr), tocompare);
+
+ /* Enqueue parent nodes */
+ if(pSetHasChanged) {
+ for(int i=0; i<curr.numPrev(); i++) {
+ tovisit.add(curr.getPrev(i));
+ }
+ /* Overwrite the new prefetch set to the global hash table */
+ prefetch_hash.put(curr,tocompare);
+ }
+ }
+
+ /** This function prints the Prefetch pairs of a given flatnode */
+ private void printPrefetchPairs(FlatNode fn) {
+ if(prefetch_hash.containsKey(fn)) {
+ System.out.print("Prefetch" + "(");
+ Hashtable<PrefetchPair, Float> currhash = (Hashtable) prefetch_hash.get(fn);
+ for(Enumeration pphash= currhash.keys(); pphash.hasMoreElements();) {
+ PrefetchPair pp = (PrefetchPair) pphash.nextElement();
+ System.out.print(pp.toString() + ", ");
+ }
+ System.out.println(")");
+ } else {
+ System.out.println("Flatnode is currently not present in the global hash: Prefetch Set is Empty");
+ }
+ }
+
+ private void doInsPrefetchAnalysis(FlatMethod fm) {
+ HashSet<PrefetchPair> pset1_init = new HashSet<PrefetchPair>();
+ LinkedList<FlatNode> newtovisit = new LinkedList<FlatNode>();
+ newvisited = new LinkedList<FlatNode>();
+
+ newtovisit.addLast((FlatNode)fm);
+ while(!newtovisit.isEmpty()) {
+ FlatNode fn = (FlatNode) newtovisit.iterator().next();
+ newtovisit.remove(0);
+ pset1_hash.put(fn, pset1_init);
+ newvisited.addLast(fn);
+ for(int i=0; i<fn.numNext(); i++) {
+ FlatNode nn = fn.getNext(i);
+ if(!newtovisit.contains(nn) && !newvisited.contains(nn)){
+ newtovisit.addLast(nn);
+ }
+ }
+ }
+
+ while(!newvisited.isEmpty()) {
+ applyPrefetchInsertRules((FlatNode) newvisited.getFirst());
+ newvisited.remove(0);
+ }
+ }
+
+
+
+ /**This function compares all the prefetch pairs in a Prefetch set hashtable and
+ * returns: true if something has changed in the new Prefetch set else
+ * returns: false
+ */
+ private boolean comparePSet1(HashSet<PrefetchPair> oldPSet, HashSet<PrefetchPair>newPSet) {
+ boolean hasChanged = false;
+
+ if(oldPSet.size() != newPSet.size()) {
+ return true;
+ } else {
+ for(Iterator it = newPSet.iterator();it.hasNext();) {
+ if(!oldPSet.contains((PrefetchPair)it.next())) {
+ return true;
+ }
+ }
+ }
+ return hasChanged;
+ }
+
+ private void applyPrefetchInsertRules(FlatNode fn) {
+ HashSet<PrefetchPair> pset1 = new HashSet<PrefetchPair>();
+ HashSet<PrefetchPair> pset2 = new HashSet<PrefetchPair>();
+ HashSet<PrefetchPair> newpset = new HashSet<PrefetchPair>();
+ Hashtable<PrefetchPair, Float> prefetchset = new Hashtable<PrefetchPair, Float>();
+ boolean ppairIsPresent = false;
+ boolean mapIsPresent = true;
+ boolean pprobIsGreater = false;
+ boolean mapprobIsLess = false;
+ boolean probIsLess = false;
+ boolean pSet1HasChanged = false;
+ Enumeration e = null;
+ /* Create pset1 */
+ if(fn.kind() == FKind.FlatMethod) {
+ if(prefetch_hash.containsKey(fn)) {
+ prefetchset = prefetch_hash.get(fn);
+ e = prefetchset.keys();
+ while(e.hasMoreElements()) {
+ PrefetchPair pp = (PrefetchPair) e.nextElement();
+ /* Apply initial rule */
+ if(((float)prefetchset.get(pp).floatValue()) > PREFETCH_THRESHOLD_PROB) {
+ pset1.add(pp);
+ }
+ }
+ /* Enqueue child node is Pset1 has changed */
+ pSet1HasChanged = comparePSet1(pset1_hash.get(fn), pset1);
+ if(pSet1HasChanged) {
+ for(int j=0; j<fn.numNext(); j++) {
+ FlatNode nn = fn.getNext(j);
+ newvisited.addLast((FlatNode)nn);
+ }
+ }
+ pset1_hash.put(fn, pset1);
+ if(pset1.size() > 0) {
+ newprefetchset.put(fn, pset1);
+ }
+ }
+ } else {
+ if(prefetch_hash.containsKey(fn)) {
+ prefetchset = prefetch_hash.get(fn);
+ for(Enumeration epset = prefetchset.keys(); epset.hasMoreElements();) {
+ PrefetchPair pp = (PrefetchPair) epset.nextElement();
+ /* Create pset2 */
+ Hashtable<FlatNode, PairMap> ppairmaphash = new Hashtable<FlatNode, PairMap>();
+ ppairmaphash = pmap_hash.get(fn);
+ if(!ppairmaphash.isEmpty()) {
+ e = ppairmaphash.keys();
+ while(e.hasMoreElements()) {
+ FlatNode parentnode = (FlatNode) e.nextElement();
+ PairMap pm = (PairMap) ppairmaphash.get(parentnode);
+ if(pset1_hash.containsKey(parentnode)) {
+ Set pset = pset1_hash.get(parentnode);
+ if(!pset.isEmpty()) {
+ if(ppairIsPresent = (pset.contains((PrefetchPair) pm.getPair(pp)))) {
+ mapIsPresent = ppairIsPresent && mapIsPresent;
+ }
+ } else {
+ mapIsPresent = false;
+ }
+ }
+ }
+ if(mapIsPresent) {
+ pset2.add(pp);
+ }
+ }
+
+ /* Create newprefetchset */
+ if(pprobIsGreater = (prefetchset.get(pp).floatValue() > PREFETCH_THRESHOLD_PROB)) {
+ ppairmaphash = pmap_hash.get(fn);
+ if(!ppairmaphash.isEmpty()) {
+ e = ppairmaphash.keys();
+ while(e.hasMoreElements()) {
+ FlatNode parentnode = (FlatNode) e.nextElement();
+ PairMap pm = (PairMap) ppairmaphash.get(parentnode);
+ PrefetchPair mappedpp = pm.getPair(pp);
+ if(mappedpp != null) {
+ if(prefetch_hash.get(parentnode).containsKey(mappedpp)) {
+ float prob = (float)prefetch_hash.get(parentnode).get(mappedpp).floatValue();
+ if(probIsLess = (prob < PREFETCH_THRESHOLD_PROB))
+ mapprobIsLess = mapprobIsLess || probIsLess;
+ }
+ } else {
+ mapprobIsLess = false;
+ }
+ }
+ } else {
+ mapprobIsLess = true;
+ }
+ }
+ if(pprobIsGreater && mapprobIsLess) {
+ newpset.add(pp);
+ }
+ }
+ }
+ if(!pset2.isEmpty())
+ pset1.addAll(pset2);
+ if(!newpset.isEmpty())
+ pset1.addAll(newpset);
+ /* Enqueue child node if Pset1 has changed */
+ pSet1HasChanged = comparePSet1(pset1_hash.get(fn), pset1);
+ if(pSet1HasChanged) {
+ for(int i=0; i<fn.numNext(); i++) {
+ FlatNode nn = fn.getNext(i);
+ newvisited.addLast((FlatNode)nn);
+ }
+ }
+ pset1_hash.put(fn, pset1);
+ }
+
+ /* To insert prefetch apply rule */
+ HashSet s = null;
+ if(!newpset.isEmpty() && !pset2.isEmpty()) {
+ for(Iterator it = newpset.iterator(); it.hasNext();) {
+ PrefetchPair pp = (PrefetchPair) it.next();
+ if(!pset2.contains(pp)) {
+ s.add(pp);
+ }
+ }
+ }
+ if(s != null) {
+ newprefetchset.put(fn, s);
+ }
+ }
+
+
+ private void addFlatPrefetchNode(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
+ int i;
+ Enumeration e = null;
+ e = newprefetchset.keys();
+ /* This modifies the graph */
+ while(e.hasMoreElements()) {
+ FlatNode fn = (FlatNode) e.nextElement();
+ FlatPrefetchNode fpn = new FlatPrefetchNode();
+ for(i = 0; i< newprefetchset.get(fn).size(); i++) {
+ fpn.insAllpp((HashSet)newprefetchset.get(fn));
+ }
+ if(fn.kind() == FKind.FlatMethod) {
+ FlatNode nn = fn.getNext(0);
+ TempDescriptor tdsrc = new TempDescriptor("a");
+ TempDescriptor tddst = new TempDescriptor("b");
+ TypeDescriptor type = new TypeDescriptor("Hash");
+ FlatNode fpn2 = new FlatNode();
+ FlatNop fpn1 = new FlatNop();
+ FlatCastNode fcn = new FlatCastNode(type,tdsrc,tddst);
+ fn.setNext(0, fcn);
+ fcn.addNext(nn);
+
+ } else {
+ while(fn.numPrev() > 0) {
+ FlatNode nn = fn.getPrev(0);
+ for(int j = 0; j<nn.numNext(); j++) {
+ if(nn.getNext(j) == fn) {
+ nn.setNext(j, fpn);
+ }
+ }
+ }
+ fpn.addNext(fn);
+ }
+ }
+ }
+
+ private void doAnalysis() {
+ Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
+ while(classit.hasNext()) {
+ ClassDescriptor cn=(ClassDescriptor)classit.next();
+ Iterator methodit=cn.getMethods();
+ while(methodit.hasNext()) {
+ /* Classify parameters */
+ MethodDescriptor md=(MethodDescriptor)methodit.next();
+ FlatMethod fm=state.getMethodFlat(md);
+ printMethod(fm);
+ }
+ }
+ }
+
+ private void printMethod(FlatMethod fm) {
+ System.out.println(fm.getMethod()+" {");
+ HashSet tovisit=new HashSet();
+ HashSet visited=new HashSet();
+ int labelindex=0;
+ Hashtable nodetolabel=new Hashtable();
+ tovisit.add(fm);
+ FlatNode current_node=null;
+ //Assign labels 1st
+ //Node needs a label if it is
+ while(!tovisit.isEmpty()) {
+ FlatNode fn=(FlatNode)tovisit.iterator().next();
+ tovisit.remove(fn);
+ visited.add(fn);
+
+ for(int i=0;i<fn.numNext();i++) {
+ FlatNode nn=fn.getNext(i);
+ if(i>0) {
+ //1) Edge >1 of node
+ nodetolabel.put(nn,new Integer(labelindex++));
+ }
+ if (!visited.contains(nn)&&!tovisit.contains(nn)) {
+ tovisit.add(nn);
+ } else {
+ //2) Join point
+ nodetolabel.put(nn,new Integer(labelindex++));
+ }
+ }
+ }
+ //Do the actual printing
+ tovisit=new HashSet();
+ visited=new HashSet();
+ tovisit.add(fm);
+ while(current_node!=null||!tovisit.isEmpty()) {
+ if (current_node==null) {
+ current_node=(FlatNode)tovisit.iterator().next();
+ tovisit.remove(current_node);
+ }
+ visited.add(current_node);
+ if (nodetolabel.containsKey(current_node))
+ System.out.println("L"+nodetolabel.get(current_node)+":");
+ if (current_node.numNext()==0) {
+ System.out.println(" "+current_node.toString());
+ current_node=null;
+ } else if(current_node.numNext()==1) {
+ System.out.println(" "+current_node.toString());
+ FlatNode nextnode=current_node.getNext(0);
+ if (visited.contains(nextnode)) {
+ System.out.println("goto L"+nodetolabel.get(nextnode));
+ current_node=null;
+ } else
+ current_node=nextnode;
+ } else if (current_node.numNext()==2) {
+ /* Branch */
+ System.out.println(" "+((FlatCondBranch)current_node).toString("L"+nodetolabel.get(current_node.getNext(1))));
+ if (!visited.contains(current_node.getNext(1)))
+ tovisit.add(current_node.getNext(1));
+ if (visited.contains(current_node.getNext(0))) {
+ System.out.println("goto L"+nodetolabel.get(current_node.getNext(0)));
+ current_node=null;
+ } else
+ current_node=current_node.getNext(0);
+ } else throw new Error();
+ }
+ System.out.println("}");
+ }
}