Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 5.6k
Update the JIT to support rewriting more complex intrinsics as user calls#102702
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
ba591a345d9e2339e424cc41dfd2a0cea27a0a0749File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -559,6 +559,7 @@ enum GenTreeFlags : unsigned int | ||
| #ifdef FEATURE_HW_INTRINSICS | ||
| GTF_HW_EM_OP = 0x10000000, // GT_HWINTRINSIC -- node is used as an operand to an embedded mask | ||
| GTF_HW_USER_CALL = 0x20000000, // GT_HWINTRINSIC -- node is implemented via a user call | ||
| #endif // FEATURE_HW_INTRINSICS | ||
| }; | ||
| @@ -6089,6 +6090,15 @@ struct GenTreeMultiOp : public GenTree | ||
| } | ||
| #endif | ||
| bool IsUserCall() const | ||
| { | ||
| #if defined(FEATURE_HW_INTRINSICS) | ||
| return OperIs(GT_HWINTRINSIC) && (gtFlags & GTF_HW_USER_CALL) != 0; | ||
| #else | ||
| return false; | ||
| #endif | ||
| } | ||
| GenTree*& Op(size_t index) | ||
| { | ||
| size_t actualIndex = index - 1; | ||
| @@ -6217,7 +6227,29 @@ class IntrinsicNodeBuilder final | ||
| struct GenTreeJitIntrinsic : public GenTreeMultiOp | ||
| { | ||
| protected: | ||
| GenTree* gtInlineOperands[2]; | ||
| union | ||
| { | ||
| // We don't have enough space to carry both the inline operands | ||
| // and the necessary information required to support rewriting | ||
| // the intrinsic back into a user call. As such, we union the | ||
| // data instead and use the GTF_HW_USER_CALL flag to indicate | ||
| // which fields are valid to access. -- Tracking the fields | ||
| // independently causes TREE_NODE_SZ_LARGE to increase and for | ||
| // GenTreeJitIntrinsic to become the largest node, which is | ||
| // undesirable, so this approach helps keep things pay-for-play. | ||
| GenTree* gtInlineOperands[2]; | ||
| ||
| struct | ||
| { | ||
| CORINFO_METHOD_HANDLE gtMethodHandle; | ||
| #if defined(FEATURE_READYTORUN) | ||
| // Call target lookup info for method call from a Ready To Run module | ||
| CORINFO_CONST_LOOKUP* gtEntryPoint; | ||
| #endif // FEATURE_READYTORUN | ||
| }; | ||
| }; | ||
| regNumberSmall gtOtherReg; // The second register for multi-reg intrinsics. | ||
| MultiRegSpillFlags gtSpillFlags; // Spill flags for multi-reg intrinsics. | ||
| unsigned char gtAuxiliaryJitType; // For intrinsics than need another type (e.g. Avx2.Gather* or SIMD (by element)) | ||
| @@ -6226,6 +6258,24 @@ struct GenTreeJitIntrinsic : public GenTreeMultiOp | ||
| NamedIntrinsic gtHWIntrinsicId; | ||
| public: | ||
| CORINFO_METHOD_HANDLE GetMethodHandle() const | ||
| { | ||
| assert(IsUserCall()); | ||
| return gtMethodHandle; | ||
| } | ||
| void SetMethodHandle(Compiler* comp, CORINFO_METHOD_HANDLE methodHandle); | ||
| #if defined(FEATURE_READYTORUN) | ||
| CORINFO_CONST_LOOKUP GetEntryPoint() const | ||
| { | ||
| assert(IsUserCall()); | ||
| return *gtEntryPoint; | ||
| } | ||
| void SetEntryPoint(Compiler* comp, CORINFO_CONST_LOOKUP entryPoint); | ||
| #endif // FEATURE_READYTORUN | ||
| //----------------------------------------------------------- | ||
| // GetRegNumByIdx: Get regNumber of i'th position. | ||
| // | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.