1 19 20 25 26 27 package soot.jimple.toolkits.graph; 28 import soot.options.*; 29 30 31 import soot.*; 32 import soot.util.*; 33 import java.util.*; 34 import soot.jimple.*; 35 import soot.jimple.internal.*; 36 37 49 public class CriticalEdgeRemover extends BodyTransformer { 50 public CriticalEdgeRemover( Singletons.Global g ) {} 51 public static CriticalEdgeRemover v() { return G.v().soot_jimple_toolkits_graph_CriticalEdgeRemover(); } 52 53 56 protected void internalTransform(Body b, String phaseName, Map options) { 57 if(Options.v().verbose()) 58 G.v().out.println("[" + b.getMethod().getName() + 59 "] Removing Critical Edges..."); 60 removeCriticalEdges(b); 61 if(Options.v().verbose()) 62 G.v().out.println("[" + b.getMethod().getName() + 63 "] Removing Critical Edges done."); 64 65 } 66 67 77 private static Unit insertGotoAfter(Chain unitChain, Unit node, Unit target) { 78 Unit newGoto = Jimple.v().newGotoStmt(target); 79 unitChain.insertAfter(newGoto, node); 80 return newGoto; 81 } 82 83 93 94 private static Unit insertGotoBefore(Chain unitChain, Unit node, Unit target) 95 { 96 Unit newGoto = Jimple.v().newGotoStmt(target); 97 unitChain.insertBefore(newGoto, node); 98 newGoto.redirectJumpsToThisTo(node); 99 return newGoto; 100 } 101 102 110 private static void redirectBranch(Unit node, Unit oldTarget, Unit newTarget) { 111 Iterator targetIt = node.getUnitBoxes().iterator(); 112 while (targetIt.hasNext()) { 113 UnitBox targetBox = (UnitBox)targetIt.next(); 114 Unit target = (Unit)targetBox.getUnit(); 115 if (target == oldTarget) 116 targetBox.setUnit(newTarget); 117 } 118 } 119 120 132 135 private void removeCriticalEdges(Body b) { 136 Chain unitChain = b.getUnits(); 137 int size = unitChain.size(); 138 Map predecessors = new HashMap(2 * size + 1, 0.7f); 139 140 142 { 143 Iterator unitIt = unitChain.snapshotIterator(); 144 while (unitIt.hasNext()) { 145 Unit currentUnit = (Unit)unitIt.next(); 146 147 Iterator succsIt = currentUnit.getUnitBoxes().iterator(); 148 while (succsIt.hasNext()) { 149 Unit target = ((UnitBox)succsIt.next()).getUnit(); 150 List predList = (List)predecessors.get(target); 151 if (predList == null) { 152 predList = new ArrayList(); 153 predList.add(currentUnit); 154 predecessors.put(target, predList); 155 } else 156 predList.add(currentUnit); 157 } 158 } 159 } 160 161 162 { 163 165 166 167 Iterator unitIt = unitChain.snapshotIterator(); 168 169 Unit currentUnit = null; 170 Unit directPredecessor; 171 while (unitIt.hasNext()) { 172 directPredecessor = currentUnit; 173 currentUnit = (Unit)unitIt.next(); 174 175 List predList = (List)predecessors.get(currentUnit); 176 int nbPreds = (predList == null)? 0: predList.size(); 177 if (directPredecessor != null && directPredecessor.fallsThrough()) 178 nbPreds++; 179 180 if (nbPreds >= 2) { 181 185 if (directPredecessor != null && 186 directPredecessor.fallsThrough()) { 187 directPredecessor = insertGotoAfter(unitChain, directPredecessor, 188 currentUnit); 189 } 190 191 193 Iterator predIt = predList.iterator(); 194 while (predIt.hasNext()) { 195 Unit predecessor = (Unit)predIt.next(); 196 198 int nbSuccs = predecessor.getUnitBoxes().size(); 199 nbSuccs += predecessor.fallsThrough()? 1: 0; 200 if (nbSuccs >= 2) { 201 203 if (directPredecessor == null) 204 directPredecessor = insertGotoBefore(unitChain, currentUnit, 205 currentUnit); 206 else 207 directPredecessor = insertGotoAfter(unitChain, 208 directPredecessor, currentUnit); 209 210 redirectBranch(predecessor, currentUnit, directPredecessor); 211 } 212 } 213 } 214 } 215 } 216 } 217 } 218 | Popular Tags |