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. 3
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  3. 24
      ILSpy/ILAstLanguage.cs

19
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -8,16 +8,29 @@ using Decompiler.Rocks; @@ -8,16 +8,29 @@ using Decompiler.Rocks;
namespace Decompiler.ControlFlow
{
public enum ILAstOptimizationStep
{
SplitToMovableBlocks,
FindLoops,
FindConditions,
FlattenNestedMovableBlocks,
SimpleGotoRemoval,
RemoveDeadLabels,
None
}
public class ILAstOptimizer
{
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()) {
SplitToMovableBlocks(block);
}
if (abortBeforeStep == ILAstOptimizationStep.FindLoops) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) {
ControlFlowGraph graph;
graph = BuildGraph(block.Body, block.EntryPoint);
@ -26,6 +39,7 @@ namespace Decompiler.ControlFlow @@ -26,6 +39,7 @@ namespace Decompiler.ControlFlow
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()) {
ControlFlowGraph graph;
graph = BuildGraph(block.Body, block.EntryPoint);
@ -35,8 +49,11 @@ namespace Decompiler.ControlFlow @@ -35,8 +49,11 @@ namespace Decompiler.ControlFlow
}
// OrderNodes(method);
if (abortBeforeStep == ILAstOptimizationStep.FlattenNestedMovableBlocks) return;
FlattenNestedMovableBlocks(method);
if (abortBeforeStep == ILAstOptimizationStep.SimpleGotoRemoval) return;
SimpleGotoRemoval(method);
if (abortBeforeStep == ILAstOptimizationStep.RemoveDeadLabels) return;
RemoveDeadLabels(method);
}

3
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

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

24
ILSpy/ILAstLanguage.cs

@ -21,6 +21,7 @@ using System.Collections.Generic; @@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Decompiler;
using Decompiler.ControlFlow;
using Decompiler.Transforms;
using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.CSharp;
@ -33,17 +34,26 @@ namespace ICSharpCode.ILSpy @@ -33,17 +34,26 @@ namespace ICSharpCode.ILSpy
/// </summary>
public class ILAstLanguage : Language
{
string name;
bool inlineVariables = true;
ILAstOptimizationStep? abortBeforeStep;
public override string Name {
get {
return "ILAst";
return name;
}
}
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);
output.WriteLine();
}
@ -52,7 +62,13 @@ namespace ICSharpCode.ILSpy @@ -52,7 +62,13 @@ namespace ICSharpCode.ILSpy
#if DEBUG
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

Loading…
Cancel
Save