From cc6938bced884ead1943676ac67128dbeca3a53c Mon Sep 17 00:00:00 2001 From: liboz Date: Sat, 24 Dec 2016 15:23:15 -0500 Subject: [PATCH 1/4] return the union's tag when case is nullary --- src/fsharp/AugmentWithHashCompare.fs | 49 ++++++++++++++++------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/fsharp/AugmentWithHashCompare.fs b/src/fsharp/AugmentWithHashCompare.fs index 3c379320b34..e3c69e6c785 100644 --- a/src/fsharp/AugmentWithHashCompare.fs +++ b/src/fsharp/AugmentWithHashCompare.fs @@ -626,27 +626,36 @@ let mkUnionHashWithComparer g tcref (tycon:Tycon) compe = let mkCase i ucase1 = let c1ref = tcref.MakeNestedUnionCaseRef ucase1 let m = c1ref.Range - let mkHash thise j (rfield:RecdField) = - let fty = rfield.FormalType - let e = mkUnionCaseFieldGetProvenViaExprAddr(thise, c1ref, tinst, j, m) - mkCallGenericHashWithComparerOuter g m fty compe e - - let test = - if tycon.IsStructOrEnumTycon then - mkCompGenSequential m - (mkValSet m (mkLocalValRef accv) (mkInt g m i)) - (mkCombineHashGenerators g m (List.mapi (mkHash thise) ucase1.RecdFields) (mkLocalValRef accv) acce) - else - let ucv,ucve = mkCompGenLocal m "unionCase" (mkProvenUnionCaseTy c1ref tinst) - mkCompGenLet m ucv - (mkUnionCaseProof (thise,c1ref,tinst,m)) - (mkCompGenSequential m + if ucase1.IsNullary then None + else + let mkHash thise j (rfield:RecdField) = + let fty = rfield.FormalType + let e = mkUnionCaseFieldGetProvenViaExprAddr(thise, c1ref, tinst, j, m) + mkCallGenericHashWithComparerOuter g m fty compe e + + let test = + if tycon.IsStructOrEnumTycon then + mkCompGenSequential m (mkValSet m (mkLocalValRef accv) (mkInt g m i)) - (mkCombineHashGenerators g m (List.mapi (mkHash ucve) ucase1.RecdFields) (mkLocalValRef accv) acce)) - - mkCase(Test.UnionCase(c1ref,tinst),mbuilder.AddResultTarget(test,SuppressSequencePointAtTarget)) - - let dtree = TDSwitch(thise, List.mapi mkCase ucases, None,m) + (mkCombineHashGenerators g m (List.mapi (mkHash thise) ucase1.RecdFields) (mkLocalValRef accv) acce) + else + let ucv,ucve = mkCompGenLocal m "unionCase" (mkProvenUnionCaseTy c1ref tinst) + mkCompGenLet m ucv + (mkUnionCaseProof (thise,c1ref,tinst,m)) + (mkCompGenSequential m + (mkValSet m (mkLocalValRef accv) (mkInt g m i)) + (mkCombineHashGenerators g m (List.mapi (mkHash ucve) ucase1.RecdFields) (mkLocalValRef accv) acce)) + Some(mkCase(Test.UnionCase(c1ref,tinst),mbuilder.AddResultTarget(test,SuppressSequencePointAtTarget))) + + let nullary,nonNullary = ucases + |> List.mapi mkCase + |> List.partition (fun i -> i.IsNone) + let cases = nonNullary |> List.map (function (Some c) -> c | None -> failwith "mkUnionHash") + let dflt = if isNil nullary then None + else + let tag = mkUnionCaseTagGetViaExprAddr (thise,tcref,tinst,m) + Some(mbuilder.AddResultTarget(tag,SuppressSequencePointAtTarget)) + let dtree = TDSwitch(thise, cases, dflt,m) let stmt = mbuilder.Close(dtree,m,g.int_ty) let expr = mkCompGenLet m accv (mkZero g m) stmt let expr = if tycon.IsStructOrEnumTycon then expr else mkBindNullHash g m thise expr From 2d2a841e19598a147fc191f0b3aa5df3599d6ce6 Mon Sep 17 00:00:00 2001 From: liboz Date: Sun, 25 Dec 2016 13:01:09 -0500 Subject: [PATCH 2/4] fix IL tests --- .../CCtorDUWithMember01.il.bsl | 47 +++-------- .../cctorduwithmember01.il.netfx4.bsl | 43 +++------- .../EmittedIL/Misc/EqualsOnUnions01.il.bsl | 78 +++++++++---------- .../Misc/EqualsOnUnions01.il.netfx4.bsl | 78 +++++++++---------- .../Misc/GeneralizationOnUnions01.il.bsl | 19 ++--- .../SteppingMatch/SteppingMatch06.il.bsl | 39 ++-------- .../SteppingMatch/SteppingMatch07.il.bsl | 37 ++------- .../steppingmatch06.il.netfx4.bsl | 39 ++-------- .../steppingmatch07.il.netfx4.bsl | 37 ++------- 9 files changed, 123 insertions(+), 294 deletions(-) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember01.il.bsl index 4ce7f058625..2fa850209f3 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/CCtorDUWithMember01.il.bsl @@ -406,61 +406,36 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 40 (0x28) + // Code size 15 (0xf) .maxstack 3 - .locals init (int32 V_0, - class CCtorDUWithMember01a/C V_1, - class CCtorDUWithMember01a/C V_2) + .locals init (int32 V_0) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull IL_0003: cgt.un IL_0005: brfalse.s IL_0009 - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0026 - + IL_0009: br.s IL_0014 IL_000b: ldc.i4.0 IL_000c: stloc.0 IL_000d: ldarg.0 - IL_000e: call instance int32 CCtorDUWithMember01a/C::get_Tag() - IL_0013: ldc.i4.0 - IL_0014: bne.un.s IL_0018 - - IL_0016: br.s IL_001a - - IL_0018: br.s IL_0020 - - IL_001a: ldarg.0 - IL_001b: stloc.1 - IL_001c: ldc.i4.0 - IL_001d: stloc.0 - IL_001e: ldloc.0 - IL_001f: ret - - IL_0020: ldarg.0 - IL_0021: stloc.2 - IL_0022: ldc.i4.1 - IL_0023: stloc.0 - IL_0024: ldloc.0 - IL_0025: ret - - IL_0026: ldc.i4.0 - IL_0027: ret + IL_000e: ldfld int32 CCtorDUWithMember01a/C::_tag + IL_0013: ret + IL_0014: ldc.i4.0 + IL_0015: ret } // end of method C::GetHashCode .method public hidebysig virtual final instance int32 GetHashCode() cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) - .maxstack 4 - .line 3,3 : 6,7 + // Code size 21 (0x15) + .maxstack 8 + .line 3,3 : 6,7 '' IL_0000: nop IL_0001: ldarg.0 IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0007: call instance int32 CCtorDUWithMember01a/C::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) + IL_0007: callvirt instance int32 CCtorDUWithMember01a/C::GetHashCode(class [mscorlib]System.Collections.IEqualityComparer) IL_000c: ret } // end of method C::GetHashCode diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/cctorduwithmember01.il.netfx4.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/cctorduwithmember01.il.netfx4.bsl index 31d0820c370..4ff8d8dcbde 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/cctorduwithmember01.il.netfx4.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/CCtorDUWithMember/cctorduwithmember01.il.netfx4.bsl @@ -409,57 +409,32 @@ instance int32 GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 40 (0x28) + // Code size 15 (0xf) .maxstack 3 - .locals init (int32 V_0, - class CCtorDUWithMember01a/C V_1, - class CCtorDUWithMember01a/C V_2) + .locals init (int32 V_0) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull IL_0003: cgt.un IL_0005: brfalse.s IL_0009 - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0026 - + IL_0009: br.s IL_0014 IL_000b: ldc.i4.0 IL_000c: stloc.0 IL_000d: ldarg.0 - IL_000e: call instance int32 CCtorDUWithMember01a/C::get_Tag() - IL_0013: ldc.i4.0 - IL_0014: bne.un.s IL_0018 - - IL_0016: br.s IL_001a - - IL_0018: br.s IL_0020 - - IL_001a: ldarg.0 - IL_001b: stloc.1 - IL_001c: ldc.i4.0 - IL_001d: stloc.0 - IL_001e: ldloc.0 - IL_001f: ret - - IL_0020: ldarg.0 - IL_0021: stloc.2 - IL_0022: ldc.i4.1 - IL_0023: stloc.0 - IL_0024: ldloc.0 - IL_0025: ret - - IL_0026: ldc.i4.0 - IL_0027: ret + IL_000e: ldfld int32 CCtorDUWithMember01a/C::_tag + IL_0013: ret + IL_0014: ldc.i4.0 + IL_0015: ret } // end of method C::GetHashCode .method public hidebysig virtual final instance int32 GetHashCode() cil managed { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - // Code size 13 (0xd) + // Code size 21 (0x15) .maxstack 8 - .line 3,3 : 6,7 + .line 3,3 : 6,7 '' IL_0000: nop IL_0001: ldarg.0 IL_0002: call class [mscorlib]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.bsl index 3fb89cf65e3..5473a031767 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.bsl @@ -622,62 +622,56 @@ // Code size 72 (0x48) .maxstack 7 .locals init (int32 V_0, - class EqualsOnUnions01/U/_A V_1, - class EqualsOnUnions01/U/B V_2, - class [mscorlib]System.Collections.IEqualityComparer V_3) + class EqualsOnUnions01/U/B V_1, + class [mscorlib]System.Collections.IEqualityComparer V_2, + class EqualsOnUnions01/U V_3) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull IL_0003: cgt.un IL_0005: brfalse.s IL_0009 - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0046 - + IL_0009: br.s IL_004a IL_000b: ldc.i4.0 IL_000c: stloc.0 IL_000d: ldarg.0 - IL_000e: isinst EqualsOnUnions01/U/_A + IL_000e: isinst EqualsOnUnions01/U/B IL_0013: brfalse.s IL_0017 - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0024 - + IL_0017: br.s IL_003b IL_0019: ldarg.0 - IL_001a: castclass EqualsOnUnions01/U/_A + IL_001a: castclass EqualsOnUnions01/U/B IL_001f: stloc.1 - IL_0020: ldc.i4.0 + IL_0020: ldc.i4.1 IL_0021: stloc.0 - IL_0022: ldloc.0 - IL_0023: ret - - IL_0024: ldarg.0 - IL_0025: castclass EqualsOnUnions01/U/B - IL_002a: stloc.2 - IL_002b: ldc.i4.1 - IL_002c: stloc.0 - IL_002d: ldc.i4 0x9e3779b9 - IL_0032: ldarg.1 - IL_0033: stloc.3 - IL_0034: ldloc.2 - IL_0035: ldfld int32 EqualsOnUnions01/U/B::item - IL_003a: ldloc.0 - IL_003b: ldc.i4.6 - IL_003c: shl - IL_003d: ldloc.0 - IL_003e: ldc.i4.2 - IL_003f: shr - IL_0040: add - IL_0041: add - IL_0042: add - IL_0043: stloc.0 - IL_0044: ldloc.0 - IL_0045: ret - - IL_0046: ldc.i4.0 - IL_0047: ret + IL_0022: ldc.i4 0x9e3779b9 + IL_0027: ldarg.1 + IL_0028: stloc.2 + IL_0029: ldloc.1 + IL_002a: ldfld int32 EqualsOnUnions01/U/B::item + IL_002f: ldloc.0 + IL_0030: ldc.i4.6 + IL_0031: shl + IL_0032: ldloc.0 + IL_0033: ldc.i4.2 + IL_0034: shr + IL_0035: add + IL_0036: add + IL_0037: add + IL_0038: stloc.0 + IL_0039: ldloc.0 + IL_003a: ret + IL_003b: ldarg.0 + IL_003c: stloc.3 + IL_003d: ldloc.3 + IL_003e: isinst EqualsOnUnions01/U/B + IL_0043: brfalse.s IL_0048 + IL_0045: ldc.i4.1 + IL_0046: br.s IL_0049 + IL_0048: ldc.i4.0 + IL_0049: ret + IL_004a: ldc.i4.0 + IL_004b: ret } // end of method U::GetHashCode .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.netfx4.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.netfx4.bsl index 3fb89cf65e3..5473a031767 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.netfx4.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/EqualsOnUnions01.il.netfx4.bsl @@ -622,62 +622,56 @@ // Code size 72 (0x48) .maxstack 7 .locals init (int32 V_0, - class EqualsOnUnions01/U/_A V_1, - class EqualsOnUnions01/U/B V_2, - class [mscorlib]System.Collections.IEqualityComparer V_3) + class EqualsOnUnions01/U/B V_1, + class [mscorlib]System.Collections.IEqualityComparer V_2, + class EqualsOnUnions01/U V_3) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull IL_0003: cgt.un IL_0005: brfalse.s IL_0009 - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0046 - + IL_0009: br.s IL_004a IL_000b: ldc.i4.0 IL_000c: stloc.0 IL_000d: ldarg.0 - IL_000e: isinst EqualsOnUnions01/U/_A + IL_000e: isinst EqualsOnUnions01/U/B IL_0013: brfalse.s IL_0017 - IL_0015: br.s IL_0019 - - IL_0017: br.s IL_0024 - + IL_0017: br.s IL_003b IL_0019: ldarg.0 - IL_001a: castclass EqualsOnUnions01/U/_A + IL_001a: castclass EqualsOnUnions01/U/B IL_001f: stloc.1 - IL_0020: ldc.i4.0 + IL_0020: ldc.i4.1 IL_0021: stloc.0 - IL_0022: ldloc.0 - IL_0023: ret - - IL_0024: ldarg.0 - IL_0025: castclass EqualsOnUnions01/U/B - IL_002a: stloc.2 - IL_002b: ldc.i4.1 - IL_002c: stloc.0 - IL_002d: ldc.i4 0x9e3779b9 - IL_0032: ldarg.1 - IL_0033: stloc.3 - IL_0034: ldloc.2 - IL_0035: ldfld int32 EqualsOnUnions01/U/B::item - IL_003a: ldloc.0 - IL_003b: ldc.i4.6 - IL_003c: shl - IL_003d: ldloc.0 - IL_003e: ldc.i4.2 - IL_003f: shr - IL_0040: add - IL_0041: add - IL_0042: add - IL_0043: stloc.0 - IL_0044: ldloc.0 - IL_0045: ret - - IL_0046: ldc.i4.0 - IL_0047: ret + IL_0022: ldc.i4 0x9e3779b9 + IL_0027: ldarg.1 + IL_0028: stloc.2 + IL_0029: ldloc.1 + IL_002a: ldfld int32 EqualsOnUnions01/U/B::item + IL_002f: ldloc.0 + IL_0030: ldc.i4.6 + IL_0031: shl + IL_0032: ldloc.0 + IL_0033: ldc.i4.2 + IL_0034: shr + IL_0035: add + IL_0036: add + IL_0037: add + IL_0038: stloc.0 + IL_0039: ldloc.0 + IL_003a: ret + IL_003b: ldarg.0 + IL_003c: stloc.3 + IL_003d: ldloc.3 + IL_003e: isinst EqualsOnUnions01/U/B + IL_0043: brfalse.s IL_0048 + IL_0045: ldc.i4.1 + IL_0046: br.s IL_0049 + IL_0048: ldc.i4.0 + IL_0049: ret + IL_004a: ldc.i4.0 + IL_004b: ret } // end of method U::GetHashCode .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GeneralizationOnUnions01.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GeneralizationOnUnions01.il.bsl index 69d77f96985..74b156ee342 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GeneralizationOnUnions01.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/Misc/GeneralizationOnUnions01.il.bsl @@ -257,31 +257,22 @@ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 23 (0x17) .maxstack 3 - .locals init (int32 V_0, - class GeneralizationOnUnions01/Weirdo V_1) + .locals init (int32 V_0) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull IL_0003: cgt.un IL_0005: brfalse.s IL_0009 - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0015 - + IL_0009: br.s IL_0011 IL_000b: ldc.i4.0 IL_000c: stloc.0 IL_000d: ldarg.0 IL_000e: pop - IL_000f: ldarg.0 - IL_0010: stloc.1 + IL_000f: ldc.i4.0 + IL_0010: ret IL_0011: ldc.i4.0 - IL_0012: stloc.0 - IL_0013: ldloc.0 - IL_0014: ret - - IL_0015: ldc.i4.0 - IL_0016: ret + IL_0012: ret } // end of method Weirdo::GetHashCode .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch06.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch06.il.bsl index 6ad8e66c0c9..ce31aada34f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch06.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch06.il.bsl @@ -357,47 +357,22 @@ { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 40 (0x28) - .maxstack 3 - .locals init (int32 V_0, - class SteppingMatch06/Discr V_1, - class SteppingMatch06/Discr V_2) + .maxstack 3 + .locals init (int32 V_0) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull IL_0003: cgt.un IL_0005: brfalse.s IL_0009 - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0026 - + IL_0009: br.s IL_0014 IL_000b: ldc.i4.0 IL_000c: stloc.0 IL_000d: ldarg.0 - IL_000e: call instance int32 SteppingMatch06/Discr::get_Tag() - IL_0013: ldc.i4.0 - IL_0014: bne.un.s IL_0018 - - IL_0016: br.s IL_001a - - IL_0018: br.s IL_0020 - - IL_001a: ldarg.0 - IL_001b: stloc.1 - IL_001c: ldc.i4.0 - IL_001d: stloc.0 - IL_001e: ldloc.0 - IL_001f: ret - - IL_0020: ldarg.0 - IL_0021: stloc.2 - IL_0022: ldc.i4.1 - IL_0023: stloc.0 - IL_0024: ldloc.0 - IL_0025: ret - - IL_0026: ldc.i4.0 - IL_0027: ret + IL_000e: ldfld int32 SteppingMatch06/Discr::_tag + IL_0013: ret + IL_0014: ldc.i4.0 + IL_0015: ret } // end of method Discr::GetHashCode .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch07.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch07.il.bsl index 5d85514044f..475c7e4339b 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch07.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/SteppingMatch07.il.bsl @@ -358,46 +358,21 @@ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 40 (0x28) .maxstack 3 - .locals init (int32 V_0, - class SteppingMatch07/Discr V_1, - class SteppingMatch07/Discr V_2) + .locals init (int32 V_0) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull IL_0003: cgt.un IL_0005: brfalse.s IL_0009 - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0026 - + IL_0009: br.s IL_0014 IL_000b: ldc.i4.0 IL_000c: stloc.0 IL_000d: ldarg.0 - IL_000e: call instance int32 SteppingMatch07/Discr::get_Tag() - IL_0013: ldc.i4.0 - IL_0014: bne.un.s IL_0018 - - IL_0016: br.s IL_001a - - IL_0018: br.s IL_0020 - - IL_001a: ldarg.0 - IL_001b: stloc.1 - IL_001c: ldc.i4.0 - IL_001d: stloc.0 - IL_001e: ldloc.0 - IL_001f: ret - - IL_0020: ldarg.0 - IL_0021: stloc.2 - IL_0022: ldc.i4.1 - IL_0023: stloc.0 - IL_0024: ldloc.0 - IL_0025: ret - - IL_0026: ldc.i4.0 - IL_0027: ret + IL_000e: ldfld int32 SteppingMatch07/Discr::_tag + IL_0013: ret + IL_0014: ldc.i4.0 + IL_0015: ret } // end of method Discr::GetHashCode .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/steppingmatch06.il.netfx4.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/steppingmatch06.il.netfx4.bsl index cde17845fa8..ad23ecaebb5 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/steppingmatch06.il.netfx4.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/steppingmatch06.il.netfx4.bsl @@ -360,47 +360,22 @@ { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 40 (0x28) - .maxstack 3 - .locals init (int32 V_0, - class SteppingMatch06/Discr V_1, - class SteppingMatch06/Discr V_2) + .maxstack 3 + .locals init (int32 V_0) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull IL_0003: cgt.un IL_0005: brfalse.s IL_0009 - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0026 - + IL_0009: br.s IL_0014 IL_000b: ldc.i4.0 IL_000c: stloc.0 IL_000d: ldarg.0 - IL_000e: call instance int32 SteppingMatch06/Discr::get_Tag() - IL_0013: ldc.i4.0 - IL_0014: bne.un.s IL_0018 - - IL_0016: br.s IL_001a - - IL_0018: br.s IL_0020 - - IL_001a: ldarg.0 - IL_001b: stloc.1 - IL_001c: ldc.i4.0 - IL_001d: stloc.0 - IL_001e: ldloc.0 - IL_001f: ret - - IL_0020: ldarg.0 - IL_0021: stloc.2 - IL_0022: ldc.i4.1 - IL_0023: stloc.0 - IL_0024: ldloc.0 - IL_0025: ret - - IL_0026: ldc.i4.0 - IL_0027: ret + IL_000e: ldfld int32 SteppingMatch06/Discr::_tag + IL_0013: ret + IL_0014: ldc.i4.0 + IL_0015: ret } // end of method Discr::GetHashCode .method public hidebysig virtual final diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/steppingmatch07.il.netfx4.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/steppingmatch07.il.netfx4.bsl index 2086ae565ba..d6e062dd289 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/steppingmatch07.il.netfx4.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/SteppingMatch/steppingmatch07.il.netfx4.bsl @@ -361,46 +361,21 @@ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Code size 40 (0x28) .maxstack 3 - .locals init (int32 V_0, - class SteppingMatch07/Discr V_1, - class SteppingMatch07/Discr V_2) + .locals init (int32 V_0) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldnull IL_0003: cgt.un IL_0005: brfalse.s IL_0009 - IL_0007: br.s IL_000b - - IL_0009: br.s IL_0026 - + IL_0009: br.s IL_0014 IL_000b: ldc.i4.0 IL_000c: stloc.0 IL_000d: ldarg.0 - IL_000e: call instance int32 SteppingMatch07/Discr::get_Tag() - IL_0013: ldc.i4.0 - IL_0014: bne.un.s IL_0018 - - IL_0016: br.s IL_001a - - IL_0018: br.s IL_0020 - - IL_001a: ldarg.0 - IL_001b: stloc.1 - IL_001c: ldc.i4.0 - IL_001d: stloc.0 - IL_001e: ldloc.0 - IL_001f: ret - - IL_0020: ldarg.0 - IL_0021: stloc.2 - IL_0022: ldc.i4.1 - IL_0023: stloc.0 - IL_0024: ldloc.0 - IL_0025: ret - - IL_0026: ldc.i4.0 - IL_0027: ret + IL_000e: ldfld int32 SteppingMatch07/Discr::_tag + IL_0013: ret + IL_0014: ldc.i4.0 + IL_0015: ret } // end of method Discr::GetHashCode .method public hidebysig virtual final From 8d36e8d5a5aa124701b7ea8885270e061d899237 Mon Sep 17 00:00:00 2001 From: liboz Date: Tue, 27 Dec 2016 13:52:19 -0500 Subject: [PATCH 3/4] ensure that gethashcode is not inlined --- src/fsharp/Optimizer.fs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 53241837f71..dac5ddc5e4c 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -2500,7 +2500,7 @@ and TryDevirtualizeApplication cenv env (f,tyargs,args,m) = | _ -> None /// Attempt to inline an application of a known value at callsites -and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr list,m) = +and TryInlineApplication cenv env finfo (tyargs: TType list,args: Expr list,m) = // Considering inlining app match finfo.Info with | StripLambdaValue (lambdaId,arities,size,f2,f2ty) when @@ -2522,6 +2522,8 @@ and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr li match args.[0] with | Expr.Val(vref,_,_) when vref.BaseOrThisInfo = BaseVal -> true | _ -> false + + if isBaseCall then None else // Since Lazy`1 moved from FSharp.Core to mscorlib on .NET 4.0, inlining Lazy values from 2.0 will // confuse the optimizer if the assembly is referenced on 4.0, since there will be no value to tie back @@ -2539,15 +2541,23 @@ and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr li | _ -> false | _ -> false | _ -> false - + + if isValFromLazyExtensions then None else + let isSecureMethod = match finfo.Info with | ValValue(vref,_) -> vref.Attribs |> List.exists (fun a -> (IsSecurityAttribute cenv.g cenv.amap cenv.casApplied a m) || (IsSecurityCriticalAttribute cenv.g a)) | _ -> false - if isBaseCall || isSecureMethod || isValFromLazyExtensions then None - else + if isSecureMethod then None else + + let isGetHashCode = + match finfo.Info with + | ValValue(vref,_) -> vref.DisplayName = "GetHashCode" + | _ -> false + + if isGetHashCode then None else // Inlining lambda (* ---------- printf "Inlining lambda near %a = %s\n" outputRange m (showL (exprL f2)) (* JAMES: *) ----------*) @@ -2577,7 +2587,7 @@ and OptimizeApplication cenv env (f0,f0ty,tyargs,args,m) = res | None -> let newf0,finfo = OptimizeExpr cenv env f0 - match TryInlineApplication cenv env (newf0,finfo) (tyargs,args,m) with + match TryInlineApplication cenv env finfo (tyargs,args,m) with | Some res -> // inlined res From f8474f6a4ecf41522fecc8e74bde6fbca5e1f720 Mon Sep 17 00:00:00 2001 From: liboz Date: Wed, 28 Dec 2016 10:00:00 -0500 Subject: [PATCH 4/4] only for compilergenerated cases now --- src/fsharp/Optimizer.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index dac5ddc5e4c..b3a1d2e5b36 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -2554,7 +2554,7 @@ and TryInlineApplication cenv env finfo (tyargs: TType list,args: Expr list,m) = let isGetHashCode = match finfo.Info with - | ValValue(vref,_) -> vref.DisplayName = "GetHashCode" + | ValValue(vref,_) -> vref.DisplayName = "GetHashCode" && vref.IsCompilerGenerated | _ -> false if isGetHashCode then None else