Browse Source

ConditionDetection: Remove empty else-branches.

pull/900/head
Siegfried Pammer 8 years ago
parent
commit
2d2ca893e9
  1. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  2. 17
      ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs
  3. 20
      ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -271,6 +271,7 @@ @@ -271,6 +271,7 @@
<Compile Include="DotNetCore\DotNetCorePathFinder.cs" />
<Compile Include="DotNetCore\DotNetCorePathFinderExtensions.cs" />
<Compile Include="DotNetCore\UnresolvedAssemblyNameReference.cs" />
<Compile Include="IL\Instructions\ILInstructionExtensions.cs" />
<Compile Include="IL\Transforms\EarlyExpressionTransforms.cs" />
<Compile Include="IL\Transforms\UsingTransform.cs" />
<Compile Include="IL\ControlFlow\AsyncAwaitDecompiler.cs" />

17
ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs

@ -176,10 +176,19 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -176,10 +176,19 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (DetectExitPoints.CompatibleExitInstruction(trueExitInst, falseExitInst)) {
// if (...) { ...; goto exitPoint; } goto nextBlock; nextBlock: ...; goto exitPoint;
// -> if (...) { ... } else { ... } goto exitPoint;
context.Step("Inline block as else-branch", ifInst);
targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1);
targetBlock.Remove();
ifInst.FalseInst = targetBlock;
// the else block is not empty or nop-only:
if (!targetBlock.IsNopBlock(ignoreExitPoint: falseExitInst)) {
context.Step("Inline block as else-branch", ifInst);
targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1);
targetBlock.Remove();
ifInst.FalseInst = targetBlock;
} else {
// the else block is empty or nop-only and can be safely removed:
context.Step("Remove empty else-branch", ifInst);
targetBlock.Instructions.RemoveAt(targetBlock.Instructions.Count - 1);
targetBlock.Remove();
}
exitInst = block.Instructions[block.Instructions.Count - 1] = falseExitInst;
Block trueBlock = ifInst.TrueInst as Block;
if (trueBlock != null) {

20
ICSharpCode.Decompiler/IL/Instructions/ILInstructionExtensions.cs

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
namespace ICSharpCode.Decompiler.IL
{
public static class ILInstructionExtensions
{
/// <summary>
/// Determines whether a block only consists of nop instructions or is empty.
/// </summary>
public static bool IsNopBlock(this Block block, ILInstruction ignoreExitPoint = null)
{
if (block == null)
throw new ArgumentNullException(nameof(block));
return block.Children.Count(i => !(i is Nop) && i != ignoreExitPoint) == 0;
}
}
}
Loading…
Cancel
Save