@@ -3425,6 +3425,8 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
34253425 // This one is just `return true/false`
34263426 case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant:
34273427
3428+ case NI_System_Runtime_CompilerServices_RuntimeHelpers_WriteBarrierUnchecked:
3429+
34283430 // Not expanding this can lead to noticeable allocations in T0
34293431 case NI_System_Runtime_CompilerServices_RuntimeHelpers_CreateSpan:
34303432
@@ -3657,6 +3659,14 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
36573659 break ;
36583660 }
36593661
3662+ case NI_System_Runtime_CompilerServices_RuntimeHelpers_WriteBarrierUnchecked:
3663+ {
3664+ GenTree* val = impPopStack ().val ;
3665+ GenTree* dst = impPopStack ().val ;
3666+ retNode = gtNewStoreIndNode (TYP_REF , dst, val, GTF_IND_TGT_HEAP );
3667+ break ;
3668+ }
3669+
36603670 case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant:
36613671 {
36623672 GenTree* op1 = impPopStack ().val ;
@@ -7702,6 +7712,47 @@ void Compiler::addGuardedDevirtualizationCandidate(GenTreeCall* call,
77027712 call->AddGDVCandidateInfo (this , pInfo);
77037713}
77047714
7715+ // ------------------------------------------------------------------------
7716+ // impConvertToUserCallAndMarkForInlining: convert a helper call to a user call
7717+ // and mark it for inlining. This is used for helper calls that are
7718+ // known to be backed by a user method that can be inlined.
7719+ //
7720+ // Arguments:
7721+ // call - the helper call to convert
7722+ //
7723+ void Compiler::impConvertToUserCallAndMarkForInlining (GenTreeCall* call)
7724+ {
7725+ assert (call->IsHelperCall ());
7726+
7727+ if (!opts.OptEnabled (CLFLG_INLINING ))
7728+ {
7729+ return ;
7730+ }
7731+
7732+ CORINFO_METHOD_HANDLE helperCallHnd = call->gtCallMethHnd ;
7733+ CORINFO_METHOD_HANDLE managedCallHnd = NO_METHOD_HANDLE ;
7734+ CORINFO_CONST_LOOKUP pNativeEntrypoint = {};
7735+ info.compCompHnd ->getHelperFtn (eeGetHelperNum (helperCallHnd), &pNativeEntrypoint, &managedCallHnd);
7736+
7737+ if (managedCallHnd != NO_METHOD_HANDLE )
7738+ {
7739+ call->gtCallMethHnd = managedCallHnd;
7740+ call->gtCallType = CT_USER_FUNC ;
7741+
7742+ CORINFO_CALL_INFO hCallInfo = {};
7743+ hCallInfo.hMethod = managedCallHnd;
7744+ hCallInfo.methodFlags = info.compCompHnd ->getMethodAttribs (hCallInfo.hMethod );
7745+ impMarkInlineCandidate (call, nullptr , false , &hCallInfo, compInlineContext);
7746+
7747+ if (ISMETHOD (" Test" ))
7748+ printf (" " );
7749+
7750+ impInlineRoot ()->GetHelperToManagedMap ()->Set (helperCallHnd, managedCallHnd, HelperToManagedMap::Overwrite);
7751+ JITDUMP (" Converting helperCall [%06u] to user call [%s] and marking for inlining\n " , dspTreeID (call),
7752+ eeGetMethodFullName (managedCallHnd));
7753+ }
7754+ }
7755+
77057756// ------------------------------------------------------------------------
77067757// impMarkInlineCandidate: determine if this call can be subsequently inlined
77077758//
@@ -10618,7 +10669,14 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
1061810669 {
1061910670 namespaceName += 8 ;
1062010671
10621- if (strcmp (namespaceName, " CompilerServices" ) == 0 )
10672+ if (strcmp (className, " TypeCast" ) == 0 )
10673+ {
10674+ if (strcmp (methodName, " WriteBarrierUnchecked" ) == 0 )
10675+ {
10676+ result = NI_System_Runtime_CompilerServices_RuntimeHelpers_WriteBarrierUnchecked;
10677+ }
10678+ }
10679+ else if (strcmp (namespaceName, " CompilerServices" ) == 0 )
1062210680 {
1062310681 if (strcmp (className, " RuntimeHelpers" ) == 0 )
1062410682 {
@@ -10634,6 +10692,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
1063410692 {
1063510693 result = NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant;
1063610694 }
10695+ else if (strcmp (methodName, " WriteBarrierUnchecked" ) == 0 )
10696+ {
10697+ result = NI_System_Runtime_CompilerServices_RuntimeHelpers_WriteBarrierUnchecked;
10698+ }
1063710699 else if (strcmp (methodName, " IsReferenceOrContainsReferences" ) == 0 )
1063810700 {
1063910701 result =
0 commit comments