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

BlockMap.java

00001 package edu.ksu.cis.bandera.prog;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998, 1999   Shawn Laubach (laubach@acm.org)        *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the 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 toolkit; 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 SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 //BlockMap.java
00036 //import java.io.*;
00037 import ca.mcgill.sable.soot.*;
00038 import java.util.*;
00039 import ca.mcgill.sable.soot.jimple.*;
00040 
00041 /**
00042  * A blockmap structure.  It holds the information for a method that
00043  * makes a control flow graph.  This holds the data to lookup a block
00044  * using the index.  It also keeps the local variables and other
00045  * information needed to create a new method from a block map.
00046  *
00047  * @author <a href="mailto:laubach@cis.ksu.edu">Shawn Laubach</a>
00048  *
00049  * @version 0.1
00050  */
00051 public class BlockMap extends HashMap implements Cloneable {
00052     /**
00053        * Option to set block level structure in the basic blocks.
00054        */
00055     public final static int BLOCKLEVEL = 0;
00056 
00057     /**
00058        * Option to set statement level structures in the basic blocks.
00059        */
00060     public final static int STMTLEVEL = 1;
00061 
00062     /**
00063        * Option to set a hammock CFG when there is only one entrance and
00064        * one exit.
00065        */
00066     public final static int HAMMOCK = 2;
00067 
00068     /**
00069        * String name for the return variable used in hammock mode.
00070        */
00071     public static String returnVariable = "$RESULT$";
00072     protected Index initBlock; // Start block
00073     protected List finalBlocks; // List of final blocks
00074     protected Map stmtToIndex; // maps statements to their block indexes
00075     protected JimpleBody listBody; // The jimple body
00076     protected ca.mcgill.sable.util.List locals; // The list of local variables
00077     protected StmtList stmtList; // List of statements
00078     protected SootMethod method; // method that the BlockMap is created from
00079     protected Map nameToLocal; // Maps string names to locals.
00080 // Current only keeps new locals added 
00081 // elsewhere
00082 
00083 /**
00084    * Constructs a new empty blockmap.
00085    */
00086 public BlockMap() {
00087     super();
00088     stmtToIndex = new HashMap();
00089     locals = new ca.mcgill.sable.util.VectorList();
00090     nameToLocal = new HashMap();
00091     finalBlocks = new ArrayList();
00092 }
00093   /**
00094    * Constructs a new blockmap from a method with the flags.
00095    *
00096    * @param m the method to create the block map from.
00097    * @param flags these are the flags that specify statement level,
00098    * block level, and hammock configuration.
00099    */
00100   public BlockMap(SootMethod m, int flags)
00101   {
00102     this();
00103 
00104     boolean hammock = (flags & HAMMOCK) > 0; // Check if hammock is set
00105     boolean stmtLevel = (flags & STMTLEVEL) > 0; //Check if statement level
00106 
00107     method = m;
00108 
00109     if (stmtLevel)
00110       setupStmtLevel(hammock);
00111     else
00112       setupBlockLevel(hammock);
00113   }  
00114   /**
00115    * Adds a local to the local list.
00116    *
00117    * @param l local to add.
00118    */
00119   public void addLocal(Local l)
00120   {
00121     locals.add(l);
00122   }  
00123 /**
00124    * Collapses all the block into a list of statements.  It merges
00125    * blocks that end with a goto to another block that only has one
00126    * entry point.  It then puts goto's and other structures as
00127    * necessesary to ensure correct list construction.
00128    *
00129    * @return A list of statements made form the blockmap.
00130    */
00131 public ca.mcgill.sable.util.List collapse() {
00132     Vector pending = new Vector();
00133     ca.mcgill.sable.util.List stmtList = new ca.mcgill.sable.util.ArrayList();
00134     List visited = new ArrayList();
00135     Iterator it, jt;
00136     Index index;
00137     BasicBlock bb = null, previous = null;
00138     Map indexToStmt = new HashMap();
00139     int count = 0;
00140     setJumps();
00141     it = keySet().iterator();
00142     while (it.hasNext()) {
00143         bb = (BasicBlock) get(it.next());
00144         indexToStmt.put(bb.getIndex(), bb.get(0));
00145     }
00146     pending.addElement(initBlock);
00147     while (pending.size() > 0) {
00148         index = (Index) pending.firstElement();
00149         pending.removeElementAt(0);
00150         if (!visited.contains(index)) {
00151             visited.add(index);
00152             bb = (BasicBlock) get(index);
00153             if (bb == null)
00154                 System.out.println("Null basic block:  why?");
00155             else {
00156                 stmtList.addAll(bb.get());
00157                 switch (bb.getSuccs().size()) {
00158                     case 1 :
00159                         if (visited.contains(bb.getSuccs(0)))
00160                             stmtList.add(Jimple.v().newGotoStmt((Stmt) indexToStmt.get(bb.getSuccs(0))));
00161                         else
00162                             pending.insertElementAt(bb.getSuccs(0), 0);
00163                         break;
00164                     case 2 :
00165                         if (!visited.contains(bb.getSuccs(0)))
00166                             pending.addElement(bb.getSuccs(0));
00167                         if (visited.contains(bb.getSuccs(1)))
00168                             stmtList.add(Jimple.v().newGotoStmt((Stmt) indexToStmt.get(bb.getSuccs(1))));
00169                         else
00170                             pending.insertElementAt(bb.getSuccs(1), 0);
00171                         break;
00172                 }
00173                 previous = bb;
00174             }
00175         }
00176     }
00177     return stmtList;
00178 }
00179 protected void compress() {
00180     Iterator it;
00181 
00182     // Set the predecessors to all the blocks
00183     {
00184         BasicBlock bb1, bb2;
00185         Index index;
00186         it = keySet().iterator();
00187         Iterator jt;
00188         while (it.hasNext()) {
00189             bb1 = (BasicBlock) get(it.next());
00190             jt = bb1.getSuccs().iterator();
00191             while (jt.hasNext()) {
00192                 bb2 = (BasicBlock) get(jt.next());
00193                 bb2.addPreds(bb1.getIndex());
00194             }
00195         }
00196     }
00197     Set s = new HashSet();
00198     s.addAll(keySet());
00199     it = s.iterator();
00200     while (it.hasNext()) {
00201         BasicBlock bb = (BasicBlock) get(it.next());
00202         if (bb.get().size() == 0) {
00203             if (bb.getIndex().equals(initBlock))
00204                 initBlock = bb.getSuccs(0);
00205             BasicBlock tmp;
00206             Iterator jt;
00207             jt = bb.getPreds().iterator();
00208             while (jt.hasNext()) {
00209                 tmp = (BasicBlock) get(jt.next());
00210                 tmp.changeSuccs(bb.getIndex(), bb.getSuccs(0));
00211             }
00212             tmp = (BasicBlock) get(bb.getSuccs(0));
00213             tmp.changePreds(bb.getIndex(), bb.getPreds());
00214             remove(bb.getIndex());
00215         }
00216     }
00217 }
00218 /**
00219    * Creates a method from the blockmap.  It takes the name,
00220    * parameters, and the return type and creates the methods.
00221    *
00222    * @param name the name of the method.
00223    * @param params a list of parameters like what soot would take.
00224    * @param ret the return type of the method.
00225    *
00226    * @return The method that can be created from the block map.
00227    */
00228 public SootMethod createMethod(String name, ca.mcgill.sable.util.List params, Type ret) {
00229     SootMethod method = new SootMethod(name, params, ret);
00230     JimpleBody body = (JimpleBody) Jimple.v().newBody(method);
00231     ca.mcgill.sable.util.Iterator it = locals.iterator();
00232     while (it.hasNext())
00233         body.addLocal((Local) it.next());
00234     ca.mcgill.sable.util.Iterator it2 = collapse().iterator();
00235     StmtList stmtList = body.getStmtList();
00236     while (it2.hasNext())
00237         stmtList.add(it2.next());
00238     method.storeBody(Jimple.v(), body);
00239     //Transformations.cleanupCode(body);
00240     //Transformations.removeUnusedLocals(body);
00241 
00242     return method;
00243 }
00244   /**
00245    * Return the list of final blocks.
00246    *
00247    * @return List of final blocks.
00248    */
00249   public List getFinalBlocks()
00250   {
00251     return finalBlocks;
00252   }  
00253   /**
00254    * Get the initial index.
00255    */
00256   public Index getInit()
00257   {
00258     return initBlock;
00259   }  
00260   /**
00261    * Return the list body made from the method.
00262    */
00263   public JimpleBody getListBody()
00264   {
00265     return listBody;
00266   }  
00267   /**
00268    * Get a reference to a local.  If it is not there, it creates and
00269    * adds it.
00270    *
00271    * @param name the name of the local.
00272    */
00273   public Local getLocal(String name, Type t)
00274   {
00275     Map types;
00276 
00277     if ((types = (Map)nameToLocal.get(name)) == null)
00278       {
00279         Map tmp = new HashMap();
00280         Local l = Jimple.v().newLocal(name, t);
00281         tmp.put(t, l);
00282         nameToLocal.put(name, tmp);
00283         locals.add(l);
00284       }
00285     else
00286       if (types.get(t) == null)
00287       {
00288         Local l = Jimple.v().newLocal(name, t);
00289         types.put(t, l);
00290         locals.add(l);
00291       }
00292     
00293     return (Local)((Map)nameToLocal.get(name)).get(t);
00294   }  
00295   /**
00296    * Get the list of locals declared for the block map.
00297    */
00298   public ca.mcgill.sable.util.List getLocals()
00299   {
00300     return locals;
00301   }  
00302   /**
00303    * Returns the statement to index map.
00304    */
00305   public Map getStmtToIndex()
00306   {
00307     return stmtToIndex;
00308   }  
00309   /**
00310    * Set the initial index of a block map.
00311    */
00312   public void setInit(Index i)
00313   {
00314     initBlock = i;
00315   }  
00316 /**
00317    * Set all the jumps so that they point to the correct statement.
00318    * This method is used before any outside analysis because the
00319    * statements jumps point to can be null because they can be unknown
00320    * during the creation of a blockmap.  This sets all the statements
00321    * to the correct points.
00322    */
00323 protected void setJumps() {
00324     Iterator it;
00325     int s;
00326     Stmt last;
00327     final Map indexToStmt = new HashMap();
00328     compress();
00329     it = keySet().iterator();
00330     while (it.hasNext()) {
00331         BasicBlock bb = (BasicBlock) get(it.next());
00332         indexToStmt.put(bb.getIndex(), bb.get(0));
00333         stmtToIndex.put(bb.get(0), bb.getIndex());
00334     }
00335     it = keySet().iterator();
00336     while (it.hasNext()) {
00337         final BasicBlock bb = (BasicBlock) get(it.next());
00338         AbstractStmtSwitch asw = new AbstractStmtSwitch() {
00339             public void caseGotoStmt(GotoStmt s) {
00340                 s.setTarget((Stmt) indexToStmt.get(bb.getSuccs(0)));
00341             }
00342             public void caseIfStmt(IfStmt s) {
00343                 s.setTarget((Stmt) indexToStmt.get(bb.getSuccs(0)));
00344             }
00345         };
00346         if (bb.getGoOn() != null) {
00347             Iterator jt = bb.getGoOn().iterator();
00348             while (jt.hasNext()) {
00349                 last = (Stmt) jt.next();
00350                 last.apply(asw);
00351             }
00352         } else {
00353             last = bb.get(bb.get().size() - 1);
00354             last.apply(asw);
00355         }
00356     }
00357 
00358     // Set the predecessors to all the blocks
00359     {
00360         BasicBlock bb1, bb2;
00361         Index index;
00362         it = keySet().iterator();
00363         Iterator jt;
00364         while (it.hasNext()) {
00365             bb1 = (BasicBlock) get(it.next());
00366             jt = bb1.getSuccs().iterator();
00367             while (jt.hasNext()) {
00368                 bb2 = (BasicBlock) get(jt.next());
00369                 bb2.addPreds(bb1.getIndex());
00370             }
00371         }
00372     }
00373 }
00374 /**
00375    * Set the list of locals.
00376    */
00377 public void setLocals(ca.mcgill.sable.util.List l) {
00378     locals = l;
00379 }
00380 protected void setupBlockLevel(boolean hammock) {
00381     JimpleBody body = listBody = (JimpleBody) method.getBody(Jimple.v());
00382     stmtList = body.getStmtList(); // The statements in the body
00383 
00384     Map stmtToName = new HashMap(stmtList.size() * 2 + 1, 0.7f);
00385     StmtGraph stmtGraph = new BriefStmtGraph(stmtList);
00386     BasicBlock bb, finalBlock; // current and final basic blocks
00387     int blockCount = 0;
00388     Local returnValue = null;
00389     ca.mcgill.sable.util.Iterator it = body.getLocals().iterator();
00390     // Add the locals to the locals list
00391     while (it.hasNext())
00392         locals.add(it.next());
00393 
00394     // Set up for hammock form
00395     if (hammock) {
00396         Stmt returnStmt;
00397 
00398         // Adds to the block index
00399         finalBlock = new BasicBlock(new Index(blockCount++));
00400 
00401         // Set up the return statement with the correct type
00402         if (method.getReturnType() instanceof VoidType)
00403             finalBlock.addStmt(Jimple.v().newReturnVoidStmt());
00404         else {
00405             if (method.getReturnType() instanceof BooleanType)
00406                 returnValue = Jimple.v().newLocal(method.getReturnType().toString() + returnVariable, IntType.v());
00407             else
00408                 returnValue = Jimple.v().newLocal(method.getReturnType().toString() + returnVariable, method.getReturnType());
00409         finalBlock.addStmt(Jimple.v().newReturnStmt(returnValue));
00410         locals.add(returnValue);
00411     }
00412 
00413     // Put statement in the final block
00414     stmtToIndex.put(finalBlock.get(0), finalBlock.getIndex());
00415     put(finalBlock.getIndex(), finalBlock);
00416 } else
00417     finalBlock = null;
00418 
00419 
00420 // Create statement name table
00421 {
00422     ca.mcgill.sable.util.Iterator boxIt = body.getUnitBoxes().iterator();
00423     Set labelStmts = new HashSet();
00424 
00425     // Build labelStmts
00426     {
00427         while (boxIt.hasNext()) {
00428             UnitBox box = (UnitBox) boxIt.next();
00429             Stmt stmt = (Stmt) box.getUnit();
00430             labelStmts.add(stmt);
00431         }
00432     }
00433 
00434     // Traverse the stmts and assign a label if necessary
00435     {
00436         int labelCount = 0;
00437         ca.mcgill.sable.util.Iterator stmtIt = stmtList.iterator();
00438         while (stmtIt.hasNext()) {
00439             Stmt s = (Stmt) stmtIt.next();
00440             if (labelStmts.contains(s))
00441                 stmtToName.put(s, "label" + (labelCount++));
00442         }
00443     }
00444 }
00445 bb = new BasicBlock(new Index(blockCount++));
00446 put(bb.getIndex(), bb);
00447 initBlock = bb.getIndex();
00448 stmtToIndex.put(stmtList.get(0), bb.getIndex());
00449 for (int j = 0; j < stmtList.size(); j++) {
00450     Stmt s = ((Stmt) stmtList.get(j));
00451 
00452     // Put an empty line if the previous node was a branch node,
00453     // the current node is a join node or the previous statement
00454     // does not have this statement as a successor, or if this
00455     // statement has a label on it
00456     {
00457         if (j != 0) {
00458             Stmt previousStmt = (Stmt) stmtList.get(j - 1);
00459             if (stmtGraph.getSuccsOf(previousStmt).size() != 1 || stmtGraph.getPredsOf(s).size() != 1 || stmtToName.containsKey(s)) {
00460                 ca.mcgill.sable.util.Iterator succsIterator = stmtGraph.getSuccsOf(previousStmt).iterator();
00461                 while (succsIterator.hasNext()) {
00462                     Stmt stmt = (Stmt) succsIterator.next();
00463                     if (!stmtToIndex.containsKey(stmt))
00464                         stmtToIndex.put(stmt, new Index(blockCount++));
00465                     bb.addSuccs((Index) stmtToIndex.get(stmt));
00466                 }
00467 
00468                 // Create the new block and place in the map
00469                 if (!stmtToIndex.containsKey(s))
00470                     stmtToIndex.put(s, new Index(blockCount++));
00471                 bb = new BasicBlock((Index) stmtToIndex.get(s));
00472                 put(bb.getIndex(), bb);
00473                 if (!hammock && stmtGraph.getSuccsOf(s).size() == 0)
00474                     finalBlocks.add(bb.getIndex());
00475             } else {
00476                 // Or if the previous node does not have this
00477                 // statement as a successor.
00478 
00479                 ca.mcgill.sable.util.List succs = stmtGraph.getSuccsOf(previousStmt);
00480                 if (succs.get(0) != s) {
00481                     ca.mcgill.sable.util.Iterator succsIterator = stmtGraph.getSuccsOf(previousStmt).iterator();
00482                     while (succsIterator.hasNext()) {
00483                         Stmt stmt = (Stmt) succsIterator.next();
00484                         if (!stmtToIndex.containsKey(stmt))
00485                             stmtToIndex.put(stmt, new Index(blockCount++));
00486                         bb.addSuccs((Index) stmtToIndex.get(stmt));
00487                     }
00488 
00489                     // Create the new block and place in the map
00490                     if (!stmtToIndex.containsKey(s))
00491                         stmtToIndex.put(s, new Index(blockCount++));
00492                     bb = new BasicBlock((Index) stmtToIndex.get(s));
00493                     put(bb.getIndex(), bb);
00494                 }
00495             }
00496         }
00497     }
00498     {
00499         if (s instanceof GotoStmt)
00500             bb.addStmt(s);
00501         else
00502             if (s instanceof ReturnStmt && hammock) {
00503                 if (returnValue != null) {
00504                     Stmt stmt = Jimple.v().newAssignStmt(returnValue, ((ReturnStmt) s).getReturnValue());
00505                     bb.addStmt(stmt);
00506                 }
00507                 bb.addSuccs(finalBlock.getIndex());
00508             } else
00509                 bb.addStmt(s);
00510     }
00511 }
00512 ca.mcgill.sable.util.Iterator succsIterator = stmtGraph.getSuccsOf((Stmt) stmtList.get(stmtList.size() - 1)).iterator();
00513 while (succsIterator.hasNext()) {
00514     Stmt stmt = (Stmt) succsIterator.next();
00515     if (!stmtToIndex.containsKey(stmt))
00516         stmtToIndex.put(stmt, new Index(blockCount++));
00517     bb.addSuccs((Index) stmtToIndex.get(stmt));
00518 }
00519 
00520 // Set the predecessors to all the blocks
00521 {
00522     BasicBlock bb1, bb2;
00523     Index index;
00524     Iterator it2 = keySet().iterator();
00525     Iterator jt;
00526     while (it2.hasNext()) {
00527         bb1 = (BasicBlock) get(it2.next());
00528         jt = bb1.getSuccs().iterator();
00529         while (jt.hasNext()) {
00530             bb2 = (BasicBlock) get(jt.next());
00531             bb2.addPreds(bb1.getIndex());
00532         }
00533     }
00534 }
00535 }
00536 protected void setupStmtLevel(boolean hammock) {
00537     JimpleBody body = listBody = (JimpleBody) method.getBody(Jimple.v());
00538     stmtList = body.getStmtList(); // The statements in the body
00539 
00540     Map stmtToName = new HashMap(stmtList.size() * 2 + 1, 0.7f);
00541     StmtGraph stmtGraph = new BriefStmtGraph(stmtList);
00542     BasicBlock bb = null, finalBlock; // current and final basic blocks
00543     int blockCount = 0;
00544     Local returnValue = null;
00545     ca.mcgill.sable.util.Iterator it = body.getLocals().iterator();
00546     while (it.hasNext())
00547 
00548         
00549         // Add the locals to the locals list
00550         locals.add(it.next());
00551 
00552     // Create statement name table
00553     {
00554         ca.mcgill.sable.util.Iterator boxIt = body.getUnitBoxes().iterator();
00555         Set labelStmts = new HashSet();
00556 
00557         // Build labelStmts
00558         {
00559             while (boxIt.hasNext()) {
00560                 UnitBox box = (UnitBox) boxIt.next();
00561                 Stmt stmt = (Stmt) box.getUnit();
00562                 labelStmts.add(stmt);
00563             }
00564         }
00565 
00566         // Traverse the stmts and assign a label if necessary
00567         {
00568             int labelCount = 0;
00569             ca.mcgill.sable.util.Iterator stmtIt = stmtList.iterator();
00570             while (stmtIt.hasNext()) {
00571                 Stmt s = (Stmt) stmtIt.next();
00572                 if (labelStmts.contains(s))
00573                     stmtToName.put(s, "label" + (labelCount++));
00574             }
00575         }
00576     }
00577     if (hammock)
00578 
00579         
00580         // Set up for hammock form
00581         {
00582         Stmt returnStmt;
00583 
00584         // Adds to the block index
00585         finalBlock = new BasicBlock(new Index(blockCount++));
00586 
00587         // Set up the return statement with the correct type
00588         if (method.getReturnType() instanceof VoidType)
00589             finalBlock.addStmt(Jimple.v().newReturnVoidStmt());
00590         else {
00591             if (method.getReturnType() instanceof BooleanType)
00592                 returnValue = Jimple.v().newLocal(method.getReturnType().toString() + returnVariable, IntType.v());
00593             else
00594                 returnValue = Jimple.v().newLocal(method.getReturnType().toString() + returnVariable, method.getReturnType());
00595         finalBlock.addStmt(Jimple.v().newReturnStmt(returnValue));
00596         locals.add(returnValue);
00597     }
00598 
00599     // Put statement in the final block
00600     stmtToIndex.put(finalBlock.get(0), finalBlock.getIndex());
00601     put(finalBlock.getIndex(), finalBlock);
00602 } else
00603     finalBlock = null;
00604 for (int j = 0; j < stmtList.size(); j++) {
00605     boolean noGoto = false;
00606     Stmt s = ((Stmt) stmtList.get(j));
00607     if (!noGoto) {
00608         if (!stmtToIndex.containsKey(s))
00609             stmtToIndex.put(s, new Index(blockCount++));
00610         bb = new BasicBlock((Index) stmtToIndex.get(s));
00611         ca.mcgill.sable.util.Iterator succsIterator = stmtGraph.getSuccsOf(s).iterator();
00612         while (succsIterator.hasNext()) {
00613             Stmt stmt = (Stmt) succsIterator.next();
00614             if (!stmtToIndex.containsKey(stmt))
00615                 stmtToIndex.put(stmt, new Index(blockCount++));
00616             bb.addSuccs((Index) stmtToIndex.get(stmt));
00617         }
00618     } else {
00619         noGoto = false;
00620         stmtToIndex.put(s, bb.getIndex());
00621         ca.mcgill.sable.util.Iterator succsIterator = stmtGraph.getSuccsOf(s).iterator();
00622         while (succsIterator.hasNext()) {
00623             Stmt stmt = (Stmt) succsIterator.next();
00624             if (!stmtToIndex.containsKey(stmt))
00625                 stmtToIndex.put(stmt, new Index(blockCount++));
00626             bb.addSuccs((Index) stmtToIndex.get(stmt));
00627         }
00628     }
00629     put(bb.getIndex(), bb);
00630     if (j == 0)
00631         initBlock = bb.getIndex();
00632     stmtToIndex.put(stmtList.get(0), bb.getIndex());
00633     if (s instanceof GotoStmt)
00634         noGoto = true;
00635     else
00636         if (s instanceof ReturnStmt)
00637             if (hammock) {
00638                 if (returnValue != null) {
00639                     Stmt stmt = Jimple.v().newAssignStmt(returnValue, ((ReturnStmt) s).getReturnValue());
00640                     bb.addStmt(stmt);
00641                 }
00642                 bb.addSuccs(finalBlock.getIndex());
00643             } else
00644                 finalBlocks.add(bb);
00645         else
00646             bb.addStmt(s);
00647 }
00648 
00649 // Set the predecessors to all the blocks
00650 {
00651     BasicBlock bb1, bb2;
00652     Index index;
00653     Iterator it2 = keySet().iterator();
00654     Iterator jt;
00655     while (it2.hasNext()) {
00656         bb1 = (BasicBlock) get(it2.next());
00657         jt = bb1.getSuccs().iterator();
00658         while (jt.hasNext()) {
00659             bb2 = (BasicBlock) get(jt.next());
00660             bb2.addPreds(bb1.getIndex());
00661         }
00662     }
00663 }
00664 }
00665   public String toString()
00666   {
00667     Index index;
00668     String s = "";
00669     Iterator i;
00670 
00671     //      setJumps();
00672 
00673     i = keySet().iterator();
00674 
00675     //      s += get(initBlock).toString();
00676     while (i.hasNext())
00677       {
00678         index = (Index)i.next();
00679         //    if (!index.equals(initBlock))
00680         s += get(index);
00681       }
00682 
00683     return s;
00684   }  
00685 }

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