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

ConstantAndCopyPropagator.java

00001 package ca.mcgill.sable.soot.jimple;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Jimple, a 3-address code Java(TM) bytecode representation.        *
00005  * Copyright (C) 1999 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 14, 1999 by Raja Vallee-Rai (rvalleerai@sable.mcgill.ca) (*)
00068    First release.
00069 */
00070 
00071 import ca.mcgill.sable.soot.*;
00072 import ca.mcgill.sable.util.*;
00073 
00074 public class ConstantAndCopyPropagator
00075 {
00076     /** Cascaded constant/copy propagator.
00077     
00078         If it encounters situations of the form: A: a = ...; B: ... x = a; C:... use (x); 
00079         where a has only one definition, and x has only one definition (B), then it can 
00080         propagate immediately without checking between B and C for redefinitions
00081         of a (namely) A because they cannot occur.  In this case the propagator is global.
00082         
00083         Otherwise, if a has multiple definitions then it only checks for redefinitions of
00084         Propagates constants and copies in extended basic blocks. */
00085     
00086     public static void propagateConstantsAndCopies(StmtBody stmtBody)
00087     {
00088         int fastCopyPropagationCount = 0;
00089         int slowCopyPropagationCount = 0;
00090         int constantPropagationCount = 0;
00091         
00092         if(Main.isVerbose)
00093             System.out.println("[" + stmtBody.getMethod().getName() +
00094                 "] Propagating constants and copies...");
00095 
00096         if(Main.isProfilingOptimization)
00097             Main.propagatorTimer.start();                
00098                 
00099         StmtList stmtList = stmtBody.getStmtList();
00100 
00101         Map localToDefCount = new HashMap();
00102         
00103         // Count number of definitions for each local.
00104         {
00105             Iterator stmtIt = stmtList.iterator();
00106         
00107             while(stmtIt.hasNext())
00108             {
00109                 Stmt s = (Stmt) stmtIt.next();
00110                 
00111                 if(s instanceof DefinitionStmt &&
00112                     ((DefinitionStmt) s).getLeftOp() instanceof Local)
00113                 {
00114                     Local l = (Local) ((DefinitionStmt) s).getLeftOp();
00115                      
00116                     if(!localToDefCount.containsKey(l))
00117                         localToDefCount.put(l, new Integer(1));
00118                     else 
00119                         localToDefCount.put(l, new Integer(((Integer) localToDefCount.get(l)).intValue() + 1));
00120                 }
00121                 
00122             }
00123         }
00124         
00125 //            ((JimpleBody) stmtBody).printDebugTo(new java.io.PrintWriter(System.out, true));
00126             
00127         CompleteStmtGraph graph = new CompleteStmtGraph(stmtList);
00128 
00129         LocalDefs localDefs;
00130         
00131         if(Main.usePackedDefs) 
00132         {
00133             localDefs = new SimpleLocalDefs(graph);
00134         }
00135         else {
00136             LiveLocals liveLocals;
00137         
00138             if(Main.usePackedLive) 
00139                 liveLocals = new SimpleLiveLocals(graph);
00140             else
00141                 liveLocals = new SparseLiveLocals(graph);    
00142 
00143             localDefs = new SparseLocalDefs(graph, liveLocals);                
00144         }           
00145 
00146 
00147         LocalUses localUses = new SimpleLocalUses(graph, localDefs);
00148 
00149         // Perform a constant/local propagation pass.
00150         {
00151             Iterator stmtIt = graph.pseudoTopologicalOrderIterator();
00152 
00153             while(stmtIt.hasNext())
00154             {
00155                 Stmt stmt = (Stmt) stmtIt.next();
00156                 Iterator useBoxIt = stmt.getUseBoxes().iterator();
00157 
00158                 while(useBoxIt.hasNext())
00159                 {
00160                     ValueBox useBox = (ValueBox) useBoxIt.next();
00161 
00162                     if(useBox.getValue() instanceof Local)
00163                     {
00164                         Local l = (Local) useBox.getValue();
00165 
00166                         List defsOfUse = localDefs.getDefsOfAt(l, stmt);
00167 
00168                         if(defsOfUse.size() == 1)
00169                         {
00170                             DefinitionStmt def = (DefinitionStmt) defsOfUse.get(0);
00171 
00172                             if(def.getRightOp() instanceof Constant)
00173                             {
00174                                 if(useBox.canContainValue(def.getRightOp()))
00175                                 {
00176                                     // Check to see if this box can actually contain
00177                                     // a constant.  (bases can't)
00178 
00179                                      useBox.setValue(def.getRightOp());
00180                                      constantPropagationCount++;
00181                                 }
00182                             }
00183                             else if(def.getRightOp() instanceof Local)
00184                             {
00185                                 Local m = (Local) def.getRightOp();
00186 
00187                                 if(l != m)
00188                                 {   
00189                                     int defCount = ((Integer) localToDefCount.get(m)).intValue();
00190                                     
00191                                     if(defCount == 0)
00192                                         throw new RuntimeException("Variable " + m + " used without definition!");
00193                                     else if(defCount == 1)
00194                                     {
00195                                         useBox.setValue(m);
00196                                         fastCopyPropagationCount++;
00197                                         continue;
00198                                     }
00199 
00200                                     List path = graph.getExtendedBasicBlockPathBetween(def, stmt);
00201                                     
00202                                     if(path == null)
00203                                     {
00204                                         // no path in the extended basic block
00205                                         continue;
00206                                     }
00207                                      
00208                                     Iterator pathIt = path.iterator();
00209                                     
00210                                     // Skip first node
00211                                         pathIt.next();
00212                                         
00213                                     // Make sure that m is not redefined along path
00214                                     {
00215                                         boolean isRedefined = false;
00216                                         
00217                                         while(pathIt.hasNext())
00218                                         {
00219                                             Stmt s = (Stmt) pathIt.next();
00220                                             
00221                                             if(stmt == s)
00222                                             {
00223                                                 // Don't look at the last statement 
00224                                                 // since it is evaluated after the uses
00225                                                 
00226                                                 break;
00227                                             }   
00228                                             if(s instanceof DefinitionStmt)
00229                                             {
00230                                                 if(((DefinitionStmt) s).getLeftOp() == m)
00231                                                 {
00232                                                     isRedefined = true;
00233                                                     break;
00234                                                 }        
00235                                             }
00236                                         }
00237                                         
00238                                         if(isRedefined)
00239                                             continue;
00240                                             
00241                                     }
00242                                     
00243                                     useBox.setValue(m);
00244                                     slowCopyPropagationCount++;
00245                                 }
00246                             }
00247                         }
00248                     }
00249 
00250                  }
00251             }
00252         }
00253 
00254 
00255         if(Main.isVerbose)
00256             System.out.println("[" + stmtBody.getMethod().getName() +
00257                 "] Propagated: " + constantPropagationCount + " constants  " +
00258                 fastCopyPropagationCount + " fast copies  " +
00259                 slowCopyPropagationCount + " slow copies");
00260      
00261         if(Main.isProfilingOptimization)
00262             Main.propagatorTimer.end();
00263     
00264     }
00265 }

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