@@ -1031,14 +1031,26 @@ protected static boolean reduceJsr(BitSet visited, BasicBlock basicBlock, BitSet
10311031 }
10321032
10331033 protected static boolean reduceLoop (BitSet visited , BasicBlock basicBlock , BitSet jsrTargets ) {
1034+ Object clone = visited .clone ();
10341035 boolean reduced = reduce (visited , basicBlock .getSub1 (), jsrTargets );
10351036
10361037 if (reduced == false ) {
10371038 BitSet visitedMembers = new BitSet ();
1038- createContinueLoop (visitedMembers , basicBlock .getSub1 ());
1039- visited .andNot (visitedMembers );
1039+ BasicBlock updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visitedMembers , basicBlock .getSub1 ());
1040+
1041+ visited = (BitSet )((BitSet )clone ).clone ();
10401042 reduced = reduce (visited , basicBlock .getSub1 (), jsrTargets );
10411043
1044+ if (updateBasicBlock != null ) {
1045+ BasicBlock ifBasicBlock = basicBlock .getControlFlowGraph ().newBasicBlock (TYPE_IF , basicBlock .getSub1 ().getFromOffset (), basicBlock .getToOffset ());
1046+
1047+ ifBasicBlock .setCondition (END );
1048+ ifBasicBlock .setSub1 (basicBlock .getSub1 ());
1049+ ifBasicBlock .setNext (updateBasicBlock );
1050+ updateBasicBlock .getPredecessors ().add (ifBasicBlock );
1051+ basicBlock .setSub1 (ifBasicBlock );
1052+ }
1053+
10421054 if (reduced == false ) {
10431055 visitedMembers .clear ();
10441056
@@ -1209,7 +1221,9 @@ protected static void replaceLoopStartWithSwitchBreak(BitSet visited, BasicBlock
12091221 }
12101222 }
12111223
1212- protected static void createContinueLoop (BitSet visited , BasicBlock basicBlock ) {
1224+ protected static BasicBlock searchUpdateBlockAndCreateContinueLoop (BitSet visited , BasicBlock basicBlock ) {
1225+ BasicBlock updateBasicBlock = null ;
1226+
12131227 if (!basicBlock .matchType (GROUP_END ) && (visited .get (basicBlock .getIndex ()) == false )) {
12141228 visited .set (basicBlock .getIndex ());
12151229
@@ -1218,92 +1232,103 @@ protected static void createContinueLoop(BitSet visited, BasicBlock basicBlock)
12181232 case TYPE_JSR :
12191233 case TYPE_CONDITION :
12201234 case TYPE_CONDITION_TERNARY_OPERATOR :
1221- createContinueLoop (visited , basicBlock , basicBlock .getBranch ());
1235+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getBranch ());
12221236 case TYPE_START :
12231237 case TYPE_STATEMENTS :
12241238 case TYPE_GOTO :
12251239 case TYPE_GOTO_IN_TERNARY_OPERATOR :
12261240 case TYPE_LOOP :
1227- createContinueLoop (visited , basicBlock , basicBlock .getNext ());
1241+ if (updateBasicBlock == null ) {
1242+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getNext ());
1243+ }
12281244 break ;
12291245 case TYPE_TRY :
12301246 case TYPE_TRY_JSR :
12311247 case TYPE_TRY_ECLIPSE :
1232- createContinueLoop (visited , basicBlock , basicBlock .getSub1 ());
1248+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getSub1 ());
12331249 case TYPE_TRY_DECLARATION :
12341250 for (BasicBlock .ExceptionHandler exceptionHandler : basicBlock .getExceptionHandlers ()) {
1235- createContinueLoop (visited , basicBlock , exceptionHandler .getBasicBlock ());
1251+ if (updateBasicBlock == null ) {
1252+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , exceptionHandler .getBasicBlock ());
1253+ }
1254+ }
1255+ if (updateBasicBlock == null ) {
1256+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getNext ());
12361257 }
1237- createContinueLoop (visited , basicBlock , basicBlock .getNext ());
12381258 break ;
12391259 case TYPE_IF_ELSE :
12401260 case TYPE_TERNARY_OPERATOR :
1241- createContinueLoop (visited , basicBlock , basicBlock .getSub2 ());
1261+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getSub2 ());
12421262 case TYPE_IF :
1243- createContinueLoop (visited , basicBlock , basicBlock .getSub1 ());
1244- createContinueLoop (visited , basicBlock , basicBlock .getNext ());
1263+ if (updateBasicBlock == null ) {
1264+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getSub1 ());
1265+ }
1266+ if (updateBasicBlock == null ) {
1267+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getNext ());
1268+ }
12451269 break ;
12461270 case TYPE_CONDITION_OR :
12471271 case TYPE_CONDITION_AND :
1248- createContinueLoop (visited , basicBlock , basicBlock .getSub1 ());
1249- createContinueLoop (visited , basicBlock , basicBlock .getSub2 ());
1272+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getSub1 ());
1273+ if (updateBasicBlock == null ) {
1274+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getSub2 ());
1275+ }
12501276 break ;
12511277 case TYPE_SWITCH :
1252- createContinueLoop (visited , basicBlock , basicBlock .getNext ());
1278+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , basicBlock .getNext ());
12531279 case TYPE_SWITCH_DECLARATION :
12541280 for (SwitchCase switchCase : basicBlock .getSwitchCases ()) {
1255- createContinueLoop (visited , basicBlock , switchCase .getBasicBlock ());
1281+ if (updateBasicBlock == null ) {
1282+ updateBasicBlock = searchUpdateBlockAndCreateContinueLoop (visited , basicBlock , switchCase .getBasicBlock ());
1283+ }
12561284 }
12571285 break ;
12581286 }
12591287 }
1288+
1289+ return updateBasicBlock ;
12601290 }
12611291
1262- protected static void createContinueLoop (BitSet visited , BasicBlock basicBlock , BasicBlock subBasicBlock ) {
1292+ protected static BasicBlock searchUpdateBlockAndCreateContinueLoop (BitSet visited , BasicBlock basicBlock , BasicBlock subBasicBlock ) {
12631293 if (subBasicBlock != null ) {
1264- if ((subBasicBlock .getPredecessors ().size () > 1 ) && (basicBlock .getFromOffset () < subBasicBlock .getFromOffset ())) {
1265- boolean condition ;
1294+ if (basicBlock .getFromOffset () < subBasicBlock .getFromOffset ()) {
12661295
12671296 if (basicBlock .getFirstLineNumber () == Expression .UNKNOWN_LINE_NUMBER ) {
1268- condition = subBasicBlock .matchType (GROUP_SINGLE_SUCCESSOR ) && (subBasicBlock .getNext ().getType () == TYPE_LOOP_START );
1269- } else {
1270- condition = (basicBlock .getFirstLineNumber () > subBasicBlock .getFirstLineNumber ());
1271- }
1272-
1273- if (condition ) {
1274- Set <BasicBlock > predecessors = subBasicBlock .getPredecessors ();
1275- Iterator <BasicBlock > iterator = predecessors .iterator ();
1276- BasicBlock lastPredecessor = iterator .next ();
1297+ if (subBasicBlock .matchType (GROUP_SINGLE_SUCCESSOR ) && (subBasicBlock .getNext ().getType () == TYPE_LOOP_START )) {
1298+ int stackDepth = ByteCodeParser .evalStackDepth (subBasicBlock );
12771299
1278- if (lastPredecessor .getType () != TYPE_GOTO_IN_TERNARY_OPERATOR ) {
1279- while (iterator .hasNext ()) {
1280- BasicBlock predecessor = iterator .next ();
1281- if (predecessor .getType () == TYPE_GOTO_IN_TERNARY_OPERATOR ) {
1282- lastPredecessor = null ;
1300+ while (stackDepth != 0 ) {
1301+ Set <BasicBlock > predecessors = basicBlock .getPredecessors ();
1302+ if (predecessors .size () != 1 ) {
12831303 break ;
12841304 }
1285- if (lastPredecessor .getFromOffset () < predecessor .getFromOffset ()) {
1286- lastPredecessor = predecessor ;
1287- }
1305+ stackDepth += ByteCodeParser .evalStackDepth (subBasicBlock = predecessors .iterator ().next ());
12881306 }
12891307
1290- if (lastPredecessor != null ) {
1291- iterator = predecessors .iterator ();
1292-
1293- while (iterator .hasNext ()) {
1294- BasicBlock predecessor = iterator .next ();
1295- if (predecessor != lastPredecessor ) {
1296- iterator .remove ();
1297- predecessor .replace (subBasicBlock , LOOP_CONTINUE );
1298- }
1299- }
1300- }
1308+ removePredecessors (subBasicBlock );
1309+ return subBasicBlock ;
13011310 }
1311+ } else if (basicBlock .getFirstLineNumber () > subBasicBlock .getFirstLineNumber ()) {
1312+ removePredecessors (subBasicBlock );
1313+ return subBasicBlock ;
13021314 }
13031315 }
13041316
1305- createContinueLoop (visited , subBasicBlock );
1317+ return searchUpdateBlockAndCreateContinueLoop (visited , subBasicBlock );
13061318 }
1319+
1320+ return null ;
1321+ }
1322+
1323+ protected static void removePredecessors (BasicBlock basicBlock ) {
1324+ Set <BasicBlock > predecessors = basicBlock .getPredecessors ();
1325+ Iterator <BasicBlock > iterator = predecessors .iterator ();
1326+
1327+ while (iterator .hasNext ()) {
1328+ iterator .next ().replace (basicBlock , LOOP_CONTINUE );
1329+ }
1330+
1331+ predecessors .clear ();
13071332 }
13081333
13091334 protected static void changeEndLoopToJump (BitSet visited , BasicBlock target , BasicBlock basicBlock ) {
0 commit comments