Report SIMD intrinsics to RyuJIT#3678
Conversation
* Implement `isInSIMDModule` * Implement `appendClassName` * Implement a type name formatter that roughly approximates typestring.cpp in the CLR. Should be enough for the purposes of recognizing SIMD intrinsics. Hopefully, we won't ever have to be complete. This is the formatter used by reflection - the rules are complex and long.
|
Do we also need to adjust the size of (Look for https://github.com/dotnet/coreclr/search?q=getMaxIntrinsicSIMDVectorLength in CoreCLR.) |
Without AVX, the size in IL (16) matches the size used by RyuJIT. But I made the changes to also support AVX in the future (once we make RyuJIT stop conditioning it on conditions that might make sense for a JIT, but don't make sense for an AOT compiler). Instead of I don't particularly like how ingrained |
| { | ||
| // We support enough of this to make SIMD work, but not much else. | ||
|
|
||
| // TODO: figure out why the marshalling for fFullInst and fAssembly is wrong. |
There was a problem hiding this comment.
This kinda looks like a bug in marshalling. I couldn't figure out what's wrong with the signature. Suggestions welcome.
There was a problem hiding this comment.
Should be UnmanagedType.Bool from what I can see.
There was a problem hiding this comment.
Found the culprit: the generated jitinterface.h we use as the wrapper declares this method as int (__stdcall * appendClassName)(void * thisHandle, CorInfoException** ppException, wchar_t** ppBuf, int* pnBufLen, void* cls, bool fNamespace, bool fFullInst, bool fAssembly);. There's a bool/BOOL mismatch.
We need to either fix the generated wrapper code, or our mashalling annotations. Probably former rather than the latter.
Either way, out of scope of this pull request.
| Jit * pJit, | ||
| CORJIT_FLAGS flags) | ||
| { | ||
| // BUGBUG: the signature on the Jit side is actually "pass by value", but for reasons that escape me, |
There was a problem hiding this comment.
Again, couldn't figure out why the ABI doesn't match. The flags that come from the managed side look alright in the debugger, but become broken on the RyuJIT side. Of course it can't be checked in like this, but I already spent too much time on this and need a fresh pair of eyes to have a look.
There was a problem hiding this comment.
This may have to do with different calling convention for Plain-Old-Datatype structs vs. C++ structs. Does it change if you add constructor to CORJIT_FLAGS ?
There was a problem hiding this comment.
Adding a copy constructor did the trick. Thanks!
|
|
||
| namespace Internal.TypeSystem | ||
| { | ||
| // Extension to TargetDetails related to code generation |
There was a problem hiding this comment.
We might want to kick things like the Abi to this flavor of TargetDetails too.
|
|
||
| public MaximumSimdVectorLength MaximumSimdVectorLength | ||
| { | ||
| get; |
There was a problem hiding this comment.
Now that I had a chance to think about this a little on the way to get lunch: would we just want to introduce this as a TargetArchitecture flavor? E.g. TargetArchitecture.x64, TargetArchitecture.x64_Avx, with a IsX64 convenience property on TargetDetails? (Similar for other arches, in the future.) Yes, it feels weird to put instruction set details on a type system object, but as we see here, this does affect type layout, and it is a type system concern.
There was a problem hiding this comment.
I don't really like that idea. Its very much readable to have a switch case arrangement around use of target architecture, and while it doesn't cover all cases, its pretty good. Forcing the use of a series of helper functions is a bit of a kludge.
davidwrighton
left a comment
There was a problem hiding this comment.
Looks basically good, but please fix or at the very least understand the marshaling issues before checking in.
|
|
||
| public MaximumSimdVectorLength MaximumSimdVectorLength | ||
| { | ||
| get; |
There was a problem hiding this comment.
I don't really like that idea. Its very much readable to have a switch case arrangement around use of target architecture, and while it doesn't cover all cases, its pretty good. Forcing the use of a series of helper functions is a bit of a kludge.
| None, | ||
| VectorLength16, | ||
| VectorLength32, | ||
| } |
There was a problem hiding this comment.
I don't like these enum names. What does the 16 or 32 refer to? Bytes? Bits? Elements? In general, I've seen vectors named based on bit length more than on byte length. (For instance, AVX512) I'd prefer something like Vector64Bit
| { | ||
| // We support enough of this to make SIMD work, but not much else. | ||
|
|
||
| // TODO: figure out why the marshalling for fFullInst and fAssembly is wrong. |
There was a problem hiding this comment.
Should be UnmanagedType.Bool from what I can see.
Only stomp over the field size and byte count for maximum CLR compat.
isInSIMDModuleappendClassNametypestring.cpp in the CLR. Should be enough for the purposes of
recognizing SIMD intrinsics. Hopefully, we won't ever have to be
complete. This is the formatter used by reflection - the rules are
complex and long.