-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Inline CORINFO_HELP_ARRADDR_ST helper call, remove WriteBarrier FCall #117583
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
base: main
Are you sure you want to change the base?
Changes from 13 commits
872e969
e93c1cf
7279b86
894c0ef
fd9a81c
c6da245
68e68a5
c526462
6c036c8
fcf80b9
cc5f12b
3c9049f
bfb7194
7300f5c
8c3900a
e4d9fde
5bd0911
2731fb3
130f490
5b5b037
85d566d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5149,6 +5149,30 @@ class Compiler | |
| GenTree* dereferencedAddress, | ||
| InlArgInfo* inlArgInfo); | ||
|
|
||
| typedef JitHashTable<CORINFO_METHOD_HANDLE, JitPtrKeyFuncs<struct CORINFO_METHOD_STRUCT_>, CORINFO_METHOD_HANDLE> HelperToManagedMap; | ||
| HelperToManagedMap* m_helperToManagedMap = nullptr; | ||
|
|
||
| public: | ||
| HelperToManagedMap* GetHelperToManagedMap() | ||
| { | ||
| if (m_helperToManagedMap == nullptr) | ||
| { | ||
| m_helperToManagedMap = new (getAllocator()) HelperToManagedMap(getAllocator()); | ||
| } | ||
| return m_helperToManagedMap; | ||
| } | ||
| bool HelperToManagedMapLookup(CORINFO_METHOD_HANDLE helperCallHnd, CORINFO_METHOD_HANDLE* userCallHnd) | ||
| { | ||
| if (m_helperToManagedMap == nullptr) | ||
| { | ||
| return false; | ||
| } | ||
| bool found = m_helperToManagedMap->Lookup(helperCallHnd, userCallHnd); | ||
| return found; | ||
| } | ||
| private: | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This I could just do it via |
||
|
|
||
| void impConvertToUserCallAndMarkForInlining(GenTreeCall* call); | ||
| void impMarkInlineCandidate(GenTree* call, | ||
| CORINFO_CONTEXT_HANDLE exactContextHnd, | ||
| bool exactContextNeedsRuntimeLookup, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3363,6 +3363,8 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, | |||||||||||||||||||
| // This one is just `return true/false` | ||||||||||||||||||||
| case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant: | ||||||||||||||||||||
|
|
||||||||||||||||||||
| case NI_System_Runtime_CompilerServices_RuntimeHelpers_WriteBarrier: | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Not expanding this can lead to noticeable allocations in T0 | ||||||||||||||||||||
| case NI_System_Runtime_CompilerServices_RuntimeHelpers_CreateSpan: | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -3595,6 +3597,14 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, | |||||||||||||||||||
| break; | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| case NI_System_Runtime_CompilerServices_RuntimeHelpers_WriteBarrier: | ||||||||||||||||||||
| { | ||||||||||||||||||||
| GenTree* val = impPopStack().val; | ||||||||||||||||||||
| GenTree* dst = impPopStack().val; | ||||||||||||||||||||
| retNode = gtNewStoreIndNode(TYP_REF, dst, val, GTF_IND_TGT_HEAP); | ||||||||||||||||||||
| break; | ||||||||||||||||||||
| } | ||||||||||||||||||||
jakobbotsch marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant: | ||||||||||||||||||||
| { | ||||||||||||||||||||
| GenTree* op1 = impPopStack().val; | ||||||||||||||||||||
|
|
@@ -7893,6 +7903,53 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call, | |||||||||||||||||||
| call->AddGDVCandidateInfo(this, pInfo); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| //------------------------------------------------------------------------ | ||||||||||||||||||||
| // impConvertToUserCallAndMarkForInlining: convert a helper call to a user call | ||||||||||||||||||||
| // and mark it for inlining. This is used for helper calls that are | ||||||||||||||||||||
| // known to be backed by a user method that can be inlined. | ||||||||||||||||||||
| // | ||||||||||||||||||||
| // Arguments: | ||||||||||||||||||||
| // call - the helper call to convert | ||||||||||||||||||||
| // | ||||||||||||||||||||
| void Compiler::impConvertToUserCallAndMarkForInlining(GenTreeCall* call) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| assert(call->IsHelperCall()); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if (!opts.OptEnabled(CLFLG_INLINING)) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| return; | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| CORINFO_METHOD_HANDLE helperCallHnd = call->gtCallMethHnd; | ||||||||||||||||||||
| CORINFO_METHOD_HANDLE managedCallHnd = NO_METHOD_HANDLE; | ||||||||||||||||||||
| CORINFO_CONST_LOOKUP pNativeEntrypoint = {}; | ||||||||||||||||||||
| info.compCompHnd->getHelperFtn(eeGetHelperNum(helperCallHnd), &pNativeEntrypoint, &managedCallHnd); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if (managedCallHnd != NO_METHOD_HANDLE) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| call->gtCallMethHnd = managedCallHnd; | ||||||||||||||||||||
| call->gtCallType = CT_USER_FUNC; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| CORINFO_CALL_INFO hCallInfo = {}; | ||||||||||||||||||||
| hCallInfo.hMethod = managedCallHnd; | ||||||||||||||||||||
| hCallInfo.methodFlags = info.compCompHnd->getMethodAttribs(hCallInfo.hMethod); | ||||||||||||||||||||
| impMarkInlineCandidate(call, nullptr, false, &hCallInfo, compInlineContext); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| #if DEBUG | ||||||||||||||||||||
| CORINFO_METHOD_HANDLE existingValue = NO_METHOD_HANDLE; | ||||||||||||||||||||
| if (impInlineRoot()->GetHelperToManagedMap()->Lookup(helperCallHnd, &existingValue)) | ||||||||||||||||||||
EgorBo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||
| { | ||||||||||||||||||||
| // Let's make sure HelperToManagedMap::Overwrite behavior always overwrites the same value. | ||||||||||||||||||||
| assert(existingValue == managedCallHnd); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| #endif | ||||||||||||||||||||
|
|
||||||||||||||||||||
| impInlineRoot()->GetHelperToManagedMap()->Set(helperCallHnd, managedCallHnd, HelperToManagedMap::Overwrite); | ||||||||||||||||||||
| JITDUMP("Converting helperCall [%06u] to user call [%s] and marking for inlining\n", dspTreeID(call), | ||||||||||||||||||||
| eeGetMethodFullName(managedCallHnd)); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| //------------------------------------------------------------------------ | ||||||||||||||||||||
| // impMarkInlineCandidate: determine if this call can be subsequently inlined | ||||||||||||||||||||
| // | ||||||||||||||||||||
|
|
@@ -10811,7 +10868,14 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) | |||||||||||||||||||
| { | ||||||||||||||||||||
| namespaceName += 8; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if (strcmp(namespaceName, "CompilerServices") == 0) | ||||||||||||||||||||
| if (strcmp(className, "TypeCast") == 0) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| if (strcmp(methodName, "WriteBarrier") == 0) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| result = NI_System_Runtime_CompilerServices_RuntimeHelpers_WriteBarrier; | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
| else if (strcmp(namespaceName, "CompilerServices") == 0) | ||||||||||||||||||||
|
||||||||||||||||||||
| if (strcmp(className, "TypeCast") == 0) | |
| { | |
| if (strcmp(methodName, "WriteBarrier") == 0) | |
| { | |
| result = NI_System_Runtime_CompilerServices_RuntimeHelpers_WriteBarrier; | |
| } | |
| } | |
| else if (strcmp(namespaceName, "CompilerServices") == 0) | |
| if (strcmp(namespaceName, "CompilerServices") == 0) |
And move the WriteBarrier into RuntimeHelpers for NAOT instead? We prefer things to be the same between NAOT and non-NAOT where possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jkotas I could not use [Intrinsic] for RuntimeHelpers inside Runtime.Base (and presumably in Test.CoreLib) 🙁 so this was exactly why I ended up with this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not? Runtime.Base has its own simplified copy of [Intrinsic]: https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/IntrinsicAttribute.cs
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ignore me, I think I fixed it 🙂
Uh oh!
There was an error while loading. Please reload this page.