Skip to content
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

Delete JitDoOldStructRetyping artifacts. #51092

Merged
merged 2 commits into from
Apr 13, 2021

Conversation

sandreenko
Copy link
Contributor

@sandreenko sandreenko commented Apr 12, 2021

Delete the code that was handling JitDoOldStructRetyping = true.

@sandreenko sandreenko added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 12, 2021
@sandreenko
Copy link
Contributor Author

/azp run runtime-coreclr jitstress

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@sandreenko
Copy link
Contributor Author

PTAL @dotnet/jit-contrib

Copy link
Member

@AndyAyersMS AndyAyersMS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to see all that code going away.

call->gtReturnType = returnType;
}
assert(returnType == TYP_STRUCT);
assert((howToReturnStruct == SPK_ByValueAsHfa) || (howToReturnStruct == SPK_ByValue));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is is a possible change in the functionality of this method before we were handling SPK_EnclosingType, now we don't.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SPK_EnclosingType becomes unreachable without compDoOldStructRetyping, I have added an assert that only SPK_ByValueAsHfa and SPK_ByValue can come here.

We used SPK_EnclosingType only for structs that are smaller than TARGET_POINTER_SIZE and we were retyping them as int/long, now we keep them as structs, so now need for this part.

The part that is left handles the multi-reg case.

{
GenTree* op1 = op->AsObj()->Addr();

// We will fold away OBJ/ADDR, except for OBJ/ADDR/INDEX
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your change here also removes this folding,
This doesn't seem to be directly related to compDoOldStructRetyping

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is also unreachable, the previous condition was:

if (!compDoOldStructRetyping() && (!op->IsCall() || !op->AsCall()->TreatAsHasRetBufArg(this)))

now it is

if (!op->IsCall() || !op->AsCall()->TreatAsHasRetBufArg(this))

so op can't be anything but call.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the SPK_EnclosingType clause in fgUpdateInlineReturnExpressionPlaceHolder also now unreachable? Would be nice if it was.

I pushed the change to delete the handling, there are no asm diffs but Jit log is smaller now.

Excellent. Thanks.

@AndyAyersMS
Copy link
Member

Is the SPK_EnclosingType clause in fgUpdateInlineReturnExpressionPlaceHolder also now unreachable? Would be nice if it was.

case SPK_EnclosingType:
{
// For enclosing type returns, we must return the call value to a temp since
// the return type is larger than the struct type.
if (!tree->IsCall())
{
break;
}
GenTreeCall* call = tree->AsCall();
assert(call->gtReturnType == TYP_STRUCT);
if (call->gtReturnType != TYP_STRUCT)
{
break;
}
JITDUMP("\nCall returns small struct via enclosing type, retyping. Before:\n");
DISPTREE(call);
// Create new struct typed temp for return value
const unsigned tmpNum =
comp->lvaGrabTemp(true DEBUGARG("small struct return temp for rejected inline"));
comp->lvaSetStruct(tmpNum, retClsHnd, false);
GenTree* assign = comp->gtNewTempAssign(tmpNum, call);
// Modify assign tree and call return types to the primitive return type
call->gtReturnType = returnType;
call->gtType = returnType;
assign->gtType = returnType;
// Modify the temp reference in the assign as a primitive reference via GT_LCL_FLD
GenTree* tempAsPrimitive = assign->AsOp()->gtOp1;
assert(tempAsPrimitive->gtOper == GT_LCL_VAR);
tempAsPrimitive->gtType = returnType;
tempAsPrimitive->ChangeOper(GT_LCL_FLD);
// Return temp as value of call tree via comma
GenTree* tempAsStruct = comp->gtNewLclvNode(tmpNum, TYP_STRUCT);
GenTree* comma = comp->gtNewOperNode(GT_COMMA, TYP_STRUCT, assign, tempAsStruct);
parent->ReplaceOperand(pTree, comma);
JITDUMP("\nAfter:\n");
DISPTREE(comma);
}
break;

@sandreenko
Copy link
Contributor Author

Is the SPK_EnclosingType clause in fgUpdateInlineReturnExpressionPlaceHolder also now unreachable? Would be nice if it was.

It is reachable but we don't need to do anything for it,

// If an inline was rejected and the call returns a struct, we may
// have deferred some work when importing call for cases where the
// struct is returned in register(s).
//
// See the bail-out clauses in impFixupCallStructReturn for inline
// candidates.
//
// Do the deferred work now.

we don't do retyping so there is no deferred work nowadays.

I pushed the change to delete the handling, there are no asm diffs but Jit log is smaller now.

For example, for

    [StructLayout(LayoutKind.Explicit, Size = 3)]
    public struct ThreeByteStruct
    {
        [FieldOffset(0)] public Byte b1;
        [FieldOffset(0)] public Byte b2;
        [FieldOffset(0)] public Byte b3;
    }


    static ThreeByteStruct Test2()
    {
        ThreeByteStruct s = new ThreeByteStruct();
        s.b1 = 1;
        s.b2 = 2;
        s.b3 = 3;
        return s;
    }

on unix x64 we have:

               [000004] -ACXG+------              *  ASG       struct (copy)
               [000002] D----+-N----              +--*  LCL_VAR   struct<ThreeByteStruct, 3> V01 tmp1         
               [000000] --CXG+------              \--*  CALL      struct TestMethodInfo.Tes

instead of

               [000004] -ACXG+------              *  ASG       struct (copy)
               [000002] D----+-N----              +--*  LCL_VAR   struct<ThreeByteStruct, 3> V01 tmp1         
               [000017] -ACXG+------              \--*  IND       struct
               [000015] -ACXG+------                 \--*  COMMA     byref 
               [000013] -ACXG+------                    +--*  ASG       int   
               [000011] U----+-N----                    |  +--*  LCL_FLD   int    V02 tmp2         [+0]
               [000000] --CXG+-N----                    |  \--*  CALL      int    TestMethodInfo.Test
               [000016] -----+------                    \--*  ADDR      byref 
               [000014] -----+-N----                       \--*  LCL_VAR   struct<ThreeByteStruct, 3> V02 tmp2 

Copy link
Contributor

@briansull briansull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks Good

@sandreenko sandreenko merged commit f9fcb8b into dotnet:main Apr 13, 2021
@JulieLeeMSFT JulieLeeMSFT added this to the 6.0.0 milestone Apr 15, 2021
@sandreenko sandreenko mentioned this pull request May 10, 2021
10 tasks
@ghost ghost locked as resolved and limited conversation to collaborators May 15, 2021
@sandreenko sandreenko deleted the deleteOldRetyping branch May 17, 2021 07:50
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants