1 pnkfelix 1.1.2.1 // CachingLiveTemps.java, created Sat Jul 29 15:22:48 2000 by pnkfelix 2 cananian 1.1.2.4 // Copyright (C) 2000 Felix S. Klock II <pnkfelix@mit.edu> 3 pnkfelix 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 pnkfelix 1.1.2.1 package harpoon.Analysis.DataFlow; 5 pnkfelix 1.1.2.1 6 pnkfelix 1.1.2.1 import harpoon.Analysis.BasicBlock; 7 pnkfelix 1.1.2.1 import harpoon.IR.Properties.UseDefer; 8 pnkfelix 1.1.2.1 import harpoon.ClassFile.HCode; 9 pnkfelix 1.1.2.1 import harpoon.ClassFile.HCodeElement; 10 pnkfelix 1.1.2.1 import harpoon.Temp.Temp; 11 pnkfelix 1.1.2.1 import harpoon.Util.CloneableIterator; 12 pnkfelix 1.1.2.1 import harpoon.Util.Util; 13 cananian 1.4 import net.cscott.jutil.BitSetFactory; 14 cananian 1.4 import net.cscott.jutil.ReverseIterator; 15 cananian 1.4 import net.cscott.jutil.SetFactory; 16 pnkfelix 1.1.2.1 17 pnkfelix 1.1.2.1 import java.util.Set; 18 pnkfelix 1.1.2.1 import java.util.Map; 19 pnkfelix 1.1.2.1 import java.util.HashSet; 20 pnkfelix 1.1.2.1 import java.util.HashMap; 21 pnkfelix 1.1.2.1 import java.util.Iterator; 22 pnkfelix 1.1.2.1 23 pnkfelix 1.1.2.1 /** 24 pnkfelix 1.1.2.1 * <code>CachingLiveTemps</code> is an extension of 25 pnkfelix 1.1.2.1 * <code>LiveTemps</code> that keeps a cache of the recent results 26 pnkfelix 1.1.2.1 * that it calculated. The cache keeps the last few basic blocks 27 pnkfelix 1.1.2.1 * accessed, along with the results of liveness analysis on all of the 28 pnkfelix 1.1.2.1 * statements in the basic blocks. 29 pnkfelix 1.1.2.1 * 30 cananian 1.1.2.4 * @author Felix S. Klock II <pnkfelix@mit.edu> 31 cananian 1.4 * @version $Id: CachingLiveTemps.java,v 1.4 2004/02/08 01:51:05 cananian Exp $ 32 pnkfelix 1.1.2.1 */ 33 pnkfelix 1.1.2.1 public class CachingLiveTemps extends LiveTemps { 34 pnkfelix 1.1.2.3 35 pnkfelix 1.1.2.3 public static LiveTemps make(HCode code, Set liveOnExit) { 36 pnkfelix 1.1.2.3 BasicBlock.Factory bbf = new BasicBlock.Factory(code); 37 pnkfelix 1.1.2.3 LiveTemps lt = new CachingLiveTemps(bbf, liveOnExit); 38 pnkfelix 1.1.2.3 Solver.worklistSolve 39 pnkfelix 1.1.2.3 // (bbFact.preorderBlocksIter(), 40 cananian 1.3 (new ReverseIterator(bbf.postorderBlocksIter()), 41 pnkfelix 1.1.2.3 lt); 42 pnkfelix 1.1.2.3 return lt; 43 pnkfelix 1.1.2.3 } 44 pnkfelix 1.1.2.1 45 pnkfelix 1.1.2.1 /** Creates a <code>CachingLiveTemps</code>. */ 46 pnkfelix 1.1.2.1 public CachingLiveTemps(BasicBlock.Factory bbf, Set liveOnExit) { 47 pnkfelix 1.1.2.1 super(bbf, liveOnExit); 48 pnkfelix 1.1.2.1 } 49 pnkfelix 1.1.2.1 50 pnkfelix 1.1.2.1 public CachingLiveTemps(BasicBlock.Factory bbf, Set liveOnExit, 51 pnkfelix 1.1.2.1 UseDefer ud) { 52 pnkfelix 1.1.2.1 super(bbf, liveOnExit, ud); 53 pnkfelix 1.1.2.1 } 54 pnkfelix 1.1.2.1 55 pnkfelix 1.1.2.1 public CachingLiveTemps(BasicBlock.Factory bbf, Set liveOnExit, 56 pnkfelix 1.1.2.1 SetFactory tempSetFact, UseDefer ud) { 57 pnkfelix 1.1.2.1 super(bbf, liveOnExit, tempSetFact, ud); 58 pnkfelix 1.1.2.1 } 59 pnkfelix 1.1.2.1 60 pnkfelix 1.1.2.1 public String cachePerformance() { 61 pnkfelix 1.1.2.1 return "HITS: "+hits+" MISSES: "+misses+" SETUP: "+setup; 62 pnkfelix 1.1.2.1 } 63 pnkfelix 1.1.2.1 64 pnkfelix 1.1.2.1 private int hits = 0, misses = 0, setup = 0; 65 pnkfelix 1.1.2.1 66 pnkfelix 1.1.2.1 67 pnkfelix 1.1.2.3 private static final int CACHE_SIZE = 20; 68 pnkfelix 1.1.2.1 private int nextPt = 0; 69 pnkfelix 1.1.2.1 private BasicBlock[] lastBBs = new BasicBlock[CACHE_SIZE]; 70 pnkfelix 1.1.2.1 // a cache of results for the getLiveAfter(HCodeElement) method 71 pnkfelix 1.1.2.1 // each index corresponds to the basic block in lastBBs 72 pnkfelix 1.1.2.1 private HashMap hce2liveAfters[] = new HashMap[CACHE_SIZE]; 73 pnkfelix 1.1.2.1 74 pnkfelix 1.1.2.1 private HashSet blocksSeenBefore = new HashSet(); 75 pnkfelix 1.1.2.1 76 pnkfelix 1.1.2.1 private HashMap addToCache(BasicBlock bb) { 77 pnkfelix 1.1.2.1 if (blocksSeenBefore.contains(bb)) { 78 pnkfelix 1.1.2.1 misses++; 79 pnkfelix 1.1.2.1 } else { 80 pnkfelix 1.1.2.1 setup++; 81 pnkfelix 1.1.2.1 blocksSeenBefore.add(bb); 82 pnkfelix 1.1.2.1 } 83 pnkfelix 1.1.2.1 84 pnkfelix 1.1.2.1 if (lastBBs[ nextPt ] != null) { 85 pnkfelix 1.1.2.1 hce2liveAfters[ nextPt ].clear(); 86 pnkfelix 1.1.2.1 } else { 87 pnkfelix 1.1.2.1 hce2liveAfters[ nextPt ] = new HashMap(bb.statements().size()); 88 pnkfelix 1.1.2.1 } 89 pnkfelix 1.1.2.1 lastBBs[ nextPt ] = bb; 90 pnkfelix 1.1.2.1 final HashMap hce2liveAfter = hce2liveAfters[ nextPt ]; 91 pnkfelix 1.1.2.1 nextPt = (nextPt == lastBBs.length-1)?0:nextPt+1; 92 pnkfelix 1.1.2.1 93 pnkfelix 1.1.2.1 94 pnkfelix 1.1.2.1 Set liveAfter = 95 pnkfelix 1.1.2.1 mySetFactory.makeSet(this.getLiveOnExit(bb)); 96 pnkfelix 1.1.2.1 97 pnkfelix 1.1.2.1 // Starting from the last element in hce's basic block, 98 pnkfelix 1.1.2.1 // traverse the block in reverse order, until hce is 99 pnkfelix 1.1.2.1 // reached. Each step updates the liveness information. 100 pnkfelix 1.1.2.1 101 pnkfelix 1.1.2.1 java.util.List stms = bb.statements(); 102 pnkfelix 1.1.2.1 // System.out.print(" M"+stms.size()); 103 pnkfelix 1.1.2.1 java.util.ListIterator iter = stms.listIterator(stms.size()); 104 pnkfelix 1.1.2.1 105 pnkfelix 1.1.2.1 while(iter.hasPrevious()) { 106 pnkfelix 1.1.2.1 HCodeElement current = (HCodeElement) iter.previous(); 107 pnkfelix 1.1.2.1 108 pnkfelix 1.1.2.1 // System.out.println("doing live after for "+current); 109 pnkfelix 1.1.2.1 110 pnkfelix 1.1.2.1 hce2liveAfter.put(current, mySetFactory.makeSet(liveAfter)); 111 pnkfelix 1.1.2.1 112 pnkfelix 1.1.2.1 // update set for before 'current' 113 pnkfelix 1.1.2.1 liveAfter.removeAll(ud.defC(current)); 114 pnkfelix 1.1.2.1 liveAfter.addAll(ud.useC(current)); 115 pnkfelix 1.1.2.1 } 116 pnkfelix 1.1.2.1 117 pnkfelix 1.1.2.1 return hce2liveAfter; 118 pnkfelix 1.1.2.1 } 119 pnkfelix 1.1.2.1 120 pnkfelix 1.1.2.1 public Set getLiveAfter(HCodeElement hce) { 121 pnkfelix 1.1.2.1 BasicBlock bb = bbFact.getBlock(hce); 122 pnkfelix 1.1.2.1 123 pnkfelix 1.1.2.1 for(int i=0; i < lastBBs.length; i++) { 124 pnkfelix 1.1.2.1 if (lastBBs[i] == bb) { 125 pnkfelix 1.1.2.1 hits++; 126 pnkfelix 1.1.2.1 return (Set) hce2liveAfters[i].get(hce); 127 pnkfelix 1.1.2.1 } 128 pnkfelix 1.1.2.1 } 129 pnkfelix 1.1.2.1 130 pnkfelix 1.1.2.1 return (Set) addToCache( bb ).get(hce); 131 pnkfelix 1.1.2.1 } 132 cananian 1.2 }