-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
JIT: enable tail calls and copy omission for implicit byref structs #33004
Changes from 5 commits
13f0f6a
364a302
5a34292
a0b9591
c3cc4b0
cf98b3e
50da720
7084ebf
a33348c
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 | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -16193,6 +16193,55 @@ bool GenTree::IsLocalAddrExpr(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, | |||||||
return false; | ||||||||
} | ||||||||
|
||||||||
//------------------------------------------------------------------------ | ||||||||
// IsImplicitByrefParameterValue: determine if this tree is the entire | ||||||||
// value of a local implicit byref parameter | ||||||||
// | ||||||||
// Arguments: | ||||||||
// compiler -- compiler instance | ||||||||
// | ||||||||
// Return Value: | ||||||||
// GenTreeLclVarCommon node for the local, or nullptr. | ||||||||
|
||||||||
GenTreeLclVarCommon* GenTree::IsImplicitByrefParameterValue(Compiler* compiler) | ||||||||
{ | ||||||||
#if defined(TARGET_AMD64) || defined(TARGET_ARM64) | ||||||||
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. Shouldn't this be limited to windows amd64? 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. Windows, yes. We seem to think arm64 can have these too. I don't know the ABI well enough to say one way or another. runtime/src/coreclr/src/jit/compiler.h Lines 444 to 446 in 5ea5b57
Perhaps we need a define just for this and a cleanup of all references? 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. Looks like windows arm64 uses the standard ARM64 EABI, so there are no implicit byrefs there. I'll put up a separate PR to clean this up here and throughout the rest of the jit codebase. 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. I was under the impression that arm64 has implicit byrefs, but defining it for unix amd64 seems incorrect for sure. 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. > 16 byte structs on arm64 windows or linux I believe are passed by reference. 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. Ah, I see it now.. (from the EABI)
So the right condition is windows x64, and all arm64. |
||||||||
|
||||||||
GenTreeLclVarCommon* lcl = nullptr; | ||||||||
|
||||||||
if (OperIs(GT_LCL_VAR)) | ||||||||
{ | ||||||||
lcl = AsLclVarCommon(); | ||||||||
} | ||||||||
else if (OperIs(GT_OBJ)) | ||||||||
{ | ||||||||
GenTree* addr = AsIndir()->Addr(); | ||||||||
|
||||||||
if (addr->OperIs(GT_LCL_VAR)) | ||||||||
{ | ||||||||
lcl = addr->AsLclVarCommon(); | ||||||||
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. I don't understand this case, 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. Yes, this is potentially confusing. The short answer is that before morph, arguments passed implicitly by-reference are represented by-value in the IR. Note the first two "match" cases here are pre-existing logic; all I did was move this to a helper method and add the last case. |
||||||||
} | ||||||||
else if (addr->OperIs(GT_ADDR)) | ||||||||
{ | ||||||||
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. Is there a semantic difference between 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. What this means changes over time, and we're straddling that change. See above? |
||||||||
GenTree* base = addr->AsOp()->gtOp1; | ||||||||
|
||||||||
if (base->OperIs(GT_LCL_VAR)) | ||||||||
{ | ||||||||
lcl = base->AsLclVarCommon(); | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
if ((lcl != nullptr) && compiler->lvaIsImplicitByRefLocal(lcl->GetLclNum())) | ||||||||
{ | ||||||||
return lcl; | ||||||||
} | ||||||||
|
||||||||
#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) | ||||||||
|
||||||||
return nullptr; | ||||||||
} | ||||||||
|
||||||||
//------------------------------------------------------------------------ | ||||||||
// IsLclVarUpdateTree: Determine whether this is an assignment tree of the | ||||||||
// form Vn = Vn 'oper' 'otherTree' where Vn is a lclVar | ||||||||
|
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.
You can change
GenTreeLclVarCommon
toGenTreeLclVar
, it is more precise for this case.