Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

FastColorer.java

00001 package ca.mcgill.sable.soot.jimple;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Jimple, a 3-address code Java(TM) bytecode representation.        *
00005  * Copyright (C) 1997, 1998 Raja Vallee-Rai (kor@sable.mcgill.ca)    *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project of the Sable Research Group,      *
00009  * School of Computer Science, McGill University, Canada             *
00010  * (http://www.sable.mcgill.ca/).  It is understood that any         *
00011  * modification not identified as such is not covered by the         *
00012  * preceding statement.                                              *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this library; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other Sable Research Group projects, please      *
00033  * visit the web site: http://www.sable.mcgill.ca/                   *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 
00036 /*
00037  Reference Version
00038  -----------------
00039  This is the latest official version on which this file is based.
00040  The reference version is: $SootVersion: 1.beta.4 $
00041 
00042  Change History
00043  --------------
00044  A) Notes:
00045 
00046  Please use the following template.  Most recent changes should
00047  appear at the top of the list.
00048 
00049  - Modified on [date (March 1, 1900)] by [name]. [(*) if appropriate]
00050    [description of modification].
00051 
00052  Any Modification flagged with "(*)" was done as a project of the
00053  Sable Research Group, School of Computer Science,
00054  McGill University, Canada (http://www.sable.mcgill.ca/).
00055 
00056  You should add your copyright, using the following template, at
00057  the top of this file, along with other copyrights.
00058 
00059  *                                                                   *
00060  * Modifications by [name] are                                       *
00061  * Copyright (C) [year(s)] [your name (or company)].  All rights     *
00062  * reserved.                                                         *
00063  *                                                                   *
00064 
00065  B) Changes:
00066 
00067  - Modified on March 13, 1999 by Raja Vallee-Rai (rvalleerai@sable.mcgill.ca) (*)
00068    Re-organized the timers.
00069 
00070  - Modified on February 28, 1999 by Raja Vallee-Rai (rvalleerai@sable.mcgill.ca). (*)
00071    Initial release.
00072 */
00073 
00074 import ca.mcgill.sable.soot.*;
00075 import ca.mcgill.sable.util.*;
00076 
00077 public class FastColorer
00078 {   
00079     public class InterferenceGraph
00080     {
00081         Map localToLocals;// Maps a local to its interfering locals.
00082     
00083         private InterferenceGraph()
00084         {
00085         }
00086     
00087         public Set getLocals()
00088         {
00089             return localToLocals.keySet();
00090         }
00091         
00092         public InterferenceGraph(StmtBody body, Map localToGroup, LiveLocals liveLocals)
00093         {
00094             StmtList stmtList = body.getStmtList();
00095     
00096             // Initialize localToLocals
00097             {
00098                 localToLocals = new HashMap(body.getLocalCount() * 2 + 1, 0.7f);
00099     
00100                 Iterator localIt = body.getLocals().iterator();
00101     
00102                 while(localIt.hasNext())
00103                 {
00104                     Local local = (Local) localIt.next();
00105     
00106                     localToLocals.put(local, new ArraySet());
00107                 }
00108             }
00109     
00110             // Go through code, noting interferences
00111             {
00112                 Iterator codeIt = stmtList.iterator();
00113     
00114                 while(codeIt.hasNext())
00115                 {
00116                     Stmt stmt = (Stmt) codeIt.next();
00117     
00118                     List liveLocalsAtStmt = liveLocals.getLiveLocalsAfter(stmt);
00119                     
00120                     // Note interferences if this statement is a definition
00121                     {
00122                         if(stmt instanceof DefinitionStmt)
00123                         {
00124                             DefinitionStmt def = (DefinitionStmt) stmt;
00125     
00126                             if(def.getLeftOp() instanceof Local)
00127                             {
00128                                 Local defLocal = (Local) def.getLeftOp();
00129                   
00130                                 Iterator localIt = liveLocalsAtStmt.iterator();
00131                                     
00132                                 while(localIt.hasNext())
00133                                 {
00134                                     Local otherLocal = (Local) localIt.next();
00135                                     
00136                                     if(localToGroup.get(otherLocal).equals(
00137                                         localToGroup.get(defLocal)))
00138                                         setInterference(defLocal, otherLocal);
00139                                 }
00140                             }    
00141                         }
00142                     }                    
00143                 }
00144             }
00145         }
00146     
00147         public boolean localsInterfere(Local l1, Local l2)
00148         {
00149             return ((Set) localToLocals.get(l1)).contains(l2);
00150         }
00151     
00152         public void setInterference(Local l1, Local l2)
00153         {
00154             ((Set) localToLocals.get(l1)).add(l2);
00155             ((Set) localToLocals.get(l2)).add(l1);
00156         }
00157     
00158         public boolean isEmpty()
00159         {
00160             return localToLocals.isEmpty();
00161         }
00162         
00163         Local[] getInterferencesOf(Local l)
00164         {
00165             Object[] objects = ((Set) localToLocals.get(l)).toArray();
00166             Local[] locals = new Local[objects.length];
00167     
00168             for(int i = 0; i < objects.length; i++)
00169                 locals[i] = (Local) objects[i];
00170     
00171             return locals; 
00172         }
00173     }
00174     private FastColorer(StmtBody stmtBody, Map localToGroup,
00175         Map localToColor, Map groupToColorCount)
00176     {
00177         StmtList stmtList = stmtBody.getStmtList();
00178 
00179         CompleteStmtGraph stmtGraph = new CompleteStmtGraph(stmtList);
00180 
00181         LiveLocals liveLocals;
00182 
00183         if(Main.usePackedLive)
00184             liveLocals = new SimpleLiveLocals(stmtGraph);
00185         else 
00186             liveLocals = new SparseLiveLocals(stmtGraph);
00187 
00188         InterferenceGraph intGraph = new InterferenceGraph(stmtBody, localToGroup, liveLocals);
00189 
00190         // Assign a color for each local.
00191         {
00192             int[] freeColors = new int[10];
00193             Iterator localIt = intGraph.getLocals().iterator();
00194             
00195             while(localIt.hasNext())
00196             {
00197                 Local local = (Local) localIt.next();
00198                 
00199                 if(localToColor.containsKey(local))
00200                 {
00201                     // Already assigned, probably a parameter
00202                     continue;
00203                 }
00204                 
00205                 Object group = localToGroup.get(local);
00206                 int colorCount = ((Integer) groupToColorCount.get(group)).intValue();
00207                 
00208                 if(freeColors.length < colorCount)
00209                     freeColors = new int[Math.max(freeColors.length * 2, colorCount)];
00210                 
00211                 // Set all colors to free.
00212                 {
00213                     for(int i= 0; i < colorCount; i++)
00214                         freeColors[i] = 1;
00215                 }
00216                 
00217                 // Remove unavailable colors for this local
00218                 {
00219                     Local[] interferences = intGraph.getInterferencesOf(local);
00220 
00221                     for(int i = 0; i < interferences.length; i++)
00222                     {
00223                         if(localToColor.containsKey(interferences[i]))
00224                         {
00225                             int usedColor = ((Integer) localToColor.get(interferences[i])).intValue();
00226                 
00227                             freeColors[usedColor] = 0;
00228                         }
00229                     }
00230                 }
00231                 
00232                 // Assign a color to this local.
00233                 {
00234                     boolean found = false;
00235                     int assignedColor = 0;
00236                     
00237                     for(int i = 0; i < colorCount; i++)
00238                         if(freeColors[i] == 1)
00239                         {
00240                             found = true;
00241                             assignedColor = i;
00242                         }
00243                     
00244                     if(!found)
00245                     {
00246                         assignedColor = colorCount++;
00247                         groupToColorCount.put(group, new Integer(colorCount));
00248                     }   
00249                     
00250                     localToColor.put(local, new Integer(assignedColor));
00251                 }
00252             }
00253         }
00254                             
00255     }
00256     public static void assignColorsToLocals(StmtBody stmtBody, Map localToGroup, 
00257         Map localToColor, Map groupToColorCount)
00258     {
00259         new FastColorer(stmtBody, localToGroup, localToColor, groupToColorCount);
00260     }
00261 }

Generated at Thu Feb 7 06:45:27 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001