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:
Tomáš Rylek 2018-11-08 10:23:39 +01:00 коммит произвёл GitHub
Родитель 93ee893418
Коммит 93cc8811fe
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 110 добавлений и 7 удалений

Просмотреть файл

@ -27,7 +27,7 @@ namespace ILCompiler
private ArrayOfTRuntimeInterfacesAlgorithm _arrayOfTRuntimeInterfacesAlgorithm;
private MetadataVirtualMethodAlgorithm _virtualMethodAlgorithm = new MetadataVirtualMethodAlgorithm();
private SimdHelper _simdHelper;
protected SimdHelper _simdHelper;
private TypeDesc[] _arrayOfTInterfaces;

Просмотреть файл

@ -426,7 +426,7 @@ namespace ILCompiler.DependencyAnalysis
{
// Canonical definition types are *not* constructed types (call NecessaryTypeSymbol to get them)
Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any));
if (CompilationModuleGroup.ContainsType(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
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 SystemObjectFieldLayoutAlgorithm _systemObjectFieldLayoutAlgorithm;
private VectorFieldLayoutAlgorithm _vectorFieldLayoutAlgorithm;
public ReadyToRunCompilerContext(TargetDetails details, SharedGenericsMode genericsMode)
: base(details, genericsMode)
{
_r2rFieldLayoutAlgorithm = new ReadyToRunMetadataFieldLayoutAlgorithm();
_systemObjectFieldLayoutAlgorithm = new SystemObjectFieldLayoutAlgorithm(_r2rFieldLayoutAlgorithm);
_vectorFieldLayoutAlgorithm = new VectorFieldLayoutAlgorithm(_r2rFieldLayoutAlgorithm);
}
public override FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type)
@ -30,10 +32,10 @@ namespace ILCompiler
throw new NotImplementedException();
else if (type.IsRuntimeDeterminedType)
throw new NotImplementedException();
/* TODO
else if (_simdHelper.IsVectorOfT(type))
throw new NotImplementedException();
*/
{
return _vectorFieldLayoutAlgorithm;
}
else
{
Debug.Assert(_r2rFieldLayoutAlgorithm != null);
@ -70,5 +72,56 @@ namespace ILCompiler
{
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
{
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.
_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
{
// This is just a bug somewhere.
@ -1220,7 +1227,14 @@ namespace Internal.JitInterface
private uint getClassSize(CORINFO_CLASS_STRUCT_* 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)

Просмотреть файл

@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;
using System.Text;
internal class ClassWithStatic
@ -627,6 +628,27 @@ internal class Program
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)
{
if (args.Length > 0)
@ -671,6 +693,7 @@ internal class Program
RunTest("ThisObjGenericLookupTest", ThisObjGenericLookupTest());
RunTest("ClassParamGenericLookupTest", ClassParamGenericLookupTest());
RunTest("MethodParamGenericLookupTest", MethodParamGenericLookupTest());
RunTest("VectorTest", VectorTest());
Console.WriteLine($@"{_passedTests.Count} tests pass:");
foreach (string testName in _passedTests)

Просмотреть файл

@ -1,5 +1,6 @@
Program..cctor()
Program.VectorTestOf(!!0,!!0,!!0)
Program+DisposeStruct..cctor()
Program+DisposeClass.Dispose()
Program+DisposeClass..cctor()
ClassWithStatic..cctor()
ClassWithStatic..cctor()