From 0cf43014897b3fe735c720edb74c82445a5ee96d Mon Sep 17 00:00:00 2001 From: Frank Laub Date: Mon, 15 Mar 2010 13:42:59 -0700 Subject: [PATCH] OptmizeReturn in order to replace gotos to a single return with a duplicate return for each branch --- .../Core/ControlFlowGraph.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/DotWeb.Decompiler/Core/ControlFlowGraph.cs b/src/DotWeb.Decompiler/Core/ControlFlowGraph.cs index 8fc5980..98c4663 100644 --- a/src/DotWeb.Decompiler/Core/ControlFlowGraph.cs +++ b/src/DotWeb.Decompiler/Core/ControlFlowGraph.cs @@ -33,6 +33,7 @@ public ControlFlowGraph() public void Structure() { CompoundConditionals(); + OptimizeReturn(); StructureLoops(); StructureConditionals(); StructureExceptions(); @@ -329,5 +330,32 @@ public ControlFlowGraph() } } } + + public void OptimizeReturn() { + var returns = this.Nodes.Cast().Where(x => x.FlowControl == FlowControl.Return); + if (returns.Count() == 1) { + var exit = returns.Single(); + if (exit.Statements.Count == 1) { + var returnStmt = exit.Statements.Single() as CodeReturnStatement; + if (returnStmt != null) { + var variableRef = returnStmt.Expression as CodeVariableReference; + if (variableRef != null) { + foreach (BasicBlock pred in exit.Predecessors) { + pred.Successors.Remove(exit); + var copy = new CodeReturnStatement { + Expression = returnStmt.Expression + }; + pred.Statements.Add(copy); + if (pred.LastInstruction.OpCode.FlowControl == FlowControl.Branch) { + pred.Instructions.Remove(pred.LastInstruction); + } + pred.Instructions.AddRange(exit.Instructions); + } + this.Nodes.Remove(exit); + } + } + } + } + } } }