Add Vector<T> to CoreLib.
authorEric Erhardt <eric.erhardt@microsoft.com>
Wed, 31 Jan 2018 16:59:35 +0000 (10:59 -0600)
committerEric Erhardt <eric.erhardt@microsoft.com>
Wed, 31 Jan 2018 21:06:25 +0000 (15:06 -0600)
This requires the runtime to change to recognize the Vector classes in either System.Numerics.Vectors.dll or in System.Private.CoreLib.dll.  To do this, I added the [Intrinsic] attribute to Vector<T> struct and Vector static class.

src/mscorlib/Resources/Strings.resx
src/mscorlib/System.Private.CoreLib.csproj
src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
src/mscorlib/shared/System/Numerics/Vector.cs
src/mscorlib/shared/System/Numerics/Vector.tt
src/mscorlib/shared/System/Runtime/CompilerServices/IntrinsicAttribute.cs
src/vm/jitinterface.cpp
src/vm/methodtablebuilder.cpp
src/vm/methodtablebuilder.h

index 585cbc7..2b66ce5 100644 (file)
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <root>
-  <!--
-    Microsoft ResX Schema
-
+  <!-- 
+    Microsoft ResX Schema 
+    
     Version 2.0
-
-    The primary goals of this format is to allow a simple XML format
-    that is mostly human readable. The generation and parsing of the
-    various data types are done through the TypeConverter classes
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
     associated with the data types.
-
+    
     Example:
-
+    
     ... ado.net/XML headers & schema ...
     <resheader name="resmimetype">text/microsoft-resx</resheader>
     <resheader name="version">2.0</resheader>
         <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
         <comment>This is a comment</comment>
     </data>
-
-    There are any number of "resheader" rows that contain simple
+                
+    There are any number of "resheader" rows that contain simple 
     name/value pairs.
-
-    Each data row contains a name, and value. The row also contains a
-    type or mimetype. Type corresponds to a .NET class that support
-    text/value conversion through the TypeConverter architecture.
-    Classes that don't support this are serialized and stored with the
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
     mimetype set.
-
-    The mimetype is used for serialized objects, and tells the
-    ResXResourceReader how to depersist the object. This is currently not
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
     extensible. For a given mimetype the value must be set accordingly:
-
-    Note - application/x-microsoft.net.object.binary.base64 is the format
-    that the ResXResourceWriter will generate, however the reader can
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
     read any of the formats listed below.
-
+    
     mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with
+    value   : The object must be serialized with 
             : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
-
+    
     mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with
+    value   : The object must be serialized with 
             : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
             : and then encoded with base64 encoding.
 
     mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array
+    value   : The object must be serialized into a byte array 
             : using a System.ComponentModel.TypeConverter
             : and then encoded with base64 encoding.
     -->
   <data name="IO_InvalidReadLength" xml:space="preserve">
     <value>The read operation returned an invalid length.</value>
   </data>
-</root>
+  <data name="Arg_ElementsInSourceIsGreaterThanDestination" xml:space="preserve">
+    <value>Number of elements in source vector is greater than the destination array</value>
+  </data>
+  <data name="Arg_NullArgumentNullRef" xml:space="preserve">
+    <value>The method was called with a null array argument.</value>
+  </data>
+</root>
\ No newline at end of file
index df394ed..6c08a12 100644 (file)
     <Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolBoundHandle.Windows.cs" />
     <Compile Include="$(BclSourcesRoot)\System\Environment.Windows.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <!--
+    These are files are also added to CoreLib.Shared.projitems, but they don't show up in
+    Visual Studio Solution Explorer. Adding them here as well so developers can
+    edit them and regenerate the .cs files.
+    -->
+    <Content Include="shared\System\Numerics\ConstantHelper.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>ConstantHelper.cs</LastGenOutput>
+    </Content>
+    <None Include="shared\System\Numerics\GenerationConfig.ttinclude" />
+    <Content Include="shared\System\Numerics\Register.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>Register.cs</LastGenOutput>
+    </Content>
+    <Content Include="shared\System\Numerics\Vector.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>Vector.cs</LastGenOutput>
+    </Content>
+  </ItemGroup>
   <!-- Include additional sources shared files in the compilation -->
   <ItemGroup>
     <!-- These are files are preprocessed  -->
index bb1a284..26b0ba6 100644 (file)
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingTypeInfo.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TypeAnalysis.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\ConstantHelper.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>ConstantHelper.tt</DependentUpon>
+    </Compile>
+    <Content Include="$(MSBuildThisFileDirectory)System\Numerics\ConstantHelper.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>ConstantHelper.cs</LastGenOutput>
+    </Content>
+    <None Include="$(MSBuildThisFileDirectory)System\Numerics\GenerationConfig.ttinclude" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\JitIntrinsicAttribute.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Register.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Register.tt</DependentUpon>
+    </Compile>
+    <Content Include="$(MSBuildThisFileDirectory)System\Numerics\Register.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>Register.cs</LastGenOutput>
+    </Content>
+    <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Vector.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Vector.tt</DependentUpon>
+    </Compile>
+    <Content Include="$(MSBuildThisFileDirectory)System\Numerics\Vector.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>Vector.cs</LastGenOutput>
+    </Content>
+    <Compile Include="$(MSBuildThisFileDirectory)System\Numerics\Vector_Operations.cs" />
+  </ItemGroup>
   <ItemGroup Condition="$(TargetsWindows)">
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Crypt32\Interop.CryptProtectMemory.cs" />
index 984f82f..5fd2867 100644 (file)
@@ -38,6 +38,7 @@ namespace System.Numerics
     /// This struct only supports numerical types. This type is intended to be used as a building block for vectorizing
     /// large algorithms. This type is immutable, individual elements cannot be modified.
     /// </summary>
+    [Intrinsic]
     public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
     {
         #region Fields
@@ -4953,6 +4954,7 @@ namespace System.Numerics
         #endregion
     }
 
+    [Intrinsic]
     public static partial class Vector
     {
         #region Widen/Narrow
index 84e57b0..82aa73d 100644 (file)
@@ -43,6 +43,7 @@ namespace System.Numerics
     /// This struct only supports numerical types. This type is intended to be used as a building block for vectorizing
     /// large algorithms. This type is immutable, individual elements cannot be modified.
     /// </summary>
+    [Intrinsic]
     public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
     {
         #region Fields
@@ -1681,6 +1682,7 @@ namespace System.Numerics
         #endregion
     }
 
+    [Intrinsic]
     public static partial class Vector
     {
         #region Widen/Narrow
index 381b4c6..bb73946 100644 (file)
@@ -7,7 +7,7 @@ namespace System.Runtime.CompilerServices
     // Calls to methods or references to fields marked with this attribute may be replaced at
     // some call sites with jit intrinsic expansions.
     // Types marked with this attribute may be specially treated by the rumtime/compiler.
-    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field, Inherited = false)]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field, Inherited = false)]
     internal sealed class IntrinsicAttribute : Attribute
     {
     }
index a5981d3..0fb8ea6 100644 (file)
@@ -8689,6 +8689,7 @@ CorInfoIntrinsics CEEInfo::getIntrinsicID(CORINFO_METHOD_HANDLE methodHnd,
 }
 
 /*********************************************************************/
+// This method should probably be renamed to something like "isSIMDType"
 bool CEEInfo::isInSIMDModule(CORINFO_CLASS_HANDLE classHnd)
 {
 CONTRACTL {
@@ -8702,10 +8703,23 @@ CONTRACTL {
     JIT_TO_EE_TRANSITION_LEAF();
 
     TypeHandle VMClsHnd(classHnd);
-    if (VMClsHnd.GetMethodTable()->GetAssembly()->IsSIMDVectorAssembly())
+    PTR_MethodTable methodTable = VMClsHnd.GetMethodTable();
+    if (methodTable->GetAssembly()->IsSIMDVectorAssembly())
     {
         result = true;
     }
+    else if (methodTable->IsIntrinsicType())
+    {
+        LPCUTF8 namespaceName;
+        LPCUTF8 className = methodTable->GetFullyQualifiedNameInfo(&namespaceName);
+
+        if (strcmp(className, "Vector`1") == 0 || strcmp(className, "Vector") == 0)
+        {
+            assert(strcmp(namespaceName, "System.Numerics") == 0);
+
+            result = true;
+        }
+    }
     EE_TO_JIT_TRANSITION_LEAF();
 
     return result;
index 1d58704..dce3e3c 100644 (file)
@@ -1170,7 +1170,7 @@ BOOL MethodTableBuilder::CheckIfSIMDAndUpdateSize()
     STANDARD_VM_CONTRACT;
 
 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
-    if (!GetAssembly()->IsSIMDVectorAssembly())
+    if (!(GetAssembly()->IsSIMDVectorAssembly() || GetModule()->IsSystem()))
         return false;
 
     if (bmtFP->NumInstanceFieldBytes != 16)
@@ -10432,7 +10432,8 @@ MethodTableBuilder::SetupMethodTable2(
     // Currently, only SIMD types have [Intrinsic] attribute
     //
     // We check this here fairly early to ensure other downstream checks on these types can be slightly more efficient.
-    if ((GetModule()->IsSystem() || GetAssembly()->IsSIMDVectorAssembly()) && IsValueClass() && bmtGenerics->HasInstantiation())
+    if ((GetModule()->IsSystem() || GetAssembly()->IsSIMDVectorAssembly()) && 
+        ((IsValueClass() && bmtGenerics->HasInstantiation()) || (IsAbstract() && IsSealed())))
     {
         HRESULT hr = GetMDImport()->GetCustomAttributeByName(bmtInternal->pType->GetTypeDefToken(), 
             g_CompilerServicesIntrinsicAttribute, 
index d736368..1d10904 100644 (file)
@@ -218,7 +218,8 @@ private:
     BOOL HasNonPublicFields() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->HasNonPublicFields(); }
     BOOL IsValueClass() { WRAPPER_NO_CONTRACT; return bmtProp->fIsValueClass; } 
     BOOL IsUnsafeValueClass() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsUnsafeValueClass(); }
-    BOOL IsAbstract() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsAbstract(); } 
+    BOOL IsAbstract() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsAbstract(); }
+    BOOL IsSealed() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsSealed(); }
     BOOL HasLayout() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->HasLayout(); } 
     BOOL IsDelegate() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsDelegate(); } 
     BOOL IsNested() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsNested(); }