From 08528a768aeeb2a1e460134d63553b35fdceb728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Sun, 27 Jan 2008 23:43:05 +0000 Subject: [PATCH] Reduce 'if' statements in loops. --- src/AstBuilder.cs | 12 ++++++------ src/ControlFlow/Node-Optimize.cs | 30 +++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/AstBuilder.cs b/src/AstBuilder.cs index 94d86d32f..a67b9af8b 100644 --- a/src/AstBuilder.cs +++ b/src/AstBuilder.cs @@ -35,12 +35,12 @@ namespace Decompiler astCompileUnit.AcceptVisitor(csOutVisitor, null); 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", ": "); - 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\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", ": "); +// code = code.Replace(": }", ":\r\n\t}"); code = code.Replace("\t", " "); code = code.Replace("\"/*", ""); code = code.Replace("*/\";", ""); diff --git a/src/ControlFlow/Node-Optimize.cs b/src/ControlFlow/Node-Optimize.cs index c9258da2b..c251331a8 100644 --- a/src/ControlFlow/Node-Optimize.cs +++ b/src/ControlFlow/Node-Optimize.cs @@ -39,30 +39,42 @@ namespace Decompiler.ControlFlow } } - NodeCollection GetReachableNodes() + NodeCollection GetReachableNodes(Node exclude) { NodeCollection reachableNodes = new NodeCollection(); reachableNodes.Add(this); for(int i = 0; i < reachableNodes.Count; i++) { reachableNodes.AddRange(reachableNodes[i].Successors); + reachableNodes.Remove(exclude); } return reachableNodes; } public void OptimizeIf() { + foreach(Node child in this.Childs) { + if (child is Loop) { + child.OptimizeIf(); + } + } + Node conditionNode = this.HeadChild; // Find conditionNode (the start) - while(true) { + while(conditionNode != null) { if (conditionNode is BasicBlock && conditionNode.Successors.Count == 2) { // Found if start OptimizeIf((BasicBlock)conditionNode); - return; - } else if (conditionNode.Successors.Count == 1) { + conditionNode = this.HeadChild; + continue; // Restart + } else if (conditionNode.Successors.Count > 0) { + // Keep looking down conditionNode = conditionNode.Successors[0]; + if (conditionNode == this.HeadChild) { + return; + } continue; // Next } else { - return; // Just give up + return; // End of block } } } @@ -75,8 +87,8 @@ namespace Decompiler.ControlFlow Debug.Assert(falseStart != null); Debug.Assert(trueStart != falseStart); - NodeCollection trueReachable = trueStart.GetReachableNodes(); - NodeCollection falseReachable = falseStart.GetReachableNodes(); + NodeCollection trueReachable = trueStart.GetReachableNodes(condition); + NodeCollection falseReachable = falseStart.GetReachableNodes(condition); NodeCollection commonReachable = NodeCollection.Intersect(trueReachable, falseReachable); NodeCollection trueNodes = trueReachable.Clone(); @@ -96,6 +108,10 @@ namespace Decompiler.ControlFlow if (Options.ReduceGraph-- <= 0) return; falseNodes.MoveTo(conditionalNode.FalseBody); + + // Optimize the created subtrees + conditionalNode.TrueBody.OptimizeIf(); + conditionalNode.FalseBody.OptimizeIf(); } } }