Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Conversation

briansull
Copy link

@briansull briansull commented Jul 8, 2016

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

@briansull
Copy link
Author

@dotnet-bot Test Windows_NT arm64 Checked

@briansull briansull force-pushed the multireg-refactor branch from 1703fd4 to 1ee30a8 Compare July 8, 2016 23:29
@briansull
Copy link
Author

@dotnet-bot Test Windows_NT arm64 Checked

@briansull
Copy link
Author

@dotnet-bot Test Windows_NT arm64 Checked

@briansull
Copy link
Author

@dotnet/jit-contrib PTAL

@briansull
Copy link
Author

@dotnet-bot test Windows_NT arm64 Checked pri1r2r

@BruceForstall
Copy link

On ARM, a struct can also be passed partially in registers and partially on the stack.

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

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)

Copy link
Author

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.

@BruceForstall
Copy link

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?

//
// Notes:
// About returning TYP_STRUCT:
// Whenever the return type is TYP_STRUCT it always means multiple registers

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.

Copy link
Author

@briansull briansull Jul 11, 2016

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/

Copy link

@RussKeldorph RussKeldorph Jul 11, 2016

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.

Copy link
Author

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)

@RussKeldorph
Copy link

RussKeldorph commented Jul 11, 2016

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.

// 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

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?

Copy link
Author

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.

@briansull briansull force-pushed the multireg-refactor branch from 3a0b626 to cae20f9 Compare July 11, 2016 20:09
@briansull
Copy link
Author

@dotnet-bot Test Windows_NT arm64 Checked

// 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.

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.

Copy link
Author

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.

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"?

Copy link
Author

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)
//

@briansull
Copy link
Author

@dotnet-bot Test Ubuntu x64 Checked Build and Test

@briansull briansull force-pushed the multireg-refactor branch from cae20f9 to 8ee7fe7 Compare July 11, 2016 23:29
@briansull
Copy link
Author

@dotnet-bot test Windows_NT arm64 Checked pri1r2r

@briansull
Copy link
Author

@dotnet-bot Test Windows_NT Arm64 Checked Pri1r2r

@briansull
Copy link
Author

@dotnet-bot Test Windows_NT arm64 Checked

@briansull
Copy link
Author

@dotnet-bot Test Windows_NT Arm64 Checked Pri1r2r

@CarolEidt
Copy link

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.
@briansull briansull force-pushed the multireg-refactor branch from 8ee7fe7 to 6530924 Compare July 12, 2016 01:39
@briansull
Copy link
Author

@dotnet-bot Test Windows_NT Arm64 Checked Pri1r2r

@briansull
Copy link
Author

@dotnet-bot Test Windows_NT arm64 Checked

1 similar comment
@briansull
Copy link
Author

@dotnet-bot Test Windows_NT arm64 Checked

@briansull
Copy link
Author

@dotnet-bot Test Linux ARM Emulator Cross Debug Build

@briansull
Copy link
Author

@dotnet-bot Test Windows_NT Arm64 Checked Pri1r2r

@briansull
Copy link
Author

@dotnet-bot Test Linux ARM Emulator Cross Release Build

@briansull
Copy link
Author

@dotnet-bot Test Linux ARM Emulator Cross Release Build

@briansull briansull merged commit b33bd67 into dotnet:master Jul 12, 2016
@briansull briansull deleted the multireg-refactor branch July 12, 2016 17:06
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Refactor and cleanup work for passing and returning struct types

Commit migrated from dotnet/coreclr@b33bd67
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants