-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Refactor and cleanup work for passing and returning struct types #6198
Conversation
@dotnet-bot Test Windows_NT arm64 Checked |
1703fd4
to
1ee30a8
Compare
@dotnet-bot Test Windows_NT arm64 Checked |
1ee30a8
to
3a0b626
Compare
@dotnet-bot Test Windows_NT arm64 Checked |
@dotnet/jit-contrib PTAL |
@dotnet-bot test Windows_NT arm64 Checked pri1r2r |
On ARM, a struct can also be passed partially in registers and partially on the stack. |
src/jit/compiler.h
Outdated
var_types argOrReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd, bool forReturn); | ||
enum structPassingKind { SPK_Unknown, // Invalid value, never returned | ||
SPK_PrimitiveType, // The struct is passed/returned using a primitive type | ||
SPK_ByValue, // The struct is passed/returned by value, usually in multiple registers |
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.
Does this include both on stack, in registers, and split between registers and stack? (if so, probably the comment should say that)
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.
Yes I will add to the comment. This method is classifing what should be done, it doesn't actually implement the passing or returning of structure.
LGTM module comments. I like how all this ABI info is encapsulated in these functions. Can they be used in more cases, to remove similar logic elsewhere? |
src/jit/compiler.cpp
Outdated
// | ||
// Notes: | ||
// About returning TYP_STRUCT: | ||
// Whenever the return type is TYP_STRUCT it always means multiple registers |
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.
For consistency with surrounding comments, you should change "return type" to "return value" even though in some sense what you have now is valid.
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.
In my comments when referring to the 'var_types' return value, I used "this method's return value" and in the method getReturnTypeForStruct the phrase "return type" refers to how the struct will be returned.
Also in out coding conventions we have defined that method header comment contains a
section called "Return Type:" which describes what the function returns/
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.
I'm failing to resolve your distinction with immediately surrounding comments. For example:
- Just above: "When *wbPassStruct is SPK_ByValue or SPK_ByValueAsHfa the _return value:_..."
- Just below: "If there are two or more elements in the HFA type then the _return value_ is TYP_STRUCT...
But perhaps it's just me. If you are convinced you wrote what you meant to write, then disregard.
Also, coding convention specifies "Return Value:" not "Return Type:", though I'm not sure how that's relevant.
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.
"this method's return value" means the value returned by getArgTypeForStruct()
The only occurances of "return type" remainig in my comments is this phrase:
"and the target supports multireg return types then the return value is TYP_STRUCT"
The comments that you refered to now reads:
// Return Value:
// For wbPassStruct you can pass a 'nullptr' and nothing will be written
// or returned for that out parameter.
// When *wbPassStruct is SPK_PrimitiveType this method's return value
// is the primitive type used to pass the struct.
// When *wbPassStruct is SPK_ByReference this method's return value
// is TYP_UNKNOWN and the struct type is passed by reference to a copy
// When *wbPassStruct is SPK_ByValue or SPK_ByValueAsHfa this method's return value
// can be TYP_STRUCT and the struct type is passed using multiple registers.
// or can be TYP_UNKNOWN and the struct type is passed by value (for x86 and ARM32)
Regarding the description of this change: "4. A struct type may be passed/returned by value using a copy on the stack," I believe you should remove the "/returned" part. [Edit] This is done. |
src/jit/compiler.cpp
Outdated
// false if we are asking for this in a parameter passing context | ||
// clsHnd - the handle for the struct type, used when may have | ||
// an HFA or if we need the GC layout for an object ref. | ||
// structSize - the size of the struct type, cannot be zero |
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.
Is there a reason you swapped the order of the argument descriptions, relative to how they are passed?
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.
I will switch these to the correct order.
3a0b626
to
cae20f9
Compare
@dotnet-bot Test Windows_NT arm64 Checked |
src/jit/compiler.cpp
Outdated
// When *wbReturnStruct is SPK_ByReference this method's return value | ||
// is TYP_UNKNOWN when the struct type is returned using a return buffer | ||
// When *wbReturnStruct is SPK_ByValue or SPK_ByValueAsHfa this method's return value | ||
// is TYP_STRUCT when the struct type is returned using multiple registers. |
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.
These comments don't appear to cover all the cases - if these cases can't occur, the comment make it clear:
I think it's the case that when *wbReturnStruct is SPK_ByReference, the return value is always TYP_UNKNOWN, AND (not "when") the struct type is (always) returned using a return buffer.
I also think it's the case that when *wbReturnStruct is SPK_ByValue or SPK_ByValueAsHfa, then the methods return value is always TYP_STRUCT, AND (not "when") the struct type is returned using multiple registers.
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.
Yes, I have undated this comment as you suggested.
I also checked the other method getArgTypeForStruct in this area and found it to be correct.
// When *wbPassStruct is SPK_ByReference this method's return value | ||
// is TYP_UNKNOWN and the struct type is passed by reference to a copy | ||
// When *wbPassStruct is SPK_ByValue or SPK_ByValueAsHfa this method's return value | ||
// can be TYP_STRUCT and the struct type is passed using multiple registers. |
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.
Should this say "is passed using multiple registers, if sufficient argument registers are available, and is otherwise passed by value on the stack"?
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.
In the Notes section I cover this:
// About returning TYP_STRUCT:
// Whenever this method's return value is TYP_STRUCT it usually means that multiple
// registers will be used to pass this struct.
// The only exception occurs if all of the parameters registers are used up
// then we must use stack slots instead. In such a case the amount of stack needed
// is always equal to the structSize (rounded up to the next pointer size)
//
@dotnet-bot Test Ubuntu x64 Checked Build and Test |
cae20f9
to
8ee7fe7
Compare
@dotnet-bot test Windows_NT arm64 Checked pri1r2r |
@dotnet-bot Test Windows_NT Arm64 Checked Pri1r2r |
@dotnet-bot Test Windows_NT arm64 Checked |
@dotnet-bot Test Windows_NT Arm64 Checked Pri1r2r |
LGTM |
Replaces argOrReturnTypeForStruct with two new methods: getArgTypeForStruct - Provides information on how to pass a struct type getReturnTypeForStruct - Provides information on how to return a struct type A struct can be passed or return in the following different ways: 1. A struct type may be passed/returned as a primitive type when its size is small 2. A struct type may be passed/returned by reference to a copy 3. A struct type may be passed/returned by value using multiple registers 4. A struct type may be passed by value using a copy on the stack Incorporated code review feedback with expanded comments.
8ee7fe7
to
6530924
Compare
@dotnet-bot Test Windows_NT Arm64 Checked Pri1r2r |
@dotnet-bot Test Windows_NT arm64 Checked |
1 similar comment
@dotnet-bot Test Windows_NT arm64 Checked |
@dotnet-bot Test Linux ARM Emulator Cross Debug Build |
@dotnet-bot Test Windows_NT Arm64 Checked Pri1r2r |
@dotnet-bot Test Linux ARM Emulator Cross Release Build |
@dotnet-bot Test Linux ARM Emulator Cross Release Build |
Refactor and cleanup work for passing and returning struct types Commit migrated from dotnet/coreclr@b33bd67
Replaces argOrReturnTypeForStruct with two new methods:
getArgTypeForStruct - Provides information on how to pass a struct type
getReturnTypeForStruct - Provides information on how to return a struct type
A struct can be passed or returned in the following different ways:
1. A struct type may be passed/returned as a primitive type when its size is small
2. A struct type may be passed/returned by reference to a copy
3. A struct type may be passed/returned by value using multiple registers
4. A struct type may be passed by value using a copy on the stack