Exclude code dealing with System.Numeric.Vector`1 from CPAOT compilation (#6527)
I have added a new field layout algorithm for Vector<T> and checks to abort method compilation when it tries to access this information.
This commit is contained in:
Родитель
93ee893418
Коммит
93cc8811fe
|
@ -27,7 +27,7 @@ namespace ILCompiler
|
||||||
private ArrayOfTRuntimeInterfacesAlgorithm _arrayOfTRuntimeInterfacesAlgorithm;
|
private ArrayOfTRuntimeInterfacesAlgorithm _arrayOfTRuntimeInterfacesAlgorithm;
|
||||||
private MetadataVirtualMethodAlgorithm _virtualMethodAlgorithm = new MetadataVirtualMethodAlgorithm();
|
private MetadataVirtualMethodAlgorithm _virtualMethodAlgorithm = new MetadataVirtualMethodAlgorithm();
|
||||||
|
|
||||||
private SimdHelper _simdHelper;
|
protected SimdHelper _simdHelper;
|
||||||
|
|
||||||
private TypeDesc[] _arrayOfTInterfaces;
|
private TypeDesc[] _arrayOfTInterfaces;
|
||||||
|
|
||||||
|
|
|
@ -426,7 +426,7 @@ namespace ILCompiler.DependencyAnalysis
|
||||||
{
|
{
|
||||||
// Canonical definition types are *not* constructed types (call NecessaryTypeSymbol to get them)
|
// Canonical definition types are *not* constructed types (call NecessaryTypeSymbol to get them)
|
||||||
Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any));
|
Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any));
|
||||||
|
|
||||||
if (CompilationModuleGroup.ContainsType(type))
|
if (CompilationModuleGroup.ContainsType(type))
|
||||||
{
|
{
|
||||||
return new AvailableType(this, type);
|
return new AvailableType(this, type);
|
||||||
|
|
|
@ -128,6 +128,10 @@ namespace ILCompiler
|
||||||
// If compilation fails, don't emit code for this method. It will be Jitted at runtime
|
// If compilation fails, don't emit code for this method. It will be Jitted at runtime
|
||||||
Logger.Writer.WriteLine($"Warning: Method `{method}` was not compiled because: {ex.Message}");
|
Logger.Writer.WriteLine($"Warning: Method `{method}` was not compiled because: {ex.Message}");
|
||||||
}
|
}
|
||||||
|
catch (RequiresRuntimeJitException ex)
|
||||||
|
{
|
||||||
|
Logger.Writer.WriteLine($"Info: Method `{method}` was not compiled because `{ex.Message}` requires runtime JIT");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,14 @@ namespace ILCompiler
|
||||||
{
|
{
|
||||||
private FieldLayoutAlgorithm _r2rFieldLayoutAlgorithm;
|
private FieldLayoutAlgorithm _r2rFieldLayoutAlgorithm;
|
||||||
private SystemObjectFieldLayoutAlgorithm _systemObjectFieldLayoutAlgorithm;
|
private SystemObjectFieldLayoutAlgorithm _systemObjectFieldLayoutAlgorithm;
|
||||||
|
private VectorFieldLayoutAlgorithm _vectorFieldLayoutAlgorithm;
|
||||||
|
|
||||||
public ReadyToRunCompilerContext(TargetDetails details, SharedGenericsMode genericsMode)
|
public ReadyToRunCompilerContext(TargetDetails details, SharedGenericsMode genericsMode)
|
||||||
: base(details, genericsMode)
|
: base(details, genericsMode)
|
||||||
{
|
{
|
||||||
_r2rFieldLayoutAlgorithm = new ReadyToRunMetadataFieldLayoutAlgorithm();
|
_r2rFieldLayoutAlgorithm = new ReadyToRunMetadataFieldLayoutAlgorithm();
|
||||||
_systemObjectFieldLayoutAlgorithm = new SystemObjectFieldLayoutAlgorithm(_r2rFieldLayoutAlgorithm);
|
_systemObjectFieldLayoutAlgorithm = new SystemObjectFieldLayoutAlgorithm(_r2rFieldLayoutAlgorithm);
|
||||||
|
_vectorFieldLayoutAlgorithm = new VectorFieldLayoutAlgorithm(_r2rFieldLayoutAlgorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type)
|
public override FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type)
|
||||||
|
@ -30,10 +32,10 @@ namespace ILCompiler
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
else if (type.IsRuntimeDeterminedType)
|
else if (type.IsRuntimeDeterminedType)
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
/* TODO
|
|
||||||
else if (_simdHelper.IsVectorOfT(type))
|
else if (_simdHelper.IsVectorOfT(type))
|
||||||
throw new NotImplementedException();
|
{
|
||||||
*/
|
return _vectorFieldLayoutAlgorithm;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Assert(_r2rFieldLayoutAlgorithm != null);
|
Debug.Assert(_r2rFieldLayoutAlgorithm != null);
|
||||||
|
@ -70,5 +72,56 @@ namespace ILCompiler
|
||||||
{
|
{
|
||||||
return BaseTypeRuntimeInterfacesAlgorithm.Instance;
|
return BaseTypeRuntimeInterfacesAlgorithm.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class VectorFieldLayoutAlgorithm : FieldLayoutAlgorithm
|
||||||
|
{
|
||||||
|
private FieldLayoutAlgorithm _fallbackAlgorithm;
|
||||||
|
|
||||||
|
public VectorFieldLayoutAlgorithm(FieldLayoutAlgorithm fallbackAlgorithm)
|
||||||
|
{
|
||||||
|
_fallbackAlgorithm = fallbackAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ComputeContainsGCPointers(DefType type)
|
||||||
|
{
|
||||||
|
return _fallbackAlgorithm.ComputeContainsGCPointers(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DefType ComputeHomogeneousFloatAggregateElementType(DefType type)
|
||||||
|
{
|
||||||
|
return _fallbackAlgorithm.ComputeHomogeneousFloatAggregateElementType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind)
|
||||||
|
{
|
||||||
|
List<FieldAndOffset> fieldsAndOffsets = new List<FieldAndOffset>();
|
||||||
|
foreach (FieldDesc field in type.GetFields())
|
||||||
|
{
|
||||||
|
if (!field.IsStatic)
|
||||||
|
{
|
||||||
|
fieldsAndOffsets.Add(new FieldAndOffset(field, LayoutInt.Indeterminate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ComputedInstanceFieldLayout instanceLayout = new ComputedInstanceFieldLayout()
|
||||||
|
{
|
||||||
|
FieldSize = LayoutInt.Indeterminate,
|
||||||
|
FieldAlignment = LayoutInt.Indeterminate,
|
||||||
|
ByteCountUnaligned = LayoutInt.Indeterminate,
|
||||||
|
ByteCountAlignment = LayoutInt.Indeterminate,
|
||||||
|
Offsets = fieldsAndOffsets.ToArray(),
|
||||||
|
};
|
||||||
|
return instanceLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind)
|
||||||
|
{
|
||||||
|
return _fallbackAlgorithm.ComputeStaticFieldLayout(type, layoutKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type)
|
||||||
|
{
|
||||||
|
return _fallbackAlgorithm.ComputeValueTypeShapeCharacteristics(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,14 @@ namespace Internal.JitInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class RequiresRuntimeJitException : Exception
|
||||||
|
{
|
||||||
|
public RequiresRuntimeJitException(object reason)
|
||||||
|
: base(reason.ToString())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe partial class CorInfoImpl
|
unsafe partial class CorInfoImpl
|
||||||
{
|
{
|
||||||
private const CORINFO_RUNTIME_ABI TargetABI = CORINFO_RUNTIME_ABI.CORINFO_CORECLR_ABI;
|
private const CORINFO_RUNTIME_ABI TargetABI = CORINFO_RUNTIME_ABI.CORINFO_CORECLR_ABI;
|
||||||
|
|
|
@ -187,6 +187,13 @@ namespace Internal.JitInterface
|
||||||
// Type system exceptions can be turned into code that throws the exception at runtime.
|
// Type system exceptions can be turned into code that throws the exception at runtime.
|
||||||
_lastException.Throw();
|
_lastException.Throw();
|
||||||
}
|
}
|
||||||
|
#if READYTORUN
|
||||||
|
else if (_lastException.SourceException is RequiresRuntimeJitException)
|
||||||
|
{
|
||||||
|
// Runtime JIT requirement is not a cause for failure, we just mustn't JIT a particular method
|
||||||
|
_lastException.Throw();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This is just a bug somewhere.
|
// This is just a bug somewhere.
|
||||||
|
@ -1220,7 +1227,14 @@ namespace Internal.JitInterface
|
||||||
private uint getClassSize(CORINFO_CLASS_STRUCT_* cls)
|
private uint getClassSize(CORINFO_CLASS_STRUCT_* cls)
|
||||||
{
|
{
|
||||||
TypeDesc type = HandleToObject(cls);
|
TypeDesc type = HandleToObject(cls);
|
||||||
return (uint)type.GetElementSize().AsInt;
|
LayoutInt classSize = type.GetElementSize();
|
||||||
|
#if READYTORUN
|
||||||
|
if (classSize.IsIndeterminate)
|
||||||
|
{
|
||||||
|
throw new RequiresRuntimeJitException(type);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return (uint)classSize.AsInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint getHeapClassSize(CORINFO_CLASS_STRUCT_* cls)
|
private uint getHeapClassSize(CORINFO_CLASS_STRUCT_* cls)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Numerics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
internal class ClassWithStatic
|
internal class ClassWithStatic
|
||||||
|
@ -627,6 +628,27 @@ internal class Program
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool VectorTestOf<T>(T value1, T value2, T sum)
|
||||||
|
where T : struct
|
||||||
|
{
|
||||||
|
Console.WriteLine("Constructing vector of {0}", value1);
|
||||||
|
Vector<T> vector1 = new Vector<T>(value1);
|
||||||
|
Console.WriteLine("Vector[0] = {0}", vector1[0]);
|
||||||
|
Vector<T> vector2 = new Vector<T>(value2);
|
||||||
|
Vector<T> vectorSum = vector1 + vector2;
|
||||||
|
Console.WriteLine("Vector sum = {0}, {1} expected", vectorSum[0], sum);
|
||||||
|
return vectorSum[0].Equals(sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool VectorTest()
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
success &= VectorTestOf<int>(10, 20, 30);
|
||||||
|
success &= VectorTestOf<float>(15.0f, 30.0f, 45.0f);
|
||||||
|
success &= VectorTestOf<double>(50.0, 100.0, 150.0);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
{
|
{
|
||||||
if (args.Length > 0)
|
if (args.Length > 0)
|
||||||
|
@ -671,6 +693,7 @@ internal class Program
|
||||||
RunTest("ThisObjGenericLookupTest", ThisObjGenericLookupTest());
|
RunTest("ThisObjGenericLookupTest", ThisObjGenericLookupTest());
|
||||||
RunTest("ClassParamGenericLookupTest", ClassParamGenericLookupTest());
|
RunTest("ClassParamGenericLookupTest", ClassParamGenericLookupTest());
|
||||||
RunTest("MethodParamGenericLookupTest", MethodParamGenericLookupTest());
|
RunTest("MethodParamGenericLookupTest", MethodParamGenericLookupTest());
|
||||||
|
RunTest("VectorTest", VectorTest());
|
||||||
|
|
||||||
Console.WriteLine($@"{_passedTests.Count} tests pass:");
|
Console.WriteLine($@"{_passedTests.Count} tests pass:");
|
||||||
foreach (string testName in _passedTests)
|
foreach (string testName in _passedTests)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
Program..cctor()
|
Program..cctor()
|
||||||
|
Program.VectorTestOf(!!0,!!0,!!0)
|
||||||
Program+DisposeStruct..cctor()
|
Program+DisposeStruct..cctor()
|
||||||
Program+DisposeClass.Dispose()
|
Program+DisposeClass.Dispose()
|
||||||
Program+DisposeClass..cctor()
|
Program+DisposeClass..cctor()
|
||||||
ClassWithStatic..cctor()
|
ClassWithStatic..cctor()
|
||||||
|
|
Загрузка…
Ссылка в новой задаче