Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync shared crossgen2 files #35504

Merged
merged 1 commit into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 0 additions & 151 deletions src/coreclr/src/tools/Common/Compiler/HardwareIntrinsicHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,156 +20,5 @@ public static bool IsHardwareIntrinsic(MethodDesc method)
{
return !string.IsNullOrEmpty(InstructionSetSupport.GetHardwareIntrinsicId(method.Context.Target.Architecture, method.OwningType));
}

#if !READYTORUN
public static bool IsIsSupportedMethod(MethodDesc method)
{
return method.Name == "get_IsSupported";
}

public static MethodIL GetUnsupportedImplementationIL(MethodDesc method)
{
// The implementation of IsSupported for codegen backends that don't support hardware intrinsics
// at all is to return 0.
if (IsIsSupportedMethod(method))
{
return new ILStubMethodIL(method,
new byte[] {
(byte)ILOpcode.ldc_i4_0,
(byte)ILOpcode.ret
},
Array.Empty<LocalVariableDefinition>(), null);
}

// Other methods throw PlatformNotSupportedException
MethodDesc throwPnse = method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowPlatformNotSupportedException");

return new ILStubMethodIL(method,
new byte[] {
(byte)ILOpcode.call, 1, 0, 0, 0,
(byte)ILOpcode.br_s, unchecked((byte)-7),
},
Array.Empty<LocalVariableDefinition>(),
new object[] { throwPnse });
}

/// <summary>
/// Generates IL for the IsSupported property that reads this information from a field initialized by the runtime
/// at startup. Returns null for hardware intrinsics whose support level is known at compile time
/// (i.e. they're known to be always supported or always unsupported).
/// </summary>
public static MethodIL EmitIsSupportedIL(MethodDesc method, FieldDesc isSupportedField)
{
Debug.Assert(IsIsSupportedMethod(method));
Debug.Assert(isSupportedField.IsStatic && isSupportedField.FieldType.IsWellKnownType(WellKnownType.Int32));

TargetDetails target = method.Context.Target;
MetadataType owningType = (MetadataType)method.OwningType;

// Check for case of nested "X64" types
if (owningType.Name == "X64")
{
if (target.Architecture != TargetArchitecture.X64)
return null;

// Un-nest the type so that we can do a name match
owningType = (MetadataType)owningType.ContainingType;
}

int flag;
if ((target.Architecture == TargetArchitecture.X64 || target.Architecture == TargetArchitecture.X86)
&& owningType.Namespace == "System.Runtime.Intrinsics.X86")
{
switch (owningType.Name)
{
case "Aes":
flag = XArchIntrinsicConstants.Aes;
break;
case "Pclmulqdq":
flag = XArchIntrinsicConstants.Pclmulqdq;
break;
case "Sse3":
flag = XArchIntrinsicConstants.Sse3;
break;
case "Ssse3":
flag = XArchIntrinsicConstants.Ssse3;
break;
case "Lzcnt":
flag = XArchIntrinsicConstants.Lzcnt;
break;
// NOTE: this switch is complemented by IsKnownSupportedIntrinsicAtCompileTime
// in the method below.
default:
return null;
}
}
else
{
return null;
}

var emit = new ILEmitter();
ILCodeStream codeStream = emit.NewCodeStream();

codeStream.Emit(ILOpcode.ldsfld, emit.NewToken(isSupportedField));
codeStream.EmitLdc(flag);
codeStream.Emit(ILOpcode.and);
codeStream.EmitLdc(0);
codeStream.Emit(ILOpcode.cgt_un);
codeStream.Emit(ILOpcode.ret);

return emit.Link(method);
}

/// <summary>
/// Gets a value indicating whether the support for a given intrinsic is known at compile time.
/// </summary>
public static bool IsKnownSupportedIntrinsicAtCompileTime(MethodDesc method)
{
TargetDetails target = method.Context.Target;

if (target.Architecture == TargetArchitecture.X64
|| target.Architecture == TargetArchitecture.X86)
{
var owningType = (MetadataType)method.OwningType;
if (owningType.Name == "X64")
{
if (target.Architecture != TargetArchitecture.X64)
return true;
owningType = (MetadataType)owningType.ContainingType;
}

if (owningType.Namespace != "System.Runtime.Intrinsics.X86")
return true;

// Sse and Sse2 are baseline required intrinsics.
// RyuJIT also uses Sse41/Sse42 with the general purpose Vector APIs.
// RyuJIT only respects Popcnt if Sse41/Sse42 is also enabled.
// Avx/Avx2/Bmi1/Bmi2 require VEX encoding and RyuJIT currently can't enable them
// without enabling VEX encoding everywhere. We don't support them.
// This list complements EmitIsSupportedIL above.
return owningType.Name == "Sse" || owningType.Name == "Sse2"
|| owningType.Name == "Sse41" || owningType.Name == "Sse42"
|| owningType.Name == "Popcnt"
|| owningType.Name == "Bmi1" || owningType.Name == "Bmi2"
|| owningType.Name == "Avx" || owningType.Name == "Avx2";
}

return false;
}

// Keep this enumeration in sync with startup.cpp in the native runtime.
private static class XArchIntrinsicConstants
{
public const int Aes = 0x0001;
public const int Pclmulqdq = 0x0002;
public const int Sse3 = 0x0004;
public const int Ssse3 = 0x0008;
public const int Sse41 = 0x0010;
public const int Sse42 = 0x0020;
public const int Popcnt = 0x0040;
public const int Lzcnt = 0x0080;
}
#endif // !READYTORUN
}
}
4 changes: 1 addition & 3 deletions src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ private IntPtr AllocException(Exception ex)
[DllImport(JitSupportLibrary)]
private extern static char* GetExceptionMessage(IntPtr obj);

private static readonly UnboxingMethodDescFactory _unboxingThunkFactory = new UnboxingMethodDescFactory();

public static void Startup()
{
jitStartup(GetJitHost(JitConfigProvider.Instance.UnmanagedInstance));
Expand Down Expand Up @@ -874,7 +872,7 @@ private void getEHinfo(CORINFO_METHOD_STRUCT_* ftn, uint EHnumber, ref CORINFO_E
{
if (impl.OwningType.IsValueType)
{
impl = _unboxingThunkFactory.GetUnboxingMethod(impl);
impl = getUnboxingThunk(impl);
}

return ObjectToHandle(impl);
Expand Down
90 changes: 46 additions & 44 deletions src/coreclr/src/tools/Common/JitInterface/CorInfoInstructionSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -396,12 +396,14 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe
public struct InstructionSetInfo
{
public readonly string Name;
public readonly string ManagedName;
public readonly InstructionSet InstructionSet;
public readonly bool Specifiable;

public InstructionSetInfo(string name, InstructionSet instructionSet, bool specifiable)
public InstructionSetInfo(string name, string managedName, InstructionSet instructionSet, bool specifiable)
{
Name = name;
ManagedName = managedName;
InstructionSet = instructionSet;
Specifiable = specifiable;
}
Expand All @@ -413,55 +415,55 @@ public static IEnumerable<InstructionSetInfo> ArchitectureToValidInstructionSets
{

case TargetArchitecture.ARM64:
yield return new InstructionSetInfo("base", InstructionSet.ARM64_ArmBase, true);
yield return new InstructionSetInfo("neon", InstructionSet.ARM64_AdvSimd, true);
yield return new InstructionSetInfo("aes", InstructionSet.ARM64_Aes, true);
yield return new InstructionSetInfo("crc", InstructionSet.ARM64_Crc32, true);
yield return new InstructionSetInfo("sha1", InstructionSet.ARM64_Sha1, true);
yield return new InstructionSetInfo("sha2", InstructionSet.ARM64_Sha256, true);
yield return new InstructionSetInfo("lse", InstructionSet.ARM64_Atomics, true);
yield return new InstructionSetInfo("Vector64", InstructionSet.ARM64_Vector64, false);
yield return new InstructionSetInfo("Vector128", InstructionSet.ARM64_Vector128, false);
yield return new InstructionSetInfo("base", "ArmBase", InstructionSet.ARM64_ArmBase, true);
yield return new InstructionSetInfo("neon", "AdvSimd", InstructionSet.ARM64_AdvSimd, true);
yield return new InstructionSetInfo("aes", "Aes", InstructionSet.ARM64_Aes, true);
yield return new InstructionSetInfo("crc", "Crc32", InstructionSet.ARM64_Crc32, true);
yield return new InstructionSetInfo("sha1", "Sha1", InstructionSet.ARM64_Sha1, true);
yield return new InstructionSetInfo("sha2", "Sha256", InstructionSet.ARM64_Sha256, true);
yield return new InstructionSetInfo("lse", "", InstructionSet.ARM64_Atomics, true);
yield return new InstructionSetInfo("Vector64", "", InstructionSet.ARM64_Vector64, false);
yield return new InstructionSetInfo("Vector128", "", InstructionSet.ARM64_Vector128, false);
break;

case TargetArchitecture.X64:
yield return new InstructionSetInfo("sse", InstructionSet.X64_SSE, true);
yield return new InstructionSetInfo("sse2", InstructionSet.X64_SSE2, true);
yield return new InstructionSetInfo("sse3", InstructionSet.X64_SSE3, true);
yield return new InstructionSetInfo("ssse3", InstructionSet.X64_SSSE3, true);
yield return new InstructionSetInfo("sse4.1", InstructionSet.X64_SSE41, true);
yield return new InstructionSetInfo("sse4.2", InstructionSet.X64_SSE42, true);
yield return new InstructionSetInfo("avx", InstructionSet.X64_AVX, true);
yield return new InstructionSetInfo("avx2", InstructionSet.X64_AVX2, true);
yield return new InstructionSetInfo("aes", InstructionSet.X64_AES, true);
yield return new InstructionSetInfo("bmi", InstructionSet.X64_BMI1, true);
yield return new InstructionSetInfo("bmi2", InstructionSet.X64_BMI2, true);
yield return new InstructionSetInfo("fma", InstructionSet.X64_FMA, true);
yield return new InstructionSetInfo("lzcnt", InstructionSet.X64_LZCNT, true);
yield return new InstructionSetInfo("pclmul", InstructionSet.X64_PCLMULQDQ, true);
yield return new InstructionSetInfo("popcnt", InstructionSet.X64_POPCNT, true);
yield return new InstructionSetInfo("Vector128", InstructionSet.X64_Vector128, false);
yield return new InstructionSetInfo("Vector256", InstructionSet.X64_Vector256, false);
yield return new InstructionSetInfo("sse", "Sse", InstructionSet.X64_SSE, true);
yield return new InstructionSetInfo("sse2", "Sse2", InstructionSet.X64_SSE2, true);
yield return new InstructionSetInfo("sse3", "Sse3", InstructionSet.X64_SSE3, true);
yield return new InstructionSetInfo("ssse3", "Ssse3", InstructionSet.X64_SSSE3, true);
yield return new InstructionSetInfo("sse4.1", "Sse41", InstructionSet.X64_SSE41, true);
yield return new InstructionSetInfo("sse4.2", "Sse42", InstructionSet.X64_SSE42, true);
yield return new InstructionSetInfo("avx", "Avx", InstructionSet.X64_AVX, true);
yield return new InstructionSetInfo("avx2", "Avx2", InstructionSet.X64_AVX2, true);
yield return new InstructionSetInfo("aes", "Aes", InstructionSet.X64_AES, true);
yield return new InstructionSetInfo("bmi", "Bmi1", InstructionSet.X64_BMI1, true);
yield return new InstructionSetInfo("bmi2", "Bmi2", InstructionSet.X64_BMI2, true);
yield return new InstructionSetInfo("fma", "Fma", InstructionSet.X64_FMA, true);
yield return new InstructionSetInfo("lzcnt", "Lzcnt", InstructionSet.X64_LZCNT, true);
yield return new InstructionSetInfo("pclmul", "Pclmulqdq", InstructionSet.X64_PCLMULQDQ, true);
yield return new InstructionSetInfo("popcnt", "Popcnt", InstructionSet.X64_POPCNT, true);
yield return new InstructionSetInfo("Vector128", "", InstructionSet.X64_Vector128, false);
yield return new InstructionSetInfo("Vector256", "", InstructionSet.X64_Vector256, false);
break;

case TargetArchitecture.X86:
yield return new InstructionSetInfo("sse", InstructionSet.X86_SSE, true);
yield return new InstructionSetInfo("sse2", InstructionSet.X86_SSE2, true);
yield return new InstructionSetInfo("sse3", InstructionSet.X86_SSE3, true);
yield return new InstructionSetInfo("ssse3", InstructionSet.X86_SSSE3, true);
yield return new InstructionSetInfo("sse4.1", InstructionSet.X86_SSE41, true);
yield return new InstructionSetInfo("sse4.2", InstructionSet.X86_SSE42, true);
yield return new InstructionSetInfo("avx", InstructionSet.X86_AVX, true);
yield return new InstructionSetInfo("avx2", InstructionSet.X86_AVX2, true);
yield return new InstructionSetInfo("aes", InstructionSet.X86_AES, true);
yield return new InstructionSetInfo("bmi", InstructionSet.X86_BMI1, true);
yield return new InstructionSetInfo("bmi2", InstructionSet.X86_BMI2, true);
yield return new InstructionSetInfo("fma", InstructionSet.X86_FMA, true);
yield return new InstructionSetInfo("lzcnt", InstructionSet.X86_LZCNT, true);
yield return new InstructionSetInfo("pclmul", InstructionSet.X86_PCLMULQDQ, true);
yield return new InstructionSetInfo("popcnt", InstructionSet.X86_POPCNT, true);
yield return new InstructionSetInfo("Vector128", InstructionSet.X86_Vector128, false);
yield return new InstructionSetInfo("Vector256", InstructionSet.X86_Vector256, false);
yield return new InstructionSetInfo("sse", "Sse", InstructionSet.X86_SSE, true);
yield return new InstructionSetInfo("sse2", "Sse2", InstructionSet.X86_SSE2, true);
yield return new InstructionSetInfo("sse3", "Sse3", InstructionSet.X86_SSE3, true);
yield return new InstructionSetInfo("ssse3", "Ssse3", InstructionSet.X86_SSSE3, true);
yield return new InstructionSetInfo("sse4.1", "Sse41", InstructionSet.X86_SSE41, true);
yield return new InstructionSetInfo("sse4.2", "Sse42", InstructionSet.X86_SSE42, true);
yield return new InstructionSetInfo("avx", "Avx", InstructionSet.X86_AVX, true);
yield return new InstructionSetInfo("avx2", "Avx2", InstructionSet.X86_AVX2, true);
yield return new InstructionSetInfo("aes", "Aes", InstructionSet.X86_AES, true);
yield return new InstructionSetInfo("bmi", "Bmi1", InstructionSet.X86_BMI1, true);
yield return new InstructionSetInfo("bmi2", "Bmi2", InstructionSet.X86_BMI2, true);
yield return new InstructionSetInfo("fma", "Fma", InstructionSet.X86_FMA, true);
yield return new InstructionSetInfo("lzcnt", "Lzcnt", InstructionSet.X86_LZCNT, true);
yield return new InstructionSetInfo("pclmul", "Pclmulqdq", InstructionSet.X86_PCLMULQDQ, true);
yield return new InstructionSetInfo("popcnt", "Popcnt", InstructionSet.X86_POPCNT, true);
yield return new InstructionSetInfo("Vector128", "", InstructionSet.X86_Vector128, false);
yield return new InstructionSetInfo("Vector256", "", InstructionSet.X86_Vector256, false);
break;

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,12 +522,14 @@ private static InstructionSetFlags ExpandInstructionSetByReverseImplicationHelpe
public struct InstructionSetInfo
{
public readonly string Name;
public readonly string ManagedName;
public readonly InstructionSet InstructionSet;
public readonly bool Specifiable;

public InstructionSetInfo(string name, InstructionSet instructionSet, bool specifiable)
public InstructionSetInfo(string name, string managedName, InstructionSet instructionSet, bool specifiable)
{
Name = name;
ManagedName = managedName;
InstructionSet = instructionSet;
Specifiable = specifiable;
}
Expand All @@ -548,9 +550,10 @@ public static IEnumerable<InstructionSetInfo> ArchitectureToValidInstructionSets
if (instructionSet.Architecture != architecture) continue;
bool instructionSetIsSpecifiable = !String.IsNullOrEmpty(instructionSet.CommandLineName);
string name = instructionSet.PublicName;
string managedName = instructionSet.ManagedName;
string specifiable = instructionSetIsSpecifiable ? "true" : "false";
string instructionSetString = $"InstructionSet.{architecture}_{instructionSet.JitName}";
tr.WriteLine($" yield return new InstructionSetInfo(\"{name}\", {instructionSetString}, {specifiable});");
tr.WriteLine($" yield return new InstructionSetInfo(\"{name}\", \"{managedName}\", {instructionSetString}, {specifiable});");
}
tr.WriteLine(" break;");
}
Expand Down
Loading