1 19 20 23 24 33 34 38 39 package soot.dava.toolkits.base.AST.traversals; 40 41 import soot.*; 42 import java.util.*; 43 import soot.jimple.*; 44 import soot.dava.internal.javaRep.*; 45 import soot.dava.internal.AST.*; 46 import soot.dava.internal.asg.*; 47 import soot.dava.toolkits.base.AST.analysis.*; 48 import soot.dava.toolkits.base.AST.structuredAnalysis.*; 49 50 71 72 public class CopyPropagation extends DepthFirstAdapter{ 73 ASTNode AST; 74 ASTUsesAndDefs useDefs; 75 ReachingCopies reachingCopies; 76 ASTParentNodeFinder parentOf; 77 78 boolean someCopyStmtModified; 79 80 boolean ASTMODIFIED; 83 84 public CopyPropagation(ASTNode AST){ 85 super(); 86 someCopyStmtModified=false; 87 this.AST=AST; 88 ASTMODIFIED=false; 89 setup(); 90 } 91 92 public CopyPropagation(boolean verbose,ASTNode AST){ 93 super(verbose); 94 someCopyStmtModified=false; 95 this.AST=AST; 96 ASTMODIFIED=false; 97 setup(); 98 } 99 100 101 102 private void setup(){ 103 useDefs = new ASTUsesAndDefs(AST); 105 AST.apply(useDefs); 106 107 reachingCopies = new ReachingCopies(AST); 109 110 parentOf = new ASTParentNodeFinder(); 111 AST.apply(parentOf); 112 } 113 114 115 119 public void outASTMethodNode(ASTMethodNode node){ 120 if(ASTMODIFIED){ 121 123 AST.apply(ClosestAbruptTargetFinder.v()); 125 126 128 CopyPropagation prop1 = new CopyPropagation(AST); 129 AST.apply(prop1); 130 } 131 } 132 133 134 135 136 public void inASTStatementSequenceNode(ASTStatementSequenceNode node){ 137 List statements = node.getStatements(); 138 Iterator it = statements.iterator(); 139 140 while(it.hasNext()){ 141 AugmentedStmt as = (AugmentedStmt)it.next(); 142 Stmt s = as.get_Stmt(); 143 if(isCopyStmt(s)){ 144 handleCopyStmt((DefinitionStmt)s); 145 } 146 } 147 } 148 149 150 151 152 public boolean isCopyStmt(Stmt s){ 153 if(!(s instanceof DefinitionStmt)){ 154 return false; 156 } 157 158 Value leftOp = ((DefinitionStmt)s).getLeftOp(); 161 Value rightOp = ((DefinitionStmt)s).getRightOp(); 162 163 if(leftOp instanceof Local && rightOp instanceof Local){ 164 return true; 166 } 167 return false; 168 } 169 170 171 172 179 public void handleCopyStmt(DefinitionStmt copyStmt){ 180 182 Local definedLocal = (Local)copyStmt.getLeftOp(); 184 185 Object temp = useDefs.getDUChain(copyStmt); 187 188 ArrayList uses= new ArrayList(); 189 if(temp != null){ 190 uses = (ArrayList)temp; 191 } 192 193 195 if(uses.size()!=0){ 197 198 201 202 204 Local leftLocal = (Local)copyStmt.getLeftOp(); 206 Local rightLocal = (Local)copyStmt.getRightOp(); 207 208 ReachingCopies.LocalPair localPair = reachingCopies.new LocalPair(leftLocal,rightLocal); 209 210 Iterator useIt = uses.iterator(); 212 while(useIt.hasNext()){ 213 Object tempUse = useIt.next(); 216 217 DavaFlowSet reaching = reachingCopies.getReachingCopies(tempUse); 218 219 if(!reaching.contains(localPair)){ 220 return; 223 } 224 } 225 226 228 useIt = uses.iterator(); 230 while(useIt.hasNext()){ 231 Object tempUse = useIt.next(); 232 replace(leftLocal,rightLocal,tempUse); 233 } 234 235 removeStmt(copyStmt); 237 238 239 if(someCopyStmtModified){ 240 setup(); 242 someCopyStmtModified=false; 243 } 244 } 245 else{ 246 removeStmt(copyStmt); 249 } 250 } 251 252 253 254 public void removeStmt(Stmt stmt){ 255 Object tempParent = parentOf.getParentOf(stmt); 256 if(tempParent == null){ 257 return; 259 } 260 261 ASTNode parent = (ASTNode)tempParent; 263 264 if(!(parent instanceof ASTStatementSequenceNode)){ 266 throw new RuntimeException ("Found a stmt whose parent is not an ASTStatementSequenceNode"); 268 } 269 ASTStatementSequenceNode parentNode = (ASTStatementSequenceNode)parent; 270 271 ArrayList newSequence = new ArrayList(); 272 273 Iterator it = parentNode.getStatements().iterator(); 274 while (it.hasNext()){ 275 AugmentedStmt as = (AugmentedStmt)it.next(); 276 Stmt s = as.get_Stmt(); 277 if(s.toString().compareTo(stmt.toString())!=0){ 278 newSequence.add(as); 280 } 281 } 282 parentNode.setStatements(newSequence); 284 285 ASTMODIFIED=true; 286 return; 287 } 288 289 290 291 292 293 294 298 public void replaceBoxes(Local from, Local to, List useBoxes){ 299 Iterator it = useBoxes.iterator(); 300 while(it.hasNext()){ 301 ValueBox valBox =(ValueBox)it.next(); 302 Value val = valBox.getValue(); 303 if(val instanceof Local){ 304 Local local = (Local)val; 305 if(local.getName().compareTo(from.getName())==0){ 306 valBox.setValue(to); 308 ASTMODIFIED=true; 309 } 310 } 311 } 312 } 313 314 315 316 317 318 321 public List getUseList(ASTCondition cond){ 322 if(cond instanceof ASTAggregatedCondition){ 323 ArrayList useList = new ArrayList(); 324 useList.addAll(getUseList(((ASTAggregatedCondition)cond).getLeftOp())); 325 useList.addAll(getUseList(((ASTAggregatedCondition)cond).getRightOp())); 326 return useList; 327 } 328 else if(cond instanceof ASTUnaryCondition){ 329 Value val = ((ASTUnaryCondition)cond).getValue(); 331 return val.getUseBoxes(); 332 } 333 else if(cond instanceof ASTBinaryCondition){ 334 Value val = ((ASTBinaryCondition)cond).getConditionExpr(); 336 return val.getUseBoxes(); 337 } 338 else{ 339 throw new RuntimeException ("Method getUseList in CopyPropagation encountered unknown condition type"); 340 } 341 } 342 343 344 345 346 347 348 349 350 356 357 public void replace(Local from, Local to, Object use){ 358 if(use instanceof Stmt){ 359 Stmt s = (Stmt)use; 360 if(isCopyStmt(s)){ 361 someCopyStmtModified=true; 362 } 363 List useBoxes = s.getUseBoxes(); 364 replaceBoxes(from,to,useBoxes); 365 } 366 else if (use instanceof ASTNode){ 367 if (use instanceof ASTSwitchNode){ 368 ASTSwitchNode temp = (ASTSwitchNode)use; 369 Value val = (Value)temp.get_Key(); 370 if(val instanceof Local){ 371 if(((Local)val).getName().compareTo(from.getName())==0){ 372 ASTMODIFIED=true; 374 temp.set_Key(to); 375 } 376 } 377 else{ 378 List useBoxes = val.getUseBoxes(); 379 replaceBoxes(from,to,useBoxes); 380 } 381 } 382 else if (use instanceof ASTSynchronizedBlockNode){ 383 ASTSynchronizedBlockNode temp = (ASTSynchronizedBlockNode)use; 384 Local local = temp.getLocal(); 385 if(local.getName().compareTo(from.getName())==0){ 386 temp.setLocal(to); 388 ASTMODIFIED=true; 389 } 390 } 391 else if(use instanceof ASTIfNode){ 392 ASTIfNode temp = (ASTIfNode)use; 393 ASTCondition cond = temp.get_Condition(); 394 List useBoxes = getUseList(cond); 395 replaceBoxes(from,to,useBoxes); 396 } 397 else if (use instanceof ASTIfElseNode){ 398 ASTIfElseNode temp = (ASTIfElseNode)use; 399 ASTCondition cond = temp.get_Condition(); 400 List useBoxes = getUseList(cond); 401 replaceBoxes(from,to,useBoxes); 402 } 403 else if (use instanceof ASTWhileNode){ 404 ASTWhileNode temp = (ASTWhileNode)use; 405 ASTCondition cond = temp.get_Condition(); 406 List useBoxes = getUseList(cond); 407 replaceBoxes(from,to,useBoxes); 408 } 409 else if (use instanceof ASTDoWhileNode){ 410 ASTDoWhileNode temp = (ASTDoWhileNode)use; 411 ASTCondition cond = temp.get_Condition(); 412 List useBoxes = getUseList(cond); 413 replaceBoxes(from,to,useBoxes); 414 } 415 else if (use instanceof ASTForLoopNode){ 416 ASTForLoopNode temp = (ASTForLoopNode)use; 417 418 List init = temp.getInit(); 420 Iterator it = init.iterator(); 421 while(it.hasNext()){ 422 AugmentedStmt as = (AugmentedStmt)it.next(); 423 Stmt s = as.get_Stmt(); 424 replace(from,to,s); 425 } 426 427 428 List update = temp.getUpdate(); 430 it = update.iterator(); 431 while(it.hasNext()){ 432 AugmentedStmt as = (AugmentedStmt)it.next(); 433 Stmt s = as.get_Stmt(); 434 replace(from,to,s); 435 } 436 437 438 ASTCondition cond = temp.get_Condition(); 440 List useBoxes = getUseList(cond); 441 replaceBoxes(from,to,useBoxes); 442 } 443 else{ 444 throw new RuntimeException ("Encountered an unknown ASTNode in copyPropagation method replace"); 445 } 446 } 447 else{ 448 throw new RuntimeException ("Encountered an unknown use in copyPropagation method replace"); 449 } 450 451 } 452 453 454 } | Popular Tags |