--- /dev/null
+package Analysis.Prefetch;
+
+import java.util.*;
+import IR.SymbolTable;
+import IR.State;
+import IR.TypeUtil;
+import IR.MethodDescriptor;
+import IR.Flat.*;
+import IR.*;
+import IR.ClassDescriptor;
+
+
+public class LoopExit {
+ State state;
+ Hashtable<MethodDescriptor, Set<FlatCondBranch>> results;
+
+ public LoopExit(State state) {
+ this.state=state;
+ this.results=new Hashtable<MethodDescriptor, Set<FlatCondBranch>>();
+ }
+
+ public Set<FlatCondBranch> getLoopBranches(MethodDescriptor md) {
+ if (!results.containsKey(md))
+ doAnalysis(md);
+ return results.get(md);
+ }
+
+ public boolean isLoopingBranch(MethodDescriptor md, FlatCondBranch fcb) {
+ return getLoopBranches(md).contains(fcb);
+ }
+
+ private void doAnalysis(MethodDescriptor md) {
+ FlatMethod fm=state.getMethodFlat(md);
+ HashSet<FlatNode> nodeset=new HashSet<FlatNode>();
+ nodeset.addAll(fm.getNodeSet());
+ Hashtable<FlatNode, Set<FlatCondBranch>> table=new Hashtable<FlatNode, Set<FlatCondBranch>>();
+
+ HashSet<FlatCondBranch> loopbranchset=new HashSet<FlatCondBranch>();
+ HashSet<FlatCondBranch> exitset=new HashSet<FlatCondBranch>();
+
+ while(!nodeset.isEmpty()) {
+ FlatNode fn=nodeset.iterator().next();
+ if (fn.kind()==FKind.FlatCondBranch&&((FlatCondBranch)fn).isLoopBranch()) {
+ FlatCondBranch fcb=(FlatCondBranch)fn;
+ loopbranchset.add(fcb);
+ //True edge
+ propagateset(nodeset, table, fcb, fcb.getNext(0), fcb);
+ //False edge
+ propagateset(nodeset, table, fcb, fcb.getNext(1), null);
+ loopbranchset.add(fcb);
+ } else if (fn.kind()==FKind.FlatReturnNode) {
+ exitset.addAll(table.get(fn));
+ } else {
+ for(int i=0;i<fn.numNext();i++)
+ propagateset(nodeset, table, fn, fn.getNext(i), null);
+ }
+ }
+ loopbranchset.removeAll(exitset);
+ results.put(md, loopbranchset);
+ }
+
+ void propagateset(Set<FlatNode> tovisit, Hashtable<FlatNode, Set<FlatCondBranch>> table, FlatNode fn, FlatNode fnnext, FlatCondBranch fcb) {
+ boolean enqueuechange=false;
+ if (table.containsKey(fn)) {
+ if (!table.containsKey(fnnext))
+ table.put(fnnext, new HashSet<FlatCondBranch>());
+ if(!table.get(fnnext).containsAll(table.get(fn))) {
+ table.get(fnnext).addAll(table.get(fn));
+ enqueuechange=true;
+ }
+ }
+ if (fcb!=null) {
+ if (!table.containsKey(fnnext))
+ table.put(fnnext, new HashSet<FlatCondBranch>());
+ if (!table.get(fnnext).contains(fcb)) {
+ table.get(fnnext).add(fcb);
+ enqueuechange=true;
+ }
+ }
+ if (enqueuechange)
+ tovisit.add(fnnext);
+ }
+
+}
import IR.ClassDescriptor;
public class PrefetchAnalysis {
- State state;
- CallGraph callgraph;
- TypeUtil typeutil;
- Set<FlatNode> tovisit;
- public Hashtable<FlatNode, Hashtable<PrefetchPair, Double>> prefetch_hash;//holds all flatnodes and corresponding prefetch set
- public Hashtable<FlatNode, Hashtable<FlatNode, PairMap>> pmap_hash;//holds all flatnodes and mappings between child prefetch pair and parent prefetch pair
- public static final double PROB_DIFF = 0.05; //threshold for difference in probabilities during first phase of analysis
- public static final double ANALYSIS_THRESHOLD_PROB = 0.10; //threshold for prefetches to stop propagating during first phase of analysis
- public static final double PREFETCH_THRESHOLD_PROB = 0.30;//threshold for prefetches to stop propagating while applying prefetch rules during second phase of analysis
-
+ State state;
+ CallGraph callgraph;
+ TypeUtil typeutil;
+ LoopExit loop;
+
+ Set<FlatNode> tovisit;
+ public Hashtable<FlatNode, Hashtable<PrefetchPair, Double>> prefetch_hash;//holds all flatnodes and corresponding prefetch set
+ public Hashtable<FlatNode, Hashtable<FlatNode, PairMap>> pmap_hash;//holds all flatnodes and mappings between child prefetch pair and parent prefetch pair
+ public static final double PROB_DIFF = 0.05; //threshold for difference in probabilities during first phase of analysis
+ public static final double ANALYSIS_THRESHOLD_PROB = 0.10; //threshold for prefetches to stop propagating during first phase of analysis
+ public static final double PREFETCH_THRESHOLD_PROB = 0.30;//threshold for prefetches to stop propagating while applying prefetch rules during second phase of analysis
+
public PrefetchAnalysis(State state, CallGraph callgraph, TypeUtil typeutil) {
this.typeutil=typeutil;
this.state=state;
this.callgraph=callgraph;
prefetch_hash = new Hashtable<FlatNode, Hashtable<PrefetchPair,Double>>();
pmap_hash = new Hashtable<FlatNode, Hashtable<FlatNode, PairMap>>();
+ this.loop=new LoopExit(state);
DoPrefetch();
}
tovisit = fm.getNodeSet();
while(!tovisit.isEmpty()) {
FlatNode fn = (FlatNode)tovisit.iterator().next();
- doChildNodeAnalysis(fn);
+ doChildNodeAnalysis(fm.getMethod(),fn);
tovisit.remove(fn);
}
}
* returns true: if the prefetch set has changed since last time the node was analysed
* returns false : otherwise
*/
- private void doChildNodeAnalysis(FlatNode curr) {
+ private void doChildNodeAnalysis(MethodDescriptor md, FlatNode curr) {
if (curr.kind()==FKind.FlatCondBranch) {
- Hashtable<PrefetchPair, Double> child_prefetch_set_copy = new Hashtable<PrefetchPair, Double>();
- Hashtable<PrefetchPair, Double> branch_prefetch_set = new Hashtable<PrefetchPair,Double>();
- for (int i = 0; i < curr.numNext(); i++) {
- FlatNode child_node = curr.getNext(i);
- if (prefetch_hash.containsKey(child_node)) {
- child_prefetch_set_copy = (Hashtable<PrefetchPair,Double>) prefetch_hash.get(child_node).clone();
- }
- processFlatCondBranch(curr, child_prefetch_set_copy, i, branch_prefetch_set);
- }
+ processFlatCondBranch((FlatCondBranch)curr, md);
} else {
Hashtable<PrefetchPair, Double> child_prefetch_set_copy = new Hashtable<PrefetchPair, Double>();
if(curr.numNext() != 0) {
double newprob = newPrefetchSet.get(pp).doubleValue();
if (!oldPrefetchSet.containsKey(pp))
return true;
-
double oldprob = oldPrefetchSet.get(pp).doubleValue();
-
+
if((newprob - oldprob) > PROB_DIFF) {
return true;
}
System.out.println("ERROR:" + pp);
System.out.println(oldprob + " -> "+ newprob);
}
-
}
return false;
}
* 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, Double> child_prefetch_set_copy, int index, Hashtable<PrefetchPair,Double> branch_prefetch_set) {
+ private void processFlatCondBranch(FlatCondBranch fcb, MethodDescriptor md) {
Hashtable<PrefetchPair, Double> tocompare = new Hashtable<PrefetchPair, Double>();//temporary hash table
- FlatCondBranch currfcb = (FlatCondBranch) curr;
- PairMap pm = new PairMap();
- for (Enumeration ecld = child_prefetch_set_copy.keys();ecld.hasMoreElements();) {
- PrefetchPair childpp = (PrefetchPair) ecld.nextElement();
- /* True Edge */
- if(index == 0) {
- Double newprob = child_prefetch_set_copy.get(childpp).doubleValue() * currfcb.getTrueProb();
- tocompare.put(childpp, newprob);
- pm.addPair(childpp, childpp);
- } else if(index == 1) { /* False Edge */
- Double newprob = child_prefetch_set_copy.get(childpp).doubleValue() * currfcb.getFalseProb();
- tocompare.put(childpp, newprob);
- pm.addPair(childpp, childpp);
- } else {
- throw new Error("processFlatCondBranch() has only two child edges");
- }
- }
-
- updatePairMap(curr, pm, index);
-
- /* 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) { /* True Edge */
- branch_prefetch_set.putAll(tocompare);
- }else if(index == 1) { /* False Edge */
- if(branch_prefetch_set.isEmpty()) {
- branch_prefetch_set.putAll(tocompare);
- } else {
- for (Enumeration e = tocompare.keys();e.hasMoreElements();) {
- PrefetchPair pp = (PrefetchPair) e.nextElement();
- if(branch_prefetch_set.containsKey(pp)) {
- Double newprob = (branch_prefetch_set.get(pp).doubleValue() + tocompare.get(pp).doubleValue());
- if(newprob < ANALYSIS_THRESHOLD_PROB) {
- branch_prefetch_set.remove(pp);
- } else {
- branch_prefetch_set.put(pp, newprob);
- }
- } else {
- branch_prefetch_set.put(pp,tocompare.get(pp).doubleValue());
- }
- tocompare.remove(pp);
- }
- }
- } else {
- throw new Error("processFlatCondBranch() has only two child edges");
- }
- }
-
- /* 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) {
- /* Delete the prefetch pairs below threshold */
- for(Iterator it = branch_prefetch_set.keySet().iterator(); it.hasNext();) {
- PrefetchPair pp = (PrefetchPair) it.next();
- if(branch_prefetch_set.get(pp).doubleValue() < ANALYSIS_THRESHOLD_PROB) {
- /* Delete pair mappings of PSChild-> PSParent for these prefetch pairs */
- for(int i = 0; i<curr.numNext(); i++) {
- FlatNode fn = (FlatNode) curr.getNext(i);
- Hashtable<FlatNode, PairMap> pairmap = pmap_hash.get(fn);
- PairMap childpm = pairmap.get(curr);
- if(childpm!=null && childpm.contains(pp)) {
- childpm.removePair(pp);
- }
- }
- branch_prefetch_set.remove(pp);
- it = branch_prefetch_set.keySet().iterator();
- }
+ PairMap truepm = new PairMap();
+ PairMap falsepm = new PairMap();
+ Hashtable<PrefetchPair, Double> truechild=prefetch_hash.get(fcb.getNext(0));
+ Hashtable<PrefetchPair, Double> falsechild=prefetch_hash.get(fcb.getNext(1));
+
+ HashSet<PrefetchPair> allpp=new HashSet<PrefetchPair>();
+ allpp.addAll(truechild.keySet());
+ allpp.addAll(falsechild.keySet());
+
+ for(Iterator<PrefetchPair> ppit=allpp.iterator();ppit.hasNext();) {
+ PrefetchPair pp=ppit.next();
+ double trueprob=0,falseprob=0;
+ if (truechild.containsKey(pp))
+ trueprob=truechild.get(pp).doubleValue();
+ if (falsechild.containsKey(pp))
+ falseprob=falsechild.get(pp).doubleValue();
+
+ double newprob=trueprob*fcb.getTrueProb()+falseprob*fcb.getFalseProb();
+ if (loop.isLoopingBranch(md,fcb)&&
+ newprob<falseprob) {
+ newprob=falseprob;
}
- updatePrefetchSet(curr, branch_prefetch_set);
+ if(newprob < ANALYSIS_THRESHOLD_PROB) //Skip pp that are below threshold
+ continue;
+
+ tocompare.put(pp, newprob);
+ if (truechild.containsKey(pp))
+ truepm.addPair(pp, pp);
+
+ if (falsechild.containsKey(pp))
+ falsepm.addPair(pp, pp);
+
}
+
+ updatePairMap(fcb, truepm, 0);
+ updatePairMap(fcb, falsepm, 1);
+ updatePrefetchSet(fcb, tocompare);
}
/** If FlatNode is not concerned with the prefetch set of its Child then propagate