Browse Source

Improve block ordering in ConditionDetection using the ILOffsets of Leave instruction arguments

pull/1218/merge
Chicken-Bones 7 years ago committed by Daniel Grunwald
parent
commit
5ed5ea0e0f
  1. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.cs
  2. 39
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.il
  3. 22
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.il
  4. 22
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.roslyn.il
  5. 36
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.roslyn.il
  6. 13
      ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs

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

@ -252,6 +252,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -252,6 +252,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return 2;
}
public int InferCorrectOrder()
{
if (F(1) || F(2)) {
return 1;
}
return 2;
}
#if !OPT
public void EmptyIf()
{

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

@ -1257,6 +1257,45 @@ @@ -1257,6 +1257,45 @@
IL_003d: ret
} // end of method ShortCircuit::StmtComplex6
.method public hidebysig instance int32
InferCorrectOrder() cil managed
{
// Code size 39 (0x27)
.maxstack 2
.locals init (int32 V_0,
bool V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.1
IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0008: brtrue.s IL_0016
IL_000a: ldarg.0
IL_000b: ldc.i4.2
IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0011: ldc.i4.0
IL_0012: ceq
IL_0014: br.s IL_0017
IL_0016: ldc.i4.0
IL_0017: nop
IL_0018: stloc.1
IL_0019: ldloc.1
IL_001a: brtrue.s IL_0021
IL_001c: nop
IL_001d: ldc.i4.1
IL_001e: stloc.0
IL_001f: br.s IL_0025
IL_0021: ldc.i4.2
IL_0022: stloc.0
IL_0023: br.s IL_0025
IL_0025: ldloc.0
IL_0026: ret
} // end of method ShortCircuit::InferCorrectOrder
.method public hidebysig instance void
EmptyIf() cil managed
{

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

@ -879,6 +879,28 @@ @@ -879,6 +879,28 @@
IL_0024: ret
} // end of method ShortCircuit::StmtComplex6
.method public hidebysig instance int32
InferCorrectOrder() cil managed
{
// Code size 22 (0x16)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0007: brtrue.s IL_0012
IL_0009: ldarg.0
IL_000a: ldc.i4.2
IL_000b: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0010: brfalse.s IL_0014
IL_0012: ldc.i4.1
IL_0013: ret
IL_0014: ldc.i4.2
IL_0015: ret
} // end of method ShortCircuit::InferCorrectOrder
.method public hidebysig instance void
PreferLogicalToBitwise(bool a,
bool b,

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

@ -883,6 +883,28 @@ @@ -883,6 +883,28 @@
IL_0024: ret
} // end of method ShortCircuit::StmtComplex6
.method public hidebysig instance int32
InferCorrectOrder() cil managed
{
// Code size 22 (0x16)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0007: brtrue.s IL_0012
IL_0009: ldarg.0
IL_000a: ldc.i4.2
IL_000b: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0010: brfalse.s IL_0014
IL_0012: ldc.i4.1
IL_0013: ret
IL_0014: ldc.i4.2
IL_0015: ret
} // end of method ShortCircuit::InferCorrectOrder
.method public hidebysig instance void
PreferLogicalToBitwise(bool a,
bool b,

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

@ -1193,6 +1193,42 @@ @@ -1193,6 +1193,42 @@
IL_0036: ret
} // end of method ShortCircuit::StmtComplex6
.method public hidebysig instance int32
InferCorrectOrder() cil managed
{
// Code size 35 (0x23)
.maxstack 2
.locals init (bool V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.1
IL_0003: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0008: brtrue.s IL_0013
IL_000a: ldarg.0
IL_000b: ldc.i4.2
IL_000c: callvirt instance bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::F(int32)
IL_0011: br.s IL_0014
IL_0013: ldc.i4.1
IL_0014: stloc.0
IL_0015: ldloc.0
IL_0016: brfalse.s IL_001d
IL_0018: nop
IL_0019: ldc.i4.1
IL_001a: stloc.1
IL_001b: br.s IL_0021
IL_001d: ldc.i4.2
IL_001e: stloc.1
IL_001f: br.s IL_0021
IL_0021: ldloc.1
IL_0022: ret
} // end of method ShortCircuit::InferCorrectOrder
.method public hidebysig instance void
EmptyIf() cil managed
{

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

@ -514,12 +514,15 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -514,12 +514,15 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (strongly)
return 0;
if (exit1.MatchBranch(out var block1) && exit2.MatchBranch(out var block2)) {
// prefer arranging stuff in IL order
return block1.ILRange.Start.CompareTo(block2.ILRange.Start);
}
// prefer arranging stuff in IL order
if (exit1.MatchBranch(out var block1) && exit2.MatchBranch(out var block2))
return block1.ILRange.Start.CompareTo(block2.ILRange.Start);
// use the IL offsets of the arguments of leave instructions instead of the leaves themselves if possible
if (exit1.MatchLeave(out var _, out var arg1) && exit2.MatchLeave(out var _, out var arg2))
return arg1.ILRange.Start.CompareTo(arg2.ILRange.Start);
return exit1.ILRange.Start.CompareTo(exit2.ILRange.Start);
}

Loading…
Cancel
Save