From ab9397d0990b14b6e3a99f4d4abfa84c4a8234c1 Mon Sep 17 00:00:00 2001 From: Chicken-Bones Date: Sun, 2 Sep 2018 13:16:46 +1000 Subject: [PATCH] Add ReduceNestingTransform --- .../ICSharpCode.Decompiler.Tests.csproj | 1 + .../PrettyTestRunner.cs | 6 + .../TestCases/Pretty/ExpressionTrees.cs | 82 +- .../TestCases/Pretty/ReduceNesting.cs | 270 +++++ .../TestCases/Pretty/ReduceNesting.il | 949 +++++++++++++++++ .../TestCases/Pretty/ReduceNesting.opt.il | 650 ++++++++++++ .../Pretty/ReduceNesting.opt.roslyn.il | 668 ++++++++++++ .../TestCases/Pretty/ReduceNesting.roslyn.il | 954 ++++++++++++++++++ .../CSharp/CSharpDecompiler.cs | 1 + .../ICSharpCode.Decompiler.csproj | 1 + .../IL/Transforms/ReduceNestingTransform.cs | 418 ++++++++ 11 files changed, 3959 insertions(+), 41 deletions(-) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.opt.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.opt.roslyn.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.roslyn.il create mode 100644 ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 229eea694..390649a39 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -73,6 +73,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index 285f3a86c..ec3a5eb64 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -127,6 +127,12 @@ namespace ICSharpCode.Decompiler.Tests }); } + [Test] + public void ReduceNesting([ValueSource("defaultOptions")] CSharpCompilerOptions cscOptions) + { + RunForLibrary(cscOptions: cscOptions); + } + [Test] public void DelegateConstruction([ValueSource("defaultOptions")] CSharpCompilerOptions cscOptions) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs index 727680634..bde2e1d55 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs @@ -322,47 +322,47 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { if (ID == 0) { ViewBag.data = "''"; - } else { - var model = (from a in db.Contracts - where a.ID == ID - select new { - ID = a.ID, - ContractNo = a.ContractNo, - HouseAddress = a.HouseAddress, - AdminID = (from b in db.Administrator - where b.ID == a.AdminID - select b.TrueName).FirstOrDefault(), - StoreID = (from b in db.Store - where b.ID == a.StoreID - select b.Name).FirstOrDefault(), - SigningTime = a.SigningTime, - YeWuPhone = (from b in db.Administrator - where b.ID == a.AdminID - select b.Phone).FirstOrDefault(), - BuyerName = a.BuyerName, - BuyerTelephone = a.BuyerTelephone, - Customer = a.Customer, - CustTelephone = a.CustTelephone, - Credit = (from b in db.Loan - where b.ContractNo == a.ContractNo - select b.Credit).FirstOrDefault(), - LoanBank = (from b in db.Loan - where b.ContractNo == a.ContractNo - select b.LoanBank).FirstOrDefault(), - Remarks = (from b in db.Loan - where b.ContractNo == a.ContractNo - select b.Remarks).FirstOrDefault() - }).FirstOrDefault(); - ViewBag.data = model.ToJson(); - DateTime? dateTime = (from b in db.Loan - where b.ContractNo == model.ContractNo - select b.ShenDate).FirstOrDefault(); - DateTime? dateTime2 = (from b in db.Loan - where b.ContractNo == model.ContractNo - select b.LoanDate).FirstOrDefault(); - ViewBag.ShenDate = ((!dateTime.HasValue) ? "" : dateTime.ParseDateTime().ToString("yyyy-MM-dd")); - ViewBag.LoanDate = ((!dateTime2.HasValue) ? "" : dateTime2.ParseDateTime().ToString("yyyy-MM-dd")); - } + return; + } + var model = (from a in db.Contracts + where a.ID == ID + select new { + ID = a.ID, + ContractNo = a.ContractNo, + HouseAddress = a.HouseAddress, + AdminID = (from b in db.Administrator + where b.ID == a.AdminID + select b.TrueName).FirstOrDefault(), + StoreID = (from b in db.Store + where b.ID == a.StoreID + select b.Name).FirstOrDefault(), + SigningTime = a.SigningTime, + YeWuPhone = (from b in db.Administrator + where b.ID == a.AdminID + select b.Phone).FirstOrDefault(), + BuyerName = a.BuyerName, + BuyerTelephone = a.BuyerTelephone, + Customer = a.Customer, + CustTelephone = a.CustTelephone, + Credit = (from b in db.Loan + where b.ContractNo == a.ContractNo + select b.Credit).FirstOrDefault(), + LoanBank = (from b in db.Loan + where b.ContractNo == a.ContractNo + select b.LoanBank).FirstOrDefault(), + Remarks = (from b in db.Loan + where b.ContractNo == a.ContractNo + select b.Remarks).FirstOrDefault() + }).FirstOrDefault(); + ViewBag.data = model.ToJson(); + DateTime? dateTime = (from b in db.Loan + where b.ContractNo == model.ContractNo + select b.ShenDate).FirstOrDefault(); + DateTime? dateTime2 = (from b in db.Loan + where b.ContractNo == model.ContractNo + select b.LoanDate).FirstOrDefault(); + ViewBag.ShenDate = ((!dateTime.HasValue) ? "" : dateTime.ParseDateTime().ToString("yyyy-MM-dd")); + ViewBag.LoanDate = ((!dateTime2.HasValue) ? "" : dateTime2.ParseDateTime().ToString("yyyy-MM-dd")); } private static object ToCode(object x, Expression> expr) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.cs new file mode 100644 index 000000000..a08cd43e9 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.cs @@ -0,0 +1,270 @@ +using System; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + public abstract class ReduceNesting + { + public abstract bool B(int i); + public abstract int I(int i); + + public void IfIf() + { + if (B(0)) { + Console.WriteLine(0); + return; + } + + if (B(1)) { + Console.WriteLine(1); + } + + Console.WriteLine("end"); + } + + public void IfSwitch() + { + if (B(0)) { + Console.WriteLine(0); + return; + } + + Console.WriteLine("switch"); + switch (I(0)) { + case 0: + Console.WriteLine("case 0"); + break; + case 1: + Console.WriteLine("case 1"); + break; + default: + Console.WriteLine("end"); + break; + } + } + + public void IfSwitchSwitch() + { + if (B(0)) { + Console.WriteLine(0); + return; + } + + Console.WriteLine("switch 0"); + switch (I(1)) { + case 0: + Console.WriteLine("case 0"); + return; + case 1: + Console.WriteLine("case 1"); + return; + } + + Console.WriteLine("switch 1"); + switch (I(1)) { + case 0: + Console.WriteLine("case 0"); + break; + case 1: + Console.WriteLine("case 1"); + break; + default: + Console.WriteLine("end"); + break; + } + } + + public void IfLoop() + { + if (B(0)) { + Console.WriteLine(0); + return; + } + + for (int i = 0; i < 10; i++) { + Console.WriteLine(i); + } + + Console.WriteLine("end"); + } + + public void LoopContinue() + { + for (int i = 0; i < 10; i++) { + Console.WriteLine(i); + if (B(0)) { + Console.WriteLine(0); + continue; + } + + if (B(1)) { + Console.WriteLine(1); + } + Console.WriteLine("loop-tail"); + } + } + + public void LoopBreak() + { + for (int i = 0; i < 10; i++) { + Console.WriteLine(i); + if (B(0)) { + Console.WriteLine(0); + continue; + } + + if (B(1)) { + Console.WriteLine(1); + break; + } + + if (B(2)) { + Console.WriteLine(2); + } + + Console.WriteLine("break"); + break; + } + Console.WriteLine("end"); + } + + public void LoopBreakElseIf() + { + for (int i = 0; i < 10; i++) { + Console.WriteLine(i); + if (B(0)) { + Console.WriteLine(0); + continue; + } + + if (B(1)) { + Console.WriteLine(1); + } else if (B(2)) { + Console.WriteLine(2); + } + break; + } + Console.WriteLine("end"); + } + + public void SwitchIf() + { + switch (I(0)) { + case 0: + Console.WriteLine("case 0"); + return; + case 1: + Console.WriteLine("case 1"); + return; + } + + if (B(0)) { + Console.WriteLine(0); + } + Console.WriteLine("end"); + } + + public void NestedSwitchIf() + { + if (B(0)) { + switch (I(0)) { + case 0: + Console.WriteLine("case 0"); + return; + case 1: + Console.WriteLine("case 1"); + return; + } + + if (B(1)) { + Console.WriteLine(1); + } + } else { + Console.WriteLine("else"); + } + } + + // nesting should not be reduced as maximum nesting level is 1 + public void EarlyExit1() + { + if (!B(0)) { + for (int i = 0; i < 10; i++) { + Console.WriteLine(i); + } + Console.WriteLine("end"); + } + } + + // nesting should not be reduced as maximum nesting level is 2 + public void EarlyExit2() + { + if (B(0)) { + return; + } + + for (int i = 0; i < 10; i++) { + Console.WriteLine(i); + if (i % 2 == 0) { + Console.WriteLine("even"); + } + } + + Console.WriteLine("end"); + } + + // nesting should not be reduced as maximum nesting level is 1 and the else block has no more instructions than any other block + public void BalancedIf() + { + if (B(0)) { + Console.WriteLine("true"); + if (B(1)) { + Console.WriteLine(1); + } + } else { + if (B(2)) { + Console.WriteLine(2); + } + Console.WriteLine("false"); + } + } + + public string ComplexCase1(string s) + { + if (B(0)) { + return s; + } + + for (int i = 0; i < s.Length; i++) { + if (B(1)) { + Console.WriteLine(1); + } else if (B(2)) { + switch (i) { + case 1: + if (B(3)) { + Console.WriteLine(3); + break; + } + + Console.WriteLine("case1"); + if (B(4)) { + Console.WriteLine(4); + } + break; + case 2: + case 3: + Console.WriteLine("case23"); + break; + } + Console.WriteLine(2); + } else if (B(5)) { + Console.WriteLine(5); + } else { + if (B(6)) { + Console.WriteLine(6); + } + Console.WriteLine("else"); + } + } + return s; + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.il new file mode 100644 index 000000000..b4493229c --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.il @@ -0,0 +1,949 @@ + + + + +// 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 ReduceNesting +{ + .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 ReduceNesting.dll +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public abstract auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting + extends [mscorlib]System.Object +{ + .method public hidebysig newslot abstract virtual + instance bool B(int32 i) cil managed + { + } // end of method ReduceNesting::B + + .method public hidebysig newslot abstract virtual + instance int32 I(int32 i) cil managed + { + } // end of method ReduceNesting::I + + .method public hidebysig instance void + IfIf() cil managed + { + // Code size 60 (0x3c) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: brtrue.s IL_0019 + + IL_000f: nop + IL_0010: ldc.i4.0 + IL_0011: call void [mscorlib]System.Console::WriteLine(int32) + IL_0016: nop + IL_0017: br.s IL_003b + + IL_0019: ldarg.0 + IL_001a: ldc.i4.1 + IL_001b: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0020: ldc.i4.0 + IL_0021: ceq + IL_0023: stloc.0 + IL_0024: ldloc.0 + IL_0025: brtrue.s IL_0030 + + IL_0027: nop + IL_0028: ldc.i4.1 + IL_0029: call void [mscorlib]System.Console::WriteLine(int32) + IL_002e: nop + IL_002f: nop + IL_0030: ldstr "end" + IL_0035: call void [mscorlib]System.Console::WriteLine(string) + IL_003a: nop + IL_003b: ret + } // end of method ReduceNesting::IfIf + + .method public hidebysig instance void + IfSwitch() cil managed + { + // Code size 100 (0x64) + .maxstack 2 + .locals init (bool V_0, + int32 V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: brtrue.s IL_0019 + + IL_000f: nop + IL_0010: ldc.i4.0 + IL_0011: call void [mscorlib]System.Console::WriteLine(int32) + IL_0016: nop + IL_0017: br.s IL_0063 + + IL_0019: ldstr "switch" + IL_001e: call void [mscorlib]System.Console::WriteLine(string) + IL_0023: nop + IL_0024: ldarg.0 + IL_0025: ldc.i4.0 + IL_0026: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_002b: stloc.1 + IL_002c: ldloc.1 + IL_002d: switch ( + IL_003c, + IL_0049) + IL_003a: br.s IL_0056 + + IL_003c: ldstr "case 0" + IL_0041: call void [mscorlib]System.Console::WriteLine(string) + IL_0046: nop + IL_0047: br.s IL_0063 + + IL_0049: ldstr "case 1" + IL_004e: call void [mscorlib]System.Console::WriteLine(string) + IL_0053: nop + IL_0054: br.s IL_0063 + + IL_0056: ldstr "end" + IL_005b: call void [mscorlib]System.Console::WriteLine(string) + IL_0060: nop + IL_0061: br.s IL_0063 + + IL_0063: ret + } // end of method ReduceNesting::IfSwitch + + .method public hidebysig instance void + IfSwitchSwitch() cil managed + { + // Code size 164 (0xa4) + .maxstack 2 + .locals init (bool V_0, + int32 V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: brtrue.s IL_001c + + IL_000f: nop + IL_0010: ldc.i4.0 + IL_0011: call void [mscorlib]System.Console::WriteLine(int32) + IL_0016: nop + IL_0017: br IL_00a3 + + IL_001c: ldstr "switch 0" + IL_0021: call void [mscorlib]System.Console::WriteLine(string) + IL_0026: nop + IL_0027: ldarg.0 + IL_0028: ldc.i4.1 + IL_0029: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_002e: stloc.1 + IL_002f: ldloc.1 + IL_0030: switch ( + IL_003f, + IL_004c) + IL_003d: br.s IL_0059 + + IL_003f: ldstr "case 0" + IL_0044: call void [mscorlib]System.Console::WriteLine(string) + IL_0049: nop + IL_004a: br.s IL_00a3 + + IL_004c: ldstr "case 1" + IL_0051: call void [mscorlib]System.Console::WriteLine(string) + IL_0056: nop + IL_0057: br.s IL_00a3 + + IL_0059: ldstr "switch 1" + IL_005e: call void [mscorlib]System.Console::WriteLine(string) + IL_0063: nop + IL_0064: ldarg.0 + IL_0065: ldc.i4.1 + IL_0066: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_006b: stloc.1 + IL_006c: ldloc.1 + IL_006d: switch ( + IL_007c, + IL_0089) + IL_007a: br.s IL_0096 + + IL_007c: ldstr "case 0" + IL_0081: call void [mscorlib]System.Console::WriteLine(string) + IL_0086: nop + IL_0087: br.s IL_00a3 + + IL_0089: ldstr "case 1" + IL_008e: call void [mscorlib]System.Console::WriteLine(string) + IL_0093: nop + IL_0094: br.s IL_00a3 + + IL_0096: ldstr "end" + IL_009b: call void [mscorlib]System.Console::WriteLine(string) + IL_00a0: nop + IL_00a1: br.s IL_00a3 + + IL_00a3: ret + } // end of method ReduceNesting::IfSwitchSwitch + + .method public hidebysig instance void + IfLoop() cil managed + { + // Code size 63 (0x3f) + .maxstack 2 + .locals init (int32 V_0, + bool V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: stloc.1 + IL_000c: ldloc.1 + IL_000d: brtrue.s IL_0019 + + IL_000f: nop + IL_0010: ldc.i4.0 + IL_0011: call void [mscorlib]System.Console::WriteLine(int32) + IL_0016: nop + IL_0017: br.s IL_003e + + IL_0019: ldc.i4.0 + IL_001a: stloc.0 + IL_001b: br.s IL_002a + + IL_001d: nop + IL_001e: ldloc.0 + IL_001f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0024: nop + IL_0025: nop + IL_0026: ldloc.0 + IL_0027: ldc.i4.1 + IL_0028: add + IL_0029: stloc.0 + IL_002a: ldloc.0 + IL_002b: ldc.i4.s 10 + IL_002d: clt + IL_002f: stloc.1 + IL_0030: ldloc.1 + IL_0031: brtrue.s IL_001d + + IL_0033: ldstr "end" + IL_0038: call void [mscorlib]System.Console::WriteLine(string) + IL_003d: nop + IL_003e: ret + } // end of method ReduceNesting::IfLoop + + .method public hidebysig instance void + LoopContinue() cil managed + { + // Code size 86 (0x56) + .maxstack 2 + .locals init (int32 V_0, + bool V_1) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: br.s IL_004c + + IL_0005: nop + IL_0006: ldloc.0 + IL_0007: call void [mscorlib]System.Console::WriteLine(int32) + IL_000c: nop + IL_000d: ldarg.0 + IL_000e: ldc.i4.0 + IL_000f: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0014: ldc.i4.0 + IL_0015: ceq + IL_0017: stloc.1 + IL_0018: ldloc.1 + IL_0019: brtrue.s IL_0025 + + IL_001b: nop + IL_001c: ldc.i4.0 + IL_001d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0022: nop + IL_0023: br.s IL_0048 + + IL_0025: ldarg.0 + IL_0026: ldc.i4.1 + IL_0027: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_002c: ldc.i4.0 + IL_002d: ceq + IL_002f: stloc.1 + IL_0030: ldloc.1 + IL_0031: brtrue.s IL_003c + + IL_0033: nop + IL_0034: ldc.i4.1 + IL_0035: call void [mscorlib]System.Console::WriteLine(int32) + IL_003a: nop + IL_003b: nop + IL_003c: ldstr "loop-tail" + IL_0041: call void [mscorlib]System.Console::WriteLine(string) + IL_0046: nop + IL_0047: nop + IL_0048: ldloc.0 + IL_0049: ldc.i4.1 + IL_004a: add + IL_004b: stloc.0 + IL_004c: ldloc.0 + IL_004d: ldc.i4.s 10 + IL_004f: clt + IL_0051: stloc.1 + IL_0052: ldloc.1 + IL_0053: brtrue.s IL_0005 + + IL_0055: ret + } // end of method ReduceNesting::LoopContinue + + .method public hidebysig instance void + LoopBreak() cil managed + { + // Code size 122 (0x7a) + .maxstack 2 + .locals init (int32 V_0, + bool V_1) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: br.s IL_0065 + + IL_0005: nop + IL_0006: ldloc.0 + IL_0007: call void [mscorlib]System.Console::WriteLine(int32) + IL_000c: nop + IL_000d: ldarg.0 + IL_000e: ldc.i4.0 + IL_000f: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0014: ldc.i4.0 + IL_0015: ceq + IL_0017: stloc.1 + IL_0018: ldloc.1 + IL_0019: brtrue.s IL_0025 + + IL_001b: nop + IL_001c: ldc.i4.0 + IL_001d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0022: nop + IL_0023: br.s IL_0061 + + IL_0025: ldarg.0 + IL_0026: ldc.i4.1 + IL_0027: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_002c: ldc.i4.0 + IL_002d: ceq + IL_002f: stloc.1 + IL_0030: ldloc.1 + IL_0031: brtrue.s IL_003d + + IL_0033: nop + IL_0034: ldc.i4.1 + IL_0035: call void [mscorlib]System.Console::WriteLine(int32) + IL_003a: nop + IL_003b: br.s IL_006e + + IL_003d: ldarg.0 + IL_003e: ldc.i4.2 + IL_003f: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0044: ldc.i4.0 + IL_0045: ceq + IL_0047: stloc.1 + IL_0048: ldloc.1 + IL_0049: brtrue.s IL_0054 + + IL_004b: nop + IL_004c: ldc.i4.2 + IL_004d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0052: nop + IL_0053: nop + IL_0054: ldstr "break" + IL_0059: call void [mscorlib]System.Console::WriteLine(string) + IL_005e: nop + IL_005f: br.s IL_006e + + IL_0061: ldloc.0 + IL_0062: ldc.i4.1 + IL_0063: add + IL_0064: stloc.0 + IL_0065: ldloc.0 + IL_0066: ldc.i4.s 10 + IL_0068: clt + IL_006a: stloc.1 + IL_006b: ldloc.1 + IL_006c: brtrue.s IL_0005 + + IL_006e: ldstr "end" + IL_0073: call void [mscorlib]System.Console::WriteLine(string) + IL_0078: nop + IL_0079: ret + } // end of method ReduceNesting::LoopBreak + + .method public hidebysig instance void + LoopBreakElseIf() cil managed + { + // Code size 112 (0x70) + .maxstack 2 + .locals init (int32 V_0, + bool V_1) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: br.s IL_005b + + IL_0005: nop + IL_0006: ldloc.0 + IL_0007: call void [mscorlib]System.Console::WriteLine(int32) + IL_000c: nop + IL_000d: ldarg.0 + IL_000e: ldc.i4.0 + IL_000f: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0014: ldc.i4.0 + IL_0015: ceq + IL_0017: stloc.1 + IL_0018: ldloc.1 + IL_0019: brtrue.s IL_0025 + + IL_001b: nop + IL_001c: ldc.i4.0 + IL_001d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0022: nop + IL_0023: br.s IL_0057 + + IL_0025: ldarg.0 + IL_0026: ldc.i4.1 + IL_0027: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_002c: ldc.i4.0 + IL_002d: ceq + IL_002f: stloc.1 + IL_0030: ldloc.1 + IL_0031: brtrue.s IL_003e + + IL_0033: nop + IL_0034: ldc.i4.1 + IL_0035: call void [mscorlib]System.Console::WriteLine(int32) + IL_003a: nop + IL_003b: nop + IL_003c: br.s IL_0055 + + IL_003e: ldarg.0 + IL_003f: ldc.i4.2 + IL_0040: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0045: ldc.i4.0 + IL_0046: ceq + IL_0048: stloc.1 + IL_0049: ldloc.1 + IL_004a: brtrue.s IL_0055 + + IL_004c: nop + IL_004d: ldc.i4.2 + IL_004e: call void [mscorlib]System.Console::WriteLine(int32) + IL_0053: nop + IL_0054: nop + IL_0055: br.s IL_0064 + + IL_0057: ldloc.0 + IL_0058: ldc.i4.1 + IL_0059: add + IL_005a: stloc.0 + IL_005b: ldloc.0 + IL_005c: ldc.i4.s 10 + IL_005e: clt + IL_0060: stloc.1 + IL_0061: ldloc.1 + IL_0062: brtrue.s IL_0005 + + IL_0064: ldstr "end" + IL_0069: call void [mscorlib]System.Console::WriteLine(string) + IL_006e: nop + IL_006f: ret + } // end of method ReduceNesting::LoopBreakElseIf + + .method public hidebysig instance void + SwitchIf() cil managed + { + // Code size 86 (0x56) + .maxstack 2 + .locals init (int32 V_0, + bool V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: switch ( + IL_0019, + IL_0026) + IL_0017: br.s IL_0033 + + IL_0019: ldstr "case 0" + IL_001e: call void [mscorlib]System.Console::WriteLine(string) + IL_0023: nop + IL_0024: br.s IL_0055 + + IL_0026: ldstr "case 1" + IL_002b: call void [mscorlib]System.Console::WriteLine(string) + IL_0030: nop + IL_0031: br.s IL_0055 + + IL_0033: ldarg.0 + IL_0034: ldc.i4.0 + IL_0035: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_003a: ldc.i4.0 + IL_003b: ceq + IL_003d: stloc.1 + IL_003e: ldloc.1 + IL_003f: brtrue.s IL_004a + + IL_0041: nop + IL_0042: ldc.i4.0 + IL_0043: call void [mscorlib]System.Console::WriteLine(int32) + IL_0048: nop + IL_0049: nop + IL_004a: ldstr "end" + IL_004f: call void [mscorlib]System.Console::WriteLine(string) + IL_0054: nop + IL_0055: ret + } // end of method ReduceNesting::SwitchIf + + .method public hidebysig instance void + NestedSwitchIf() cil managed + { + // Code size 106 (0x6a) + .maxstack 2 + .locals init (bool V_0, + int32 V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: brtrue.s IL_005c + + IL_000f: nop + IL_0010: ldarg.0 + IL_0011: ldc.i4.0 + IL_0012: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0017: stloc.1 + IL_0018: ldloc.1 + IL_0019: switch ( + IL_0028, + IL_0035) + IL_0026: br.s IL_0042 + + IL_0028: ldstr "case 0" + IL_002d: call void [mscorlib]System.Console::WriteLine(string) + IL_0032: nop + IL_0033: br.s IL_0069 + + IL_0035: ldstr "case 1" + IL_003a: call void [mscorlib]System.Console::WriteLine(string) + IL_003f: nop + IL_0040: br.s IL_0069 + + IL_0042: ldarg.0 + IL_0043: ldc.i4.1 + IL_0044: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0049: ldc.i4.0 + IL_004a: ceq + IL_004c: stloc.0 + IL_004d: ldloc.0 + IL_004e: brtrue.s IL_0059 + + IL_0050: nop + IL_0051: ldc.i4.1 + IL_0052: call void [mscorlib]System.Console::WriteLine(int32) + IL_0057: nop + IL_0058: nop + IL_0059: nop + IL_005a: br.s IL_0069 + + IL_005c: nop + IL_005d: ldstr "else" + IL_0062: call void [mscorlib]System.Console::WriteLine(string) + IL_0067: nop + IL_0068: nop + IL_0069: ret + } // end of method ReduceNesting::NestedSwitchIf + + .method public hidebysig instance void + EarlyExit1() cil managed + { + // Code size 52 (0x34) + .maxstack 2 + .locals init (int32 V_0, + bool V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: stloc.1 + IL_0009: ldloc.1 + IL_000a: brtrue.s IL_0033 + + IL_000c: nop + IL_000d: ldc.i4.0 + IL_000e: stloc.0 + IL_000f: br.s IL_001e + + IL_0011: nop + IL_0012: ldloc.0 + IL_0013: call void [mscorlib]System.Console::WriteLine(int32) + IL_0018: nop + IL_0019: nop + IL_001a: ldloc.0 + IL_001b: ldc.i4.1 + IL_001c: add + IL_001d: stloc.0 + IL_001e: ldloc.0 + IL_001f: ldc.i4.s 10 + IL_0021: clt + IL_0023: stloc.1 + IL_0024: ldloc.1 + IL_0025: brtrue.s IL_0011 + + IL_0027: ldstr "end" + IL_002c: call void [mscorlib]System.Console::WriteLine(string) + IL_0031: nop + IL_0032: nop + IL_0033: ret + } // end of method ReduceNesting::EarlyExit1 + + .method public hidebysig instance void + EarlyExit2() cil managed + { + // Code size 82 (0x52) + .maxstack 2 + .locals init (int32 V_0, + bool V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: stloc.1 + IL_000c: ldloc.1 + IL_000d: brtrue.s IL_0012 + + IL_000f: nop + IL_0010: br.s IL_0051 + + IL_0012: ldc.i4.0 + IL_0013: stloc.0 + IL_0014: br.s IL_003d + + IL_0016: nop + IL_0017: ldloc.0 + IL_0018: call void [mscorlib]System.Console::WriteLine(int32) + IL_001d: nop + IL_001e: ldloc.0 + IL_001f: ldc.i4.2 + IL_0020: rem + IL_0021: ldc.i4.0 + IL_0022: ceq + IL_0024: ldc.i4.0 + IL_0025: ceq + IL_0027: stloc.1 + IL_0028: ldloc.1 + IL_0029: brtrue.s IL_0038 + + IL_002b: nop + IL_002c: ldstr "even" + IL_0031: call void [mscorlib]System.Console::WriteLine(string) + IL_0036: nop + IL_0037: nop + IL_0038: nop + IL_0039: ldloc.0 + IL_003a: ldc.i4.1 + IL_003b: add + IL_003c: stloc.0 + IL_003d: ldloc.0 + IL_003e: ldc.i4.s 10 + IL_0040: clt + IL_0042: stloc.1 + IL_0043: ldloc.1 + IL_0044: brtrue.s IL_0016 + + IL_0046: ldstr "end" + IL_004b: call void [mscorlib]System.Console::WriteLine(string) + IL_0050: nop + IL_0051: ret + } // end of method ReduceNesting::EarlyExit2 + + .method public hidebysig instance void + BalancedIf() cil managed + { + // Code size 90 (0x5a) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: brtrue.s IL_0035 + + IL_000f: nop + IL_0010: ldstr "true" + IL_0015: call void [mscorlib]System.Console::WriteLine(string) + IL_001a: nop + IL_001b: ldarg.0 + IL_001c: ldc.i4.1 + IL_001d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0022: ldc.i4.0 + IL_0023: ceq + IL_0025: stloc.0 + IL_0026: ldloc.0 + IL_0027: brtrue.s IL_0032 + + IL_0029: nop + IL_002a: ldc.i4.1 + IL_002b: call void [mscorlib]System.Console::WriteLine(int32) + IL_0030: nop + IL_0031: nop + IL_0032: nop + IL_0033: br.s IL_0059 + + IL_0035: nop + IL_0036: ldarg.0 + IL_0037: ldc.i4.2 + IL_0038: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_003d: ldc.i4.0 + IL_003e: ceq + IL_0040: stloc.0 + IL_0041: ldloc.0 + IL_0042: brtrue.s IL_004d + + IL_0044: nop + IL_0045: ldc.i4.2 + IL_0046: call void [mscorlib]System.Console::WriteLine(int32) + IL_004b: nop + IL_004c: nop + IL_004d: ldstr "false" + IL_0052: call void [mscorlib]System.Console::WriteLine(string) + IL_0057: nop + IL_0058: nop + IL_0059: ret + } // end of method ReduceNesting::BalancedIf + + .method public hidebysig instance string + ComplexCase1(string s) cil managed + { + // Code size 269 (0x10d) + .maxstack 2 + .locals init (int32 V_0, + string V_1, + bool V_2, + int32 V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: stloc.2 + IL_000c: ldloc.2 + IL_000d: brtrue.s IL_0017 + + IL_000f: nop + IL_0010: ldarg.1 + IL_0011: stloc.1 + IL_0012: br IL_010b + + IL_0017: ldc.i4.0 + IL_0018: stloc.0 + IL_0019: br IL_00f7 + + IL_001e: nop + IL_001f: ldarg.0 + IL_0020: ldc.i4.1 + IL_0021: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0026: ldc.i4.0 + IL_0027: ceq + IL_0029: stloc.2 + IL_002a: ldloc.2 + IL_002b: brtrue.s IL_003b + + IL_002d: nop + IL_002e: ldc.i4.1 + IL_002f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0034: nop + IL_0035: nop + IL_0036: br IL_00f2 + + IL_003b: ldarg.0 + IL_003c: ldc.i4.2 + IL_003d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0042: ldc.i4.0 + IL_0043: ceq + IL_0045: stloc.2 + IL_0046: ldloc.2 + IL_0047: brtrue.s IL_00b5 + + IL_0049: nop + IL_004a: ldloc.0 + IL_004b: stloc.3 + IL_004c: ldloc.3 + IL_004d: ldc.i4.1 + IL_004e: sub + IL_004f: switch ( + IL_0062, + IL_009e, + IL_009e) + IL_0060: br.s IL_00ab + + IL_0062: ldarg.0 + IL_0063: ldc.i4.3 + IL_0064: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0069: ldc.i4.0 + IL_006a: ceq + IL_006c: stloc.2 + IL_006d: ldloc.2 + IL_006e: brtrue.s IL_007a + + IL_0070: nop + IL_0071: ldc.i4.3 + IL_0072: call void [mscorlib]System.Console::WriteLine(int32) + IL_0077: nop + IL_0078: br.s IL_00ab + + IL_007a: ldstr "case1" + IL_007f: call void [mscorlib]System.Console::WriteLine(string) + IL_0084: nop + IL_0085: ldarg.0 + IL_0086: ldc.i4.4 + IL_0087: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_008c: ldc.i4.0 + IL_008d: ceq + IL_008f: stloc.2 + IL_0090: ldloc.2 + IL_0091: brtrue.s IL_009c + + IL_0093: nop + IL_0094: ldc.i4.4 + IL_0095: call void [mscorlib]System.Console::WriteLine(int32) + IL_009a: nop + IL_009b: nop + IL_009c: br.s IL_00ab + + IL_009e: ldstr "case23" + IL_00a3: call void [mscorlib]System.Console::WriteLine(string) + IL_00a8: nop + IL_00a9: br.s IL_00ab + + IL_00ab: ldc.i4.2 + IL_00ac: call void [mscorlib]System.Console::WriteLine(int32) + IL_00b1: nop + IL_00b2: nop + IL_00b3: br.s IL_00f2 + + IL_00b5: ldarg.0 + IL_00b6: ldc.i4.5 + IL_00b7: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_00bc: ldc.i4.0 + IL_00bd: ceq + IL_00bf: stloc.2 + IL_00c0: ldloc.2 + IL_00c1: brtrue.s IL_00ce + + IL_00c3: nop + IL_00c4: ldc.i4.5 + IL_00c5: call void [mscorlib]System.Console::WriteLine(int32) + IL_00ca: nop + IL_00cb: nop + IL_00cc: br.s IL_00f2 + + IL_00ce: nop + IL_00cf: ldarg.0 + IL_00d0: ldc.i4.6 + IL_00d1: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_00d6: ldc.i4.0 + IL_00d7: ceq + IL_00d9: stloc.2 + IL_00da: ldloc.2 + IL_00db: brtrue.s IL_00e6 + + IL_00dd: nop + IL_00de: ldc.i4.6 + IL_00df: call void [mscorlib]System.Console::WriteLine(int32) + IL_00e4: nop + IL_00e5: nop + IL_00e6: ldstr "else" + IL_00eb: call void [mscorlib]System.Console::WriteLine(string) + IL_00f0: nop + IL_00f1: nop + IL_00f2: nop + IL_00f3: ldloc.0 + IL_00f4: ldc.i4.1 + IL_00f5: add + IL_00f6: stloc.0 + IL_00f7: ldloc.0 + IL_00f8: ldarg.1 + IL_00f9: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_00fe: clt + IL_0100: stloc.2 + IL_0101: ldloc.2 + IL_0102: brtrue IL_001e + + IL_0107: ldarg.1 + IL_0108: stloc.1 + IL_0109: br.s IL_010b + + IL_010b: ldloc.1 + IL_010c: ret + } // end of method ReduceNesting::ComplexCase1 + + .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 ReduceNesting::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.opt.il new file mode 100644 index 000000000..4a5b3e019 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.opt.il @@ -0,0 +1,650 @@ + + + + +// 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 ReduceNesting.opt +{ + .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 ReduceNesting.opt.dll +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public abstract auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting + extends [mscorlib]System.Object +{ + .method public hidebysig newslot abstract virtual + instance bool B(int32 i) cil managed + { + } // end of method ReduceNesting::B + + .method public hidebysig newslot abstract virtual + instance int32 I(int32 i) cil managed + { + } // end of method ReduceNesting::I + + .method public hidebysig instance void + IfIf() cil managed + { + // Code size 42 (0x2a) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0010 + + IL_0009: ldc.i4.0 + IL_000a: call void [mscorlib]System.Console::WriteLine(int32) + IL_000f: ret + + IL_0010: ldarg.0 + IL_0011: ldc.i4.1 + IL_0012: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0017: brfalse.s IL_001f + + IL_0019: ldc.i4.1 + IL_001a: call void [mscorlib]System.Console::WriteLine(int32) + IL_001f: ldstr "end" + IL_0024: call void [mscorlib]System.Console::WriteLine(string) + IL_0029: ret + } // end of method ReduceNesting::IfIf + + .method public hidebysig instance void + IfSwitch() cil managed + { + // Code size 83 (0x53) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0010 + + IL_0009: ldc.i4.0 + IL_000a: call void [mscorlib]System.Console::WriteLine(int32) + IL_000f: ret + + IL_0010: ldstr "switch" + IL_0015: call void [mscorlib]System.Console::WriteLine(string) + IL_001a: ldarg.0 + IL_001b: ldc.i4.0 + IL_001c: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: switch ( + IL_0032, + IL_003d) + IL_0030: br.s IL_0048 + + IL_0032: ldstr "case 0" + IL_0037: call void [mscorlib]System.Console::WriteLine(string) + IL_003c: ret + + IL_003d: ldstr "case 1" + IL_0042: call void [mscorlib]System.Console::WriteLine(string) + IL_0047: ret + + IL_0048: ldstr "end" + IL_004d: call void [mscorlib]System.Console::WriteLine(string) + IL_0052: ret + } // end of method ReduceNesting::IfSwitch + + .method public hidebysig instance void + IfSwitchSwitch() cil managed + { + // Code size 139 (0x8b) + .maxstack 2 + .locals init (int32 V_0, + int32 V_1) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0010 + + IL_0009: ldc.i4.0 + IL_000a: call void [mscorlib]System.Console::WriteLine(int32) + IL_000f: ret + + IL_0010: ldstr "switch 0" + IL_0015: call void [mscorlib]System.Console::WriteLine(string) + IL_001a: ldarg.0 + IL_001b: ldc.i4.1 + IL_001c: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: switch ( + IL_0032, + IL_003d) + IL_0030: br.s IL_0048 + + IL_0032: ldstr "case 0" + IL_0037: call void [mscorlib]System.Console::WriteLine(string) + IL_003c: ret + + IL_003d: ldstr "case 1" + IL_0042: call void [mscorlib]System.Console::WriteLine(string) + IL_0047: ret + + IL_0048: ldstr "switch 1" + IL_004d: call void [mscorlib]System.Console::WriteLine(string) + IL_0052: ldarg.0 + IL_0053: ldc.i4.1 + IL_0054: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0059: stloc.1 + IL_005a: ldloc.1 + IL_005b: switch ( + IL_006a, + IL_0075) + IL_0068: br.s IL_0080 + + IL_006a: ldstr "case 0" + IL_006f: call void [mscorlib]System.Console::WriteLine(string) + IL_0074: ret + + IL_0075: ldstr "case 1" + IL_007a: call void [mscorlib]System.Console::WriteLine(string) + IL_007f: ret + + IL_0080: ldstr "end" + IL_0085: call void [mscorlib]System.Console::WriteLine(string) + IL_008a: ret + } // end of method ReduceNesting::IfSwitchSwitch + + .method public hidebysig instance void + IfLoop() cil managed + { + // Code size 46 (0x2e) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0010 + + IL_0009: ldc.i4.0 + IL_000a: call void [mscorlib]System.Console::WriteLine(int32) + IL_000f: ret + + IL_0010: ldc.i4.0 + IL_0011: stloc.0 + IL_0012: br.s IL_001e + + IL_0014: ldloc.0 + IL_0015: call void [mscorlib]System.Console::WriteLine(int32) + IL_001a: ldloc.0 + IL_001b: ldc.i4.1 + IL_001c: add + IL_001d: stloc.0 + IL_001e: ldloc.0 + IL_001f: ldc.i4.s 10 + IL_0021: blt.s IL_0014 + + IL_0023: ldstr "end" + IL_0028: call void [mscorlib]System.Console::WriteLine(string) + IL_002d: ret + } // end of method ReduceNesting::IfLoop + + .method public hidebysig instance void + LoopContinue() cil managed + { + // Code size 62 (0x3e) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: br.s IL_0038 + + IL_0004: ldloc.0 + IL_0005: call void [mscorlib]System.Console::WriteLine(int32) + IL_000a: ldarg.0 + IL_000b: ldc.i4.0 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0011: brfalse.s IL_001b + + IL_0013: ldc.i4.0 + IL_0014: call void [mscorlib]System.Console::WriteLine(int32) + IL_0019: br.s IL_0034 + + IL_001b: ldarg.0 + IL_001c: ldc.i4.1 + IL_001d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0022: brfalse.s IL_002a + + IL_0024: ldc.i4.1 + IL_0025: call void [mscorlib]System.Console::WriteLine(int32) + IL_002a: ldstr "loop-tail" + IL_002f: call void [mscorlib]System.Console::WriteLine(string) + IL_0034: ldloc.0 + IL_0035: ldc.i4.1 + IL_0036: add + IL_0037: stloc.0 + IL_0038: ldloc.0 + IL_0039: ldc.i4.s 10 + IL_003b: blt.s IL_0004 + + IL_003d: ret + } // end of method ReduceNesting::LoopContinue + + .method public hidebysig instance void + LoopBreak() cil managed + { + // Code size 91 (0x5b) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: br.s IL_004b + + IL_0004: ldloc.0 + IL_0005: call void [mscorlib]System.Console::WriteLine(int32) + IL_000a: ldarg.0 + IL_000b: ldc.i4.0 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0011: brfalse.s IL_001b + + IL_0013: ldc.i4.0 + IL_0014: call void [mscorlib]System.Console::WriteLine(int32) + IL_0019: br.s IL_0047 + + IL_001b: ldarg.0 + IL_001c: ldc.i4.1 + IL_001d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0022: brfalse.s IL_002c + + IL_0024: ldc.i4.1 + IL_0025: call void [mscorlib]System.Console::WriteLine(int32) + IL_002a: br.s IL_0050 + + IL_002c: ldarg.0 + IL_002d: ldc.i4.2 + IL_002e: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0033: brfalse.s IL_003b + + IL_0035: ldc.i4.2 + IL_0036: call void [mscorlib]System.Console::WriteLine(int32) + IL_003b: ldstr "break" + IL_0040: call void [mscorlib]System.Console::WriteLine(string) + IL_0045: br.s IL_0050 + + IL_0047: ldloc.0 + IL_0048: ldc.i4.1 + IL_0049: add + IL_004a: stloc.0 + IL_004b: ldloc.0 + IL_004c: ldc.i4.s 10 + IL_004e: blt.s IL_0004 + + IL_0050: ldstr "end" + IL_0055: call void [mscorlib]System.Console::WriteLine(string) + IL_005a: ret + } // end of method ReduceNesting::LoopBreak + + .method public hidebysig instance void + LoopBreakElseIf() cil managed + { + // Code size 81 (0x51) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: br.s IL_0041 + + IL_0004: ldloc.0 + IL_0005: call void [mscorlib]System.Console::WriteLine(int32) + IL_000a: ldarg.0 + IL_000b: ldc.i4.0 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0011: brfalse.s IL_001b + + IL_0013: ldc.i4.0 + IL_0014: call void [mscorlib]System.Console::WriteLine(int32) + IL_0019: br.s IL_003d + + IL_001b: ldarg.0 + IL_001c: ldc.i4.1 + IL_001d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0022: brfalse.s IL_002c + + IL_0024: ldc.i4.1 + IL_0025: call void [mscorlib]System.Console::WriteLine(int32) + IL_002a: br.s IL_0046 + + IL_002c: ldarg.0 + IL_002d: ldc.i4.2 + IL_002e: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0033: brfalse.s IL_0046 + + IL_0035: ldc.i4.2 + IL_0036: call void [mscorlib]System.Console::WriteLine(int32) + IL_003b: br.s IL_0046 + + IL_003d: ldloc.0 + IL_003e: ldc.i4.1 + IL_003f: add + IL_0040: stloc.0 + IL_0041: ldloc.0 + IL_0042: ldc.i4.s 10 + IL_0044: blt.s IL_0004 + + IL_0046: ldstr "end" + IL_004b: call void [mscorlib]System.Console::WriteLine(string) + IL_0050: ret + } // end of method ReduceNesting::LoopBreakElseIf + + .method public hidebysig instance void + SwitchIf() cil managed + { + // Code size 72 (0x48) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: switch ( + IL_0018, + IL_0023) + IL_0016: br.s IL_002e + + IL_0018: ldstr "case 0" + IL_001d: call void [mscorlib]System.Console::WriteLine(string) + IL_0022: ret + + IL_0023: ldstr "case 1" + IL_0028: call void [mscorlib]System.Console::WriteLine(string) + IL_002d: ret + + IL_002e: ldarg.0 + IL_002f: ldc.i4.0 + IL_0030: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0035: brfalse.s IL_003d + + IL_0037: ldc.i4.0 + IL_0038: call void [mscorlib]System.Console::WriteLine(int32) + IL_003d: ldstr "end" + IL_0042: call void [mscorlib]System.Console::WriteLine(string) + IL_0047: ret + } // end of method ReduceNesting::SwitchIf + + .method public hidebysig instance void + NestedSwitchIf() cil managed + { + // Code size 82 (0x52) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0047 + + IL_0009: ldarg.0 + IL_000a: ldc.i4.0 + IL_000b: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0010: stloc.0 + IL_0011: ldloc.0 + IL_0012: switch ( + IL_0021, + IL_002c) + IL_001f: br.s IL_0037 + + IL_0021: ldstr "case 0" + IL_0026: call void [mscorlib]System.Console::WriteLine(string) + IL_002b: ret + + IL_002c: ldstr "case 1" + IL_0031: call void [mscorlib]System.Console::WriteLine(string) + IL_0036: ret + + IL_0037: ldarg.0 + IL_0038: ldc.i4.1 + IL_0039: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_003e: brfalse.s IL_0051 + + IL_0040: ldc.i4.1 + IL_0041: call void [mscorlib]System.Console::WriteLine(int32) + IL_0046: ret + + IL_0047: ldstr "else" + IL_004c: call void [mscorlib]System.Console::WriteLine(string) + IL_0051: ret + } // end of method ReduceNesting::NestedSwitchIf + + .method public hidebysig instance void + EarlyExit1() cil managed + { + // Code size 39 (0x27) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brtrue.s IL_0026 + + IL_0009: ldc.i4.0 + IL_000a: stloc.0 + IL_000b: br.s IL_0017 + + IL_000d: ldloc.0 + IL_000e: call void [mscorlib]System.Console::WriteLine(int32) + IL_0013: ldloc.0 + IL_0014: ldc.i4.1 + IL_0015: add + IL_0016: stloc.0 + IL_0017: ldloc.0 + IL_0018: ldc.i4.s 10 + IL_001a: blt.s IL_000d + + IL_001c: ldstr "end" + IL_0021: call void [mscorlib]System.Console::WriteLine(string) + IL_0026: ret + } // end of method ReduceNesting::EarlyExit1 + + .method public hidebysig instance void + EarlyExit2() cil managed + { + // Code size 55 (0x37) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_000a + + IL_0009: ret + + IL_000a: ldc.i4.0 + IL_000b: stloc.0 + IL_000c: br.s IL_0027 + + IL_000e: ldloc.0 + IL_000f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0014: ldloc.0 + IL_0015: ldc.i4.2 + IL_0016: rem + IL_0017: brtrue.s IL_0023 + + IL_0019: ldstr "even" + IL_001e: call void [mscorlib]System.Console::WriteLine(string) + IL_0023: ldloc.0 + IL_0024: ldc.i4.1 + IL_0025: add + IL_0026: stloc.0 + IL_0027: ldloc.0 + IL_0028: ldc.i4.s 10 + IL_002a: blt.s IL_000e + + IL_002c: ldstr "end" + IL_0031: call void [mscorlib]System.Console::WriteLine(string) + IL_0036: ret + } // end of method ReduceNesting::EarlyExit2 + + .method public hidebysig instance void + BalancedIf() cil managed + { + // Code size 61 (0x3d) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0023 + + IL_0009: ldstr "true" + IL_000e: call void [mscorlib]System.Console::WriteLine(string) + IL_0013: ldarg.0 + IL_0014: ldc.i4.1 + IL_0015: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_001a: brfalse.s IL_003c + + IL_001c: ldc.i4.1 + IL_001d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0022: ret + + IL_0023: ldarg.0 + IL_0024: ldc.i4.2 + IL_0025: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_002a: brfalse.s IL_0032 + + IL_002c: ldc.i4.2 + IL_002d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0032: ldstr "false" + IL_0037: call void [mscorlib]System.Console::WriteLine(string) + IL_003c: ret + } // end of method ReduceNesting::BalancedIf + + .method public hidebysig instance string + ComplexCase1(string s) cil managed + { + // Code size 193 (0xc1) + .maxstack 2 + .locals init (int32 V_0, + int32 V_1) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_000b + + IL_0009: ldarg.1 + IL_000a: ret + + IL_000b: ldc.i4.0 + IL_000c: stloc.0 + IL_000d: br IL_00b3 + + IL_0012: ldarg.0 + IL_0013: ldc.i4.1 + IL_0014: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0019: brfalse.s IL_0026 + + IL_001b: ldc.i4.1 + IL_001c: call void [mscorlib]System.Console::WriteLine(int32) + IL_0021: br IL_00af + + IL_0026: ldarg.0 + IL_0027: ldc.i4.2 + IL_0028: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_002d: brfalse.s IL_0085 + + IL_002f: ldloc.0 + IL_0030: stloc.1 + IL_0031: ldloc.1 + IL_0032: ldc.i4.1 + IL_0033: sub + IL_0034: switch ( + IL_0047, + IL_0073, + IL_0073) + IL_0045: br.s IL_007d + + IL_0047: ldarg.0 + IL_0048: ldc.i4.3 + IL_0049: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_004e: brfalse.s IL_0058 + + IL_0050: ldc.i4.3 + IL_0051: call void [mscorlib]System.Console::WriteLine(int32) + IL_0056: br.s IL_007d + + IL_0058: ldstr "case1" + IL_005d: call void [mscorlib]System.Console::WriteLine(string) + IL_0062: ldarg.0 + IL_0063: ldc.i4.4 + IL_0064: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0069: brfalse.s IL_007d + + IL_006b: ldc.i4.4 + IL_006c: call void [mscorlib]System.Console::WriteLine(int32) + IL_0071: br.s IL_007d + + IL_0073: ldstr "case23" + IL_0078: call void [mscorlib]System.Console::WriteLine(string) + IL_007d: ldc.i4.2 + IL_007e: call void [mscorlib]System.Console::WriteLine(int32) + IL_0083: br.s IL_00af + + IL_0085: ldarg.0 + IL_0086: ldc.i4.5 + IL_0087: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_008c: brfalse.s IL_0096 + + IL_008e: ldc.i4.5 + IL_008f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0094: br.s IL_00af + + IL_0096: ldarg.0 + IL_0097: ldc.i4.6 + IL_0098: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_009d: brfalse.s IL_00a5 + + IL_009f: ldc.i4.6 + IL_00a0: call void [mscorlib]System.Console::WriteLine(int32) + IL_00a5: ldstr "else" + IL_00aa: call void [mscorlib]System.Console::WriteLine(string) + IL_00af: ldloc.0 + IL_00b0: ldc.i4.1 + IL_00b1: add + IL_00b2: stloc.0 + IL_00b3: ldloc.0 + IL_00b4: ldarg.1 + IL_00b5: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_00ba: blt IL_0012 + + IL_00bf: ldarg.1 + IL_00c0: ret + } // end of method ReduceNesting::ComplexCase1 + + .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 ReduceNesting::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.opt.roslyn.il new file mode 100644 index 000000000..e257c826a --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.opt.roslyn.il @@ -0,0 +1,668 @@ + + + + +// 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 ReduceNesting +{ + .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. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ReduceNesting.dll +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public abstract auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting + extends [mscorlib]System.Object +{ + .method public hidebysig newslot abstract virtual + instance bool B(int32 i) cil managed + { + } // end of method ReduceNesting::B + + .method public hidebysig newslot abstract virtual + instance int32 I(int32 i) cil managed + { + } // end of method ReduceNesting::I + + .method public hidebysig instance void + IfIf() cil managed + { + // Code size 42 (0x2a) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0010 + + IL_0009: ldc.i4.0 + IL_000a: call void [mscorlib]System.Console::WriteLine(int32) + IL_000f: ret + + IL_0010: ldarg.0 + IL_0011: ldc.i4.1 + IL_0012: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0017: brfalse.s IL_001f + + IL_0019: ldc.i4.1 + IL_001a: call void [mscorlib]System.Console::WriteLine(int32) + IL_001f: ldstr "end" + IL_0024: call void [mscorlib]System.Console::WriteLine(string) + IL_0029: ret + } // end of method ReduceNesting::IfIf + + .method public hidebysig instance void + IfSwitch() cil managed + { + // Code size 76 (0x4c) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0010 + + IL_0009: ldc.i4.0 + IL_000a: call void [mscorlib]System.Console::WriteLine(int32) + IL_000f: ret + + IL_0010: ldstr "switch" + IL_0015: call void [mscorlib]System.Console::WriteLine(string) + IL_001a: ldarg.0 + IL_001b: ldc.i4.0 + IL_001c: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: brfalse.s IL_002b + + IL_0025: ldloc.0 + IL_0026: ldc.i4.1 + IL_0027: beq.s IL_0036 + + IL_0029: br.s IL_0041 + + IL_002b: ldstr "case 0" + IL_0030: call void [mscorlib]System.Console::WriteLine(string) + IL_0035: ret + + IL_0036: ldstr "case 1" + IL_003b: call void [mscorlib]System.Console::WriteLine(string) + IL_0040: ret + + IL_0041: ldstr "end" + IL_0046: call void [mscorlib]System.Console::WriteLine(string) + IL_004b: ret + } // end of method ReduceNesting::IfSwitch + + .method public hidebysig instance void + IfSwitchSwitch() cil managed + { + // Code size 125 (0x7d) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0010 + + IL_0009: ldc.i4.0 + IL_000a: call void [mscorlib]System.Console::WriteLine(int32) + IL_000f: ret + + IL_0010: ldstr "switch 0" + IL_0015: call void [mscorlib]System.Console::WriteLine(string) + IL_001a: ldarg.0 + IL_001b: ldc.i4.1 + IL_001c: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0021: stloc.0 + IL_0022: ldloc.0 + IL_0023: brfalse.s IL_002b + + IL_0025: ldloc.0 + IL_0026: ldc.i4.1 + IL_0027: beq.s IL_0036 + + IL_0029: br.s IL_0041 + + IL_002b: ldstr "case 0" + IL_0030: call void [mscorlib]System.Console::WriteLine(string) + IL_0035: ret + + IL_0036: ldstr "case 1" + IL_003b: call void [mscorlib]System.Console::WriteLine(string) + IL_0040: ret + + IL_0041: ldstr "switch 1" + IL_0046: call void [mscorlib]System.Console::WriteLine(string) + IL_004b: ldarg.0 + IL_004c: ldc.i4.1 + IL_004d: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0052: stloc.0 + IL_0053: ldloc.0 + IL_0054: brfalse.s IL_005c + + IL_0056: ldloc.0 + IL_0057: ldc.i4.1 + IL_0058: beq.s IL_0067 + + IL_005a: br.s IL_0072 + + IL_005c: ldstr "case 0" + IL_0061: call void [mscorlib]System.Console::WriteLine(string) + IL_0066: ret + + IL_0067: ldstr "case 1" + IL_006c: call void [mscorlib]System.Console::WriteLine(string) + IL_0071: ret + + IL_0072: ldstr "end" + IL_0077: call void [mscorlib]System.Console::WriteLine(string) + IL_007c: ret + } // end of method ReduceNesting::IfSwitchSwitch + + .method public hidebysig instance void + IfLoop() cil managed + { + // Code size 46 (0x2e) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0010 + + IL_0009: ldc.i4.0 + IL_000a: call void [mscorlib]System.Console::WriteLine(int32) + IL_000f: ret + + IL_0010: ldc.i4.0 + IL_0011: stloc.0 + IL_0012: br.s IL_001e + + IL_0014: ldloc.0 + IL_0015: call void [mscorlib]System.Console::WriteLine(int32) + IL_001a: ldloc.0 + IL_001b: ldc.i4.1 + IL_001c: add + IL_001d: stloc.0 + IL_001e: ldloc.0 + IL_001f: ldc.i4.s 10 + IL_0021: blt.s IL_0014 + + IL_0023: ldstr "end" + IL_0028: call void [mscorlib]System.Console::WriteLine(string) + IL_002d: ret + } // end of method ReduceNesting::IfLoop + + .method public hidebysig instance void + LoopContinue() cil managed + { + // Code size 62 (0x3e) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: br.s IL_0038 + + IL_0004: ldloc.0 + IL_0005: call void [mscorlib]System.Console::WriteLine(int32) + IL_000a: ldarg.0 + IL_000b: ldc.i4.0 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0011: brfalse.s IL_001b + + IL_0013: ldc.i4.0 + IL_0014: call void [mscorlib]System.Console::WriteLine(int32) + IL_0019: br.s IL_0034 + + IL_001b: ldarg.0 + IL_001c: ldc.i4.1 + IL_001d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0022: brfalse.s IL_002a + + IL_0024: ldc.i4.1 + IL_0025: call void [mscorlib]System.Console::WriteLine(int32) + IL_002a: ldstr "loop-tail" + IL_002f: call void [mscorlib]System.Console::WriteLine(string) + IL_0034: ldloc.0 + IL_0035: ldc.i4.1 + IL_0036: add + IL_0037: stloc.0 + IL_0038: ldloc.0 + IL_0039: ldc.i4.s 10 + IL_003b: blt.s IL_0004 + + IL_003d: ret + } // end of method ReduceNesting::LoopContinue + + .method public hidebysig instance void + LoopBreak() cil managed + { + // Code size 91 (0x5b) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: br.s IL_004b + + IL_0004: ldloc.0 + IL_0005: call void [mscorlib]System.Console::WriteLine(int32) + IL_000a: ldarg.0 + IL_000b: ldc.i4.0 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0011: brfalse.s IL_001b + + IL_0013: ldc.i4.0 + IL_0014: call void [mscorlib]System.Console::WriteLine(int32) + IL_0019: br.s IL_0047 + + IL_001b: ldarg.0 + IL_001c: ldc.i4.1 + IL_001d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0022: brfalse.s IL_002c + + IL_0024: ldc.i4.1 + IL_0025: call void [mscorlib]System.Console::WriteLine(int32) + IL_002a: br.s IL_0050 + + IL_002c: ldarg.0 + IL_002d: ldc.i4.2 + IL_002e: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0033: brfalse.s IL_003b + + IL_0035: ldc.i4.2 + IL_0036: call void [mscorlib]System.Console::WriteLine(int32) + IL_003b: ldstr "break" + IL_0040: call void [mscorlib]System.Console::WriteLine(string) + IL_0045: br.s IL_0050 + + IL_0047: ldloc.0 + IL_0048: ldc.i4.1 + IL_0049: add + IL_004a: stloc.0 + IL_004b: ldloc.0 + IL_004c: ldc.i4.s 10 + IL_004e: blt.s IL_0004 + + IL_0050: ldstr "end" + IL_0055: call void [mscorlib]System.Console::WriteLine(string) + IL_005a: ret + } // end of method ReduceNesting::LoopBreak + + .method public hidebysig instance void + LoopBreakElseIf() cil managed + { + // Code size 81 (0x51) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: br.s IL_0041 + + IL_0004: ldloc.0 + IL_0005: call void [mscorlib]System.Console::WriteLine(int32) + IL_000a: ldarg.0 + IL_000b: ldc.i4.0 + IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0011: brfalse.s IL_001b + + IL_0013: ldc.i4.0 + IL_0014: call void [mscorlib]System.Console::WriteLine(int32) + IL_0019: br.s IL_003d + + IL_001b: ldarg.0 + IL_001c: ldc.i4.1 + IL_001d: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0022: brfalse.s IL_002c + + IL_0024: ldc.i4.1 + IL_0025: call void [mscorlib]System.Console::WriteLine(int32) + IL_002a: br.s IL_0046 + + IL_002c: ldarg.0 + IL_002d: ldc.i4.2 + IL_002e: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0033: brfalse.s IL_0046 + + IL_0035: ldc.i4.2 + IL_0036: call void [mscorlib]System.Console::WriteLine(int32) + IL_003b: br.s IL_0046 + + IL_003d: ldloc.0 + IL_003e: ldc.i4.1 + IL_003f: add + IL_0040: stloc.0 + IL_0041: ldloc.0 + IL_0042: ldc.i4.s 10 + IL_0044: blt.s IL_0004 + + IL_0046: ldstr "end" + IL_004b: call void [mscorlib]System.Console::WriteLine(string) + IL_0050: ret + } // end of method ReduceNesting::LoopBreakElseIf + + .method public hidebysig instance void + SwitchIf() cil managed + { + // Code size 65 (0x41) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: brfalse.s IL_0011 + + IL_000b: ldloc.0 + IL_000c: ldc.i4.1 + IL_000d: beq.s IL_001c + + IL_000f: br.s IL_0027 + + IL_0011: ldstr "case 0" + IL_0016: call void [mscorlib]System.Console::WriteLine(string) + IL_001b: ret + + IL_001c: ldstr "case 1" + IL_0021: call void [mscorlib]System.Console::WriteLine(string) + IL_0026: ret + + IL_0027: ldarg.0 + IL_0028: ldc.i4.0 + IL_0029: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_002e: brfalse.s IL_0036 + + IL_0030: ldc.i4.0 + IL_0031: call void [mscorlib]System.Console::WriteLine(int32) + IL_0036: ldstr "end" + IL_003b: call void [mscorlib]System.Console::WriteLine(string) + IL_0040: ret + } // end of method ReduceNesting::SwitchIf + + .method public hidebysig instance void + NestedSwitchIf() cil managed + { + // Code size 75 (0x4b) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0040 + + IL_0009: ldarg.0 + IL_000a: ldc.i4.0 + IL_000b: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0010: stloc.0 + IL_0011: ldloc.0 + IL_0012: brfalse.s IL_001a + + IL_0014: ldloc.0 + IL_0015: ldc.i4.1 + IL_0016: beq.s IL_0025 + + IL_0018: br.s IL_0030 + + IL_001a: ldstr "case 0" + IL_001f: call void [mscorlib]System.Console::WriteLine(string) + IL_0024: ret + + IL_0025: ldstr "case 1" + IL_002a: call void [mscorlib]System.Console::WriteLine(string) + IL_002f: ret + + IL_0030: ldarg.0 + IL_0031: ldc.i4.1 + IL_0032: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0037: brfalse.s IL_004a + + IL_0039: ldc.i4.1 + IL_003a: call void [mscorlib]System.Console::WriteLine(int32) + IL_003f: ret + + IL_0040: ldstr "else" + IL_0045: call void [mscorlib]System.Console::WriteLine(string) + IL_004a: ret + } // end of method ReduceNesting::NestedSwitchIf + + .method public hidebysig instance void + EarlyExit1() cil managed + { + // Code size 39 (0x27) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brtrue.s IL_0026 + + IL_0009: ldc.i4.0 + IL_000a: stloc.0 + IL_000b: br.s IL_0017 + + IL_000d: ldloc.0 + IL_000e: call void [mscorlib]System.Console::WriteLine(int32) + IL_0013: ldloc.0 + IL_0014: ldc.i4.1 + IL_0015: add + IL_0016: stloc.0 + IL_0017: ldloc.0 + IL_0018: ldc.i4.s 10 + IL_001a: blt.s IL_000d + + IL_001c: ldstr "end" + IL_0021: call void [mscorlib]System.Console::WriteLine(string) + IL_0026: ret + } // end of method ReduceNesting::EarlyExit1 + + .method public hidebysig instance void + EarlyExit2() cil managed + { + // Code size 55 (0x37) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_000a + + IL_0009: ret + + IL_000a: ldc.i4.0 + IL_000b: stloc.0 + IL_000c: br.s IL_0027 + + IL_000e: ldloc.0 + IL_000f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0014: ldloc.0 + IL_0015: ldc.i4.2 + IL_0016: rem + IL_0017: brtrue.s IL_0023 + + IL_0019: ldstr "even" + IL_001e: call void [mscorlib]System.Console::WriteLine(string) + IL_0023: ldloc.0 + IL_0024: ldc.i4.1 + IL_0025: add + IL_0026: stloc.0 + IL_0027: ldloc.0 + IL_0028: ldc.i4.s 10 + IL_002a: blt.s IL_000e + + IL_002c: ldstr "end" + IL_0031: call void [mscorlib]System.Console::WriteLine(string) + IL_0036: ret + } // end of method ReduceNesting::EarlyExit2 + + .method public hidebysig instance void + BalancedIf() cil managed + { + // Code size 61 (0x3d) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_0023 + + IL_0009: ldstr "true" + IL_000e: call void [mscorlib]System.Console::WriteLine(string) + IL_0013: ldarg.0 + IL_0014: ldc.i4.1 + IL_0015: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_001a: brfalse.s IL_003c + + IL_001c: ldc.i4.1 + IL_001d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0022: ret + + IL_0023: ldarg.0 + IL_0024: ldc.i4.2 + IL_0025: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_002a: brfalse.s IL_0032 + + IL_002c: ldc.i4.2 + IL_002d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0032: ldstr "false" + IL_0037: call void [mscorlib]System.Console::WriteLine(string) + IL_003c: ret + } // end of method ReduceNesting::BalancedIf + + .method public hidebysig instance string + ComplexCase1(string s) cil managed + { + // Code size 178 (0xb2) + .maxstack 2 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0007: brfalse.s IL_000b + + IL_0009: ldarg.1 + IL_000a: ret + + IL_000b: ldc.i4.0 + IL_000c: stloc.0 + IL_000d: br IL_00a4 + + IL_0012: ldarg.0 + IL_0013: ldc.i4.1 + IL_0014: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0019: brfalse.s IL_0023 + + IL_001b: ldc.i4.1 + IL_001c: call void [mscorlib]System.Console::WriteLine(int32) + IL_0021: br.s IL_00a0 + + IL_0023: ldarg.0 + IL_0024: ldc.i4.2 + IL_0025: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_002a: brfalse.s IL_0076 + + IL_002c: ldloc.0 + IL_002d: ldc.i4.1 + IL_002e: beq.s IL_0038 + + IL_0030: ldloc.0 + IL_0031: ldc.i4.2 + IL_0032: sub + IL_0033: ldc.i4.1 + IL_0034: ble.un.s IL_0064 + + IL_0036: br.s IL_006e + + IL_0038: ldarg.0 + IL_0039: ldc.i4.3 + IL_003a: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_003f: brfalse.s IL_0049 + + IL_0041: ldc.i4.3 + IL_0042: call void [mscorlib]System.Console::WriteLine(int32) + IL_0047: br.s IL_006e + + IL_0049: ldstr "case1" + IL_004e: call void [mscorlib]System.Console::WriteLine(string) + IL_0053: ldarg.0 + IL_0054: ldc.i4.4 + IL_0055: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_005a: brfalse.s IL_006e + + IL_005c: ldc.i4.4 + IL_005d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0062: br.s IL_006e + + IL_0064: ldstr "case23" + IL_0069: call void [mscorlib]System.Console::WriteLine(string) + IL_006e: ldc.i4.2 + IL_006f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0074: br.s IL_00a0 + + IL_0076: ldarg.0 + IL_0077: ldc.i4.5 + IL_0078: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_007d: brfalse.s IL_0087 + + IL_007f: ldc.i4.5 + IL_0080: call void [mscorlib]System.Console::WriteLine(int32) + IL_0085: br.s IL_00a0 + + IL_0087: ldarg.0 + IL_0088: ldc.i4.6 + IL_0089: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_008e: brfalse.s IL_0096 + + IL_0090: ldc.i4.6 + IL_0091: call void [mscorlib]System.Console::WriteLine(int32) + IL_0096: ldstr "else" + IL_009b: call void [mscorlib]System.Console::WriteLine(string) + IL_00a0: ldloc.0 + IL_00a1: ldc.i4.1 + IL_00a2: add + IL_00a3: stloc.0 + IL_00a4: ldloc.0 + IL_00a5: ldarg.1 + IL_00a6: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_00ab: blt IL_0012 + + IL_00b0: ldarg.1 + IL_00b1: ret + } // end of method ReduceNesting::ComplexCase1 + + .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 ReduceNesting::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.roslyn.il new file mode 100644 index 000000000..c4058adaf --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.roslyn.il @@ -0,0 +1,954 @@ + + + + +// 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 ReduceNesting +{ + .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. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module ReduceNesting.dll +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public abstract auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting + extends [mscorlib]System.Object +{ + .method public hidebysig newslot abstract virtual + instance bool B(int32 i) cil managed + { + } // end of method ReduceNesting::B + + .method public hidebysig newslot abstract virtual + instance int32 I(int32 i) cil managed + { + } // end of method ReduceNesting::I + + .method public hidebysig instance void + IfIf() cil managed + { + // Code size 54 (0x36) + .maxstack 2 + .locals init (bool V_0, + bool V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: brfalse.s IL_0016 + + IL_000c: nop + IL_000d: ldc.i4.0 + IL_000e: call void [mscorlib]System.Console::WriteLine(int32) + IL_0013: nop + IL_0014: br.s IL_0035 + + IL_0016: ldarg.0 + IL_0017: ldc.i4.1 + IL_0018: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_001d: stloc.1 + IL_001e: ldloc.1 + IL_001f: brfalse.s IL_002a + + IL_0021: nop + IL_0022: ldc.i4.1 + IL_0023: call void [mscorlib]System.Console::WriteLine(int32) + IL_0028: nop + IL_0029: nop + IL_002a: ldstr "end" + IL_002f: call void [mscorlib]System.Console::WriteLine(string) + IL_0034: nop + IL_0035: ret + } // end of method ReduceNesting::IfIf + + .method public hidebysig instance void + IfSwitch() cil managed + { + // Code size 92 (0x5c) + .maxstack 2 + .locals init (bool V_0, + int32 V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: brfalse.s IL_0016 + + IL_000c: nop + IL_000d: ldc.i4.0 + IL_000e: call void [mscorlib]System.Console::WriteLine(int32) + IL_0013: nop + IL_0014: br.s IL_005b + + IL_0016: ldstr "switch" + IL_001b: call void [mscorlib]System.Console::WriteLine(string) + IL_0020: nop + IL_0021: ldarg.0 + IL_0022: ldc.i4.0 + IL_0023: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0028: stloc.1 + IL_0029: ldloc.1 + IL_002a: brfalse.s IL_0034 + + IL_002c: br.s IL_002e + + IL_002e: ldloc.1 + IL_002f: ldc.i4.1 + IL_0030: beq.s IL_0041 + + IL_0032: br.s IL_004e + + IL_0034: ldstr "case 0" + IL_0039: call void [mscorlib]System.Console::WriteLine(string) + IL_003e: nop + IL_003f: br.s IL_005b + + IL_0041: ldstr "case 1" + IL_0046: call void [mscorlib]System.Console::WriteLine(string) + IL_004b: nop + IL_004c: br.s IL_005b + + IL_004e: ldstr "end" + IL_0053: call void [mscorlib]System.Console::WriteLine(string) + IL_0058: nop + IL_0059: br.s IL_005b + + IL_005b: ret + } // end of method ReduceNesting::IfSwitch + + .method public hidebysig instance void + IfSwitchSwitch() cil managed + { + // Code size 148 (0x94) + .maxstack 2 + .locals init (bool V_0, + int32 V_1, + int32 V_2) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: brfalse.s IL_0016 + + IL_000c: nop + IL_000d: ldc.i4.0 + IL_000e: call void [mscorlib]System.Console::WriteLine(int32) + IL_0013: nop + IL_0014: br.s IL_0093 + + IL_0016: ldstr "switch 0" + IL_001b: call void [mscorlib]System.Console::WriteLine(string) + IL_0020: nop + IL_0021: ldarg.0 + IL_0022: ldc.i4.1 + IL_0023: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0028: stloc.1 + IL_0029: ldloc.1 + IL_002a: brfalse.s IL_0034 + + IL_002c: br.s IL_002e + + IL_002e: ldloc.1 + IL_002f: ldc.i4.1 + IL_0030: beq.s IL_0041 + + IL_0032: br.s IL_004e + + IL_0034: ldstr "case 0" + IL_0039: call void [mscorlib]System.Console::WriteLine(string) + IL_003e: nop + IL_003f: br.s IL_0093 + + IL_0041: ldstr "case 1" + IL_0046: call void [mscorlib]System.Console::WriteLine(string) + IL_004b: nop + IL_004c: br.s IL_0093 + + IL_004e: ldstr "switch 1" + IL_0053: call void [mscorlib]System.Console::WriteLine(string) + IL_0058: nop + IL_0059: ldarg.0 + IL_005a: ldc.i4.1 + IL_005b: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0060: stloc.2 + IL_0061: ldloc.2 + IL_0062: brfalse.s IL_006c + + IL_0064: br.s IL_0066 + + IL_0066: ldloc.2 + IL_0067: ldc.i4.1 + IL_0068: beq.s IL_0079 + + IL_006a: br.s IL_0086 + + IL_006c: ldstr "case 0" + IL_0071: call void [mscorlib]System.Console::WriteLine(string) + IL_0076: nop + IL_0077: br.s IL_0093 + + IL_0079: ldstr "case 1" + IL_007e: call void [mscorlib]System.Console::WriteLine(string) + IL_0083: nop + IL_0084: br.s IL_0093 + + IL_0086: ldstr "end" + IL_008b: call void [mscorlib]System.Console::WriteLine(string) + IL_0090: nop + IL_0091: br.s IL_0093 + + IL_0093: ret + } // end of method ReduceNesting::IfSwitchSwitch + + .method public hidebysig instance void + IfLoop() cil managed + { + // Code size 60 (0x3c) + .maxstack 2 + .locals init (bool V_0, + int32 V_1, + bool V_2) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: brfalse.s IL_0016 + + IL_000c: nop + IL_000d: ldc.i4.0 + IL_000e: call void [mscorlib]System.Console::WriteLine(int32) + IL_0013: nop + IL_0014: br.s IL_003b + + IL_0016: ldc.i4.0 + IL_0017: stloc.1 + IL_0018: br.s IL_0027 + + IL_001a: nop + IL_001b: ldloc.1 + IL_001c: call void [mscorlib]System.Console::WriteLine(int32) + IL_0021: nop + IL_0022: nop + IL_0023: ldloc.1 + IL_0024: ldc.i4.1 + IL_0025: add + IL_0026: stloc.1 + IL_0027: ldloc.1 + IL_0028: ldc.i4.s 10 + IL_002a: clt + IL_002c: stloc.2 + IL_002d: ldloc.2 + IL_002e: brtrue.s IL_001a + + IL_0030: ldstr "end" + IL_0035: call void [mscorlib]System.Console::WriteLine(string) + IL_003a: nop + IL_003b: ret + } // end of method ReduceNesting::IfLoop + + .method public hidebysig instance void + LoopContinue() cil managed + { + // Code size 80 (0x50) + .maxstack 2 + .locals init (int32 V_0, + bool V_1, + bool V_2, + bool V_3) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: br.s IL_0046 + + IL_0005: nop + IL_0006: ldloc.0 + IL_0007: call void [mscorlib]System.Console::WriteLine(int32) + IL_000c: nop + IL_000d: ldarg.0 + IL_000e: ldc.i4.0 + IL_000f: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: brfalse.s IL_0022 + + IL_0018: nop + IL_0019: ldc.i4.0 + IL_001a: call void [mscorlib]System.Console::WriteLine(int32) + IL_001f: nop + IL_0020: br.s IL_0042 + + IL_0022: ldarg.0 + IL_0023: ldc.i4.1 + IL_0024: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0029: stloc.2 + IL_002a: ldloc.2 + IL_002b: brfalse.s IL_0036 + + IL_002d: nop + IL_002e: ldc.i4.1 + IL_002f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0034: nop + IL_0035: nop + IL_0036: ldstr "loop-tail" + IL_003b: call void [mscorlib]System.Console::WriteLine(string) + IL_0040: nop + IL_0041: nop + IL_0042: ldloc.0 + IL_0043: ldc.i4.1 + IL_0044: add + IL_0045: stloc.0 + IL_0046: ldloc.0 + IL_0047: ldc.i4.s 10 + IL_0049: clt + IL_004b: stloc.3 + IL_004c: ldloc.3 + IL_004d: brtrue.s IL_0005 + + IL_004f: ret + } // end of method ReduceNesting::LoopContinue + + .method public hidebysig instance void + LoopBreak() cil managed + { + // Code size 115 (0x73) + .maxstack 2 + .locals init (int32 V_0, + bool V_1, + bool V_2, + bool V_3, + bool V_4) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: br.s IL_005c + + IL_0005: nop + IL_0006: ldloc.0 + IL_0007: call void [mscorlib]System.Console::WriteLine(int32) + IL_000c: nop + IL_000d: ldarg.0 + IL_000e: ldc.i4.0 + IL_000f: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: brfalse.s IL_0022 + + IL_0018: nop + IL_0019: ldc.i4.0 + IL_001a: call void [mscorlib]System.Console::WriteLine(int32) + IL_001f: nop + IL_0020: br.s IL_0058 + + IL_0022: ldarg.0 + IL_0023: ldc.i4.1 + IL_0024: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0029: stloc.2 + IL_002a: ldloc.2 + IL_002b: brfalse.s IL_0037 + + IL_002d: nop + IL_002e: ldc.i4.1 + IL_002f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0034: nop + IL_0035: br.s IL_0067 + + IL_0037: ldarg.0 + IL_0038: ldc.i4.2 + IL_0039: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_003e: stloc.3 + IL_003f: ldloc.3 + IL_0040: brfalse.s IL_004b + + IL_0042: nop + IL_0043: ldc.i4.2 + IL_0044: call void [mscorlib]System.Console::WriteLine(int32) + IL_0049: nop + IL_004a: nop + IL_004b: ldstr "break" + IL_0050: call void [mscorlib]System.Console::WriteLine(string) + IL_0055: nop + IL_0056: br.s IL_0067 + + IL_0058: ldloc.0 + IL_0059: ldc.i4.1 + IL_005a: add + IL_005b: stloc.0 + IL_005c: ldloc.0 + IL_005d: ldc.i4.s 10 + IL_005f: clt + IL_0061: stloc.s V_4 + IL_0063: ldloc.s V_4 + IL_0065: brtrue.s IL_0005 + + IL_0067: ldstr "end" + IL_006c: call void [mscorlib]System.Console::WriteLine(string) + IL_0071: nop + IL_0072: ret + } // end of method ReduceNesting::LoopBreak + + .method public hidebysig instance void + LoopBreakElseIf() cil managed + { + // Code size 105 (0x69) + .maxstack 2 + .locals init (int32 V_0, + bool V_1, + bool V_2, + bool V_3, + bool V_4) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: br.s IL_0052 + + IL_0005: nop + IL_0006: ldloc.0 + IL_0007: call void [mscorlib]System.Console::WriteLine(int32) + IL_000c: nop + IL_000d: ldarg.0 + IL_000e: ldc.i4.0 + IL_000f: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: brfalse.s IL_0022 + + IL_0018: nop + IL_0019: ldc.i4.0 + IL_001a: call void [mscorlib]System.Console::WriteLine(int32) + IL_001f: nop + IL_0020: br.s IL_004e + + IL_0022: ldarg.0 + IL_0023: ldc.i4.1 + IL_0024: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0029: stloc.2 + IL_002a: ldloc.2 + IL_002b: brfalse.s IL_0038 + + IL_002d: nop + IL_002e: ldc.i4.1 + IL_002f: call void [mscorlib]System.Console::WriteLine(int32) + IL_0034: nop + IL_0035: nop + IL_0036: br.s IL_004c + + IL_0038: ldarg.0 + IL_0039: ldc.i4.2 + IL_003a: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_003f: stloc.3 + IL_0040: ldloc.3 + IL_0041: brfalse.s IL_004c + + IL_0043: nop + IL_0044: ldc.i4.2 + IL_0045: call void [mscorlib]System.Console::WriteLine(int32) + IL_004a: nop + IL_004b: nop + IL_004c: br.s IL_005d + + IL_004e: ldloc.0 + IL_004f: ldc.i4.1 + IL_0050: add + IL_0051: stloc.0 + IL_0052: ldloc.0 + IL_0053: ldc.i4.s 10 + IL_0055: clt + IL_0057: stloc.s V_4 + IL_0059: ldloc.s V_4 + IL_005b: brtrue.s IL_0005 + + IL_005d: ldstr "end" + IL_0062: call void [mscorlib]System.Console::WriteLine(string) + IL_0067: nop + IL_0068: ret + } // end of method ReduceNesting::LoopBreakElseIf + + .method public hidebysig instance void + SwitchIf() cil managed + { + // Code size 78 (0x4e) + .maxstack 2 + .locals init (int32 V_0, + bool V_1) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: brfalse.s IL_0014 + + IL_000c: br.s IL_000e + + IL_000e: ldloc.0 + IL_000f: ldc.i4.1 + IL_0010: beq.s IL_0021 + + IL_0012: br.s IL_002e + + IL_0014: ldstr "case 0" + IL_0019: call void [mscorlib]System.Console::WriteLine(string) + IL_001e: nop + IL_001f: br.s IL_004d + + IL_0021: ldstr "case 1" + IL_0026: call void [mscorlib]System.Console::WriteLine(string) + IL_002b: nop + IL_002c: br.s IL_004d + + IL_002e: ldarg.0 + IL_002f: ldc.i4.0 + IL_0030: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0035: stloc.1 + IL_0036: ldloc.1 + IL_0037: brfalse.s IL_0042 + + IL_0039: nop + IL_003a: ldc.i4.0 + IL_003b: call void [mscorlib]System.Console::WriteLine(int32) + IL_0040: nop + IL_0041: nop + IL_0042: ldstr "end" + IL_0047: call void [mscorlib]System.Console::WriteLine(string) + IL_004c: nop + IL_004d: ret + } // end of method ReduceNesting::SwitchIf + + .method public hidebysig instance void + NestedSwitchIf() cil managed + { + // Code size 95 (0x5f) + .maxstack 2 + .locals init (bool V_0, + int32 V_1, + bool V_2) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: brfalse.s IL_0051 + + IL_000c: nop + IL_000d: ldarg.0 + IL_000e: ldc.i4.0 + IL_000f: callvirt instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::I(int32) + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: brfalse.s IL_0020 + + IL_0018: br.s IL_001a + + IL_001a: ldloc.1 + IL_001b: ldc.i4.1 + IL_001c: beq.s IL_002d + + IL_001e: br.s IL_003a + + IL_0020: ldstr "case 0" + IL_0025: call void [mscorlib]System.Console::WriteLine(string) + IL_002a: nop + IL_002b: br.s IL_005e + + IL_002d: ldstr "case 1" + IL_0032: call void [mscorlib]System.Console::WriteLine(string) + IL_0037: nop + IL_0038: br.s IL_005e + + IL_003a: ldarg.0 + IL_003b: ldc.i4.1 + IL_003c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0041: stloc.2 + IL_0042: ldloc.2 + IL_0043: brfalse.s IL_004e + + IL_0045: nop + IL_0046: ldc.i4.1 + IL_0047: call void [mscorlib]System.Console::WriteLine(int32) + IL_004c: nop + IL_004d: nop + IL_004e: nop + IL_004f: br.s IL_005e + + IL_0051: nop + IL_0052: ldstr "else" + IL_0057: call void [mscorlib]System.Console::WriteLine(string) + IL_005c: nop + IL_005d: nop + IL_005e: ret + } // end of method ReduceNesting::NestedSwitchIf + + .method public hidebysig instance void + EarlyExit1() cil managed + { + // Code size 55 (0x37) + .maxstack 2 + .locals init (bool V_0, + int32 V_1, + bool V_2) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: brfalse.s IL_0036 + + IL_000f: nop + IL_0010: ldc.i4.0 + IL_0011: stloc.1 + IL_0012: br.s IL_0021 + + IL_0014: nop + IL_0015: ldloc.1 + IL_0016: call void [mscorlib]System.Console::WriteLine(int32) + IL_001b: nop + IL_001c: nop + IL_001d: ldloc.1 + IL_001e: ldc.i4.1 + IL_001f: add + IL_0020: stloc.1 + IL_0021: ldloc.1 + IL_0022: ldc.i4.s 10 + IL_0024: clt + IL_0026: stloc.2 + IL_0027: ldloc.2 + IL_0028: brtrue.s IL_0014 + + IL_002a: ldstr "end" + IL_002f: call void [mscorlib]System.Console::WriteLine(string) + IL_0034: nop + IL_0035: nop + IL_0036: ret + } // end of method ReduceNesting::EarlyExit1 + + .method public hidebysig instance void + EarlyExit2() cil managed + { + // Code size 76 (0x4c) + .maxstack 2 + .locals init (bool V_0, + int32 V_1, + bool V_2, + bool V_3) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: brfalse.s IL_000f + + IL_000c: nop + IL_000d: br.s IL_004b + + IL_000f: ldc.i4.0 + IL_0010: stloc.1 + IL_0011: br.s IL_0037 + + IL_0013: nop + IL_0014: ldloc.1 + IL_0015: call void [mscorlib]System.Console::WriteLine(int32) + IL_001a: nop + IL_001b: ldloc.1 + IL_001c: ldc.i4.2 + IL_001d: rem + IL_001e: ldc.i4.0 + IL_001f: ceq + IL_0021: stloc.2 + IL_0022: ldloc.2 + IL_0023: brfalse.s IL_0032 + + IL_0025: nop + IL_0026: ldstr "even" + IL_002b: call void [mscorlib]System.Console::WriteLine(string) + IL_0030: nop + IL_0031: nop + IL_0032: nop + IL_0033: ldloc.1 + IL_0034: ldc.i4.1 + IL_0035: add + IL_0036: stloc.1 + IL_0037: ldloc.1 + IL_0038: ldc.i4.s 10 + IL_003a: clt + IL_003c: stloc.3 + IL_003d: ldloc.3 + IL_003e: brtrue.s IL_0013 + + IL_0040: ldstr "end" + IL_0045: call void [mscorlib]System.Console::WriteLine(string) + IL_004a: nop + IL_004b: ret + } // end of method ReduceNesting::EarlyExit2 + + .method public hidebysig instance void + BalancedIf() cil managed + { + // Code size 81 (0x51) + .maxstack 2 + .locals init (bool V_0, + bool V_1, + bool V_2) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: brfalse.s IL_002f + + IL_000c: nop + IL_000d: ldstr "true" + IL_0012: call void [mscorlib]System.Console::WriteLine(string) + IL_0017: nop + IL_0018: ldarg.0 + IL_0019: ldc.i4.1 + IL_001a: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_001f: stloc.1 + IL_0020: ldloc.1 + IL_0021: brfalse.s IL_002c + + IL_0023: nop + IL_0024: ldc.i4.1 + IL_0025: call void [mscorlib]System.Console::WriteLine(int32) + IL_002a: nop + IL_002b: nop + IL_002c: nop + IL_002d: br.s IL_0050 + + IL_002f: nop + IL_0030: ldarg.0 + IL_0031: ldc.i4.2 + IL_0032: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0037: stloc.2 + IL_0038: ldloc.2 + IL_0039: brfalse.s IL_0044 + + IL_003b: nop + IL_003c: ldc.i4.2 + IL_003d: call void [mscorlib]System.Console::WriteLine(int32) + IL_0042: nop + IL_0043: nop + IL_0044: ldstr "false" + IL_0049: call void [mscorlib]System.Console::WriteLine(string) + IL_004e: nop + IL_004f: nop + IL_0050: ret + } // end of method ReduceNesting::BalancedIf + + .method public hidebysig instance string + ComplexCase1(string s) cil managed + { + // Code size 255 (0xff) + .maxstack 2 + .locals init (bool V_0, + string V_1, + int32 V_2, + bool V_3, + bool V_4, + int32 V_5, + bool V_6, + bool V_7, + bool V_8, + bool V_9, + bool V_10) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0008: stloc.0 + IL_0009: ldloc.0 + IL_000a: brfalse.s IL_0014 + + IL_000c: nop + IL_000d: ldarg.1 + IL_000e: stloc.1 + IL_000f: br IL_00fd + + IL_0014: ldc.i4.0 + IL_0015: stloc.2 + IL_0016: br IL_00e7 + + IL_001b: nop + IL_001c: ldarg.0 + IL_001d: ldc.i4.1 + IL_001e: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_0023: stloc.3 + IL_0024: ldloc.3 + IL_0025: brfalse.s IL_0035 + + IL_0027: nop + IL_0028: ldc.i4.1 + IL_0029: call void [mscorlib]System.Console::WriteLine(int32) + IL_002e: nop + IL_002f: nop + IL_0030: br IL_00e2 + + IL_0035: ldarg.0 + IL_0036: ldc.i4.2 + IL_0037: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_003c: stloc.s V_4 + IL_003e: ldloc.s V_4 + IL_0040: brfalse.s IL_00a7 + + IL_0042: nop + IL_0043: ldloc.2 + IL_0044: stloc.s V_5 + IL_0046: ldloc.s V_5 + IL_0048: ldc.i4.1 + IL_0049: beq.s IL_0056 + + IL_004b: br.s IL_004d + + IL_004d: ldloc.s V_5 + IL_004f: ldc.i4.2 + IL_0050: sub + IL_0051: ldc.i4.1 + IL_0052: ble.un.s IL_0090 + + IL_0054: br.s IL_009d + + IL_0056: ldarg.0 + IL_0057: ldc.i4.3 + IL_0058: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_005d: stloc.s V_6 + IL_005f: ldloc.s V_6 + IL_0061: brfalse.s IL_006d + + IL_0063: nop + IL_0064: ldc.i4.3 + IL_0065: call void [mscorlib]System.Console::WriteLine(int32) + IL_006a: nop + IL_006b: br.s IL_009d + + IL_006d: ldstr "case1" + IL_0072: call void [mscorlib]System.Console::WriteLine(string) + IL_0077: nop + IL_0078: ldarg.0 + IL_0079: ldc.i4.4 + IL_007a: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_007f: stloc.s V_7 + IL_0081: ldloc.s V_7 + IL_0083: brfalse.s IL_008e + + IL_0085: nop + IL_0086: ldc.i4.4 + IL_0087: call void [mscorlib]System.Console::WriteLine(int32) + IL_008c: nop + IL_008d: nop + IL_008e: br.s IL_009d + + IL_0090: ldstr "case23" + IL_0095: call void [mscorlib]System.Console::WriteLine(string) + IL_009a: nop + IL_009b: br.s IL_009d + + IL_009d: ldc.i4.2 + IL_009e: call void [mscorlib]System.Console::WriteLine(int32) + IL_00a3: nop + IL_00a4: nop + IL_00a5: br.s IL_00e2 + + IL_00a7: ldarg.0 + IL_00a8: ldc.i4.5 + IL_00a9: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_00ae: stloc.s V_8 + IL_00b0: ldloc.s V_8 + IL_00b2: brfalse.s IL_00bf + + IL_00b4: nop + IL_00b5: ldc.i4.5 + IL_00b6: call void [mscorlib]System.Console::WriteLine(int32) + IL_00bb: nop + IL_00bc: nop + IL_00bd: br.s IL_00e2 + + IL_00bf: nop + IL_00c0: ldarg.0 + IL_00c1: ldc.i4.6 + IL_00c2: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting::B(int32) + IL_00c7: stloc.s V_9 + IL_00c9: ldloc.s V_9 + IL_00cb: brfalse.s IL_00d6 + + IL_00cd: nop + IL_00ce: ldc.i4.6 + IL_00cf: call void [mscorlib]System.Console::WriteLine(int32) + IL_00d4: nop + IL_00d5: nop + IL_00d6: ldstr "else" + IL_00db: call void [mscorlib]System.Console::WriteLine(string) + IL_00e0: nop + IL_00e1: nop + IL_00e2: nop + IL_00e3: ldloc.2 + IL_00e4: ldc.i4.1 + IL_00e5: add + IL_00e6: stloc.2 + IL_00e7: ldloc.2 + IL_00e8: ldarg.1 + IL_00e9: callvirt instance int32 [mscorlib]System.String::get_Length() + IL_00ee: clt + IL_00f0: stloc.s V_10 + IL_00f2: ldloc.s V_10 + IL_00f4: brtrue IL_001b + + IL_00f9: ldarg.1 + IL_00fa: stloc.1 + IL_00fb: br.s IL_00fd + + IL_00fd: ldloc.1 + IL_00fe: ret + } // end of method ReduceNesting::ComplexCase1 + + .method family hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method ReduceNesting::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.ReduceNesting + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 9328792e7..aa26c7ce2 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -153,6 +153,7 @@ namespace ICSharpCode.Decompiler.CSharp new ProxyCallReplacer(), new DelegateConstruction(), new HighLevelLoopTransform(), + new ReduceNestingTransform(), new IntroduceDynamicTypeOnLocals(), new AssignVariableNames(), }; diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 1c57853f4..7d64852ea 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -267,6 +267,7 @@ + diff --git a/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs new file mode 100644 index 000000000..e791a5c41 --- /dev/null +++ b/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs @@ -0,0 +1,418 @@ +// Copyright (c) 2018 Siegfried Pammer +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Diagnostics; +using System.Linq; +using ICSharpCode.Decompiler.IL.ControlFlow; +using ICSharpCode.Decompiler.IL.Transforms; +using ICSharpCode.Decompiler.Util; + +namespace ICSharpCode.Decompiler.IL +{ + /// + /// Improves code quality by duplicating keyword exits to reduce nesting and restoring IL order. + /// + /// + /// ConditionDetection and DetectSwitchBody both have agressive inlining policies for else blocks and default cases respectively. + /// This can lead to excessive indentation when the entire rest of the method/loop is included in the else block/default case. + /// When an If/SwitchInstruction is followed immediately by a keyword exit, the exit can be moved into the child blocks + /// allowing the else block or default case to be moved after the if/switch as all prior cases exit. + /// Most importantly, this transformatino does not change the IL order of any code. + /// + /// ConditionDetection also has a block exit priority system to assist exit point reduction which in some cases ignores IL order. + /// After HighLevelLoopTransform has run, all structures have been detected and preference can be returned to maintaining IL ordering. + /// + public class ReduceNestingTransform : IILTransform + { + private ILTransformContext context; + + public void Run(ILFunction function, ILTransformContext context) + { + this.context = context; + Visit((BlockContainer)function.Body, null); + } + + private void Visit(BlockContainer container, Block continueTarget) + { + switch (container.Kind) { + case ContainerKind.Loop: + case ContainerKind.While: + continueTarget = container.EntryPoint; + break; + case ContainerKind.DoWhile: + case ContainerKind.For: + continueTarget = container.Blocks.Last(); + break; + } + + foreach (var block in container.Blocks) + Visit(block, continueTarget); + } + + /// + /// Visits a block in context + /// + /// + /// Marks the target block of continue statements. + /// The instruction following the end point of the block. Can only be null if the end point is unreachable. + private void Visit(Block block, Block continueTarget, ILInstruction nextInstruction = null) + { + Debug.Assert(block.HasFlag(InstructionFlags.EndPointUnreachable) || nextInstruction != null); + + // process each instruction in the block. + for (int i = 0; i < block.Instructions.Count; i++) { + // Transformations may be applied to the current and following instructions but already processed instructions will not be changed + var inst = block.Instructions[i]; + + // the next instruction to be executed. Transformations will change the next instruction, so this is a method instead of a variable + ILInstruction NextInsn() => i + 1 < block.Instructions.Count ? block.Instructions[i + 1] : nextInstruction; + + switch (inst) { + case BlockContainer container: + // visit the contents of the container + Visit(container, continueTarget); + + // reduce nesting in switch blocks + if (container.Kind == ContainerKind.Switch && + CanDuplicateExit(NextInsn(), continueTarget) && + ReduceNesting(block, container, NextInsn())) + RemoveRedundantExit(block, nextInstruction); + + break; + case IfInstruction ifInst: + ImproveILOrdering(block, ifInst); + + // reduce nesting in if/else blocks + if (CanDuplicateExit(NextInsn(), continueTarget) && ReduceNesting(block, ifInst, NextInsn())) + RemoveRedundantExit(block, nextInstruction); + + // visit content blocks + if (ifInst.TrueInst is Block trueBlock) + Visit(trueBlock, continueTarget, NextInsn()); + + if (ifInst.FalseInst is Block falseBlock) { + if (ifInst.TrueInst.HasFlag(InstructionFlags.EndPointUnreachable)) { + ExtractElseBlock(ifInst); + break; + } + + Visit(falseBlock, continueTarget, NextInsn()); + } + break; + } + } + } + + /// + /// For an if statement with an unreachable end point and no else block, + /// inverts to match IL order of the first statement of each branch + /// + private void ImproveILOrdering(Block block, IfInstruction ifInst) + { + if (!block.HasFlag(InstructionFlags.EndPointUnreachable) + || !ifInst.TrueInst.HasFlag(InstructionFlags.EndPointUnreachable) + || !ifInst.FalseInst.MatchNop()) + return; + + Debug.Assert(ifInst != block.Instructions.Last()); + + var trueRange = ConditionDetection.GetILRange(ifInst.TrueInst); + var falseRange = ConditionDetection.GetILRange(block.Instructions[block.Instructions.IndexOf(ifInst)+1]); + if (!trueRange.IsEmpty && !falseRange.IsEmpty && falseRange.Start < trueRange.Start) + ConditionDetection.InvertIf(block, ifInst, context); + } + + /// + /// Reduce Nesting in if/else statements by duplicating an exit instruction. + /// Does not affect IL order + /// + private bool ReduceNesting(Block block, IfInstruction ifInst, ILInstruction exitInst) + { + // start tallying stats for heuristics from then and else-if blocks + int maxStatements = 0, maxDepth = 0; + UpdateStats(ifInst.TrueInst, ref maxStatements, ref maxDepth); + + // if (cond) { ... } exit; + if (ifInst.FalseInst.MatchNop()) { + // a separate heuristic tp ShouldReduceNesting as there is visual balancing to be performed based on number of statments + if (maxDepth < 2) + return false; + + // -> + // if (!cond) exit; + // ...; exit; + EnsureEndPointUnreachable(ifInst.TrueInst, exitInst); + EnsureEndPointUnreachable(block, exitInst); + ConditionDetection.InvertIf(block, ifInst, context); + return true; + } + + // else-if trees are considered as a single group from the root IfInstruction + if (GetElseIfParent(ifInst) != null) + return false; + + // find the else block and tally stats for each else-if block + while (Block.Unwrap(ifInst.FalseInst) is IfInstruction elseIfInst) { + UpdateStats(elseIfInst.TrueInst, ref maxStatements, ref maxDepth); + ifInst = elseIfInst; + } + + if (!ShouldReduceNesting(ifInst.FalseInst, maxStatements, maxDepth)) + return false; + + // extract the else block and insert exit points all the way up the else-if tree + do { + var elseIfInst = GetElseIfParent(ifInst); + + // if (cond) { ... } else { ... } exit; + // -> + // if (cond) { ...; exit; } + // ...; exit; + EnsureEndPointUnreachable(ifInst.TrueInst, exitInst); + ExtractElseBlock(ifInst); + ifInst = elseIfInst; + } while (ifInst != null); + + return true; + } + + /// + /// Reduce Nesting in switch statements by replacing break; in cases with the block exit, and extracting the default case + /// Does not affect IL order + /// + private bool ReduceNesting(Block parentBlock, BlockContainer switchContainer, ILInstruction exitInst) + { + // break; from outer container cannot be brought inside the switch as the meaning would change + if (exitInst is Leave leave && !leave.IsLeavingFunction) + return false; + + // find the default section, and ensure it has only one incoming edge + var switchInst = (SwitchInstruction)switchContainer.EntryPoint.Instructions.Single(); + var defaultSection = switchInst.Sections.MaxBy(s => s.Labels.Count()); + if (!defaultSection.Body.MatchBranch(out var defaultBlock) || defaultBlock.IncomingEdgeCount != 1) + return false; + + // tally stats for heuristic from each case block + int maxStatements = 0, maxDepth = 0; + foreach (var section in switchInst.Sections) + if (section != defaultSection && section.Body.MatchBranch(out var caseBlock) && caseBlock.Parent == switchContainer) + UpdateStats(caseBlock, ref maxStatements, ref maxDepth); + + if (!ShouldReduceNesting(defaultBlock, maxStatements, maxDepth)) + return false; + + Debug.Assert(defaultBlock.HasFlag(InstructionFlags.EndPointUnreachable)); + + // ensure the default case dominator tree has no exits (branches to other cases) + var cfg = new ControlFlowGraph(switchContainer, context.CancellationToken); + var defaultNode = cfg.GetNode(defaultBlock); + var defaultTree = TreeTraversal.PreOrder(defaultNode, n => n.DominatorTreeChildren).ToList(); + if (defaultTree.SelectMany(n => n.Successors).Any(n => !defaultNode.Dominates(n))) + return false; + + EnsureEndPointUnreachable(parentBlock, exitInst); + context.Step("Extract default case of switch", switchContainer); + + // replace all break; statements with the exitInst + var leaveInstructions = switchContainer.Descendants.Where(inst => inst.MatchLeave(switchContainer)); + foreach (var leaveInst in leaveInstructions.ToArray()) + leaveInst.ReplaceWith(exitInst.Clone()); + + // replace the default section branch with a break; + defaultSection.Body.ReplaceWith(new Leave(switchContainer)); + + // remove all default blocks from the switch container + var defaultBlocks = defaultTree.Select(c => (Block)c.UserData).ToList(); + foreach (var block in defaultBlocks) + switchContainer.Blocks.Remove(block); + + // replace the parent block exit with the default case instructions + parentBlock.Instructions.RemoveLast(); + parentBlock.Instructions.AddRange(defaultBlock.Instructions); + + // add any additional blocks from the default case to the parent container + var parentContainer = (BlockContainer)parentBlock.Ancestors.First(p => p is BlockContainer); + int insertAt = parentContainer.Blocks.IndexOf(parentBlock) + 1; + foreach (var block in defaultBlocks.Skip(1)) + parentContainer.Blocks.Insert(insertAt++, block); + + return true; + } + + /// + /// Checks if an exit is a duplicable keyword exit (return; break; continue;) + /// + private bool CanDuplicateExit(ILInstruction exit, Block continueTarget) => + exit != null && (exit is Leave leave && leave.Value.MatchNop() || exit.MatchBranch(continueTarget)); + + /// + /// Ensures the end point of a block is unreachable by duplicating and appending the [exit] instruction following the end point + /// + /// The instruction/block of interest + /// The next instruction to be executed (provided inst does not exit) + private void EnsureEndPointUnreachable(ILInstruction inst, ILInstruction fallthroughExit) + { + if (!(inst is Block block)) { + Debug.Assert(inst.HasFlag(InstructionFlags.EndPointUnreachable)); + return; + } + + if (!block.HasFlag(InstructionFlags.EndPointUnreachable)) { + context.Step("Duplicate block exit", fallthroughExit); + block.Instructions.Add(fallthroughExit.Clone()); + } + } + + /// + /// Removes a redundant block exit instruction. + /// + private void RemoveRedundantExit(Block block, ILInstruction implicitExit) + { + if (block.Instructions.Last().Match(implicitExit).Success) { + context.Step("Remove redundant exit", block.Instructions.Last()); + block.Instructions.RemoveLast(); + } + } + + /// + /// Determines if an IfInstruction is an else-if and returns the preceeding (parent) IfInstruction + /// + /// [else-]if (parent-cond) else { ifInst } + /// + private IfInstruction GetElseIfParent(IfInstruction ifInst) + { + Debug.Assert(ifInst.Parent is Block); + if (Block.Unwrap(ifInst.Parent) == ifInst && // only instruction in block + ifInst.Parent.Parent is IfInstruction elseIfInst && // parent of block is an IfInstruction + elseIfInst.FalseInst == ifInst.Parent) // part of the false branch not the true branch + return elseIfInst; + + return null; + } + + /// + /// Adds a code path to the current heuristic tally + /// + private void UpdateStats(ILInstruction inst, ref int maxStatements, ref int maxDepth) + { + int numStatements = 0; + ComputeStats(inst, ref numStatements, ref maxDepth, 0); + maxStatements = Math.Max(numStatements, maxStatements); + } + + /// + /// Recursively computes the number of statements and maximum nested depth of an instruction + /// + private void ComputeStats(ILInstruction inst, ref int numStatements, ref int maxDepth, int currentDepth) + { + switch (inst) { + case Block block: + foreach (var i in block.Instructions) + ComputeStats(i, ref numStatements, ref maxDepth, currentDepth); + break; + case BlockContainer container: + numStatements++; // one statement for the container head (switch/loop) + + var containerBody = container.EntryPoint; + if (container.Kind == ContainerKind.For || container.Kind == ContainerKind.While) { + if (!container.MatchConditionBlock(container.EntryPoint, out _, out containerBody)) + throw new NotSupportedException("Invalid condition block in loop."); + } + + // add the nested body + ComputeStats(containerBody, ref numStatements, ref maxDepth, currentDepth + 1); + break; + case IfInstruction ifInst: + numStatements++; // one statement for the if/condition itself + + // nested then instruction + ComputeStats(ifInst.TrueInst, ref numStatements, ref maxDepth, currentDepth + 1); + + // include all nested else-if instructions at the same depth + var elseInst = ifInst.FalseInst; + while (Block.Unwrap(elseInst) is IfInstruction elseIfInst) { + numStatements++; + ComputeStats(elseIfInst.TrueInst, ref numStatements, ref maxDepth, currentDepth + 1); + elseInst = elseIfInst.FalseInst; + } + + // include all nested else instruction + ComputeStats(elseInst, ref numStatements, ref maxDepth, currentDepth + 1); + break; + case SwitchInstruction switchInst: + // one statement per case label + numStatements += switchInst.Sections.Count + 1; + // add all the case blocks at the current depth + // most formatters indent switch blocks twice, but we don't want this heuristic to be based on formatting + // so we remain conservative and only include the increase in depth from the container and not the labels + foreach (var section in switchInst.Sections) + if (section.Body.MatchBranch(out var caseBlock) && caseBlock.Parent == switchInst.Parent.Parent) + ComputeStats(caseBlock, ref numStatements, ref maxDepth, currentDepth); + break; + default: + // just a regular statement + numStatements++; + if (currentDepth > maxDepth) + maxDepth = currentDepth; + break; + } + } + + /// + /// Heuristic to determine whether it is worth duplicating exits into the preceeding sibling blocks (then/else-if/case) + /// in order to reduce the nesting of inst by 1 + /// + /// The instruction heading the nested candidate block + /// The number of statements in the largest sibling block + /// The relative depth of the most nested statement in the sibling blocks + /// + private bool ShouldReduceNesting(ILInstruction inst, int maxStatements, int maxDepth) + { + int maxStatements2 = 0, maxDepth2 = 0; + UpdateStats(inst, ref maxStatements2, ref maxDepth2); + // if the max depth is 2, always reduce nesting (total depth 3 or more) + // if the max depth is 1, reduce nesting if this block is the largest + // otherwise reduce nesting only if this block is twice as large as any other + return maxDepth2 >= 2 || maxDepth2 >= 1 && maxStatements2 > maxStatements || maxStatements2 >= 2*maxStatements; + } + + /// + /// if (cond) { ...; exit; } else { ... } + /// ...; + /// -> + /// if (cond) { ...; exit; } + /// ...; + /// ...; + /// + /// + private void ExtractElseBlock(IfInstruction ifInst) + { + Debug.Assert(ifInst.TrueInst.HasFlag(InstructionFlags.EndPointUnreachable)); + var block = (Block)ifInst.Parent; + var falseBlock = (Block)ifInst.FalseInst; + + context.Step("Extract else block", ifInst); + int insertAt = block.Instructions.IndexOf(ifInst) + 1; + for (int i = 0; i < falseBlock.Instructions.Count; i++) + block.Instructions.Insert(insertAt++, falseBlock.Instructions[i]); + + ifInst.FalseInst = new Nop(); + } + } +}