Browse Source

Improve detection of short-circuiting operators.

pull/728/merge
Daniel Grunwald 9 years ago
parent
commit
dfe70d5366
  1. 38
      ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs
  2. 8
      ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs
  3. 36
      ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs
  4. 114
      ICSharpCode.Decompiler/Tests/TestCases/Pretty/ExceptionHandling.il
  5. 100
      ICSharpCode.Decompiler/Tests/TestCases/Pretty/ExceptionHandling.opt.il
  6. 35
      ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.cs
  7. 201
      ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.il
  8. 144
      ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.opt.il
  9. 140
      ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.opt.roslyn.il
  10. 187
      ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.roslyn.il

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

@ -133,8 +133,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -133,8 +133,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
DeleteBlockFromContainer(targetBlock);
ifInst.TrueInst = targetBlock;
ILInstruction nestedCondition, nestedTrueInst;
if (targetBlock.Instructions.Count > 0
&& targetBlock.Instructions[0].MatchIfInstruction(out nestedCondition, out nestedTrueInst)) {
while (targetBlock.Instructions.Count > 0
&& targetBlock.Instructions[0].MatchIfInstruction(out nestedCondition, out nestedTrueInst))
{
nestedTrueInst = UnpackBlockContainingOnlyBranch(nestedTrueInst);
if (CompatibleExitInstruction(exitInst, nestedTrueInst)) {
// "if (...) { if (nestedCondition) goto exitPoint; ... } goto exitPoint;"
@ -146,6 +147,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -146,6 +147,9 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
int offset = targetBlock.Instructions[0].ILRange.Start;
targetBlock.ILRange = new Interval(offset, offset);
}
continue; // try to find more nested conditions
} else {
break;
}
}
@ -188,8 +192,27 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -188,8 +192,27 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
stepper.Stepped();
}
}
if (ifInst.FalseInst.OpCode != OpCode.Nop && ifInst.FalseInst.ILRange.Start < ifInst.TrueInst.ILRange.Start
|| ifInst.TrueInst.OpCode == OpCode.Nop) {
if (IsEmpty(ifInst.TrueInst)) {
// prefer empty true-branch to empty-else branch
var oldTrue = ifInst.TrueInst;
ifInst.TrueInst = ifInst.FalseInst;
ifInst.FalseInst = new Nop { ILRange = oldTrue.ILRange };
ifInst.Condition = new LogicNot(ifInst.Condition);
stepper.Stepped();
// After swapping, it's possible that we can introduce a short-circuit operator:
Block trueBlock = ifInst.TrueInst as Block;
ILInstruction nestedCondition, nestedTrueInst;
if (trueBlock != null && trueBlock.Instructions.Count == 1
&& trueBlock.FinalInstruction is Nop
&& trueBlock.Instructions[0].MatchIfInstruction(out nestedCondition, out nestedTrueInst)) {
// if (cond) if (nestedCond) nestedTrueInst
// ==> if (cond && nestedCond) nestedTrueInst
ifInst.Condition = IfInstruction.LogicAnd(ifInst.Condition, nestedCondition);
ifInst.TrueInst = nestedTrueInst;
stepper.Stepped();
}
} else if (ifInst.FalseInst.OpCode != OpCode.Nop && ifInst.FalseInst.ILRange.Start < ifInst.TrueInst.ILRange.Start) {
// swap true and false branches of if/else construct,
// to bring them in the same order as the IL code
var oldTrue = ifInst.TrueInst;
@ -200,6 +223,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -200,6 +223,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
}
static bool IsEmpty(ILInstruction inst)
{
var block = inst as Block;
return block != null && block.Instructions.Count == 0 && block.FinalInstruction is Nop
|| inst is Nop;
}
private ILInstruction UnpackBlockContainingOnlyBranch(ILInstruction inst)
{
Block block = inst as Block;

8
ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs

@ -33,6 +33,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -33,6 +33,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
get { return switchVar; }
}
/// <summary>
/// Whether at least one the analyzed blocks contained an IL switch constructors.
/// </summary>
public bool ContainsILSwitch { get; private set; }
/// <summary>
/// Gets the sections that were detected by the previoous AnalyzeBlock() call.
/// </summary>
@ -59,6 +64,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -59,6 +64,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
targetBlockToSectionIndex.Clear();
Sections.Clear();
InnerBlocks.Clear();
ContainsILSwitch = false;
return AnalyzeBlock(block, LongSet.Universe, tailOnly: true);
}
@ -108,7 +114,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -108,7 +114,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
} else if (inst.OpCode == OpCode.SwitchInstruction) {
if (AnalyzeSwitch((SwitchInstruction)inst, inputValues, out trueValues)) {
// OK
ContainsILSwitch = true; // OK
} else { // switch analysis failed (e.g. switchVar mismatch)
return false;
}

36
ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs

@ -53,13 +53,14 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -53,13 +53,14 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
void ProcessBlock(Block block, ref bool blockContainerNeedsCleanup)
{
if (analysis.AnalyzeBlock(block) && UseCSharpSwitch(analysis)) {
bool analysisSuccess = analysis.AnalyzeBlock(block);
KeyValuePair<LongSet, ILInstruction> defaultSection;
if (analysisSuccess && UseCSharpSwitch(analysis, out defaultSection)) {
// complex multi-block switch that can be combined into a single SwitchInstruction
var hugeSection = analysis.Sections.Single(s => s.Key.Count() > 50);
var sw = new SwitchInstruction(new LdLoc(analysis.SwitchVariable));
foreach (var section in analysis.Sections) {
if (!section.Key.SetEquals(hugeSection.Key)) {
if (!section.Key.SetEquals(defaultSection.Key)) {
sw.Sections.Add(new SwitchSection
{
Labels = section.Key,
@ -68,7 +69,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -68,7 +69,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
}
block.Instructions[block.Instructions.Count - 2] = sw;
block.Instructions[block.Instructions.Count - 1] = hugeSection.Value;
block.Instructions[block.Instructions.Count - 1] = defaultSection.Value;
// mark all inner blocks that were converted to the switch statement for deletion
foreach (var innerBlock in analysis.InnerBlocks) {
Debug.Assert(innerBlock.Parent == block.Parent);
@ -123,10 +124,31 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -123,10 +124,31 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
/// <summary>
/// Tests whether we should prefer a switch statement over an if statement.
/// </summary>
static bool UseCSharpSwitch(SwitchAnalysis analysis)
static bool UseCSharpSwitch(SwitchAnalysis analysis, out KeyValuePair<LongSet, ILInstruction> defaultSection)
{
return analysis.InnerBlocks.Any()
&& analysis.Sections.Count(s => s.Key.Count() > MaxValuesPerSection) == 1;
if (!analysis.InnerBlocks.Any()) {
defaultSection = default(KeyValuePair<LongSet, ILInstruction>);
return false;
}
defaultSection = analysis.Sections.FirstOrDefault(s => s.Key.Count() > MaxValuesPerSection);
if (defaultSection.Key.IsEmpty) {
return false;
}
ulong valuePerSectionLimit = MaxValuesPerSection;
if (!analysis.ContainsILSwitch) {
// If there's no IL switch involved, limit the number of keys per section
// much more drastically to avoid generating switches where an if condition
// would be shorter.
valuePerSectionLimit = Math.Min(
valuePerSectionLimit,
(ulong)analysis.InnerBlocks.Count);
}
var defaultSectionKey = defaultSection.Key;
if (analysis.Sections.Any(s => !s.Key.SetEquals(defaultSectionKey)
&& s.Key.Count() > valuePerSectionLimit)) {
return false;
}
return analysis.InnerBlocks.Any();
}
}
}

114
ICSharpCode.Decompiler/Tests/TestCases/Pretty/ExceptionHandling.il

@ -0,0 +1,114 @@ @@ -0,0 +1,114 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.18020
// Copyright (c) Microsoft Corporation. All rights reserved.
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly cjszwdil
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module cjszwdil.dll
// MVID: {7ED95804-37F9-435D-95FF-BCC0F9019DEB}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x00E00000
// =============== CLASS MEMBERS DECLARATION ===================
.class public abstract auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ExceptionHandling
extends [mscorlib]System.Object
{
.method public hidebysig newslot abstract virtual
instance bool B(int32 i) cil managed
{
} // end of method ExceptionHandling::B
.method public hidebysig newslot abstract virtual
instance void M(int32 i) cil managed
{
} // end of method ExceptionHandling::M
.method public hidebysig instance bool
ConditionalReturnInThrow() cil managed
{
// Code size 43 (0x2b)
.maxstack 2
.locals init (bool V_0,
bool V_1)
IL_0000: nop
.try
{
IL_0001: nop
IL_0002: ldarg.0
IL_0003: ldc.i4.0
IL_0004: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ExceptionHandling::B(int32)
IL_0009: ldc.i4.0
IL_000a: ceq
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: brtrue.s IL_001b
IL_0010: nop
IL_0011: ldarg.0
IL_0012: ldc.i4.1
IL_0013: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ExceptionHandling::B(int32)
IL_0018: stloc.0
IL_0019: leave.s IL_0028
IL_001b: nop
IL_001c: leave.s IL_0023
} // end .try
catch [mscorlib]System.Object
{
IL_001e: pop
IL_001f: nop
IL_0020: nop
IL_0021: leave.s IL_0023
} // end handler
IL_0023: nop
IL_0024: ldc.i4.0
IL_0025: stloc.0
IL_0026: br.s IL_0028
IL_0028: nop
IL_0029: ldloc.0
IL_002a: ret
} // end of method ExceptionHandling::ConditionalReturnInThrow
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method ExceptionHandling::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ExceptionHandling
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../Tests/TestCases/Pretty\ExceptionHandling.res

100
ICSharpCode.Decompiler/Tests/TestCases/Pretty/ExceptionHandling.opt.il

@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.18020
// Copyright (c) Microsoft Corporation. All rights reserved.
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly cl4g010y
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module cl4g010y.dll
// MVID: {2A833493-111C-42B3-BEC8-7DD8D84E816F}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x01160000
// =============== CLASS MEMBERS DECLARATION ===================
.class public abstract auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ExceptionHandling
extends [mscorlib]System.Object
{
.method public hidebysig newslot abstract virtual
instance bool B(int32 i) cil managed
{
} // end of method ExceptionHandling::B
.method public hidebysig newslot abstract virtual
instance void M(int32 i) cil managed
{
} // end of method ExceptionHandling::M
.method public hidebysig instance bool
ConditionalReturnInThrow() cil managed
{
// Code size 28 (0x1c)
.maxstack 2
.locals init (bool V_0)
.try
{
IL_0000: ldarg.0
IL_0001: ldc.i4.0
IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ExceptionHandling::B(int32)
IL_0007: brfalse.s IL_0013
IL_0009: ldarg.0
IL_000a: ldc.i4.1
IL_000b: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ExceptionHandling::B(int32)
IL_0010: stloc.0
IL_0011: leave.s IL_001a
IL_0013: leave.s IL_0018
} // end .try
catch [mscorlib]System.Object
{
IL_0015: pop
IL_0016: leave.s IL_0018
} // end handler
IL_0018: ldc.i4.0
IL_0019: ret
IL_001a: ldloc.0
IL_001b: ret
} // end of method ExceptionHandling::ConditionalReturnInThrow
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method ExceptionHandling::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ExceptionHandling
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../Tests/TestCases/Pretty\ExceptionHandling.opt.res

35
ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.cs

@ -47,6 +47,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -47,6 +47,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
this.B(this.F(0) ? this.F(1) : this.F(2));
}
public void ExprCondAnd()
{
this.B((this.F(0) && this.F(1)) ? this.F(2) : this.F(3));
}
public void StmtAnd2()
{
if (this.F(0) && this.F(1)) {
@ -96,5 +101,35 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -96,5 +101,35 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
this.E();
}
public void StmtComplex2(int i)
{
if (i > 1000 || (i >= 1 && i <= 8) || i == 42) {
this.M1();
} else {
this.M2();
}
this.E();
}
public void StmtComplex3(int i)
{
if (i > 1000 || (i >= 1 && i <= 8) || (i >= 100 && i <= 200) || i == 42) {
this.M1();
} else {
this.M2();
}
this.E();
}
public void StmtComplex4(int i)
{
if (i > 1000 || (i >= 1 && i <= 8) || i == 42 || i == 23) {
this.M1();
} else {
this.M2();
}
this.E();
}
}
}

201
ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly '54jn3zeu'
.assembly '1usq3izz'
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module '54jn3zeu.dll'
// MVID: {95CCC6F2-466F-4752-91AB-4D6F87ADF909}
.module '1usq3izz.dll'
// MVID: {D4D671C0-C178-4664-B3F2-149E3D2D1745}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x017A0000
// Image base: 0x01380000
// =============== CLASS MEMBERS DECLARATION ===================
@ -135,6 +135,37 @@ @@ -135,6 +135,37 @@
IL_0022: ret
} // end of method ShortCircuit::ExprCond
.method public hidebysig instance void
ExprCondAnd() cil managed
{
// Code size 44 (0x2c)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.0
IL_0003: ldc.i4.0
IL_0004: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0009: brfalse.s IL_0014
IL_000b: ldarg.0
IL_000c: ldc.i4.1
IL_000d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0012: brtrue.s IL_001d
IL_0014: ldarg.0
IL_0015: ldc.i4.3
IL_0016: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_001b: br.s IL_0024
IL_001d: ldarg.0
IL_001e: ldc.i4.2
IL_001f: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0024: nop
IL_0025: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_002a: nop
IL_002b: ret
} // end of method ShortCircuit::ExprCondAnd
.method public hidebysig instance void
StmtAnd2() cil managed
{
@ -379,6 +410,168 @@ @@ -379,6 +410,168 @@
IL_0056: ret
} // end of method ShortCircuit::StmtComplex
.method public hidebysig instance void
StmtComplex2(int32 i) cil managed
{
// Code size 61 (0x3d)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4 0x3e8
IL_0007: bgt.s IL_001b
IL_0009: ldarg.1
IL_000a: ldc.i4.1
IL_000b: blt.s IL_0011
IL_000d: ldarg.1
IL_000e: ldc.i4.8
IL_000f: ble.s IL_001b
IL_0011: ldarg.1
IL_0012: ldc.i4.s 42
IL_0014: ceq
IL_0016: ldc.i4.0
IL_0017: ceq
IL_0019: br.s IL_001c
IL_001b: ldc.i4.0
IL_001c: nop
IL_001d: stloc.0
IL_001e: ldloc.0
IL_001f: brtrue.s IL_002c
IL_0021: nop
IL_0022: ldarg.0
IL_0023: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_0028: nop
IL_0029: nop
IL_002a: br.s IL_0035
IL_002c: nop
IL_002d: ldarg.0
IL_002e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0033: nop
IL_0034: nop
IL_0035: ldarg.0
IL_0036: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_003b: nop
IL_003c: ret
} // end of method ShortCircuit::StmtComplex2
.method public hidebysig instance void
StmtComplex3(int32 i) cil managed
{
// Code size 74 (0x4a)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4 0x3e8
IL_0007: bgt.s IL_0028
IL_0009: ldarg.1
IL_000a: ldc.i4.1
IL_000b: blt.s IL_0011
IL_000d: ldarg.1
IL_000e: ldc.i4.8
IL_000f: ble.s IL_0028
IL_0011: ldarg.1
IL_0012: ldc.i4.s 100
IL_0014: blt.s IL_001e
IL_0016: ldarg.1
IL_0017: ldc.i4 0xc8
IL_001c: ble.s IL_0028
IL_001e: ldarg.1
IL_001f: ldc.i4.s 42
IL_0021: ceq
IL_0023: ldc.i4.0
IL_0024: ceq
IL_0026: br.s IL_0029
IL_0028: ldc.i4.0
IL_0029: nop
IL_002a: stloc.0
IL_002b: ldloc.0
IL_002c: brtrue.s IL_0039
IL_002e: nop
IL_002f: ldarg.0
IL_0030: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_0035: nop
IL_0036: nop
IL_0037: br.s IL_0042
IL_0039: nop
IL_003a: ldarg.0
IL_003b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0040: nop
IL_0041: nop
IL_0042: ldarg.0
IL_0043: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_0048: nop
IL_0049: ret
} // end of method ShortCircuit::StmtComplex3
.method public hidebysig instance void
StmtComplex4(int32 i) cil managed
{
// Code size 66 (0x42)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4 0x3e8
IL_0007: bgt.s IL_0020
IL_0009: ldarg.1
IL_000a: ldc.i4.1
IL_000b: blt.s IL_0011
IL_000d: ldarg.1
IL_000e: ldc.i4.8
IL_000f: ble.s IL_0020
IL_0011: ldarg.1
IL_0012: ldc.i4.s 42
IL_0014: beq.s IL_0020
IL_0016: ldarg.1
IL_0017: ldc.i4.s 23
IL_0019: ceq
IL_001b: ldc.i4.0
IL_001c: ceq
IL_001e: br.s IL_0021
IL_0020: ldc.i4.0
IL_0021: nop
IL_0022: stloc.0
IL_0023: ldloc.0
IL_0024: brtrue.s IL_0031
IL_0026: nop
IL_0027: ldarg.0
IL_0028: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_002d: nop
IL_002e: nop
IL_002f: br.s IL_003a
IL_0031: nop
IL_0032: ldarg.0
IL_0033: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0038: nop
IL_0039: nop
IL_003a: ldarg.0
IL_003b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_0040: nop
IL_0041: ret
} // end of method ShortCircuit::StmtComplex4
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

144
ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.opt.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly bnt5tgxz
.assembly kcfcwzhz
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module bnt5tgxz.dll
// MVID: {B950FA21-9F7A-4262-B8CD-886373656630}
.module kcfcwzhz.dll
// MVID: {9375913F-19AE-4F80-AC4E-1691FD0225AD}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x01520000
// Image base: 0x01220000
// =============== CLASS MEMBERS DECLARATION ===================
@ -126,6 +126,34 @@ @@ -126,6 +126,34 @@
IL_001f: ret
} // end of method ShortCircuit::ExprCond
.method public hidebysig instance void
ExprCondAnd() cil managed
{
// Code size 41 (0x29)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: ldc.i4.0
IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0008: brfalse.s IL_0013
IL_000a: ldarg.0
IL_000b: ldc.i4.1
IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0011: brtrue.s IL_001c
IL_0013: ldarg.0
IL_0014: ldc.i4.3
IL_0015: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_001a: br.s IL_0023
IL_001c: ldarg.0
IL_001d: ldc.i4.2
IL_001e: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0023: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0028: ret
} // end of method ShortCircuit::ExprCondAnd
.method public hidebysig instance void
StmtAnd2() cil managed
{
@ -281,6 +309,114 @@ @@ -281,6 +309,114 @@
IL_0041: ret
} // end of method ShortCircuit::StmtComplex
.method public hidebysig instance void
StmtComplex2(int32 i) cil managed
{
// Code size 42 (0x2a)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldc.i4 0x3e8
IL_0006: bgt.s IL_0015
IL_0008: ldarg.1
IL_0009: ldc.i4.1
IL_000a: blt.s IL_0010
IL_000c: ldarg.1
IL_000d: ldc.i4.8
IL_000e: ble.s IL_0015
IL_0010: ldarg.1
IL_0011: ldc.i4.s 42
IL_0013: bne.un.s IL_001d
IL_0015: ldarg.0
IL_0016: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_001b: br.s IL_0023
IL_001d: ldarg.0
IL_001e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0023: ldarg.0
IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_0029: ret
} // end of method ShortCircuit::StmtComplex2
.method public hidebysig instance void
StmtComplex3(int32 i) cil managed
{
// Code size 55 (0x37)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldc.i4 0x3e8
IL_0006: bgt.s IL_0022
IL_0008: ldarg.1
IL_0009: ldc.i4.1
IL_000a: blt.s IL_0010
IL_000c: ldarg.1
IL_000d: ldc.i4.8
IL_000e: ble.s IL_0022
IL_0010: ldarg.1
IL_0011: ldc.i4.s 100
IL_0013: blt.s IL_001d
IL_0015: ldarg.1
IL_0016: ldc.i4 0xc8
IL_001b: ble.s IL_0022
IL_001d: ldarg.1
IL_001e: ldc.i4.s 42
IL_0020: bne.un.s IL_002a
IL_0022: ldarg.0
IL_0023: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_0028: br.s IL_0030
IL_002a: ldarg.0
IL_002b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0030: ldarg.0
IL_0031: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_0036: ret
} // end of method ShortCircuit::StmtComplex3
.method public hidebysig instance void
StmtComplex4(int32 i) cil managed
{
// Code size 47 (0x2f)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldc.i4 0x3e8
IL_0006: bgt.s IL_001a
IL_0008: ldarg.1
IL_0009: ldc.i4.1
IL_000a: blt.s IL_0010
IL_000c: ldarg.1
IL_000d: ldc.i4.8
IL_000e: ble.s IL_001a
IL_0010: ldarg.1
IL_0011: ldc.i4.s 42
IL_0013: beq.s IL_001a
IL_0015: ldarg.1
IL_0016: ldc.i4.s 23
IL_0018: bne.un.s IL_0022
IL_001a: ldarg.0
IL_001b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_0020: br.s IL_0028
IL_0022: ldarg.0
IL_0023: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0028: ldarg.0
IL_0029: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_002e: ret
} // end of method ShortCircuit::StmtComplex4
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

140
ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.opt.roslyn.il

@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module ShortCircuit.dll
// MVID: {705562DA-2C0F-43A9-B4DA-DA6EF72B9256}
// MVID: {A27E149C-542B-41C0-AB29-FA01A65D43CB}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x02D40000
// Image base: 0x01320000
// =============== CLASS MEMBERS DECLARATION ===================
@ -130,6 +130,34 @@ @@ -130,6 +130,34 @@
IL_001f: ret
} // end of method ShortCircuit::ExprCond
.method public hidebysig instance void
ExprCondAnd() cil managed
{
// Code size 41 (0x29)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: ldc.i4.0
IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0008: brfalse.s IL_0013
IL_000a: ldarg.0
IL_000b: ldc.i4.1
IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0011: brtrue.s IL_001c
IL_0013: ldarg.0
IL_0014: ldc.i4.3
IL_0015: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_001a: br.s IL_0023
IL_001c: ldarg.0
IL_001d: ldc.i4.2
IL_001e: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0023: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0028: ret
} // end of method ShortCircuit::ExprCondAnd
.method public hidebysig instance void
StmtAnd2() cil managed
{
@ -285,6 +313,114 @@ @@ -285,6 +313,114 @@
IL_0041: ret
} // end of method ShortCircuit::StmtComplex
.method public hidebysig instance void
StmtComplex2(int32 i) cil managed
{
// Code size 42 (0x2a)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldc.i4 0x3e8
IL_0006: bgt.s IL_0015
IL_0008: ldarg.1
IL_0009: ldc.i4.1
IL_000a: blt.s IL_0010
IL_000c: ldarg.1
IL_000d: ldc.i4.8
IL_000e: ble.s IL_0015
IL_0010: ldarg.1
IL_0011: ldc.i4.s 42
IL_0013: bne.un.s IL_001d
IL_0015: ldarg.0
IL_0016: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_001b: br.s IL_0023
IL_001d: ldarg.0
IL_001e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0023: ldarg.0
IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_0029: ret
} // end of method ShortCircuit::StmtComplex2
.method public hidebysig instance void
StmtComplex3(int32 i) cil managed
{
// Code size 55 (0x37)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldc.i4 0x3e8
IL_0006: bgt.s IL_0022
IL_0008: ldarg.1
IL_0009: ldc.i4.1
IL_000a: blt.s IL_0010
IL_000c: ldarg.1
IL_000d: ldc.i4.8
IL_000e: ble.s IL_0022
IL_0010: ldarg.1
IL_0011: ldc.i4.s 100
IL_0013: blt.s IL_001d
IL_0015: ldarg.1
IL_0016: ldc.i4 0xc8
IL_001b: ble.s IL_0022
IL_001d: ldarg.1
IL_001e: ldc.i4.s 42
IL_0020: bne.un.s IL_002a
IL_0022: ldarg.0
IL_0023: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_0028: br.s IL_0030
IL_002a: ldarg.0
IL_002b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0030: ldarg.0
IL_0031: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_0036: ret
} // end of method ShortCircuit::StmtComplex3
.method public hidebysig instance void
StmtComplex4(int32 i) cil managed
{
// Code size 47 (0x2f)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ldc.i4 0x3e8
IL_0006: bgt.s IL_001a
IL_0008: ldarg.1
IL_0009: ldc.i4.1
IL_000a: blt.s IL_0010
IL_000c: ldarg.1
IL_000d: ldc.i4.8
IL_000e: ble.s IL_001a
IL_0010: ldarg.1
IL_0011: ldc.i4.s 42
IL_0013: beq.s IL_001a
IL_0015: ldarg.1
IL_0016: ldc.i4.s 23
IL_0018: bne.un.s IL_0022
IL_001a: ldarg.0
IL_001b: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_0020: br.s IL_0028
IL_0022: ldarg.0
IL_0023: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0028: ldarg.0
IL_0029: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_002e: ret
} // end of method ShortCircuit::StmtComplex4
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

187
ICSharpCode.Decompiler/Tests/TestCases/Pretty/ShortCircuit.roslyn.il

@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module ShortCircuit.dll
// MVID: {B3B8C47D-78FB-4162-BB12-12183DDBD57B}
// MVID: {5FB25D31-D6C4-4D39-B72D-A6EBD832225B}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x02FC0000
// Image base: 0x00FD0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -136,6 +136,36 @@ @@ -136,6 +136,36 @@
IL_0021: ret
} // end of method ShortCircuit::ExprCond
.method public hidebysig instance void
ExprCondAnd() cil managed
{
// Code size 43 (0x2b)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.0
IL_0003: ldc.i4.0
IL_0004: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0009: brfalse.s IL_0014
IL_000b: ldarg.0
IL_000c: ldc.i4.1
IL_000d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0012: brtrue.s IL_001d
IL_0014: ldarg.0
IL_0015: ldc.i4.3
IL_0016: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_001b: br.s IL_0024
IL_001d: ldarg.0
IL_001e: ldc.i4.2
IL_001f: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0029: nop
IL_002a: ret
} // end of method ShortCircuit::ExprCondAnd
.method public hidebysig instance void
StmtAnd2() cil managed
{
@ -364,6 +394,159 @@ @@ -364,6 +394,159 @@
IL_0051: ret
} // end of method ShortCircuit::StmtComplex
.method public hidebysig instance void
StmtComplex2(int32 i) cil managed
{
// Code size 57 (0x39)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4 0x3e8
IL_0007: bgt.s IL_0018
IL_0009: ldarg.1
IL_000a: ldc.i4.1
IL_000b: blt.s IL_0011
IL_000d: ldarg.1
IL_000e: ldc.i4.8
IL_000f: ble.s IL_0018
IL_0011: ldarg.1
IL_0012: ldc.i4.s 42
IL_0014: ceq
IL_0016: br.s IL_0019
IL_0018: ldc.i4.1
IL_0019: stloc.0
IL_001a: ldloc.0
IL_001b: brfalse.s IL_0028
IL_001d: nop
IL_001e: ldarg.0
IL_001f: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_0024: nop
IL_0025: nop
IL_0026: br.s IL_0031
IL_0028: nop
IL_0029: ldarg.0
IL_002a: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_002f: nop
IL_0030: nop
IL_0031: ldarg.0
IL_0032: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_0037: nop
IL_0038: ret
} // end of method ShortCircuit::StmtComplex2
.method public hidebysig instance void
StmtComplex3(int32 i) cil managed
{
// Code size 70 (0x46)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4 0x3e8
IL_0007: bgt.s IL_0025
IL_0009: ldarg.1
IL_000a: ldc.i4.1
IL_000b: blt.s IL_0011
IL_000d: ldarg.1
IL_000e: ldc.i4.8
IL_000f: ble.s IL_0025
IL_0011: ldarg.1
IL_0012: ldc.i4.s 100
IL_0014: blt.s IL_001e
IL_0016: ldarg.1
IL_0017: ldc.i4 0xc8
IL_001c: ble.s IL_0025
IL_001e: ldarg.1
IL_001f: ldc.i4.s 42
IL_0021: ceq
IL_0023: br.s IL_0026
IL_0025: ldc.i4.1
IL_0026: stloc.0
IL_0027: ldloc.0
IL_0028: brfalse.s IL_0035
IL_002a: nop
IL_002b: ldarg.0
IL_002c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_0031: nop
IL_0032: nop
IL_0033: br.s IL_003e
IL_0035: nop
IL_0036: ldarg.0
IL_0037: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_003c: nop
IL_003d: nop
IL_003e: ldarg.0
IL_003f: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_0044: nop
IL_0045: ret
} // end of method ShortCircuit::StmtComplex3
.method public hidebysig instance void
StmtComplex4(int32 i) cil managed
{
// Code size 62 (0x3e)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4 0x3e8
IL_0007: bgt.s IL_001d
IL_0009: ldarg.1
IL_000a: ldc.i4.1
IL_000b: blt.s IL_0011
IL_000d: ldarg.1
IL_000e: ldc.i4.8
IL_000f: ble.s IL_001d
IL_0011: ldarg.1
IL_0012: ldc.i4.s 42
IL_0014: beq.s IL_001d
IL_0016: ldarg.1
IL_0017: ldc.i4.s 23
IL_0019: ceq
IL_001b: br.s IL_001e
IL_001d: ldc.i4.1
IL_001e: stloc.0
IL_001f: ldloc.0
IL_0020: brfalse.s IL_002d
IL_0022: nop
IL_0023: ldarg.0
IL_0024: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M1()
IL_0029: nop
IL_002a: nop
IL_002b: br.s IL_0036
IL_002d: nop
IL_002e: ldarg.0
IL_002f: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::M2()
IL_0034: nop
IL_0035: nop
IL_0036: ldarg.0
IL_0037: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::E()
IL_003c: nop
IL_003d: ret
} // end of method ShortCircuit::StmtComplex4
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

Loading…
Cancel
Save