Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* Soot - a J*va Optimization Framework
   * Copyright (C) 1997-1999 Raja Vallee-Rai
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 /*
  * Modified by the Sable Research Group and others 1997-1999.  
  * See the 'credits' file distributed with Soot for the complete list of
  * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
  */
 
 
 
 
 
 package soot.toolkits.scalar;
 import soot.options.*;
 
 import soot.*;
 import soot.util.*;
 import java.util.*;

A BodyTransformer that attemps to indentify and separate uses of a local varible that are independent of each other. Conceptually the inverse transform with respect to the LocalPacker transform. For example the code: for(int i; i < k; i++); for(int i; i < k; i++); would be transformed into: for(int i; i < k; i++); for(int j; j < k; j++);

 
 public class LocalSplitter extends BodyTransformer
 {
     public LocalSplitterSingletons.Global g ) {}
     public static LocalSplitter v() { return G.v().soot_toolkits_scalar_LocalSplitter(); }
 
     protected void internalTransform(Body bodyString phaseNameMap options)
     {
         Chain units = body.getUnits();
         List<Listwebs = new ArrayList<List>();
 
         if(Options.v().verbose())
             G.v()..println("[" + body.getMethod().getName() + "] Splitting locals...");
 
         Map boxToSet = new HashMap(units.size() * 2 + 1, 0.7f);
 
         if(Options.v().time())
                 Timers.v()..start();
 
         // Go through the definitions, building the webs
         {
             ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body);
 
             LocalDefs localDefs;
             
             localDefs = new SmartLocalDefs(graphnew SimpleLiveLocals(graph));
 
             LocalUses localUses = new SimpleLocalUses(graphlocalDefs);
             
             if(Options.v().time())
                 Timers.v()..end();
     
             if(Options.v().time())
                 Timers.v()..start();
 
             Set<ValueBoxmarkedBoxes = new HashSet<ValueBox>();
             Map<ValueBoxUnitboxToUnit = new HashMap<ValueBoxUnit>(units.size() * 2 + 1, 0.7f);
             
             Iterator codeIt = units.iterator();
 
             while(codeIt.hasNext())
             {
                 Unit s = (UnitcodeIt.next();
 
                if (s.getDefBoxes().size() > 1)
                    throw new RuntimeException("stmt with more than 1 defbox!");
                if (s.getDefBoxes().size() < 1)
                    continue;
                ValueBox loBox = (ValueBox)s.getDefBoxes().get(0);
                Value lo = loBox.getValue();
                if(lo instanceof Local && !markedBoxes.contains(loBox))
                {
                    LinkedList<UnitdefsToVisit = new LinkedList<Unit>();
                    LinkedList<ValueBoxboxesToVisit = new LinkedList<ValueBox>();
                    List web = new ArrayList();
                    webs.add(web);
                                        
                    defsToVisit.add(s);
                    markedBoxes.add(loBox);
                    
                    while(!boxesToVisit.isEmpty() || !defsToVisit.isEmpty())
                    {
                        if(!defsToVisit.isEmpty())
                        {
                            Unit d = defsToVisit.removeFirst();
                            web.add(d.getDefBoxes().get(0));
                            // Add all the uses of this definition to the queue
                            {
                                List uses = localUses.getUsesOf(d);
                                Iterator useIt = uses.iterator();
    
                                while(useIt.hasNext())
                                {
                                    UnitValueBoxPair use = (UnitValueBoxPairuseIt.next();
    
                                    if(!markedBoxes.contains(use.valueBox))
                                    {
                                        markedBoxes.add(use.valueBox);
                                        boxesToVisit.addLast(use.valueBox);
                                        boxToUnit.put(use.valueBoxuse.unit);
                                    }
                                }
                            }
                        }
                        else {
                            ValueBox box = boxesToVisit.removeFirst();
                            web.add(box);
                            // Add all the definitions of this use to the queue.
                            {               
                                List<Unitdefs = localDefs.getDefsOfAt((Localbox.getValue(),
                                    boxToUnit.get(box));
                                Iterator<UnitdefIt = defs.iterator();
    
                                while(defIt.hasNext())
                                {
                                    Unit u = defIt.next();
                                    Iterator defBoxesIter = u.getDefBoxes().iterator();
                                    ValueBox b;
                                    for (; defBoxesIter.hasNext(); )
                                    {
                                        b = (ValueBox)defBoxesIter.next();
                                        if(!markedBoxes.contains(b))
                                        {
                                            markedBoxes.add(b);
                                            defsToVisit.addLast(u);
                                        }
                                    }    
                                }
                            }
                        }
                    }
                }
            }
        }
        // Assign locals appropriately.
        {
            Map<LocalIntegerlocalToUseCount = new HashMap<LocalInteger>(body.getLocalCount() * 2 + 1, 0.7f);
            Iterator<ListwebIt = webs.iterator();
            while(webIt.hasNext())
            {
                List web = webIt.next();
                ValueBox rep = (ValueBoxweb.get(0);
                Local desiredLocal = (Localrep.getValue();
                if(!localToUseCount.containsKey(desiredLocal))
                {
                    // claim this local for this set
                    localToUseCount.put(desiredLocalnew Integer(1));
                }
                else {
                    // generate a new local
                    int useCount = localToUseCount.get(desiredLocal).intValue() + 1;
                    localToUseCount.put(desiredLocalnew Integer(useCount));
        
                    Local local = (LocaldesiredLocal.clone();
                    local.setName(desiredLocal.getName() + "#" + useCount);
                    
                    body.getLocals().add(local);
                    // Change all boxes to point to this new local
                    {
                        Iterator j = web.iterator();
                        while(j.hasNext())
                        {
                            ValueBox box = (ValueBoxj.next();
                            box.setValue(local);
                        }
                    }
                }
            }
        }
        
        if(Options.v().time())
            Timers.v()..end();
    }   
New to GrepCode? Check out our FAQ X