| 1 19 20 25 26 27 28 package soot.jimple.toolkits.base; 29 import soot.options.*; 30 31 import soot.*; 32 import soot.jimple.*; 33 import soot.toolkits.scalar.*; 34 import soot.toolkits.graph.*; 35 import soot.util.*; 36 import java.util.*; 37 38 public class Aggregator extends BodyTransformer 39 { 40 public Aggregator( Singletons.Global g ) {} 41 public static Aggregator v() { return G.v().soot_jimple_toolkits_base_Aggregator(); } 42 43 49 protected void internalTransform(Body b, String phaseName, Map options) 50 { 51 StmtBody body = (StmtBody)b; 52 boolean onlyStackVars = PhaseOptions.getBoolean(options, "only-stack-locals"); 53 54 int aggregateCount = 1; 55 56 if(Options.v().time()) 57 Timers.v().aggregationTimer.start(); 58 boolean changed = false; 59 60 Map boxToZone = new HashMap(body.getUnits().size() * 2 + 1, 0.7f); 61 62 { 64 Zonation zonation = new Zonation(body); 65 66 Iterator unitIt = body.getUnits().iterator(); 67 68 while(unitIt.hasNext()) 69 { 70 Unit u = (Unit) unitIt.next(); 71 Zone zone = (Zone) zonation.getZoneOf(u); 72 73 Iterator boxIt = u.getUseBoxes().iterator(); 74 while(boxIt.hasNext()) 75 { 76 ValueBox box = (ValueBox) boxIt.next(); 77 boxToZone.put(box, zone); 78 } 79 boxIt = u.getDefBoxes().iterator(); 80 while(boxIt.hasNext()) 81 { 82 ValueBox box = (ValueBox) boxIt.next(); 83 boxToZone.put(box, zone); 84 } 85 } 86 } 87 88 89 do { 90 if(Options.v().verbose()) 91 G.v().out.println("[" + body.getMethod().getName() + "] Aggregating iteration " + aggregateCount + "..."); 92 93 95 changed = internalAggregate(body, boxToZone, onlyStackVars); 96 97 aggregateCount++; 98 } while(changed); 99 100 if(Options.v().time()) 101 Timers.v().aggregationTimer.end(); 102 103 } 104 105 private static boolean internalAggregate(StmtBody body, Map boxToZone, boolean onlyStackVars) 106 { 107 Iterator stmtIt; 108 LocalUses localUses; 109 LocalDefs localDefs; 110 ExceptionalUnitGraph graph; 111 boolean hadAggregation = false; 112 Chain units = body.getUnits(); 113 114 graph = new ExceptionalUnitGraph(body); 115 localDefs = new SmartLocalDefs(graph, new SimpleLiveLocals(graph)); 116 localUses = new SimpleLocalUses(graph, localDefs); 117 118 stmtIt = (new PseudoTopologicalOrderer()).newList(graph).iterator(); 119 120 while (stmtIt.hasNext()) 121 { 122 Stmt s = (Stmt)(stmtIt.next()); 123 124 if (!(s instanceof AssignStmt)) 125 continue; 126 127 Value lhs = ((AssignStmt)s).getLeftOp(); 128 if (!(lhs instanceof Local)) 129 continue; 130 131 if(onlyStackVars && !((Local) lhs).getName().startsWith("$")) 132 continue; 133 134 List lu = localUses.getUsesOf((AssignStmt)s); 135 if (lu.size() != 1) 136 continue; 137 138 UnitValueBoxPair usepair = (UnitValueBoxPair)lu.get(0); 139 Unit use = usepair.unit; 140 ValueBox useBox = usepair.valueBox; 141 142 List ld = localDefs.getDefsOfAt((Local)lhs, use); 143 if (ld.size() != 1) 144 continue; 145 146 if(boxToZone.get(((AssignStmt) s).getRightOpBox()) != boxToZone.get(usepair.valueBox)) 148 { 149 continue; 150 } 151 152 153 154 155 159 160 boolean cantAggr = false; 161 boolean propagatingInvokeExpr = false; 162 boolean propagatingFieldRef = false; 163 boolean propagatingArrayRef = false; 164 ArrayList fieldRefList = new ArrayList(); 165 166 Value rhs = ((AssignStmt)s).getRightOp(); 167 LinkedList localsUsed = new LinkedList(); 168 for (Iterator useIt = (s.getUseBoxes()).iterator(); 169 useIt.hasNext(); ) 170 { 171 Value v = ((ValueBox)(useIt.next())).getValue(); 172 if (v instanceof Local) 173 localsUsed.add(v); 174 else if (v instanceof InvokeExpr) 175 propagatingInvokeExpr = true; 176 else if(v instanceof ArrayRef) 177 propagatingArrayRef = true; 178 else if(v instanceof FieldRef) 179 { 180 propagatingFieldRef = true; 181 fieldRefList.add(v); 182 } 183 } 184 185 188 List path = graph.getExtendedBasicBlockPathBetween(s, use); 189 190 if (path == null) 191 continue; 192 193 Iterator pathIt = path.iterator(); 194 195 if (pathIt.hasNext()) 197 pathIt.next(); 198 199 while (pathIt.hasNext() && !cantAggr) 200 { 201 Stmt between = (Stmt)(pathIt.next()); 202 203 if(between != use) 204 { 205 207 for (Iterator it = between.getDefBoxes().iterator(); 208 it.hasNext(); ) 209 { 210 Value v = ((ValueBox)(it.next())).getValue(); 211 if (localsUsed.contains(v)) 212 { 213 cantAggr = true; 214 break; 215 } 216 217 if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) 218 { 219 if (v instanceof FieldRef) 220 { 221 if(propagatingInvokeExpr) 222 { 223 cantAggr = true; 224 break; 225 } 226 else if(propagatingFieldRef) 227 { 228 231 Iterator frIt = fieldRefList.iterator(); 232 while (frIt.hasNext()) 233 { 234 FieldRef fieldRef = (FieldRef) frIt.next(); 235 if(((FieldRef) v).getField() == fieldRef.getField()) 236 { 237 cantAggr = true; 238 break; 239 } 240 } 241 } 242 } 243 else if(v instanceof ArrayRef) 244 { 245 if(propagatingInvokeExpr) 246 { 247 cantAggr = true; 249 break; 250 } 251 else if(propagatingArrayRef) 252 { 253 257 cantAggr = true; 258 break; 259 } 260 } 261 } 262 } 263 264 if(propagatingInvokeExpr && between instanceof MonitorStmt) 266 cantAggr = true; 267 } 268 269 if(propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) 271 { 272 for( Iterator boxIt = (between.getUseBoxes()).iterator(); boxIt.hasNext(); ) { 273 final ValueBox box = (ValueBox) boxIt.next(); 274 275 if(between == use && box == useBox) 276 { 277 break; 280 } 281 282 Value v = box.getValue(); 283 284 if (v instanceof InvokeExpr || 285 (propagatingInvokeExpr && (v instanceof FieldRef || v instanceof ArrayRef))) 286 { 287 cantAggr = true; 288 break; 289 } 290 291 } 292 } 293 } 294 295 if (cantAggr) 297 { 298 continue; 299 } 300 301 302 303 Value aggregatee = ((AssignStmt)s).getRightOp(); 304 305 if (usepair.valueBox.canContainValue(aggregatee)) 306 { 307 boolean wasSimpleCopy = isSimpleCopy( usepair.unit ); 308 usepair.valueBox.setValue(aggregatee); 309 units.remove(s); 310 hadAggregation = true; 311 if( wasSimpleCopy ) { 318 usepair.unit.addAllTagsOf( s ); 320 } 321 } 322 else 323 { 333 } 334 } 335 return hadAggregation; 336 } 337 private static boolean isSimpleCopy( Unit u ) { 338 if( !(u instanceof DefinitionStmt) ) return false; 339 DefinitionStmt defstmt = (DefinitionStmt) u; 340 if( !( defstmt.getRightOp() instanceof Local ) ) return false; 341 if( !( defstmt.getLeftOp() instanceof Local ) ) return false; 342 return true; 343 } 344 345 } 346 347 | Popular Tags |