Skip to content

Commit

Permalink
CORINFO_HELP_ASSIGN_STRUCT
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorBo committed Apr 30, 2024
1 parent aab8803 commit 1c9f3a4
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 5 deletions.
50 changes: 49 additions & 1 deletion src/coreclr/jit/assertionprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2769,7 +2769,50 @@ GenTree* Compiler::optVNBasedFoldExpr(BasicBlock* block, GenTree* parent, GenTre
case GT_CALL:
return optVNBasedFoldExpr_Call(block, parent, tree->AsCall());

// We can add more VN-based foldings here.
case GT_STORE_BLK:
{
if (!opts.IsReadyToRun())
{
// TODO: Implement CORINFO_HELP_ASSIGN_STRUCT for R2R/ILC
break;
}

// Replace STORE_BLK (struct copy) with CORINFO_HELP_ASSIGN_STRUCT which performs
// bulk copy for byrefs.
GenTreeBlk* blk = tree->AsBlk();
if (!blk->OperIsInitBlkOp() && blk->IsReverseOp() && (blk->GetLayout()->GetGCPtrCount() > 3))
{
GenTree* addr = blk->Addr();
GenTree* data = blk->Data();
if (data->OperIs(GT_BLK))
{
data = data->AsBlk()->Addr();
}
else
{
assert(data->OperIs(GT_LCL_VAR, GT_LCL_FLD));
}

// For now, we use it only for newly created objects where we know we don't have to
// be precise (from GC's point of view) and update card tables.
// For that, we expect addr to be "JIT_New + offset"
VNFuncApp funcApp;
if (vnStore->GetVNFunc(vnStore->VNLiberalNormalValue(addr->gtVNPair), &funcApp) &&
(funcApp.m_func == VNFunc(GT_ADD)) && vnStore->GetVNFunc(funcApp.m_args[0], &funcApp) &&
(funcApp.m_func == VNF_JitNew))
{
const unsigned gcPtrs = blk->GetLayout()->GetGCPtrCount();
if (!CheckedOps::MulOverflows((int)gcPtrs, TARGET_POINTER_SIZE, true))
{
GenTree* slots = gtNewIconNode((ssize_t)gcPtrs * TARGET_POINTER_SIZE, TYP_I_IMPL);
GenTreeCall* call = gtNewHelperCallNode(CORINFO_HELP_ASSIGN_STRUCT, TYP_VOID, data, addr, slots);
fgMorphArgs(call);
return call;
}
}
}
break;
}

default:
break;
Expand Down Expand Up @@ -6469,6 +6512,10 @@ Compiler::fgWalkResult Compiler::optVNBasedFoldCurStmt(BasicBlock* block,
// This can occur for HFA return values (see hfa_sf3E_r.exe)
if (tree->TypeGet() == TYP_STRUCT)
{
if (tree->OperIs(GT_STORE_BLK) && tree->AsBlk()->GetLayout()->HasGCPtr())
{
goto PERFORM_FOLD;
}
return WALK_CONTINUE;
}

Expand Down Expand Up @@ -6545,6 +6592,7 @@ Compiler::fgWalkResult Compiler::optVNBasedFoldCurStmt(BasicBlock* block,
// Unknown node, continue to walk.
return WALK_CONTINUE;
}
PERFORM_FOLD:

// Perform the VN-based folding:
GenTree* newTree = optVNBasedFoldExpr(block, parent, tree);
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/vm/jithelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4780,15 +4780,15 @@ HCIMPLEND
//========================================================================

/*************************************************************/
HCIMPL3(VOID, JIT_StructWriteBarrier, void *dest, void* src, CORINFO_CLASS_HANDLE typeHnd_)
HCIMPL3(VOID, JIT_StructWriteBarrier, void* src, void* dest, size_t byteSize)
{
FCALL_CONTRACT;

TypeHandle typeHnd(typeHnd_);
MethodTable *pMT = typeHnd.AsMethodTable();
_ASSERT(byteSize > 0);
_ASSERT((byteSize % TARGET_POINTER_SIZE) == 0);

HELPER_METHOD_FRAME_BEGIN_NOPOLL(); // Set up a frame
CopyValueClass(dest, src, pMT);
memmoveGCRefs(dest, src, byteSize);
HELPER_METHOD_FRAME_END_POLL();

}
Expand Down

0 comments on commit 1c9f3a4

Please sign in to comment.