Browse Source

Reduce 'if' statements in loops.

pull/1/head^2
David Srbecký 18 years ago
parent
commit
08528a768a
  1. 12
      src/AstBuilder.cs
  2. 30
      src/ControlFlow/Node-Optimize.cs

12
src/AstBuilder.cs

@ -35,12 +35,12 @@ namespace Decompiler
astCompileUnit.AcceptVisitor(csOutVisitor, null); astCompileUnit.AcceptVisitor(csOutVisitor, null);
string code = csOutVisitor.Text; string code = csOutVisitor.Text;
code = code.Replace(":\r\n\t\t\t", ": "); // code = code.Replace(":\r\n\t\t\t", ": ");
code = code.Replace(": }", ":\r\n\t\t\t}"); // code = code.Replace(": }", ":\r\n\t\t\t}");
code = code.Replace(":\r\n\t\t", ": "); // code = code.Replace(":\r\n\t\t", ": ");
code = code.Replace(": }", ":\r\n\t\t}"); // code = code.Replace(": }", ":\r\n\t\t}");
code = code.Replace(":\r\n\t", ": "); // code = code.Replace(":\r\n\t", ": ");
code = code.Replace(": }", ":\r\n\t}"); // code = code.Replace(": }", ":\r\n\t}");
code = code.Replace("\t", " "); code = code.Replace("\t", " ");
code = code.Replace("\"/*", ""); code = code.Replace("\"/*", "");
code = code.Replace("*/\";", ""); code = code.Replace("*/\";", "");

30
src/ControlFlow/Node-Optimize.cs

@ -39,30 +39,42 @@ namespace Decompiler.ControlFlow
} }
} }
NodeCollection GetReachableNodes() NodeCollection GetReachableNodes(Node exclude)
{ {
NodeCollection reachableNodes = new NodeCollection(); NodeCollection reachableNodes = new NodeCollection();
reachableNodes.Add(this); reachableNodes.Add(this);
for(int i = 0; i < reachableNodes.Count; i++) { for(int i = 0; i < reachableNodes.Count; i++) {
reachableNodes.AddRange(reachableNodes[i].Successors); reachableNodes.AddRange(reachableNodes[i].Successors);
reachableNodes.Remove(exclude);
} }
return reachableNodes; return reachableNodes;
} }
public void OptimizeIf() public void OptimizeIf()
{ {
foreach(Node child in this.Childs) {
if (child is Loop) {
child.OptimizeIf();
}
}
Node conditionNode = this.HeadChild; Node conditionNode = this.HeadChild;
// Find conditionNode (the start) // Find conditionNode (the start)
while(true) { while(conditionNode != null) {
if (conditionNode is BasicBlock && conditionNode.Successors.Count == 2) { if (conditionNode is BasicBlock && conditionNode.Successors.Count == 2) {
// Found if start // Found if start
OptimizeIf((BasicBlock)conditionNode); OptimizeIf((BasicBlock)conditionNode);
return; conditionNode = this.HeadChild;
} else if (conditionNode.Successors.Count == 1) { continue; // Restart
} else if (conditionNode.Successors.Count > 0) {
// Keep looking down
conditionNode = conditionNode.Successors[0]; conditionNode = conditionNode.Successors[0];
if (conditionNode == this.HeadChild) {
return;
}
continue; // Next continue; // Next
} else { } else {
return; // Just give up return; // End of block
} }
} }
} }
@ -75,8 +87,8 @@ namespace Decompiler.ControlFlow
Debug.Assert(falseStart != null); Debug.Assert(falseStart != null);
Debug.Assert(trueStart != falseStart); Debug.Assert(trueStart != falseStart);
NodeCollection trueReachable = trueStart.GetReachableNodes(); NodeCollection trueReachable = trueStart.GetReachableNodes(condition);
NodeCollection falseReachable = falseStart.GetReachableNodes(); NodeCollection falseReachable = falseStart.GetReachableNodes(condition);
NodeCollection commonReachable = NodeCollection.Intersect(trueReachable, falseReachable); NodeCollection commonReachable = NodeCollection.Intersect(trueReachable, falseReachable);
NodeCollection trueNodes = trueReachable.Clone(); NodeCollection trueNodes = trueReachable.Clone();
@ -96,6 +108,10 @@ namespace Decompiler.ControlFlow
if (Options.ReduceGraph-- <= 0) return; if (Options.ReduceGraph-- <= 0) return;
falseNodes.MoveTo(conditionalNode.FalseBody); falseNodes.MoveTo(conditionalNode.FalseBody);
// Optimize the created subtrees
conditionalNode.TrueBody.OptimizeIf();
conditionalNode.FalseBody.OptimizeIf();
} }
} }
} }

Loading…
Cancel
Save