From: Andy Ayers Date: Tue, 28 Feb 2017 02:10:27 +0000 (-0800) Subject: Some tests for devirtualization (dotnet/coreclr#9834) X-Git-Tag: submit/tizen/20210909.063632~11030^2~7927 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=930010893b94b3f352ddacd302f8b67dc648427d;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Some tests for devirtualization (dotnet/coreclr#9834) Commit migrated from https://github.com/dotnet/coreclr/commit/f8c2a6d20a408c955fee3c3167e557bf1b3ccba6 --- diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/enum.cs b/src/coreclr/tests/src/JIT/opt/Devirtualization/enum.cs new file mode 100644 index 0000000..994c661 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/enum.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +enum MyEnum { One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten }; + +public class Test +{ + public static int Main() + { + // Call to ToString should be devirtualize since boxed enums + // are sealed classes. This doesn't happen yet. + string s = (MyEnum.Seven).ToString(); + + // Call to Equals will devirtualize since string is sealed + return (s.Equals((object)"Seven") ? 100 : -1); + } +} diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/enum.csproj b/src/coreclr/tests/src/JIT/opt/Devirtualization/enum.csproj new file mode 100644 index 0000000..59c9791 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/enum.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages + ..\..\ + 7a9bfb7d + + + + + + + + + False + + + + PdbOnly + True + + + + + + + + + $(JitPackagesConfigFileDirectory)minimal\project.json + $(JitPackagesConfigFileDirectory)minimal\project.lock.json + + + + + diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/exacttype.cs b/src/coreclr/tests/src/JIT/opt/Devirtualization/exacttype.cs new file mode 100644 index 0000000..a1265da --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/exacttype.cs @@ -0,0 +1,71 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.CompilerServices; + +public class Base +{ + public virtual void Foo() { Console.WriteLine("Base:Foo"); } + public virtual void Bar() { Console.WriteLine("Base:Bar"); } +} + +public class Derived : Base +{ + public override sealed void Foo() { Console.WriteLine("Derived:Foo"); } + public override void Bar() { Console.WriteLine("Derived:Bar"); } +} + +// The jit should to be able to devirtualize all calls to Bar since the +// exact type is knowable. +// +// The jit should to be able to devirtualize calls to Foo when the +// type is known to be at least Derived. +// +// Currently the jit misses some of these cases, either because it has +// lost the more precise type or lost the fact that the type was +// exact. + +public class Test +{ + public static Base M() + { + return new Derived(); + } + + public static int Main() + { + // Declared type of 'd' has final method Foo(), so calls to + // Foo() will devirtualize. + // + // However the jit does not know that d's type is exact so + // currently the calls to Bar() will not devirtualize. + Derived d = new Derived(); + d.Foo(); + d.Bar(); + + // M should inline and expose an exact return type + // which will trigger late devirt for both Foo() and Bar(). + M().Foo(); + M().Bar(); + + // Copy via 'b' currently inhibits devirt + Base b = M(); + b.Foo(); + b.Bar(); + + // Direct use of newobj gives exact type so all these + // will devirtualize + new Base().Foo(); + new Base().Bar(); + new Derived().Foo(); + new Derived().Bar(); + + return 100; + } +} + + + + diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/exacttype.csproj b/src/coreclr/tests/src/JIT/opt/Devirtualization/exacttype.csproj new file mode 100644 index 0000000..243e003 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/exacttype.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages + ..\..\ + 7a9bfb7d + + + + + + + + + False + + + + PdbOnly + True + + + + + + + + + $(JitPackagesConfigFileDirectory)minimal\project.json + $(JitPackagesConfigFileDirectory)minimal\project.lock.json + + + + + diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/fromcollection.cs b/src/coreclr/tests/src/JIT/opt/Devirtualization/fromcollection.cs new file mode 100644 index 0000000..5a5df59 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/fromcollection.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; + +public class Base +{ + public virtual int GetValue(int value) + { + return value + 33; + } +} + +public sealed class Derived : Base +{ + public override int GetValue(int value) + { + return value + 44; + } +} + +// We currently fail to devirtualize these two calls to GetValue +// +// In the array case we need to handle getting types from INDEX operations. +// +// In the list case we need to get a better type for the generic return value, +// or handle the INDEX during late devirtualization, since inlining exposes +// the underlying array. Better to do the former since it doesn't rely on +// being able to inline. + +public class Test +{ + static Derived[] arrayOfDerived = new Derived[3]; + static List listOfDerived = new List(); + + public static int Main() + { + for (int i = 0; i < 3; i++) + { + Derived d = new Derived(); + arrayOfDerived[i] = d; + listOfDerived.Add(d); + } + + int result = 9 + arrayOfDerived[1].GetValue(1) + listOfDerived[1].GetValue(2); + + return result; + } +} diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/fromcollection.csproj b/src/coreclr/tests/src/JIT/opt/Devirtualization/fromcollection.csproj new file mode 100644 index 0000000..9e23ae8 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/fromcollection.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages + ..\..\ + 7a9bfb7d + + + + + + + + + False + + + + PdbOnly + True + + + + + + + + + $(JitPackagesConfigFileDirectory)extra\project.json + $(JitPackagesConfigFileDirectory)extra\project.lock.json + + + + + diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/inlinedevirt.cs b/src/coreclr/tests/src/JIT/opt/Devirtualization/inlinedevirt.cs new file mode 100644 index 0000000..0d1ed20 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/inlinedevirt.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +class ImprovedType +{ + // Jit should inline this method and then devirtualize ToString() + static void Print(object o) + { + Console.WriteLine(o.ToString()); + } + + public static int Main() + { + Print("hello, world!"); + return 100; + } +} diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/inlinedevirt.csproj b/src/coreclr/tests/src/JIT/opt/Devirtualization/inlinedevirt.csproj new file mode 100644 index 0000000..5faffa9 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/inlinedevirt.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages + ..\..\ + 7a9bfb7d + + + + + + + + + False + + + + PdbOnly + True + + + + + + + + + $(JitPackagesConfigFileDirectory)minimal\project.json + $(JitPackagesConfigFileDirectory)minimal\project.lock.json + + + + + diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedclass.cs b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedclass.cs new file mode 100644 index 0000000..4ec57dc --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedclass.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.CompilerServices; + +public class Base +{ + public virtual int GetValue(int value) + { + return 0x33; + } +} + +public sealed class Derived : Base +{ + public override int GetValue(int value) + { + return value; + } +} + +public class F +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static int TestSealedMethodInlining(Derived obj) + { + return obj.GetValue(3); + } + + public static int Main(string[] args) + { + Derived d = new Derived(); + int v = TestSealedMethodInlining(d); + return (v == 3 ? 100 : -1); + } +} diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedclass.csproj b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedclass.csproj new file mode 100644 index 0000000..7f0d4a0 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedclass.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages + ..\..\ + 7a9bfb7d + + + + + + + + + False + + + + PdbOnly + True + + + + + + + + + $(JitPackagesConfigFileDirectory)minimal\project.json + $(JitPackagesConfigFileDirectory)minimal\project.lock.json + + + + + diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/sealeddefault.cs b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealeddefault.cs new file mode 100644 index 0000000..82049cd --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealeddefault.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +public class Base +{ + public virtual int Foo() { return 33; } + + static BaseSealed s_Default = new BaseSealed(); + + public static Base Default => s_Default; +} + +sealed class BaseSealed : Base {} + +// The jit can devirtualize the call to Foo when initializing y, +// but not when initializing x. + +public class Test +{ + public static int Main() + { + Base b = Base.Default; + int x = b.Foo(); + int y = Base.Default.Foo(); + return (x == 33 && y == 33 ? 100 : -1); + } +} diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/sealeddefault.csproj b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealeddefault.csproj new file mode 100644 index 0000000..b492db1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealeddefault.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages + ..\..\ + 7a9bfb7d + + + + + + + + + False + + + + PdbOnly + True + + + + + + + + + $(JitPackagesConfigFileDirectory)minimal\project.json + $(JitPackagesConfigFileDirectory)minimal\project.lock.json + + + + + diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedmethod.cs b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedmethod.cs new file mode 100644 index 0000000..555254b --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedmethod.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.CompilerServices; + +public class Base +{ + public virtual int GetValue(int value) + { + return 0x33; + } +} + +public class Derived : Base +{ + public sealed override int GetValue(int value) + { + return value; + } +} + +public class F +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static int TestSealedMethodInlining(Derived obj) + { + return obj.GetValue(3); + } + + public static int Main(string[] args) + { + Derived d = new Derived(); + int v = TestSealedMethodInlining(d); + return (v == 3 ? 100 : -1); + } +} diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedmethod.csproj b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedmethod.csproj new file mode 100644 index 0000000..b4c421b --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/sealedmethod.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages + ..\..\ + 7a9bfb7d + + + + + + + + + False + + + + PdbOnly + True + + + + + + + + + $(JitPackagesConfigFileDirectory)minimal\project.json + $(JitPackagesConfigFileDirectory)minimal\project.lock.json + + + + + diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/sharedoverride.cs b/src/coreclr/tests/src/JIT/opt/Devirtualization/sharedoverride.cs new file mode 100644 index 0000000..7107966 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/sharedoverride.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +public class Base +{ + public virtual int Foo(int x) + { + return x + 1; + } +} + +// Override via a shared generic. +// +// Jit must be careful to set the right context +// for the shared methods when devirtualizing. + +public class Derived : Base +{ + public override sealed int Foo(int x) + { + if (typeof(T) == typeof(string)) + { + return x + 42; + } + else if (typeof(T) == typeof(int)) + { + return x + 31; + } + else + { + return x + 22; + } + } +} + +// All calls to Foo should devirtualize, however we can't +// get the b.Foo case yet because we don't recognize b +// as having an exact type. + +public class Test +{ + public static int Main() + { + var ds = new Derived(); + var dx = new Derived(); + var di = new Derived(); + var b = new Base(); + + int resultD = ds.Foo(1) + dx.Foo(1) + di.Foo(1) + b.Foo(1); + + return resultD; + } +} diff --git a/src/coreclr/tests/src/JIT/opt/Devirtualization/sharedoverride.csproj b/src/coreclr/tests/src/JIT/opt/Devirtualization/sharedoverride.csproj new file mode 100644 index 0000000..3fa7208 --- /dev/null +++ b/src/coreclr/tests/src/JIT/opt/Devirtualization/sharedoverride.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages + ..\..\ + 7a9bfb7d + + + + + + + + + False + + + + PdbOnly + True + + + + + + + + + $(JitPackagesConfigFileDirectory)minimal\project.json + $(JitPackagesConfigFileDirectory)minimal\project.lock.json + + + + +