From c7e7a24efa3a456df59f60264bd3c29ffa60c605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Tue, 15 Feb 2011 20:20:38 +0000 Subject: [PATCH] Slight improvement in the node order in loops --- .../ILAst/ILAstOptimizer.cs | 108 ++++++++++-------- 1 file changed, 58 insertions(+), 50 deletions(-) diff --git a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs index 8ac3f29f3..8e6793384 100644 --- a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs +++ b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs @@ -23,7 +23,7 @@ namespace Decompiler.ControlFlow graph = BuildGraph(block.Body, block.EntryPoint); graph.ComputeDominance(); graph.ComputeDominanceFrontier(); - block.Body = FindLoops(new HashSet(graph.Nodes.Skip(3)), graph.EntryPoint); + block.Body = FindLoops(new HashSet(graph.Nodes.Skip(3)), graph.EntryPoint, false); } foreach(ILBlock block in method.GetSelfAndChildrenRecursive().Where(b => !(b is ILMoveableBlock)).ToList()) { @@ -34,7 +34,7 @@ namespace Decompiler.ControlFlow block.Body = FindConditions(new HashSet(graph.Nodes.Skip(3)), graph.EntryPoint); } - OrderNodes(method); + // OrderNodes(method); FlattenNestedMovableBlocks(method); SimpleGotoRemoval(method); RemoveDeadLabels(method); @@ -155,7 +155,7 @@ namespace Decompiler.ControlFlow return new ControlFlowGraph(cfNodes.ToArray()); } - List FindLoops(HashSet nodes, ControlFlowNode entryPoint) + List FindLoops(HashSet nodes, ControlFlowNode entryPoint, bool excludeEntryPoint) { List result = new List(); @@ -166,7 +166,7 @@ namespace Decompiler.ControlFlow if (nodes.Contains(node) && node.DominanceFrontier.Contains(node) - && node != entryPoint) + && (node != entryPoint || !excludeEntryPoint)) { HashSet loopContents = new HashSet(); FindLoopContents(nodes, loopContents, node, node); @@ -175,7 +175,7 @@ namespace Decompiler.ControlFlow nodes.ExceptWith(loopContents); ILLabel entryLabel = new ILLabel() { Name = "Loop_" + (nextBlockIndex++) }; ((ILBlock)node.UserData).Body.Insert(0, entryLabel); - result.Add(new ILLoop() { ContentBlock = new ILBlock(FindLoops(loopContents, node)) { EntryPoint = entryLabel } }); + result.Add(new ILLoop() { ContentBlock = new ILBlock(FindLoops(loopContents, node, true)) { EntryPoint = entryLabel } }); } // Using the dominator tree should ensure we find the the widest loop first @@ -210,58 +210,66 @@ namespace Decompiler.ControlFlow while(agenda.Count > 0) { ControlFlowNode node = agenda.Dequeue(); - ILMoveableBlock block = node.UserData as ILMoveableBlock; - // Find a block that represents a simple condition - if (nodes.Contains(node) && block != null && block.Body.Count == 3) { + if (nodes.Contains(node)) { - ILLabel label = block.Body[0] as ILLabel; - ILExpression condBranch = block.Body[1] as ILExpression; - ILExpression statBranch = block.Body[2] as ILExpression; + ILMoveableBlock block = node.UserData as ILMoveableBlock; - if (label != null && - condBranch != null && condBranch.Operand is ILLabel && condBranch.Arguments.Count > 0 && - statBranch != null && statBranch.Operand is ILLabel && statBranch.Arguments.Count == 0) - { - ControlFlowNode condTarget; - ControlFlowNode statTarget; - if (labelToCfNode.TryGetValue((ILLabel)condBranch.Operand, out condTarget) && - labelToCfNode.TryGetValue((ILLabel)statBranch.Operand, out statTarget)) + if (block != null && block.Body.Count == 3) { + ILLabel label = block.Body[0] as ILLabel; + ILExpression condBranch = block.Body[1] as ILExpression; + ILExpression statBranch = block.Body[2] as ILExpression; + + if (label != null && + condBranch != null && condBranch.Operand is ILLabel && condBranch.Arguments.Count > 0 && + statBranch != null && statBranch.Operand is ILLabel && statBranch.Arguments.Count == 0) { - ILCondition condition = new ILCondition() { - Condition = condBranch, - TrueBlock = new ILBlock() { EntryPoint = (ILLabel)condBranch.Operand }, - FalseBlock = new ILBlock() { EntryPoint = (ILLabel)statBranch.Operand } - }; - - // The label will not be used - kill it - condBranch.Operand = null; - - // Replace the two branches with a conditional structure - block.Body.Remove(condBranch); - block.Body.Remove(statBranch); - block.Body.Add(condition); - result.Add(block); - - // Pull in the conditional code - HashSet frontiers = new HashSet(); - frontiers.UnionWith(condTarget.DominanceFrontier); - frontiers.UnionWith(statTarget.DominanceFrontier); - - if (!frontiers.Contains(condTarget)) { - HashSet content = FindDominatedNodes(nodes, condTarget); - nodes.ExceptWith(content); - condition.TrueBlock.Body.AddRange(FindConditions(content, condTarget)); + ControlFlowNode condTarget; + ControlFlowNode statTarget; + if (labelToCfNode.TryGetValue((ILLabel)condBranch.Operand, out condTarget) && + labelToCfNode.TryGetValue((ILLabel)statBranch.Operand, out statTarget)) + { + ILCondition condition = new ILCondition() { + Condition = condBranch, + TrueBlock = new ILBlock() { EntryPoint = (ILLabel)condBranch.Operand }, + FalseBlock = new ILBlock() { EntryPoint = (ILLabel)statBranch.Operand } + }; + + // The label will not be used - kill it + condBranch.Operand = null; + + // Replace the two branches with a conditional structure + block.Body.Remove(condBranch); + block.Body.Remove(statBranch); + block.Body.Add(condition); + result.Add(block); + + // Pull in the conditional code + HashSet frontiers = new HashSet(); + frontiers.UnionWith(condTarget.DominanceFrontier); + frontiers.UnionWith(statTarget.DominanceFrontier); + + if (!frontiers.Contains(condTarget)) { + HashSet content = FindDominatedNodes(nodes, condTarget); + nodes.ExceptWith(content); + condition.TrueBlock.Body.AddRange(FindConditions(content, condTarget)); + } + if (!frontiers.Contains(statTarget)) { + HashSet content = FindDominatedNodes(nodes, statTarget); + nodes.ExceptWith(content); + condition.FalseBlock.Body.AddRange(FindConditions(content, statTarget)); + } + + nodes.Remove(node); } - if (!frontiers.Contains(statTarget)) { - HashSet content = FindDominatedNodes(nodes, statTarget); - nodes.ExceptWith(content); - condition.FalseBlock.Body.AddRange(FindConditions(content, statTarget)); - } - - nodes.Remove(node); } } + + // Add the node now so that we have good ordering + if (nodes.Contains(node)) { + result.Add((ILNode)node.UserData); + nodes.Remove(node); + } } // Using the dominator tree should ensure we find the the widest loop first