Browse Source

Merge pull request #1213 from Chicken-Bones/logicand

Reverse Roslyn optimisation to favour && over & on boolean operands.
pull/1420/head
Daniel Grunwald 7 years ago committed by GitHub
parent
commit
4bbee5cfcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.cs
  2. 74
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.il
  3. 63
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.il
  4. 50
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.opt.roslyn.il
  5. 56
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.roslyn.il
  6. 13
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

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

@ -268,5 +268,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -268,5 +268,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
E();
}
#endif
public void PreferLogicalToBitwise(bool a, bool b, int i, float f)
{
B(a && b);
B(a && i == 1);
B(i == 1 && a);
B(i > i - 3 && a);
B(f < 0.1f && a);
}
}
}

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

@ -1369,6 +1369,80 @@ @@ -1369,6 +1369,80 @@
IL_009b: ret
} // end of method ShortCircuit::EmptyIf
.method public hidebysig instance void
PreferLogicalToBitwise(bool a,
bool b,
int32 i,
float32 f) cil managed
{
// Code size 90 (0x5a)
.maxstack 4
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: brfalse.s IL_0008
IL_0005: ldarg.2
IL_0006: br.s IL_0009
IL_0008: ldc.i4.0
IL_0009: nop
IL_000a: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_000f: nop
IL_0010: ldarg.0
IL_0011: ldarg.1
IL_0012: brfalse.s IL_001a
IL_0014: ldarg.3
IL_0015: ldc.i4.1
IL_0016: ceq
IL_0018: br.s IL_001b
IL_001a: ldc.i4.0
IL_001b: nop
IL_001c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0021: nop
IL_0022: ldarg.0
IL_0023: ldarg.3
IL_0024: ldc.i4.1
IL_0025: bne.un.s IL_002a
IL_0027: ldarg.1
IL_0028: br.s IL_002b
IL_002a: ldc.i4.0
IL_002b: nop
IL_002c: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0031: nop
IL_0032: ldarg.0
IL_0033: ldarg.3
IL_0034: ldarg.3
IL_0035: ldc.i4.3
IL_0036: sub
IL_0037: ble.s IL_003c
IL_0039: ldarg.1
IL_003a: br.s IL_003d
IL_003c: ldc.i4.0
IL_003d: nop
IL_003e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0043: nop
IL_0044: ldarg.0
IL_0045: ldarg.s f
IL_0047: ldc.r4 0.1
IL_004c: bge.un.s IL_0051
IL_004e: ldarg.1
IL_004f: br.s IL_0052
IL_0051: ldc.i4.0
IL_0052: nop
IL_0053: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0058: nop
IL_0059: ret
} // end of method ShortCircuit::PreferLogicalToBitwise
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

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

@ -879,6 +879,69 @@ @@ -879,6 +879,69 @@
IL_0024: ret
} // end of method ShortCircuit::StmtComplex6
.method public hidebysig instance void
PreferLogicalToBitwise(bool a,
bool b,
int32 i,
float32 f) cil managed
{
// Code size 79 (0x4f)
.maxstack 4
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: brfalse.s IL_0007
IL_0004: ldarg.2
IL_0005: br.s IL_0008
IL_0007: ldc.i4.0
IL_0008: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_000d: ldarg.0
IL_000e: ldarg.1
IL_000f: brfalse.s IL_0017
IL_0011: ldarg.3
IL_0012: ldc.i4.1
IL_0013: ceq
IL_0015: br.s IL_0018
IL_0017: ldc.i4.0
IL_0018: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_001d: ldarg.0
IL_001e: ldarg.3
IL_001f: ldc.i4.1
IL_0020: bne.un.s IL_0025
IL_0022: ldarg.1
IL_0023: br.s IL_0026
IL_0025: ldc.i4.0
IL_0026: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_002b: ldarg.0
IL_002c: ldarg.3
IL_002d: ldarg.3
IL_002e: ldc.i4.3
IL_002f: sub
IL_0030: ble.s IL_0035
IL_0032: ldarg.1
IL_0033: br.s IL_0036
IL_0035: ldc.i4.0
IL_0036: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_003b: ldarg.0
IL_003c: ldarg.s f
IL_003e: ldc.r4 0.1
IL_0043: bge.un.s IL_0048
IL_0045: ldarg.1
IL_0046: br.s IL_0049
IL_0048: ldc.i4.0
IL_0049: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_004e: ret
} // end of method ShortCircuit::PreferLogicalToBitwise
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

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

@ -883,6 +883,56 @@ @@ -883,6 +883,56 @@
IL_0024: ret
} // end of method ShortCircuit::StmtComplex6
.method public hidebysig instance void
PreferLogicalToBitwise(bool a,
bool b,
int32 i,
float32 f) cil managed
{
// Code size 69 (0x45)
.maxstack 4
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: and
IL_0004: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0009: ldarg.0
IL_000a: ldarg.1
IL_000b: brfalse.s IL_0013
IL_000d: ldarg.3
IL_000e: ldc.i4.1
IL_000f: ceq
IL_0011: br.s IL_0014
IL_0013: ldc.i4.0
IL_0014: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0019: ldarg.0
IL_001a: ldarg.3
IL_001b: ldc.i4.1
IL_001c: ceq
IL_001e: ldarg.1
IL_001f: and
IL_0020: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0025: ldarg.0
IL_0026: ldarg.3
IL_0027: ldarg.3
IL_0028: ldc.i4.3
IL_0029: sub
IL_002a: cgt
IL_002c: ldarg.1
IL_002d: and
IL_002e: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0033: ldarg.0
IL_0034: ldarg.s f
IL_0036: ldc.r4 0.1
IL_003b: clt
IL_003d: ldarg.1
IL_003e: and
IL_003f: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0044: ret
} // end of method ShortCircuit::PreferLogicalToBitwise
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

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

@ -1299,6 +1299,62 @@ @@ -1299,6 +1299,62 @@
IL_0090: ret
} // end of method ShortCircuit::EmptyIf
.method public hidebysig instance void
PreferLogicalToBitwise(bool a,
bool b,
int32 i,
float32 f) cil managed
{
// Code size 75 (0x4b)
.maxstack 4
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: ldarg.2
IL_0004: and
IL_0005: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_000a: nop
IL_000b: ldarg.0
IL_000c: ldarg.1
IL_000d: brfalse.s IL_0015
IL_000f: ldarg.3
IL_0010: ldc.i4.1
IL_0011: ceq
IL_0013: br.s IL_0016
IL_0015: ldc.i4.0
IL_0016: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_001b: nop
IL_001c: ldarg.0
IL_001d: ldarg.3
IL_001e: ldc.i4.1
IL_001f: ceq
IL_0021: ldarg.1
IL_0022: and
IL_0023: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0028: nop
IL_0029: ldarg.0
IL_002a: ldarg.3
IL_002b: ldarg.3
IL_002c: ldc.i4.3
IL_002d: sub
IL_002e: cgt
IL_0030: ldarg.1
IL_0031: and
IL_0032: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0037: nop
IL_0038: ldarg.0
IL_0039: ldarg.s f
IL_003b: ldc.r4 0.1
IL_0040: clt
IL_0042: ldarg.1
IL_0043: and
IL_0044: callvirt instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.ShortCircuit::B(bool)
IL_0049: nop
IL_004a: ret
} // end of method ShortCircuit::PreferLogicalToBitwise
.method family hidebysig specialname rtspecialname
instance void .ctor() cil managed
{

13
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -477,9 +477,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -477,9 +477,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms
inst.Right = lhs;
}
break;
case BinaryNumericOperator.BitAnd:
if (IsBoolean(inst.Left) && IsBoolean(inst.Right) && SemanticHelper.IsPure(inst.Right.Flags))
{
context.Step("Replace bit.and with logic.and", inst);
var expr = IfInstruction.LogicAnd(inst.Left, inst.Right);
inst.ReplaceWith(expr);
expr.AcceptVisitor(this);
}
break;
}
}
private static bool IsBoolean(ILInstruction inst) =>
inst is Comp c && c.ResultType == StackType.I4 ||
inst.InferType().IsKnownType(KnownTypeCode.Boolean);
protected internal override void VisitTryCatchHandler(TryCatchHandler inst)
{
base.VisitTryCatchHandler(inst);

Loading…
Cancel
Save