1 cananian 1.1 // DomFrontier.java, created Mon Sep 14 22:21:38 1998 by cananian 2 cananian 1.6 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.6 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1 package harpoon.Analysis; 5 cananian 1.1 6 cananian 1.6.2.3 import harpoon.ClassFile.HCode; 7 cananian 1.6.2.3 import harpoon.ClassFile.HCodeEdge; 8 cananian 1.6.2.3 import harpoon.ClassFile.HCodeElement; 9 cananian 1.6.2.8 import harpoon.IR.Properties.CFGrapher; 10 cananian 1.6.2.9 import harpoon.Util.ArrayFactory; 11 cananian 1.6.2.8 import harpoon.Util.ArrayIterator; 12 cananian 1.6.2.8 import harpoon.Util.ArraySet; 13 cananian 1.8 import net.cscott.jutil.AggregateSetFactory; 14 cananian 1.8 import net.cscott.jutil.GenericMultiMap; 15 cananian 1.8 import net.cscott.jutil.MultiMap; 16 cananian 1.8 import net.cscott.jutil.Default; 17 cananian 1.6.2.8 import harpoon.Util.Util; 18 cananian 1.8 import net.cscott.jutil.WorkSet; 19 cananian 1.1 20 cananian 1.6.2.9 import java.util.Collection; 21 cananian 1.6.2.8 import java.util.Collections; 22 cananian 1.1 import java.util.Hashtable; 23 cananian 1.6.2.8 import java.util.Iterator; 24 cananian 1.6.2.6 import java.util.Set; 25 cananian 1.6.2.6 import java.util.HashSet; 26 cananian 1.1 /** 27 cananian 1.1 * <code>DomFrontier</code> computes the dominance frontier of a 28 cananian 1.1 * flowgraph-structured IR. The <code>HCodeElement</code>s must implement 29 cananian 1.6.2.7 * the <code>harpoon.IR.Properties.CFGraphable</code> interface. 30 cananian 1.1 * 31 cananian 1.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 32 cananian 1.9 * @version $Id: DomFrontier.java,v 1.9 2004/02/08 03:19:12 cananian Exp $ 33 cananian 1.1 */ 34 cananian 1.1 35 cananian 1.1 public class DomFrontier { 36 cananian 1.6.2.9 final ArrayFactory af; 37 cananian 1.6.2.8 /** Creates a <code>DomFrontier</code> using a pre-existing 38 cananian 1.6.2.8 * <code>DomTree</code>. */ 39 cananian 1.1 public DomFrontier(DomTree dt) { 40 cananian 1.6.2.9 this.af = dt.hcode.elementArrayFactory(); 41 cananian 1.6.2.8 analyze(dt); 42 cananian 1.6.2.8 } 43 cananian 1.6.2.8 /** Creates a <code>DomFrontier</code> for the given 44 cananian 1.6.2.8 * <code>HCode</code> using the default grapher; if 45 cananian 1.6.2.8 * <code>isPost</code> is <code>false</code> creates the 46 cananian 1.6.2.8 * dominance frontier; otherwise creates the postdominance 47 cananian 1.6.2.8 * frontier. */ 48 cananian 1.6.2.8 public DomFrontier(HCode hcode, boolean isPost) { 49 cananian 1.6.2.8 this(hcode, CFGrapher.DEFAULT, isPost); 50 cananian 1.1 } 51 cananian 1.6.2.8 /** Creates a <code>DomFrontier</code> for the given 52 cananian 1.6.2.8 * <code>HCode</code> using the given <code>CFGrapher</code>; if 53 cananian 1.6.2.8 * <code>isPost</code> is <code>false</code> creates the 54 cananian 1.6.2.8 * dominance frontier; otherwise creates the postdominance 55 cananian 1.6.2.8 * frontier. */ 56 cananian 1.6.2.8 public DomFrontier(HCode hcode, CFGrapher grapher, boolean isPost) { 57 cananian 1.6.2.8 this(new DomTree(hcode, grapher, isPost)); 58 cananian 1.1 } 59 cananian 1.1 60 cananian 1.6.2.9 MultiMap DF = new GenericMultiMap(new AggregateSetFactory()); 61 cananian 1.1 62 cananian 1.5 /** Return an array of <code>HCodeElement</code>s in the (post)dominance 63 cananian 1.2 * frontier of <code>n</code>. 64 cananian 1.2 */ 65 cananian 1.6.2.8 public HCodeElement[] df(HCodeElement n) { 66 cananian 1.6.2.9 Collection c = DF.getValues(n); 67 cananian 1.6.2.9 return (HCodeElement[]) c.toArray(af.newArray(c.size())); 68 cananian 1.5 } 69 cananian 1.6.2.8 /** Return an immutable <code>Set</code> of <code>HCodeElement</code>s 70 cananian 1.6.2.8 * in the (post)dominance frontier of <code>n</code>. 71 cananian 1.5 */ 72 cananian 1.6.2.8 public Set dfS(HCodeElement n) { 73 cananian 1.6.2.9 return Collections.unmodifiableSet((Set)DF.getValues(n)); 74 cananian 1.1 } 75 cananian 1.1 76 cananian 1.6.2.8 void analyze(DomTree dt) { 77 cananian 1.6.2.8 HCodeElement[] roots = dt.roots(); 78 cananian 1.3 for (int i=0; i < roots.length; i++) 79 cananian 1.6.2.8 computeDF(dt, roots[i]); 80 cananian 1.1 } 81 cananian 1.6.2.8 void computeDF(DomTree dt, HCodeElement n) { 82 cananian 1.6.2.8 CFGrapher grapher = dt.grapher; 83 cananian 1.1 84 cananian 1.1 // for every child y in succ[n] 85 cananian 1.6.2.8 for (Iterator it=grapher.succC(n).iterator(); it.hasNext(); ) { 86 cananian 1.6.2.8 HCodeElement y = ((HCodeEdge)it.next()).to(); 87 cananian 1.6.2.8 if (!n.equals( dt.idom(y) )) 88 cananian 1.6.2.9 DF.add(n, y); 89 cananian 1.1 } 90 cananian 1.1 // for each child c of n in the (post)dominator tree 91 cananian 1.9 for (Object cO : dt.children(n)) { 92 cananian 1.9 HCodeElement c = (HCodeElement) cO; 93 cananian 1.6.2.8 computeDF(dt, c); 94 cananian 1.1 // for each element w of DF[c] 95 cananian 1.9 for (Object wO : DF.getValues(c)) { 96 cananian 1.9 HCodeElement w = (HCodeElement) wO; 97 cananian 1.6.2.9 if (!n.equals( dt.idom(w) )) 98 cananian 1.6.2.9 DF.add(n, w); 99 cananian 1.6.2.9 } 100 cananian 1.1 } 101 cananian 1.1 } 102 cananian 1.1 }