Browse Source

Handle mutually nested loops/conditions

pull/10/head
David Srbecký 15 years ago
parent
commit
bcab82ec21
  1. 20
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 20
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

20
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -151,12 +151,20 @@ namespace Decompiler @@ -151,12 +151,20 @@ namespace Decompiler
*/
} else if (node is ILCondition) {
ILCondition conditionalNode = (ILCondition)node;
// Swap bodies
yield return new Ast.IfElseStatement {
Condition = new UnaryOperatorExpression(UnaryOperatorType.Not, MakeBranchCondition(conditionalNode.Condition)),
TrueStatement = TransformBlock(conditionalNode.FalseBlock),
FalseStatement = TransformBlock(conditionalNode.TrueBlock)
};
if (conditionalNode.FalseBlock.Body.Any()) {
// Swap bodies
yield return new Ast.IfElseStatement {
Condition = new UnaryOperatorExpression(UnaryOperatorType.Not, MakeBranchCondition(conditionalNode.Condition)),
TrueStatement = TransformBlock(conditionalNode.FalseBlock),
FalseStatement = TransformBlock(conditionalNode.TrueBlock)
};
} else {
yield return new Ast.IfElseStatement {
Condition = MakeBranchCondition(conditionalNode.Condition),
TrueStatement = TransformBlock(conditionalNode.TrueBlock),
FalseStatement = TransformBlock(conditionalNode.FalseBlock)
};
}
} else if (node is ILTryCatchBlock) {
ILTryCatchBlock tryCatchNode = ((ILTryCatchBlock)node);
List<Ast.CatchClause> catchClauses = new List<CatchClause>();

20
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -14,18 +14,20 @@ namespace Decompiler.ControlFlow @@ -14,18 +14,20 @@ namespace Decompiler.ControlFlow
public void Optimize(ILBlock method)
{
var blocks = method.GetSelfAndChildrenRecursive<ILBlock>().ToList();
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
SplitToMovableBlocks(block);
}
foreach(ILBlock block in blocks) {
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) {
ControlFlowGraph graph;
SplitToMovableBlocks(block);
graph = BuildGraph(block.Body, block.EntryPoint);
graph.ComputeDominance();
graph.ComputeDominanceFrontier();
block.Body = FindLoops(new HashSet<ControlFlowNode>(graph.Nodes.Skip(3)), graph.EntryPoint);
}
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) {
ControlFlowGraph graph;
graph = BuildGraph(block.Body, block.EntryPoint);
graph.ComputeDominance();
graph.ComputeDominanceFrontier();
@ -153,7 +155,7 @@ namespace Decompiler.ControlFlow @@ -153,7 +155,7 @@ namespace Decompiler.ControlFlow
return new ControlFlowGraph(cfNodes.ToArray());
}
static List<ILNode> FindLoops(HashSet<ControlFlowNode> nodes, ControlFlowNode entryPoint)
List<ILNode> FindLoops(HashSet<ControlFlowNode> nodes, ControlFlowNode entryPoint)
{
List<ILNode> result = new List<ILNode>();
@ -171,7 +173,9 @@ namespace Decompiler.ControlFlow @@ -171,7 +173,9 @@ namespace Decompiler.ControlFlow
// Move the content into loop block
nodes.ExceptWith(loopContents);
result.Add(new ILLoop() { ContentBlock = new ILBlock(FindLoops(loopContents, node)) });
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 } });
}
// Using the dominator tree should ensure we find the the widest loop first

Loading…
Cancel
Save