1 pnkfelix 1.1.2.4 // Solver.java, created Mon Nov  8 22:52:13 1999 by pnkfelix
  2 pnkfelix 1.1.2.4 // Copyright (C) 1999 Felix S. Klock II <pnkfelix@mit.edu>
  3 pnkfelix 1.1.2.4 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 jwhaley  1.1.2.1 package harpoon.Analysis.DataFlow;
  5 jwhaley  1.1.2.1 
  6 pnkfelix 1.1.2.4 import harpoon.Analysis.BasicBlock;
  7 duncan   1.1.2.5 import harpoon.Analysis.DataFlow.ReversePostOrderEnumerator; 
  8 cananian 1.3     import net.cscott.jutil.WorkSet;
  9 jwhaley  1.1.2.1 
 10 duncan   1.1.2.5 
 11 duncan   1.1.2.5 import java.util.Enumeration; 
 12 pnkfelix 1.1.2.4 import java.util.Iterator;
 13 jwhaley  1.1.2.1 
 14 pnkfelix 1.1.2.4 /**
 15 pnkfelix 1.1.2.4  * <code>Solver</code> contains static methods to find the fixed point
 16 pnkfelix 1.1.2.4  * of a set of data-flow equations.  It is a generalization of the
 17 pnkfelix 1.1.2.4  * <code>QuadSolver</code> and <code>InstrSolver</code> that is
 18 pnkfelix 1.1.2.4  * intended for general usage on any Intermediate Representation that
 19 pnkfelix 1.1.2.4  * is amicable to data-flow analysis. 
 20 pnkfelix 1.1.2.4  * 
 21 pnkfelix 1.1.2.4  * @author  Felix S. Klock II <pnkfelix@mit.edu>
 22 cananian 1.3      * @version $Id: Solver.java,v 1.3 2004/02/08 01:51:05 cananian Exp $
 23 pnkfelix 1.1.2.4  */
 24 pnkfelix 1.1.2.4 public class Solver {
 25 jwhaley  1.1.2.1 
 26 pnkfelix 1.1.2.4     private static boolean DEBUG = false;
 27 pnkfelix 1.1.2.4     private static void db(String s) { if(DEBUG)System.out.println(s); }
 28 pnkfelix 1.1.2.7     static final boolean TIME = false;
 29 jwhaley  1.1.2.1 
 30 pnkfelix 1.1.2.4     /** Creates a <code>Solver</code>.  Ctor is made private so that
 31 pnkfelix 1.1.2.4         there won't be any instances of Solvers running around. */
 32 pnkfelix 1.1.2.4     private Solver() {
 33 pnkfelix 1.1.2.4         
 34 jwhaley  1.1.2.1     }
 35 pnkfelix 1.1.2.4     
 36 pnkfelix 1.1.2.4     /** Performs dataflow analysis on a set of
 37 pnkfelix 1.1.2.4         <code>BasicBlock</code>s.  Finds the maximum fixed point for
 38 pnkfelix 1.1.2.4         the data-flow equations defined by <code>v</code>. 
 39 pnkfelix 1.1.2.4 
 40 pnkfelix 1.1.2.7         FSK: it seems to me that the <code>blocks</code> are added to
 41 pnkfelix 1.1.2.7              a stack and then popped off for visitation, which means
 42 pnkfelix 1.1.2.7              that if you want to visit the blocks in say Reverse
 43 pnkfelix 1.1.2.7              Postorder, then <code>blocks</code> must iterate over
 44 pnkfelix 1.1.2.7              them in *Normal* Postorder.  This seems viciously
 45 pnkfelix 1.1.2.7              unintuitive... perhaps the Solver interface should be
 46 pnkfelix 1.1.2.7              revised to offer more control over the traversal... (on
 47 pnkfelix 1.1.2.7              the other hand, the current implementation doesn't seem
 48 pnkfelix 1.1.2.7              to be performing that shabbily to me, so perhaps is
 49 pnkfelix 1.1.2.7              better to leave well enough alone...)
 50 pnkfelix 1.1.2.7 
 51 pnkfelix 1.1.2.4         <BR> <B>requires:</B> <OL>
 52 pnkfelix 1.1.2.4              <LI> The elements of <code>blocks</code> are
 53 pnkfelix 1.1.2.4                   <code>BasicBlock</code>s.
 54 pnkfelix 1.1.2.4              <LI> <code>v</code> can safely visit the elements of
 55 pnkfelix 1.1.2.4                   <code>blocks</code>. 
 56 pnkfelix 1.1.2.4              </OL>
 57 pnkfelix 1.1.2.4         <BR> <B>modifies:</B> <code>v</code>, <code>blocks</code>
 58 pnkfelix 1.1.2.4         <BR> <B>effects:</B> 
 59 pnkfelix 1.1.2.4              Sends <code>v</code> into the elements of
 60 pnkfelix 1.1.2.4              <code>blocks</code> and the 'successors' of the elements
 61 pnkfelix 1.1.2.4              of <code>blocks</code> (where 'successors' is defined by
 62 pnkfelix 1.1.2.4              <code>v</code>'s addSuccessors() method).
 63 pnkfelix 1.1.2.4              On each visitation, performs <code>v</code>'s transfer
 64 pnkfelix 1.1.2.4              function on each <code>BasicBlock</code> in turn,
 65 pnkfelix 1.1.2.4              tracking for when no change occurs to the 'successors',
 66 pnkfelix 1.1.2.4              at which point analysis is complete.
 67 pnkfelix 1.1.2.4              This method guarantees that all of the
 68 pnkfelix 1.1.2.4              <code>BasicBlock</code>s. in <code>blocks</code> will be
 69 pnkfelix 1.1.2.4              visited  by <code>v</code> at least once. 
 70 pnkfelix 1.1.2.4     */
 71 pnkfelix 1.1.2.4     public static void worklistSolve(Iterator blocks,
 72 pnkfelix 1.1.2.4                                      DataFlowBasicBlockVisitor v) {
 73 pnkfelix 1.1.2.4         WorkSet w = new WorkSet();
 74 pnkfelix 1.1.2.7         int total = 0;
 75 pnkfelix 1.1.2.7         int count = 0;
 76 pnkfelix 1.1.2.7         while (blocks.hasNext()) {
 77 pnkfelix 1.1.2.7             w.push(blocks.next());
 78 pnkfelix 1.1.2.7             total++;
 79 pnkfelix 1.1.2.7         }
 80 pnkfelix 1.1.2.4         while (!w.isEmpty()) {
 81 pnkfelix 1.1.2.4             // v.changed = false;
 82 cananian 1.3                 BasicBlock b = (BasicBlock) w.removeLast();
 83 pnkfelix 1.1.2.7             if (TIME) count++;
 84 pnkfelix 1.1.2.4             if (DEBUG) 
 85 pnkfelix 1.1.2.4                 System.out.println
 86 pnkfelix 1.1.2.4                     ("Visiting block " + b);
 87 pnkfelix 1.1.2.6             b.accept(v);
 88 pnkfelix 1.1.2.4             v.addSuccessors(w, b);
 89 jwhaley  1.1.2.1         }
 90 pnkfelix 1.1.2.7         if (TIME) System.out.print("(s:"+count+"/"+total+")");
 91 pnkfelix 1.1.2.7 
 92 duncan   1.1.2.5     }
 93 duncan   1.1.2.5 
 94 duncan   1.1.2.5     public static void forwardRPOSolve(BasicBlock root,
 95 duncan   1.1.2.5                                        DataFlowBasicBlockVisitor v) { 
 96 duncan   1.1.2.5         ReversePostOrderEnumerator rpo = new ReversePostOrderEnumerator(root);
 97 duncan   1.1.2.5         boolean changed = false;
 98 duncan   1.1.2.5         do {
 99 duncan   1.1.2.5             changed = false;
100 duncan   1.1.2.5 
101 duncan   1.1.2.5             ReversePostOrderEnumerator iter = rpo.copy();
102 duncan   1.1.2.5             while (iter.hasMoreElements()) {
103 duncan   1.1.2.5                 BasicBlock q = (BasicBlock)iter.next();
104 duncan   1.1.2.5                 if (DEBUG) db("visiting: "+q);
105 pnkfelix 1.1.2.6                 q.accept(v);
106 duncan   1.1.2.5                 for (Enumeration e=q.next(); e.hasMoreElements(); ) {
107 duncan   1.1.2.5                     BasicBlock qn = (BasicBlock)e.nextElement();
108 duncan   1.1.2.5                     if (DEBUG) db("doing edge "+q+" -> "+qn);
109 duncan   1.1.2.5                     changed = v.merge(q, qn); 
110 duncan   1.1.2.5                 }
111 duncan   1.1.2.5             }
112 jwhaley  1.1.2.1 
113 duncan   1.1.2.5         } while (changed);
114 jwhaley  1.1.2.1     }
115 pnkfelix 1.1.2.2     
116 cananian 1.2     }