Browse Source

Allow viewing the intermediate ILAst steps.

pull/10/head
Daniel Grunwald 15 years ago
parent
commit
ea0c2df3ff
  1. 19
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  2. 1
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  3. 24
      ILSpy/ILAstLanguage.cs

19
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -8,16 +8,29 @@ using Decompiler.Rocks;
namespace Decompiler.ControlFlow namespace Decompiler.ControlFlow
{ {
public enum ILAstOptimizationStep
{
SplitToMovableBlocks,
FindLoops,
FindConditions,
FlattenNestedMovableBlocks,
SimpleGotoRemoval,
RemoveDeadLabels,
None
}
public class ILAstOptimizer public class ILAstOptimizer
{ {
Dictionary<ILLabel, ControlFlowNode> labelToCfNode = new Dictionary<ILLabel, ControlFlowNode>(); Dictionary<ILLabel, ControlFlowNode> labelToCfNode = new Dictionary<ILLabel, ControlFlowNode>();
public void Optimize(ILBlock method) public void Optimize(ILBlock method, ILAstOptimizationStep abortBeforeStep = ILAstOptimizationStep.None)
{ {
if (abortBeforeStep == ILAstOptimizationStep.SplitToMovableBlocks) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
SplitToMovableBlocks(block); SplitToMovableBlocks(block);
} }
if (abortBeforeStep == ILAstOptimizationStep.FindLoops) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) {
ControlFlowGraph graph; ControlFlowGraph graph;
graph = BuildGraph(block.Body, block.EntryPoint); graph = BuildGraph(block.Body, block.EntryPoint);
@ -26,6 +39,7 @@ namespace Decompiler.ControlFlow
block.Body = FindLoops(new HashSet<ControlFlowNode>(graph.Nodes.Skip(3)), graph.EntryPoint, true); block.Body = FindLoops(new HashSet<ControlFlowNode>(graph.Nodes.Skip(3)), graph.EntryPoint, true);
} }
if (abortBeforeStep == ILAstOptimizationStep.FindConditions) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) {
ControlFlowGraph graph; ControlFlowGraph graph;
graph = BuildGraph(block.Body, block.EntryPoint); graph = BuildGraph(block.Body, block.EntryPoint);
@ -35,8 +49,11 @@ namespace Decompiler.ControlFlow
} }
// OrderNodes(method); // OrderNodes(method);
if (abortBeforeStep == ILAstOptimizationStep.FlattenNestedMovableBlocks) return;
FlattenNestedMovableBlocks(method); FlattenNestedMovableBlocks(method);
if (abortBeforeStep == ILAstOptimizationStep.SimpleGotoRemoval) return;
SimpleGotoRemoval(method); SimpleGotoRemoval(method);
if (abortBeforeStep == ILAstOptimizationStep.RemoveDeadLabels) return;
RemoveDeadLabels(method); RemoveDeadLabels(method);
} }

1
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -85,6 +85,7 @@ namespace Decompiler
public override void WriteTo(ITextOutput output) public override void WriteTo(ITextOutput output)
{ {
if (EntryPoint != null)
EntryPoint.WriteTo(output); EntryPoint.WriteTo(output);
foreach(ILNode child in this.Body) { foreach(ILNode child in this.Body) {
child.WriteTo(output); child.WriteTo(output);

24
ILSpy/ILAstLanguage.cs

@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Decompiler; using Decompiler;
using Decompiler.ControlFlow;
using Decompiler.Transforms; using Decompiler.Transforms;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
@ -33,17 +34,26 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public class ILAstLanguage : Language public class ILAstLanguage : Language
{ {
string name;
bool inlineVariables = true;
ILAstOptimizationStep? abortBeforeStep;
public override string Name { public override string Name {
get { get {
return "ILAst"; return name;
} }
} }
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{ {
var body = new ILAstBuilder().Build(method, false); ILBlock ilMethod = new ILBlock();
ilMethod.Body = new ILAstBuilder().Build(method, inlineVariables);
if (abortBeforeStep != null) {
new ILAstOptimizer().Optimize(ilMethod, abortBeforeStep.Value);
}
foreach (ILNode node in body) { foreach (ILNode node in ilMethod.Body) {
node.WriteTo(output); node.WriteTo(output);
output.WriteLine(); output.WriteLine();
} }
@ -52,7 +62,13 @@ namespace ICSharpCode.ILSpy
#if DEBUG #if DEBUG
internal static IEnumerable<ILAstLanguage> GetDebugLanguages() internal static IEnumerable<ILAstLanguage> GetDebugLanguages()
{ {
yield return new ILAstLanguage(); yield return new ILAstLanguage { name = "ILAst (unoptimized)", inlineVariables = false };
string nextName = "ILAst (variable inlining)";
foreach (ILAstOptimizationStep step in Enum.GetValues(typeof(ILAstOptimizationStep))) {
yield return new ILAstLanguage { name = nextName, abortBeforeStep = step };
nextName = "ILAst (after " + step + ")";
}
} }
#endif #endif

Loading…
Cancel
Save