Browse Source

When looking what follows a 'goto' statement, exit and enter code blocks.

This simplifies code like:
if (p) {
    Code();
    goto Label;  // This goto is redundant
}
for(;;) {
    Label:
    Code();
}
pull/1/head^2
David Srbecký 18 years ago
parent
commit
ba59de34fb
  1. 60
      bin/Debug/output.cs
  2. 50
      src/Transforms/Ast/RemoveGotos.cs

60
bin/Debug/output.cs

@ -54,13 +54,11 @@ namespace Reversi
for (int j = -1; (j <= 1); j = (j + 1)) { for (int j = -1; (j <= 1); j = (j + 1)) {
if (!(i)) { if (!(i)) {
if (!(!j)) { if (!(!j)) {
goto BasicBlock_27;
} }
else { else {
continue; continue;
} }
} }
BasicBlock_27:
if (!(!@this.IsOutflanking(color, row, col, i, j))) { if (!(!@this.IsOutflanking(color, row, col, i, j))) {
int k = (row + i); int k = (row + i);
for (int l = (col + j);; l = (l + j)) { for (int l = (col + j);; l = (l + j)) {
@ -96,13 +94,11 @@ namespace Reversi
for (int j = -1; (j <= 1); j = (j + 1)) { for (int j = -1; (j <= 1); j = (j + 1)) {
if (!(i)) { if (!(i)) {
if (!(!j)) { if (!(!j)) {
goto BasicBlock_100;
} }
else { else {
continue; continue;
} }
} }
BasicBlock_100:
if (!(!@this.IsOutflanking(color, row, col, i, j))) { if (!(!@this.IsOutflanking(color, row, col, i, j))) {
return 1; return 1;
} }
@ -159,31 +155,19 @@ namespace Reversi
if (!(j > 7)) { if (!(j > 7)) {
if (!((i - dr) != row)) { if (!((i - dr) != row)) {
if (!((j - dc) == col)) { if (!((j - dc) == col)) {
goto BasicBlock_178;
} }
else { else {
goto BasicBlock_179; goto BasicBlock_179;
} }
} }
BasicBlock_178:
if (!((@this.squares).Get(i, j) == color)) { if (!((@this.squares).Get(i, j) == color)) {
goto BasicBlock_179;
} }
else { else {
goto BasicBlock_180; goto BasicBlock_180;
} }
} }
else {
goto BasicBlock_179;
}
}
else {
goto BasicBlock_179;
} }
} }
else {
goto BasicBlock_179;
}
} }
BasicBlock_179: BasicBlock_179:
return 0; return 0;
@ -215,15 +199,8 @@ namespace Reversi
if (!(@this.IsOutflankable(i, j))) { if (!(@this.IsOutflankable(i, j))) {
(@this.safeDiscs).Set(i, j, 1); (@this.safeDiscs).Set(i, j, 1);
V_2 = 1; V_2 = 1;
continue;
}
else {
continue;
} }
} }
else {
continue;
}
} }
} }
} }
@ -241,35 +218,20 @@ namespace Reversi
for (int l = -1; (l <= 1); l = (l + 1)) { for (int l = -1; (l <= 1); l = (l + 1)) {
if (!(k)) { if (!(k)) {
if (!(!l)) { if (!(!l)) {
goto BasicBlock_252;
} }
else { else {
continue; continue;
} }
} }
BasicBlock_252:
if (!((i + k) < 0)) { if (!((i + k) < 0)) {
if (!((i + k) >= 8)) { if (!((i + k) >= 8)) {
if (!((j + l) < 0)) { if (!((j + l) < 0)) {
if (!((j + l) >= 8)) { if (!((j + l) >= 8)) {
if (!((@this.squares).Get((i + k), (j + l)) != (IL__ldsfld(Empty)))) { if (!((@this.squares).Get((i + k), (j + l)) != (IL__ldsfld(Empty)))) {
V_5 = 1; V_5 = 1;
continue;
} }
else {
continue;
}
}
else {
continue;
} }
} }
else {
continue;
}
}
else {
continue;
} }
} }
} }
@ -292,10 +254,6 @@ namespace Reversi
object expr152 = expr151.blackSafeCount; object expr152 = expr151.blackSafeCount;
int expr158 = expr152 + 1; int expr158 = expr152 + 1;
expr151.blackSafeCount = expr158; expr151.blackSafeCount = expr158;
continue;
}
else {
continue;
} }
} }
else { else {
@ -349,9 +307,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(row, k))) { if (!((@this.safeDiscs).Get(row, k))) {
goto BasicBlock_400; goto BasicBlock_400;
} }
else {
goto BasicBlock_401;
}
} }
else { else {
goto BasicBlock_400; goto BasicBlock_400;
@ -381,9 +336,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(row, k))) { if (!((@this.safeDiscs).Get(row, k))) {
goto BasicBlock_409; goto BasicBlock_409;
} }
else {
goto BasicBlock_410;
}
} }
else { else {
goto BasicBlock_409; goto BasicBlock_409;
@ -427,9 +379,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(j, col))) { if (!((@this.safeDiscs).Get(j, col))) {
goto BasicBlock_425; goto BasicBlock_425;
} }
else {
goto BasicBlock_426;
}
} }
else { else {
goto BasicBlock_425; goto BasicBlock_425;
@ -459,9 +408,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(j, col))) { if (!((@this.safeDiscs).Get(j, col))) {
goto BasicBlock_434; goto BasicBlock_434;
} }
else {
goto BasicBlock_435;
}
} }
else { else {
goto BasicBlock_434; goto BasicBlock_434;
@ -508,9 +454,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(j, k))) { if (!((@this.safeDiscs).Get(j, k))) {
goto BasicBlock_450; goto BasicBlock_450;
} }
else {
goto BasicBlock_451;
}
} }
else { else {
goto BasicBlock_450; goto BasicBlock_450;
@ -547,9 +490,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(j, k))) { if (!((@this.safeDiscs).Get(j, k))) {
goto BasicBlock_460; goto BasicBlock_460;
} }
else {
goto BasicBlock_461;
}
} }
else { else {
goto BasicBlock_460; goto BasicBlock_460;

50
src/Transforms/Ast/RemoveGotos.cs

@ -80,21 +80,49 @@ namespace Decompiler.Transforms.Ast
return null; return null;
} }
public override object VisitGotoStatement(GotoStatement gotoStatement, object data) // Gets a next fall though statement, entering and exiting code blocks
// It does not matter what the current statement is
// May return null
public static Statement GetNextStatement(Statement statement)
{ {
// Find what is the next statement following this one if (statement == null) throw new ArgumentNullException();
// It does fall though loop entries (the loop must not have initializer and condition)
INode followingStmt = gotoStatement.Next(); Statement next = (Statement)statement.Next();
while(
(followingStmt as ForStatement) != null && // Exit a block of code
(followingStmt as ForStatement).Initializers.Count == 0 && if (next == null) {
(followingStmt as ForStatement).Condition.IsNull && // When an 'if' body is finished the execution continues with the
(followingStmt as ForStatement).EmbeddedStatement is BlockStatement) { // next statement after the 'if' statement
followingStmt = (followingStmt as ForStatement).EmbeddedStatement.Children.First; if (statement.Parent is BlockStatement &&
statement.Parent.Parent is IfElseStatement) {
return GetNextStatement((Statement)statement.Parent.Parent);
} else {
return null;
}
} }
// Enter a block of code
while(true) {
// If a 'for' loop does not have initializers and condition,
// the next statement is the entry point
ForStatement stmtAsForStmt = next as ForStatement;
if (stmtAsForStmt != null &&
stmtAsForStmt.Initializers.Count == 0 &&
stmtAsForStmt.Condition.IsNull &&
stmtAsForStmt.EmbeddedStatement is BlockStatement &&
stmtAsForStmt.EmbeddedStatement.Children.Count > 0) {
next = (Statement)stmtAsForStmt.EmbeddedStatement.Children.First;
continue; // Restart
}
return next;
}
}
public override object VisitGotoStatement(GotoStatement gotoStatement, object data)
{
// Remove redundant goto which goes to a label that imideately follows // Remove redundant goto which goes to a label that imideately follows
LabelStatement followingLabel = followingStmt as LabelStatement; LabelStatement followingLabel = GetNextStatement(gotoStatement) as LabelStatement;
if (followingLabel != null && followingLabel.Label == gotoStatement.Label) { if (followingLabel != null && followingLabel.Label == gotoStatement.Label) {
RemoveCurrentNode(); RemoveCurrentNode();
return null; return null;

Loading…
Cancel
Save